I was able to find a copy of kernel-source-2.6.8_2.6.8-6_all.deb and compare it with kernel-source-2.6.8_2.6.8-7_all.deb. I don't know much about all of this, but it does seem suspicious that there were a number of "acpi" changes which appear to have resulted these errors that also contain "acpi": pciehp: acpi_pciehprm:get_device PCI ROOT HID fail=0x1001 shpchp: acpi_shpchprm:get_device PCI ROOT HID fail=0x1001 Output of diff -u is attached. -- Encrypted Mail Preferred: Key ID: 8527B9AF Key Fingerprint: E1B6 40B6 B73F 695E 0D3B 644E 6427 DD74 8527 B9AF Information: http://www.gnupg.org/ ASCII ribbon campaign: () against HTML email /\ against Microsoft attachments Information: http://www.expita.com/nomime.html
diff -ur kernel-source-2.6.8-6/Debian.src.changelog kernel-source-2.6.8-7/Debian.src.changelog --- kernel-source-2.6.8-6/Debian.src.changelog 2004-09-12 20:37:37.000000000 -0600 +++ kernel-source-2.6.8-7/Debian.src.changelog 2004-10-03 01:21:32.000000000 -0600 @@ -1,3 +1,37 @@ +kernel-source-2.6.8 (2.6.8-7) unstable; urgency=medium + + * Fix VGA console on PReP systems (closes: #271852) (Jens Schmalzing). + + * Really enable i915 agpgart support (Christoph Hellwig). + + * Fix yet another bio leak (Christoph Hellwig). + + * Switch /proc/sys/net/ipv4/tcp_default_win_scale default back to 0, there's + just too many broken system out there in the wild. (closes: #267342) + (Christoph Hellwig). + + * Fix ata_piix controller numbering in combined mode (closes: #270194) + (Christoph Hellwig). + + * Update tg3 driver (Christoph Hellwig). + + * Update forcedeth driver to fix autoneg on 100Mbit cards (Christoph Hellwig). + + * Fix ALSA module locking issue (closes: #259056) (Andres Salomon). + + * Build-fix for 3c59x without pci (closes: #267240) (Maximilian Attems). + + * Fix crash in ArcNet PCMCIA card (Maximilian Attems). + + * Build-fix for airo on smp (Maximilian Attems). + + * ACK old nmu (closes: #181350, #126482, #153451, #206984) + + * Back out acpi-early caused problems on laptops, where APIC should not + be enabled. (closes: #272177, #273474, #274011) (Maximilian Attems) + + -- Andres Salomon <dilinger@voxel.net> Sun, 03 Oct 2004 03:21:14 -0400 + kernel-source-2.6.8 (2.6.8-6) unstable; urgency=medium * reiserfs xattr/acl fix if root fs (Max Attems). diff -ur kernel-source-2.6.8-6/arch/i386/kernel/dmi_scan.c kernel-source-2.6.8-7/arch/i386/kernel/dmi_scan.c --- kernel-source-2.6.8-6/arch/i386/kernel/dmi_scan.c 2004-09-12 21:28:08.000000000 -0600 +++ kernel-source-2.6.8-7/arch/i386/kernel/dmi_scan.c 2004-10-03 01:33:14.000000000 -0600 @@ -162,6 +162,26 @@ #define NO_MATCH { DMI_NONE, NULL} #define MATCH DMI_MATCH +/* + * Some machines, usually laptops, can't handle an enabled local APIC. + * The symptoms include hangs or reboots when suspending or resuming, + * attaching or detaching the power cord, or entering BIOS setup screens + * through magic key sequences. + */ +static int __init local_apic_kills_bios(struct dmi_blacklist *d) +{ +#ifdef CONFIG_X86_LOCAL_APIC + extern int enable_local_apic; + if (enable_local_apic == 0) { + enable_local_apic = -1; + printk(KERN_WARNING "%s with broken BIOS detected. " + "Refusing to enable the local APIC.\n", + d->ident); + } +#endif + return 0; +} + /* * Toshiba keyboard likes to repeat keys when they are not repeated. @@ -266,6 +286,30 @@ /* Machines which have problems handling enabled local APICs */ + { local_apic_kills_bios, "Dell Inspiron", { + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Inspiron"), + NO_MATCH, NO_MATCH + } }, + + { local_apic_kills_bios, "Dell Latitude", { + MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + MATCH(DMI_PRODUCT_NAME, "Latitude"), + NO_MATCH, NO_MATCH + } }, + + { local_apic_kills_bios, "IBM Thinkpad T20", { + MATCH(DMI_BOARD_VENDOR, "IBM"), + MATCH(DMI_BOARD_NAME, "264741U"), + NO_MATCH, NO_MATCH + } }, + + { local_apic_kills_bios, "ASUS L3C", { + MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + MATCH(DMI_BOARD_NAME, "P4_L3C"), + NO_MATCH, NO_MATCH + } }, + { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */ MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), NO_MATCH, NO_MATCH, NO_MATCH diff -ur kernel-source-2.6.8-6/arch/ppc/boot/common/misc-common.c kernel-source-2.6.8-7/arch/ppc/boot/common/misc-common.c --- kernel-source-2.6.8-6/arch/ppc/boot/common/misc-common.c 2004-08-13 23:36:58.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/common/misc-common.c 2004-10-03 01:33:14.000000000 -0600 @@ -526,6 +526,11 @@ * on others it's an offset from a given location. -- Tom */ +void ISA_init(unsigned long base) +{ + ISA_io = (unsigned char *)base; +} + void outb(int port, unsigned char val) { diff -ur kernel-source-2.6.8-6/arch/ppc/boot/common/serial_stub.c kernel-source-2.6.8-7/arch/ppc/boot/common/serial_stub.c --- kernel-source-2.6.8-6/arch/ppc/boot/common/serial_stub.c 2004-08-13 23:38:08.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/common/serial_stub.c 2004-10-03 01:33:14.000000000 -0600 @@ -11,11 +11,6 @@ * is" without any warranty of any kind, whether express or implied. */ -void __attribute__ ((weak)) -serial_fixups(void) -{ -} - unsigned long __attribute__ ((weak)) serial_init(int chan, void *ignored) { diff -ur kernel-source-2.6.8-6/arch/ppc/boot/include/nonstdio.h kernel-source-2.6.8-7/arch/ppc/boot/include/nonstdio.h --- kernel-source-2.6.8-6/arch/ppc/boot/include/nonstdio.h 2004-08-13 23:36:56.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/include/nonstdio.h 2004-10-03 01:33:14.000000000 -0600 @@ -30,3 +30,5 @@ extern void puts(const char *); extern void udelay(long delay); extern unsigned char inb(int port); +extern void board_isa_init(void); +extern void ISA_init(unsigned long base); diff -ur kernel-source-2.6.8-6/arch/ppc/boot/simple/Makefile kernel-source-2.6.8-7/arch/ppc/boot/simple/Makefile --- kernel-source-2.6.8-6/arch/ppc/boot/simple/Makefile 2004-08-13 23:36:11.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/simple/Makefile 2004-10-03 01:33:14.000000000 -0600 @@ -73,7 +73,7 @@ zimageinitrd-$(CONFIG_GEMINI) := zImage.initrd-STRIPELF end-$(CONFIG_GEMINI) := gemini - extra.o-$(CONFIG_K2) := legacy.o + extra.o-$(CONFIG_K2) := prepmap.o end-$(CONFIG_K2) := k2 cacheflag-$(CONFIG_K2) := -include $(clear_L2_L3) @@ -89,7 +89,7 @@ end-$(motorola) := pplus # Overrides previous assingment - extra.o-$(CONFIG_PPLUS) := legacy.o + extra.o-$(CONFIG_PPLUS) := prepmap.o extra.o-$(CONFIG_LOPEC) := mpc10x_memory.o zimage-$(pcore) := zImage-STRIPELF @@ -100,7 +100,7 @@ zimage-$(CONFIG_PPC_PREP) := zImage-PPLUS zimageinitrd-$(CONFIG_PPC_PREP) := zImage.initrd-PPLUS - extra.o-$(CONFIG_PPC_PREP) := legacy.o + extra.o-$(CONFIG_PPC_PREP) := prepmap.o misc-$(CONFIG_PPC_PREP) += misc-prep.o mpc10x_memory.o end-$(CONFIG_PPC_PREP) := prep Only in kernel-source-2.6.8-6/arch/ppc/boot/simple: chrpmap.S Only in kernel-source-2.6.8-7/arch/ppc/boot/simple: chrpmap.c Only in kernel-source-2.6.8-6/arch/ppc/boot/simple: legacy.S diff -ur kernel-source-2.6.8-6/arch/ppc/boot/simple/misc-prep.c kernel-source-2.6.8-7/arch/ppc/boot/simple/misc-prep.c --- kernel-source-2.6.8-6/arch/ppc/boot/simple/misc-prep.c 2004-08-13 23:36:14.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/simple/misc-prep.c 2004-10-03 01:33:14.000000000 -0600 @@ -88,6 +88,7 @@ ofinit(OFW_interface); } + board_isa_init(); #if defined(CONFIG_VGA_CONSOLE) vga_init((unsigned char *)0xC0000000); #endif /* CONFIG_VGA_CONSOLE */ diff -ur kernel-source-2.6.8-6/arch/ppc/boot/simple/misc.c kernel-source-2.6.8-7/arch/ppc/boot/simple/misc.c --- kernel-source-2.6.8-6/arch/ppc/boot/simple/misc.c 2004-08-13 23:37:38.000000000 -0600 +++ kernel-source-2.6.8-7/arch/ppc/boot/simple/misc.c 2004-10-03 01:33:14.000000000 -0600 @@ -97,7 +97,6 @@ struct bi_record *rec; unsigned long initrd_loc, TotalMemory = 0; - serial_fixups(); #ifdef CONFIG_SERIAL_8250_CONSOLE com_port = serial_init(0, NULL); #endif @@ -268,10 +267,16 @@ return rec; } +void __attribute__ ((weak)) +board_isa_init(void) +{ +} + /* Allow decompress_kernel to be hooked into. This is the default. */ void * __attribute__ ((weak)) load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, void *ign1, void *ign2) { + board_isa_init(); return decompress_kernel(load_addr, num_words, cksum); } Only in kernel-source-2.6.8-7/arch/ppc/boot/simple: prepmap.c diff -ur kernel-source-2.6.8-6/drivers/acpi/bus.c kernel-source-2.6.8-7/drivers/acpi/bus.c --- kernel-source-2.6.8-6/drivers/acpi/bus.c 2004-09-12 21:28:08.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/acpi/bus.c 2004-10-03 01:33:14.000000000 -0600 @@ -590,9 +590,10 @@ } -void __init -acpi_early_init (void) +static int __init +acpi_bus_init (void) { + int result = 0; acpi_status status = AE_OK; struct acpi_buffer buffer = {sizeof(acpi_fadt), &acpi_fadt}; @@ -616,7 +617,7 @@ status = acpi_get_table(ACPI_TABLE_FADT, 1, &buffer); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to get the FADT\n"); - goto error0; + goto error1; } #ifdef CONFIG_X86 @@ -639,40 +640,12 @@ } #endif - status = acpi_enable_subsystem(~(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE)); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to enable ACPI\n"); - goto error0; - } - - return; - -error0: - disable_acpi(); - return; -} - -static int __init -acpi_bus_init (void) -{ - int result = 0; - acpi_status status = AE_OK; - extern acpi_status acpi_os_initialize1(void); - - ACPI_FUNCTION_TRACE("acpi_bus_init"); - - status = acpi_os_initialize1(); - - status = acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE); + status = acpi_enable_subsystem(ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Unable to start the ACPI Interpreter\n"); goto error1; } - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Unable to initialize ACPI OS objects\n"); - goto error1; - } #ifdef CONFIG_ACPI_EC /* * ACPI 2.0 requires the EC driver to be loaded and work before @@ -720,6 +693,7 @@ /* Mimic structured exception handling */ error1: acpi_terminate(); +error0: return_VALUE(-ENODEV); } diff -ur kernel-source-2.6.8-6/drivers/acpi/osl.c kernel-source-2.6.8-7/drivers/acpi/osl.c --- kernel-source-2.6.8-6/drivers/acpi/osl.c 2004-09-12 21:28:08.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/acpi/osl.c 2004-10-03 01:33:14.000000000 -0600 @@ -71,12 +71,6 @@ acpi_status acpi_os_initialize(void) { - return AE_OK; -} - -acpi_status -acpi_os_initialize1(void) -{ /* * Initialize PCI configuration space access, as we'll need to access * it while walking the namespace (bus 0 and root bridges w/ _BBNs). @@ -476,8 +470,6 @@ return AE_ERROR; } - BUG_ON(!raw_pci_ops); - result = raw_pci_ops->read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); @@ -504,8 +496,6 @@ return AE_ERROR; } - BUG_ON(!raw_pci_ops); - result = raw_pci_ops->write(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), reg, size, value); diff -ur kernel-source-2.6.8-6/drivers/char/agp/intel-agp.c kernel-source-2.6.8-7/drivers/char/agp/intel-agp.c --- kernel-source-2.6.8-6/drivers/char/agp/intel-agp.c 2004-08-13 23:36:58.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/char/agp/intel-agp.c 2004-10-03 01:33:14.000000000 -0600 @@ -1770,6 +1770,7 @@ ID(PCI_DEVICE_ID_INTEL_82875_HB), ID(PCI_DEVICE_ID_INTEL_7505_0), ID(PCI_DEVICE_ID_INTEL_7205_0), + ID(PCI_DEVICE_ID_INTEL_82915G_HB), { } }; diff -ur kernel-source-2.6.8-6/drivers/net/3c59x.c kernel-source-2.6.8-7/drivers/net/3c59x.c --- kernel-source-2.6.8-6/drivers/net/3c59x.c 2004-08-13 23:36:10.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/3c59x.c 2004-10-03 01:33:14.000000000 -0600 @@ -900,7 +900,9 @@ static void update_stats(long ioaddr, struct net_device *dev); static struct net_device_stats *vortex_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); +#ifdef CONFIG_PCI static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +#endif static void vortex_tx_timeout(struct net_device *dev); static void acpi_set_WOL(struct net_device *dev); static struct ethtool_ops vortex_ethtool_ops; @@ -1468,7 +1470,9 @@ dev->stop = vortex_close; dev->get_stats = vortex_get_stats; +#ifdef CONFIG_PCI dev->do_ioctl = vortex_ioctl; +#endif dev->ethtool_ops = &vortex_ethtool_ops; dev->set_multicast_list = set_rx_mode; dev->tx_timeout = vortex_tx_timeout; @@ -2868,6 +2872,7 @@ .get_drvinfo = vortex_get_drvinfo, }; +#ifdef CONFIG_PCI static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct vortex_private *vp = netdev_priv(dev); @@ -2925,6 +2930,7 @@ return err; } +#endif /* Pre-Cyclone chips have no documented multicast filter, so the only diff -ur kernel-source-2.6.8-6/drivers/net/arcnet/arcnet.c kernel-source-2.6.8-7/drivers/net/arcnet/arcnet.c --- kernel-source-2.6.8-6/drivers/net/arcnet/arcnet.c 2004-08-13 23:37:26.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/arcnet/arcnet.c 2004-10-03 01:33:14.000000000 -0600 @@ -401,7 +401,8 @@ lp->rfc1201.sequence = 1; /* bring up the hardware driver */ - lp->hw.open(dev); + if (lp->hw.open) + lp->hw.open(dev); if (dev->dev_addr[0] == 0) BUGMSG(D_NORMAL, "WARNING! Station address 00 is reserved " diff -ur kernel-source-2.6.8-6/drivers/net/forcedeth.c kernel-source-2.6.8-7/drivers/net/forcedeth.c --- kernel-source-2.6.8-6/drivers/net/forcedeth.c 2004-08-13 23:36:12.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/forcedeth.c 2004-10-03 01:33:14.000000000 -0600 @@ -75,6 +75,7 @@ * added CK804/MCP04 device IDs, code fixes * for registers, link status and other minor fixes. * 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe + * 0.29: 31 Aug 2004: Add backup timer for link change notification. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -86,7 +87,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.28" +#define FORCEDETH_VERSION "0.29" #define DRV_NAME "forcedeth" #include <linux/module.h> @@ -120,10 +121,11 @@ * Hardware access: */ -#define DEV_NEED_LASTPACKET1 0x0001 -#define DEV_IRQMASK_1 0x0002 -#define DEV_IRQMASK_2 0x0004 -#define DEV_NEED_TIMERIRQ 0x0008 +#define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ +#define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ +#define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ +#define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */ +#define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */ enum { NvRegIrqStatus = 0x000, @@ -367,6 +369,7 @@ #define OOM_REFILL (1+HZ/20) #define POLL_WAIT (1+HZ/100) +#define LINK_TIMEOUT (3*HZ) #define DESC_VER_1 0x0 #define DESC_VER_2 0x02100 @@ -446,6 +449,11 @@ struct timer_list oom_kick; struct timer_list nic_poll; + /* media detection workaround. + * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); + */ + int need_linktimer; + unsigned long link_timeout; /* * tx specific fields. */ @@ -1384,6 +1392,25 @@ return retval; } +static void nv_linkchange(struct net_device *dev) +{ + if (nv_update_linkspeed(dev)) { + if (netif_carrier_ok(dev)) { + nv_stop_rx(dev); + } else { + netif_carrier_on(dev); + printk(KERN_INFO "%s: link up.\n", dev->name); + } + nv_start_rx(dev); + } else { + if (netif_carrier_ok(dev)) { + netif_carrier_off(dev); + printk(KERN_INFO "%s: link down.\n", dev->name); + nv_stop_rx(dev); + } + } +} + static void nv_link_irq(struct net_device *dev) { u8 *base = get_hwbase(dev); @@ -1391,25 +1418,10 @@ miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); - dprintk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat); + dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat); - if (miistat & (NVREG_MIISTAT_LINKCHANGE)) { - if (nv_update_linkspeed(dev)) { - if (netif_carrier_ok(dev)) { - nv_stop_rx(dev); - } else { - netif_carrier_on(dev); - printk(KERN_INFO "%s: link up.\n", dev->name); - } - nv_start_rx(dev); - } else { - if (netif_carrier_ok(dev)) { - netif_carrier_off(dev); - printk(KERN_INFO "%s: link down.\n", dev->name); - nv_stop_rx(dev); - } - } - } + if (miistat & (NVREG_MIISTAT_LINKCHANGE)) + nv_linkchange(dev); dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } @@ -1452,6 +1464,12 @@ nv_link_irq(dev); spin_unlock(&np->lock); } + if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { + spin_lock(&np->lock); + nv_linkchange(dev); + spin_unlock(&np->lock); + np->link_timeout = jiffies + LINK_TIMEOUT; + } if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); @@ -1816,6 +1834,14 @@ np->irqmask = NVREG_IRQMASK_WANTED_2; if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; + if (id->driver_data & DEV_NEED_LINKTIMER) { + dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev)); + np->need_linktimer = 1; + np->link_timeout = jiffies + LINK_TIMEOUT; + } else { + dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev)); + np->need_linktimer = 0; + } /* find a suitable phy */ for (i = 1; i < 32; i++) { @@ -1909,21 +1935,21 @@ .device = PCI_DEVICE_ID_NVIDIA_NVENET_1, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ, + .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce2 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, .device = PCI_DEVICE_ID_NVIDIA_NVENET_2, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce3 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, .device = PCI_DEVICE_ID_NVIDIA_NVENET_3, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce3 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, diff -ur kernel-source-2.6.8-6/drivers/net/tg3.c kernel-source-2.6.8-7/drivers/net/tg3.c --- kernel-source-2.6.8-6/drivers/net/tg3.c 2004-09-12 21:28:07.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/tg3.c 2004-10-03 01:33:14.000000000 -0600 @@ -60,8 +60,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.8" -#define DRV_MODULE_RELDATE "July 14, 2004" +#define DRV_MODULE_VERSION "3.10" +#define DRV_MODULE_RELDATE "September 14, 2004" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -445,9 +445,14 @@ 0x1f); tp->pci_clock_ctrl = clock_ctrl; - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 && - (orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { + if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) { + tw32_f(TG3PCI_CLOCK_CTRL, + clock_ctrl | CLOCK_CTRL_625_CORE); + udelay(40); + } + } else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) { tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK)); @@ -983,7 +988,7 @@ tp->link_config.orig_autoneg = tp->link_config.autoneg; } - if (tp->phy_id != PHY_ID_SERDES) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { tp->link_config.speed = SPEED_10; tp->link_config.duplex = DUPLEX_HALF; tp->link_config.autoneg = AUTONEG_ENABLE; @@ -995,7 +1000,7 @@ if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { u32 mac_mode; - if (tp->phy_id != PHY_ID_SERDES) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a); udelay(40); @@ -1117,29 +1122,33 @@ u32 old_rx_mode = tp->rx_mode; u32 old_tx_mode = tp->tx_mode; - if (local_adv & ADVERTISE_PAUSE_CAP) { - if (local_adv & ADVERTISE_PAUSE_ASYM) { - if (remote_adv & LPA_PAUSE_CAP) - new_tg3_flags |= - (TG3_FLAG_RX_PAUSE | - TG3_FLAG_TX_PAUSE); - else if (remote_adv & LPA_PAUSE_ASYM) - new_tg3_flags |= - (TG3_FLAG_RX_PAUSE); - } else { - if (remote_adv & LPA_PAUSE_CAP) - new_tg3_flags |= - (TG3_FLAG_RX_PAUSE | - TG3_FLAG_TX_PAUSE); + if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) { + if (local_adv & ADVERTISE_PAUSE_CAP) { + if (local_adv & ADVERTISE_PAUSE_ASYM) { + if (remote_adv & LPA_PAUSE_CAP) + new_tg3_flags |= + (TG3_FLAG_RX_PAUSE | + TG3_FLAG_TX_PAUSE); + else if (remote_adv & LPA_PAUSE_ASYM) + new_tg3_flags |= + (TG3_FLAG_RX_PAUSE); + } else { + if (remote_adv & LPA_PAUSE_CAP) + new_tg3_flags |= + (TG3_FLAG_RX_PAUSE | + TG3_FLAG_TX_PAUSE); + } + } else if (local_adv & ADVERTISE_PAUSE_ASYM) { + if ((remote_adv & LPA_PAUSE_CAP) && + (remote_adv & LPA_PAUSE_ASYM)) + new_tg3_flags |= TG3_FLAG_TX_PAUSE; } - } else if (local_adv & ADVERTISE_PAUSE_ASYM) { - if ((remote_adv & LPA_PAUSE_CAP) && - (remote_adv & LPA_PAUSE_ASYM)) - new_tg3_flags |= TG3_FLAG_TX_PAUSE; - } - tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE); - tp->tg3_flags |= new_tg3_flags; + tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE); + tp->tg3_flags |= new_tg3_flags; + } else { + new_tg3_flags = tp->tg3_flags; + } if (new_tg3_flags & TG3_FLAG_RX_PAUSE) tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE; @@ -1490,6 +1499,18 @@ current_speed = SPEED_INVALID; current_duplex = DUPLEX_INVALID; + if (tp->tg3_flags2 & TG3_FLG2_CAPACITIVE_COUPLING) { + u32 val; + + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007); + tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); + if (!(val & (1 << 10))) { + val |= (1 << 10); + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + goto relink; + } + } + bmsr = 0; for (i = 0; i < 100; i++) { tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1569,7 +1590,7 @@ tg3_setup_flow_control(tp, local_adv, remote_adv); } } - +relink: if (current_link_up == 0) { u32 tmp; @@ -1619,7 +1640,7 @@ tw32_f(MAC_MODE, tp->mac_mode); udelay(40); - if (tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES)) { + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { /* Polled via timer. */ tw32_f(MAC_EVENT, 0); } else { @@ -1968,62 +1989,264 @@ static int fiber_autoneg(struct tg3 *tp, u32 *flags) { int res = 0; + struct tg3_fiber_aneginfo aninfo; + int status = ANEG_FAILED; + unsigned int tick; + u32 tmp; - if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) { - u32 dig_status; + tw32_f(MAC_TX_AUTO_NEG, 0); - dig_status = tr32(SG_DIG_STATUS); - *flags = 0; - if (dig_status & SG_DIG_PARTNER_ASYM_PAUSE) - *flags |= MR_LP_ADV_ASYM_PAUSE; - if (dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE) - *flags |= MR_LP_ADV_SYM_PAUSE; - - if ((dig_status & SG_DIG_AUTONEG_COMPLETE) && - !(dig_status & (SG_DIG_AUTONEG_ERROR | - SG_DIG_PARTNER_FAULT_MASK))) - res = 1; - } else { - struct tg3_fiber_aneginfo aninfo; - int status = ANEG_FAILED; - unsigned int tick; - u32 tmp; + tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; + tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); + udelay(40); - tw32_f(MAC_TX_AUTO_NEG, 0); + tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); + udelay(40); - tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK; - tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII); - udelay(40); + memset(&aninfo, 0, sizeof(aninfo)); + aninfo.flags |= MR_AN_ENABLE; + aninfo.state = ANEG_STATE_UNKNOWN; + aninfo.cur_time = 0; + tick = 0; + while (++tick < 195000) { + status = tg3_fiber_aneg_smachine(tp, &aninfo); + if (status == ANEG_DONE || status == ANEG_FAILED) + break; - tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS); - udelay(40); + udelay(1); + } - memset(&aninfo, 0, sizeof(aninfo)); - aninfo.flags |= MR_AN_ENABLE; - aninfo.state = ANEG_STATE_UNKNOWN; - aninfo.cur_time = 0; - tick = 0; - while (++tick < 195000) { - status = tg3_fiber_aneg_smachine(tp, &aninfo); - if (status == ANEG_DONE || status == ANEG_FAILED) - break; + tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; + tw32_f(MAC_MODE, tp->mac_mode); + udelay(40); - udelay(1); + *flags = aninfo.flags; + + if (status == ANEG_DONE && + (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | + MR_LP_ADV_FULL_DUPLEX))) + res = 1; + + return res; +} + +static void tg3_init_bcm8002(struct tg3 *tp) +{ + u32 mac_status = tr32(MAC_STATUS); + int i; + + /* Reset when initting first time or we have a link. */ + if ((tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) && + !(mac_status & MAC_STATUS_PCS_SYNCED)) + return; + + /* Set PLL lock range. */ + tg3_writephy(tp, 0x16, 0x8007); + + /* SW reset */ + tg3_writephy(tp, MII_BMCR, BMCR_RESET); + + /* Wait for reset to complete. */ + /* XXX schedule_timeout() ... */ + for (i = 0; i < 500; i++) + udelay(10); + + /* Config mode; select PMA/Ch 1 regs. */ + tg3_writephy(tp, 0x10, 0x8411); + + /* Enable auto-lock and comdet, select txclk for tx. */ + tg3_writephy(tp, 0x11, 0x0a10); + + tg3_writephy(tp, 0x18, 0x00a0); + tg3_writephy(tp, 0x16, 0x41ff); + + /* Assert and deassert POR. */ + tg3_writephy(tp, 0x13, 0x0400); + udelay(40); + tg3_writephy(tp, 0x13, 0x0000); + + tg3_writephy(tp, 0x11, 0x0a50); + udelay(40); + tg3_writephy(tp, 0x11, 0x0a10); + + /* Wait for signal to stabilize */ + /* XXX schedule_timeout() ... */ + for (i = 0; i < 15000; i++) + udelay(10); + + /* Deselect the channel register so we can read the PHYID + * later. + */ + tg3_writephy(tp, 0x10, 0x8011); +} + +static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status) +{ + u32 sg_dig_ctrl, sg_dig_status; + u32 serdes_cfg, expected_sg_dig_ctrl; + int workaround, port_a; + int current_link_up; + + serdes_cfg = 0; + expected_sg_dig_ctrl = 0; + workaround = 0; + port_a = 1; + current_link_up = 0; + + if (tp->pci_chip_rev_id != CHIPREV_ID_5704_A0 && + tp->pci_chip_rev_id != CHIPREV_ID_5704_A1) { + workaround = 1; + if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) + port_a = 0; + + serdes_cfg = tr32(MAC_SERDES_CFG) & + ((1 << 23) | (1 << 22) | (1 << 21) | (1 << 20)); + } + + sg_dig_ctrl = tr32(SG_DIG_CTRL); + + if (tp->link_config.autoneg != AUTONEG_ENABLE) { + if (sg_dig_ctrl & (1 << 31)) { + if (workaround) { + u32 val = serdes_cfg; + + if (port_a) + val |= 0xc010880; + else + val |= 0x4010880; + tw32_f(MAC_SERDES_CFG, val); + } + tw32_f(SG_DIG_CTRL, 0x01388400); } + if (mac_status & MAC_STATUS_PCS_SYNCED) { + tg3_setup_flow_control(tp, 0, 0); + current_link_up = 1; + } + goto out; + } - tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS; - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); + /* Want auto-negotiation. */ + expected_sg_dig_ctrl = 0x81388400; + + /* Pause capability */ + expected_sg_dig_ctrl |= (1 << 11); + + /* Asymettric pause */ + expected_sg_dig_ctrl |= (1 << 12); + + if (sg_dig_ctrl != expected_sg_dig_ctrl) { + if (workaround) + tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011880); + tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30)); + udelay(5); + tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl); + + tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED; + } else if (mac_status & (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_SIGNAL_DET)) { + sg_dig_status = tr32(SG_DIG_STATUS); + + if ((sg_dig_status & (1 << 1)) && + (mac_status & MAC_STATUS_PCS_SYNCED)) { + u32 local_adv, remote_adv; + + local_adv = ADVERTISE_PAUSE_CAP; + remote_adv = 0; + if (sg_dig_status & (1 << 19)) + remote_adv |= LPA_PAUSE_CAP; + if (sg_dig_status & (1 << 20)) + remote_adv |= LPA_PAUSE_ASYM; + + tg3_setup_flow_control(tp, local_adv, remote_adv); + current_link_up = 1; + tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + } else if (!(sg_dig_status & (1 << 1))) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) + tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED; + else { + if (workaround) { + u32 val = serdes_cfg; + + if (port_a) + val |= 0xc010880; + else + val |= 0x4010880; - *flags = aninfo.flags; + tw32_f(MAC_SERDES_CFG, val); + } - if (status == ANEG_DONE && - (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK | - MR_LP_ADV_FULL_DUPLEX))) - res = 1; + tw32_f(SG_DIG_CTRL, 0x01388400); + udelay(40); + + mac_status = tr32(MAC_STATUS); + if (mac_status & MAC_STATUS_PCS_SYNCED) { + tg3_setup_flow_control(tp, 0, 0); + current_link_up = 1; + } + } + } } - return res; +out: + return current_link_up; +} + +static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) +{ + int current_link_up = 0; + + if (!(mac_status & MAC_STATUS_PCS_SYNCED)) { + tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; + goto out; + } + + if (tp->link_config.autoneg == AUTONEG_ENABLE) { + u32 flags; + int i; + + if (fiber_autoneg(tp, &flags)) { + u32 local_adv, remote_adv; + + local_adv = ADVERTISE_PAUSE_CAP; + remote_adv = 0; + if (flags & MR_LP_ADV_SYM_PAUSE) + remote_adv |= LPA_PAUSE_CAP; + if (flags & MR_LP_ADV_ASYM_PAUSE) + remote_adv |= LPA_PAUSE_ASYM; + + tg3_setup_flow_control(tp, local_adv, remote_adv); + + tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; + current_link_up = 1; + } + for (i = 0; i < 30; i++) { + udelay(20); + tw32_f(MAC_STATUS, + (MAC_STATUS_SYNC_CHANGED | + MAC_STATUS_CFG_CHANGED)); + udelay(40); + if ((tr32(MAC_STATUS) & + (MAC_STATUS_SYNC_CHANGED | + MAC_STATUS_CFG_CHANGED)) == 0) + break; + } + + mac_status = tr32(MAC_STATUS); + if (current_link_up == 0 && + (mac_status & MAC_STATUS_PCS_SYNCED) && + !(mac_status & MAC_STATUS_RCVD_CFG)) + current_link_up = 1; + } else { + /* Forcing 1000FD link up. */ + current_link_up = 1; + tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; + + tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); + udelay(40); + } + +out: + return current_link_up; } static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset) @@ -2031,6 +2254,7 @@ u32 orig_pause_cfg; u16 orig_active_speed; u8 orig_active_duplex; + u32 mac_status; int current_link_up; int i; @@ -2040,118 +2264,43 @@ orig_active_speed = tp->link_config.active_speed; orig_active_duplex = tp->link_config.active_duplex; - tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); - tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); - - if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) { - /* Allow time for the hardware to auto-negotiate (195ms) */ - unsigned int tick = 0; - - while (++tick < 195000) { - if (tr32(SG_DIG_STATUS) & SG_DIG_AUTONEG_COMPLETE) - break; - udelay(1); + if (!(tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) && + netif_carrier_ok(tp->dev) && + (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) { + mac_status = tr32(MAC_STATUS); + mac_status &= (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_SIGNAL_DET | + MAC_STATUS_CFG_CHANGED | + MAC_STATUS_RCVD_CFG); + if (mac_status == (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_SIGNAL_DET)) { + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | + MAC_STATUS_CFG_CHANGED)); + return 0; } - if (tick >= 195000) - printk(KERN_INFO PFX "%s: HW autoneg failed !\n", - tp->dev->name); } - /* Reset when initting first time or we have a link. */ - if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) || - (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) { - /* Set PLL lock range. */ - tg3_writephy(tp, 0x16, 0x8007); - - /* SW reset */ - tg3_writephy(tp, MII_BMCR, BMCR_RESET); - - /* Wait for reset to complete. */ - /* XXX schedule_timeout() ... */ - for (i = 0; i < 500; i++) - udelay(10); - - /* Config mode; select PMA/Ch 1 regs. */ - tg3_writephy(tp, 0x10, 0x8411); - - /* Enable auto-lock and comdet, select txclk for tx. */ - tg3_writephy(tp, 0x11, 0x0a10); - - tg3_writephy(tp, 0x18, 0x00a0); - tg3_writephy(tp, 0x16, 0x41ff); + tw32_f(MAC_TX_AUTO_NEG, 0); - /* Assert and deassert POR. */ - tg3_writephy(tp, 0x13, 0x0400); - udelay(40); - tg3_writephy(tp, 0x13, 0x0000); - - tg3_writephy(tp, 0x11, 0x0a50); - udelay(40); - tg3_writephy(tp, 0x11, 0x0a10); - - /* Wait for signal to stabilize */ - /* XXX schedule_timeout() ... */ - for (i = 0; i < 15000; i++) - udelay(10); + tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX); + tp->mac_mode |= MAC_MODE_PORT_MODE_TBI; + tw32_f(MAC_MODE, tp->mac_mode); + udelay(40); - /* Deselect the channel register so we can read the PHYID - * later. - */ - tg3_writephy(tp, 0x10, 0x8011); - } + if (tp->phy_id == PHY_ID_BCM8002) + tg3_init_bcm8002(tp); - /* Enable link change interrupt unless serdes polling. */ - if (!(tp->tg3_flags & TG3_FLAG_POLL_SERDES)) - tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); - else - tw32_f(MAC_EVENT, 0); + /* Enable link change event even when serdes polling. */ + tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED); udelay(40); current_link_up = 0; - if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) { - if (tp->link_config.autoneg == AUTONEG_ENABLE) { - u32 flags; - - if (fiber_autoneg(tp, &flags)) { - u32 local_adv, remote_adv; - - local_adv = ADVERTISE_PAUSE_CAP; - remote_adv = 0; - if (flags & MR_LP_ADV_SYM_PAUSE) - remote_adv |= LPA_PAUSE_CAP; - if (flags & MR_LP_ADV_ASYM_PAUSE) - remote_adv |= LPA_PAUSE_ASYM; - - tg3_setup_flow_control(tp, local_adv, remote_adv); + mac_status = tr32(MAC_STATUS); - tp->tg3_flags |= - TG3_FLAG_GOT_SERDES_FLOWCTL; - current_link_up = 1; - } - for (i = 0; i < 60; i++) { - udelay(20); - tw32_f(MAC_STATUS, - (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)); - udelay(40); - if ((tr32(MAC_STATUS) & - (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)) == 0) - break; - } - if (current_link_up == 0 && - (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) { - current_link_up = 1; - } - } else { - /* Forcing 1000FD link up. */ - current_link_up = 1; - tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; - } - } else - tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; + if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) + current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status); + else + current_link_up = tg3_setup_fiber_by_hand(tp, mac_status); tp->mac_mode &= ~MAC_MODE_LINK_POLARITY; tw32_f(MAC_MODE, tp->mac_mode); @@ -2162,19 +2311,24 @@ (tp->hw_status->status & ~SD_STATUS_LINK_CHG)); for (i = 0; i < 100; i++) { - udelay(20); - tw32_f(MAC_STATUS, - (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)); - udelay(40); - if ((tr32(MAC_STATUS) & - (MAC_STATUS_SYNC_CHANGED | - MAC_STATUS_CFG_CHANGED)) == 0) + tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED | + MAC_STATUS_CFG_CHANGED)); + udelay(5); + if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED | + MAC_STATUS_CFG_CHANGED)) == 0) break; } - if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) + mac_status = tr32(MAC_STATUS); + if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) { current_link_up = 0; + if (tp->link_config.autoneg == AUTONEG_ENABLE) { + tw32_f(MAC_MODE, (tp->mac_mode | + MAC_MODE_SEND_CONFIGS)); + udelay(1); + tw32_f(MAC_MODE, tp->mac_mode); + } + } if (current_link_up == 1) { tp->link_config.active_speed = SPEED_1000; @@ -2206,15 +2360,6 @@ tg3_link_report(tp); } - if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) { - tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY); - udelay(40); - if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { - tw32_f(MAC_MODE, tp->mac_mode); - udelay(40); - } - } - return 0; } @@ -2222,7 +2367,7 @@ { int err; - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { err = tg3_setup_fiber_phy(tp, force_reset); } else { err = tg3_setup_copper_phy(tp, force_reset); @@ -2741,11 +2886,11 @@ tg3_halt(tp); tg3_init_hw(tp); + tg3_netif_start(tp); + spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - if (restart_timer) mod_timer(&tp->timer, jiffies + 1); } @@ -2815,6 +2960,7 @@ dma_addr_t mapping, int len, u32 flags, u32 mss_and_is_end) { + struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry]; int is_end = (mss_and_is_end & 0x1); u32 mss = (mss_and_is_end >> 1); u32 vlan_tag = 0; @@ -2826,35 +2972,11 @@ flags &= 0xffff; } vlan_tag |= (mss << TXD_MSS_SHIFT); - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry]; - txd->addr_hi = ((u64) mapping >> 32); - txd->addr_lo = ((u64) mapping & 0xffffffff); - txd->len_flags = (len << TXD_LEN_SHIFT) | flags; - txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; - } else { - struct tx_ring_info *txr = &tp->tx_buffers[entry]; - unsigned long txd; - - txd = (tp->regs + - NIC_SRAM_WIN_BASE + - NIC_SRAM_TX_BUFFER_DESC); - txd += (entry * TXD_SIZE); - - /* Save some PIOs */ - if (sizeof(dma_addr_t) != sizeof(u32)) - writel(((u64) mapping >> 32), - txd + TXD_ADDR + TG3_64BIT_REG_HIGH); - - writel(((u64) mapping & 0xffffffff), - txd + TXD_ADDR + TG3_64BIT_REG_LOW); - writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS); - if (txr->prev_vlan_tag != vlan_tag) { - writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG); - txr->prev_vlan_tag = vlan_tag; - } - } + txd->addr_hi = ((u64) mapping >> 32); + txd->addr_lo = ((u64) mapping & 0xffffffff); + txd->len_flags = (len << TXD_LEN_SHIFT) | flags; + txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT; } static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) @@ -3043,19 +3165,7 @@ } /* Packets are ready, update Tx producer idx local and on card. */ - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + - TG3_64BIT_REG_LOW), entry); - } else { - /* First, make sure tg3 sees last descriptor fully - * in SRAM. - */ - if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) - tr32(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW); - - tw32_tx_mbox((MAILBOX_SNDNIC_PROD_IDX_0 + - TG3_64BIT_REG_LOW), entry); - } + tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); tp->tx_prod = entry; if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) @@ -3105,9 +3215,10 @@ tg3_init_hw(tp); + tg3_netif_start(tp); + spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); return 0; } @@ -3193,7 +3304,6 @@ */ static void tg3_init_rings(struct tg3 *tp) { - unsigned long start, end; u32 i; /* Free up all the SKBs. */ @@ -3203,21 +3313,7 @@ memset(tp->rx_std, 0, TG3_RX_RING_BYTES); memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES); memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); - - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); - } else { - start = (tp->regs + - NIC_SRAM_WIN_BASE + - NIC_SRAM_TX_BUFFER_DESC); - end = start + TG3_TX_RING_BYTES; - while (start < end) { - writel(0, start); - start += 4; - } - for (i = 0; i < TG3_TX_RING_SIZE; i++) - tp->tx_buffers[i].prev_vlan_tag = 0; - } + memset(tp->tx_ring, 0, TG3_TX_RING_BYTES); /* Initialize invariants of the rings, we only set this * stuff once. This works because the card does not @@ -3348,15 +3444,10 @@ if (!tp->rx_rcb) goto err_out; - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES, - &tp->tx_desc_mapping); - if (!tp->tx_ring) - goto err_out; - } else { - tp->tx_ring = NULL; - tp->tx_desc_mapping = 0; - } + tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES, + &tp->tx_desc_mapping); + if (!tp->tx_ring) + goto err_out; tp->hw_status = pci_alloc_consistent(tp->pdev, TG3_HW_STATUS_SIZE, @@ -3598,6 +3689,8 @@ } } +static void tg3_stop_fw(struct tg3 *); + /* tp->lock is held. */ static int tg3_chip_reset(struct tg3 *tp) { @@ -3605,7 +3698,7 @@ u32 flags_save; int i; - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) tg3_nvram_lock(tp); /* @@ -3700,6 +3793,11 @@ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A3) { + tg3_stop_fw(tp); + tw32(0x5000, 0x400); + } + tw32(GRC_MODE, tp->grc_mode); if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) { @@ -3716,7 +3814,7 @@ tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tp->mac_mode = MAC_MODE_PORT_MODE_TBI; tw32_f(MAC_MODE, tp->mac_mode); } else @@ -3731,7 +3829,7 @@ udelay(10); } if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { + !(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " "firmware will not restart magic=%08x\n", tp->dev->name, val); @@ -4314,10 +4412,7 @@ GRC_MODE_4X_NIC_SEND_RINGS | GRC_MODE_NO_TX_PHDR_CSUM | GRC_MODE_NO_RX_PHDR_CSUM); - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) - tp->grc_mode |= GRC_MODE_HOST_SENDBDS; - else - tp->grc_mode |= GRC_MODE_4X_NIC_SEND_RINGS; + tp->grc_mode |= GRC_MODE_HOST_SENDBDS; if (tp->tg3_flags & TG3_FLAG_NO_TX_PSEUDO_CSUM) tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; if (tp->tg3_flags & TG3_FLAG_NO_RX_PSEUDO_CSUM) @@ -4470,18 +4565,11 @@ tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0); - if (tp->tg3_flags & TG3_FLAG_HOST_TXDS) { - tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, - tp->tx_desc_mapping, - (TG3_TX_RING_SIZE << - BDINFO_FLAGS_MAXLEN_SHIFT), - NIC_SRAM_TX_BUFFER_DESC); - } else { - tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, - 0, - BDINFO_FLAGS_DISABLED, - NIC_SRAM_TX_BUFFER_DESC); - } + tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB, + tp->tx_desc_mapping, + (TG3_TX_RING_SIZE << + BDINFO_FLAGS_MAXLEN_SHIFT), + NIC_SRAM_TX_BUFFER_DESC); /* There is only one receive return ring on 5705/5750, no need * to explicitly disable the others. @@ -4747,14 +4835,14 @@ tw32(MAC_LED_CTRL, tp->led_ctrl); tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tw32_f(MAC_RX_MODE, RX_MODE_RESET); udelay(10); } tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { /* Set drive transmission level to 1.2V */ val = tr32(MAC_SERDES_CFG); @@ -4772,22 +4860,8 @@ tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2); if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - tp->phy_id == PHY_ID_SERDES) { - /* Enable hardware link auto-negotiation */ - u32 digctrl, txctrl; - - digctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_CRC16_CLEAR_N | - SG_DIG_LOCAL_DUPLEX_STATUS | SG_DIG_LOCAL_LINK_STATUS | - (2 << SG_DIG_SPEED_STATUS_SHIFT) | SG_DIG_FIBER_MODE | - SG_DIG_GBIC_ENABLE; - - txctrl = tr32(MAC_SERDES_CFG); - tw32_f(MAC_SERDES_CFG, txctrl | MAC_SERDES_CFG_EDGE_SELECT); - tw32_f(SG_DIG_CTRL, digctrl | SG_DIG_SOFT_RESET); - tr32(SG_DIG_CTRL); - udelay(5); - tw32_f(SG_DIG_CTRL, digctrl); - + (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { + /* Use hardware link auto-negotiation */ tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG; } @@ -4795,7 +4869,7 @@ if (err) return err; - if (tp->phy_id != PHY_ID_SERDES) { + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { u32 tmp; /* Clear CRC stats. */ @@ -4987,7 +5061,8 @@ need_setup = 1; } if (! netif_carrier_ok(tp->dev) && - (mac_stat & MAC_STATUS_PCS_SYNCED)) { + (mac_stat & (MAC_STATUS_PCS_SYNCED | + MAC_STATUS_SIGNAL_DET))) { need_setup = 1; } if (need_setup) { @@ -5040,8 +5115,8 @@ spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - /* If you move this call, make sure TG3_FLAG_HOST_TXDS in - * tp->tg3_flags is accurate at that new place. + /* The placement of this call is tied + * to the setup and use of Host TX descriptors. */ err = tg3_alloc_consistent(tp); if (err) @@ -5383,7 +5458,7 @@ { struct tg3_hw_stats *hw_stats = tp->hw_stats; - if (tp->phy_id != PHY_ID_SERDES && + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { unsigned long flags; @@ -5814,7 +5889,7 @@ cmd->supported |= (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); - if (tp->phy_id != PHY_ID_SERDES) + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_10baseT_Half | @@ -5843,7 +5918,7 @@ tp->link_config.phy_is_low_power) return -EAGAIN; - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { /* These are the only valid advertisement bits allowed. */ if (cmd->autoneg == AUTONEG_ENABLE && (cmd->advertising & ~(ADVERTISED_1000baseT_Half | @@ -5901,7 +5976,7 @@ if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; if ((wol->wolopts & WAKE_MAGIC) && - tp->phy_id == PHY_ID_SERDES && + tp->tg3_flags2 & TG3_FLG2_PHY_SERDES && !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) return -EINVAL; @@ -5997,10 +6072,9 @@ tg3_halt(tp); tg3_init_hw(tp); - netif_wake_queue(tp->dev); + tg3_netif_start(tp); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); return 0; } @@ -6010,8 +6084,8 @@ struct tg3 *tp = netdev_priv(dev); epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0; - epause->rx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_RX) != 0; - epause->tx_pause = (tp->tg3_flags & TG3_FLAG_PAUSE_TX) != 0; + epause->rx_pause = (tp->tg3_flags & TG3_FLAG_RX_PAUSE) != 0; + epause->tx_pause = (tp->tg3_flags & TG3_FLAG_TX_PAUSE) != 0; } static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) @@ -6026,18 +6100,18 @@ else tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; if (epause->rx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_RX; + tp->tg3_flags |= TG3_FLAG_RX_PAUSE; else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_RX; + tp->tg3_flags &= ~TG3_FLAG_RX_PAUSE; if (epause->tx_pause) - tp->tg3_flags |= TG3_FLAG_PAUSE_TX; + tp->tg3_flags |= TG3_FLAG_TX_PAUSE; else - tp->tg3_flags &= ~TG3_FLAG_PAUSE_TX; + tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; tg3_halt(tp); tg3_init_hw(tp); + tg3_netif_start(tp); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); return 0; } @@ -6124,7 +6198,7 @@ case SIOCGMIIREG: { u32 mii_regval; - if (tp->phy_id == PHY_ID_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) break; /* We have no PHY */ spin_lock_irq(&tp->lock); @@ -6137,7 +6211,7 @@ } case SIOCSMIIREG: - if (tp->phy_id == PHY_ID_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) break; /* We have no PHY */ if (!capable(CAP_NET_ADMIN)) @@ -6224,7 +6298,7 @@ { int j; - if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) return; tw32_f(GRC_EEPROM_ADDR, @@ -6311,8 +6385,8 @@ { int i; - if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { - printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 5704\n"); + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { + printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); return -EINVAL; } @@ -6374,10 +6448,10 @@ { PCI_VENDOR_ID_BROADCOM, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */ { PCI_VENDOR_ID_BROADCOM, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */ { PCI_VENDOR_ID_BROADCOM, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */ - { PCI_VENDOR_ID_BROADCOM, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */ + { PCI_VENDOR_ID_BROADCOM, 0x0003, 0 }, /* BCM95700A9 */ { PCI_VENDOR_ID_BROADCOM, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */ { PCI_VENDOR_ID_BROADCOM, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */ - { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ + { PCI_VENDOR_ID_BROADCOM, 0x0007, 0 }, /* BCM95701A7 */ { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5703 }, /* BCM95703Ax1 */ @@ -6386,7 +6460,7 @@ /* 3com boards. */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */ - { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */ + { PCI_VENDOR_ID_3COM, 0x1004, 0 }, /* 3C996SX */ { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */ { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */ @@ -6399,37 +6473,43 @@ /* Compaq boards. */ { PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */ { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */ - { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */ + { PCI_VENDOR_ID_COMPAQ, 0x007d, 0 }, /* CHANGELING */ { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */ { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }, /* NC7780_2 */ /* IBM boards. */ - { PCI_VENDOR_ID_IBM, 0x0281, PHY_ID_SERDES } /* IBM??? */ + { PCI_VENDOR_ID_IBM, 0x0281, 0 } /* IBM??? */ }; -static int __devinit tg3_phy_probe(struct tg3 *tp) +static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp) { - u32 eeprom_phy_id, hw_phy_id_1, hw_phy_id_2; - u32 hw_phy_id, hw_phy_id_masked; - u32 val; - int i, eeprom_signature_found, err; + int i; - tp->phy_id = PHY_ID_INVALID; for (i = 0; i < ARRAY_SIZE(subsys_id_to_phy_id); i++) { if ((subsys_id_to_phy_id[i].subsys_vendor == tp->pdev->subsystem_vendor) && (subsys_id_to_phy_id[i].subsys_devid == - tp->pdev->subsystem_device)) { - tp->phy_id = subsys_id_to_phy_id[i].phy_id; - break; - } + tp->pdev->subsystem_device)) + return &subsys_id_to_phy_id[i]; } + return NULL; +} +static int __devinit tg3_phy_probe(struct tg3 *tp) +{ + u32 eeprom_phy_id, hw_phy_id_1, hw_phy_id_2; + u32 hw_phy_id, hw_phy_id_masked; + u32 val; + int eeprom_signature_found, eeprom_phy_serdes, err; + + tp->phy_id = PHY_ID_INVALID; eeprom_phy_id = PHY_ID_INVALID; + eeprom_phy_serdes = 0; eeprom_signature_found = 0; tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { u32 nic_cfg, led_cfg; + u32 nic_phy_id, cfg2; tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); tp->nic_sram_data_cfg = nic_cfg; @@ -6437,21 +6517,19 @@ eeprom_signature_found = 1; if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == - NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) { - eeprom_phy_id = PHY_ID_SERDES; - } else { - u32 nic_phy_id; + NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) + eeprom_phy_serdes = 1; - tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id); - if (nic_phy_id != 0) { - u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK; - u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK; - - eeprom_phy_id = (id1 >> 16) << 10; - eeprom_phy_id |= (id2 & 0xfc00) << 16; - eeprom_phy_id |= (id2 & 0x03ff) << 0; - } - } + tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &nic_phy_id); + if (nic_phy_id != 0) { + u32 id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK; + u32 id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK; + + eeprom_phy_id = (id1 >> 16) << 10; + eeprom_phy_id |= (id2 & 0xfc00) << 16; + eeprom_phy_id |= (id2 & 0x03ff) << 0; + } else + eeprom_phy_id = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &led_cfg); @@ -6513,6 +6591,10 @@ } if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL) tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; + + tg3_read_mem(tp, NIC_SRAM_DATA_PHY_ID, &cfg2); + if (cfg2 & (1 << 17)) + tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; } /* Reading the PHY ID register can conflict with ASF @@ -6539,20 +6621,31 @@ if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) { tp->phy_id = hw_phy_id; + if (hw_phy_id_masked == PHY_ID_BCM8002) + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; } else { - /* phy_id currently holds the value found in the - * subsys_id_to_phy_id[] table or PHY_ID_INVALID - * if a match was not found there. - */ - if (tp->phy_id == PHY_ID_INVALID) { - if (!eeprom_signature_found || - !KNOWN_PHY_ID(eeprom_phy_id & PHY_ID_MASK)) - return -ENODEV; + if (eeprom_signature_found) { tp->phy_id = eeprom_phy_id; + if (eeprom_phy_serdes) + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; + } else { + struct subsys_tbl_ent *p; + + /* No eeprom signature? Try the hardcoded + * subsys device table. + */ + p = lookup_by_subsys(tp); + if (!p) + return -ENODEV; + + tp->phy_id = p->phy_id; + if (!tp->phy_id || + tp->phy_id == PHY_ID_BCM8002) + tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; } } - if (tp->phy_id != PHY_ID_SERDES && + if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { u32 bmsr, adv_reg, tg3_ctrl; @@ -6609,7 +6702,7 @@ if (!eeprom_signature_found) tp->led_ctrl = LED_CTRL_MODE_PHY_1; - if (tp->phy_id == PHY_ID_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) tp->link_config.advertising = (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | @@ -6628,11 +6721,11 @@ unsigned char vpd_data[256]; int i; - if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) { + if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { /* Sun decided not to put the necessary bits in the * NVRAM of their onboard tg3 parts :( */ - strcpy(tp->board_part_number, "Sun 5704"); + strcpy(tp->board_part_number, "Sun 570X"); return; } @@ -6693,27 +6786,21 @@ } #ifdef CONFIG_SPARC64 -static int __devinit tg3_is_sun_5704(struct tg3 *tp) +static int __devinit tg3_is_sun_570X(struct tg3 *tp) { struct pci_dev *pdev = tp->pdev; struct pcidev_cookie *pcp = pdev->sysdata; if (pcp != NULL) { int node = pcp->prom_node; - u32 venid, devid; + u32 venid; int err; err = prom_getproperty(node, "subsystem-vendor-id", (char *) &venid, sizeof(venid)); if (err == 0 || err == -1) return 0; - err = prom_getproperty(node, "subsystem-id", - (char *) &devid, sizeof(devid)); - if (err == 0 || err == -1) - return 0; - - if (venid == PCI_VENDOR_ID_SUN && - devid == PCI_DEVICE_ID_TIGON3_5704) + if (venid == PCI_VENDOR_ID_SUN) return 1; } return 0; @@ -6730,8 +6817,8 @@ int err; #ifdef CONFIG_SPARC64 - if (tg3_is_sun_5704(tp)) - tp->tg3_flags2 |= TG3_FLG2_SUN_5704; + if (tg3_is_sun_570X(tp)) + tp->tg3_flags2 |= TG3_FLG2_SUN_570X; #endif /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write @@ -6976,32 +7063,17 @@ udelay(50); tg3_nvram_init(tp); - /* Always use host TXDs, it performs better in particular - * with multi-frag packets. The tests below are kept here - * as documentation should we change this decision again - * in the future. - */ - tp->tg3_flags |= TG3_FLAG_HOST_TXDS; - -#if 0 - /* Determine if TX descriptors will reside in - * main memory or in the chip SRAM. - */ - if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) - tp->tg3_flags |= TG3_FLAG_HOST_TXDS; -#endif - grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; + /* Broadcom's driver says that CIOBE multisplit has a bug */ +#if 0 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { tp->tg3_flags |= TG3_FLAG_SPLIT_MODE; tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; } - +#endif if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) @@ -7028,7 +7100,7 @@ tg3_read_partno(tp); - if (tp->phy_id == PHY_ID_SERDES) { + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { tp->tg3_flags &= ~TG3_FLAG_USE_MI_INTERRUPT; } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) @@ -7051,13 +7123,13 @@ * upon subsystem IDs. */ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL && - tp->phy_id != PHY_ID_SERDES) { + !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { tp->tg3_flags |= (TG3_FLAG_USE_MI_INTERRUPT | TG3_FLAG_USE_LINKCHG_REG); } /* For all SERDES we poll the MAC status register. */ - if (tp->phy_id == PHY_ID_SERDES) + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) tp->tg3_flags |= TG3_FLAG_POLL_SERDES; else tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; @@ -7128,7 +7200,7 @@ mac_offset = 0x7c; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - !(tp->tg3_flags & TG3_FLG2_SUN_5704)) { + !(tp->tg3_flags & TG3_FLG2_SUN_570X)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; if (tg3_nvram_lock(tp)) @@ -7150,7 +7222,7 @@ dev->dev_addr[5] = (lo >> 0) & 0xff; } /* Next, try NVRAM. */ - else if (!(tp->tg3_flags & TG3_FLG2_SUN_5704) && + else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && !tg3_nvram_read(tp, mac_offset + 0, &hi) && !tg3_nvram_read(tp, mac_offset + 4, &lo)) { dev->dev_addr[0] = ((hi >> 16) & 0xff); @@ -7492,8 +7564,8 @@ case PHY_ID_BCM5704: return "5704"; case PHY_ID_BCM5705: return "5705"; case PHY_ID_BCM5750: return "5750"; - case PHY_ID_BCM8002: return "8002"; - case PHY_ID_SERDES: return "serdes"; + case PHY_ID_BCM8002: return "8002/serdes"; + case 0: return "serdes"; default: return "unknown"; }; } @@ -7785,6 +7857,9 @@ if (tp->tg3_flags2 & TG3_FLG2_IS_5788) dev->features &= ~NETIF_F_HIGHDMA; + /* flow control autonegotiation is default behavior */ + tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register net device, " @@ -7816,11 +7891,10 @@ printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); - printk(KERN_INFO "%s: HostTXDS[%d] RXcsums[%d] LinkChgREG[%d] " + printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " "TSOcap[%d] \n", dev->name, - (tp->tg3_flags & TG3_FLAG_HOST_TXDS) != 0, (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, @@ -7899,11 +7973,11 @@ tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); - spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); - netif_device_attach(dev); tg3_netif_start(tp); + + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); } return err; @@ -7936,11 +8010,11 @@ tg3_enable_ints(tp); + tg3_netif_start(tp); + spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); - tg3_netif_start(tp); - return 0; } diff -ur kernel-source-2.6.8-6/drivers/net/tg3.h kernel-source-2.6.8-7/drivers/net/tg3.h --- kernel-source-2.6.8-6/drivers/net/tg3.h 2004-08-13 23:36:18.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/tg3.h 2004-10-03 01:33:14.000000000 -0600 @@ -124,6 +124,7 @@ #define CHIPREV_ID_5705_A3 0x3003 #define CHIPREV_ID_5750_A0 0x4000 #define CHIPREV_ID_5750_A1 0x4001 +#define CHIPREV_ID_5750_A3 0x4003 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 @@ -1548,7 +1549,7 @@ * exist only in the cards on-chip SRAM. All 16 send bds are under * the same mode, they may not be configured individually. * - * The mode we use is controlled by TG3_FLAG_HOST_TXDS in tp->tg3_flags. + * This driver always uses host memory TX descriptors. * * To use host memory TX descriptors: * 1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register. @@ -2004,7 +2005,6 @@ spinlock_t tx_lock; - /* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */ struct tg3_tx_buffer_desc *tx_ring; struct tx_ring_info *tx_buffers; dma_addr_t tx_desc_mapping; @@ -2040,7 +2040,6 @@ u32 rx_offset; u32 tg3_flags; -#define TG3_FLAG_HOST_TXDS 0x00000001 #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 #define TG3_FLAG_RX_CHECKSUMS 0x00000004 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 @@ -2070,15 +2069,13 @@ #define TG3_FLAG_JUMBO_ENABLE 0x00800000 #define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 -#define TG3_FLAG_PAUSE_RX 0x04000000 -#define TG3_FLAG_PAUSE_TX 0x08000000 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 #define TG3_FLAG_SPLIT_MODE 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -#define TG3_FLG2_SUN_5704 0x00000002 +#define TG3_FLG2_SUN_570X 0x00000002 #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2089,6 +2086,9 @@ #define TG3_FLG2_PCI_EXPRESS 0x00000200 #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 #define TG3_FLG2_HW_AUTONEG 0x00000800 +#define TG3_FLG2_PHY_JUST_INITTED 0x00001000 +#define TG3_FLG2_PHY_SERDES 0x00002000 +#define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 @@ -2136,7 +2136,6 @@ #define PHY_ID_BCM5705 0x600081a0 #define PHY_ID_BCM5750 0x60008180 #define PHY_ID_BCM8002 0x60010140 -#define PHY_ID_SERDES 0xfeedbee0 #define PHY_ID_INVALID 0xffffffff #define PHY_ID_REV_MASK 0x0000000f #define PHY_REV_BCM5401_B0 0x1 @@ -2159,7 +2158,7 @@ (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \ (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \ (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \ - (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES) + (X) == PHY_ID_BCM8002) struct tg3_hw_stats *hw_stats; dma_addr_t stats_mapping; diff -ur kernel-source-2.6.8-6/drivers/net/wireless/airo.c kernel-source-2.6.8-7/drivers/net/wireless/airo.c --- kernel-source-2.6.8-6/drivers/net/wireless/airo.c 2004-08-13 23:36:16.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/net/wireless/airo.c 2004-10-03 01:33:14.000000000 -0600 @@ -25,6 +25,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> +#include <linux/smp_lock.h> #include <linux/sched.h> #include <linux/ptrace.h> diff -ur kernel-source-2.6.8-6/drivers/scsi/ata_piix.c kernel-source-2.6.8-7/drivers/scsi/ata_piix.c --- kernel-source-2.6.8-6/drivers/scsi/ata_piix.c 2004-08-13 23:36:57.000000000 -0600 +++ kernel-source-2.6.8-7/drivers/scsi/ata_piix.c 2004-10-03 01:33:14.000000000 -0600 @@ -272,8 +272,25 @@ static void piix_pata_phy_reset(struct ata_port *ap) { + unsigned int controller; + + /* + * In combined legacy mode, port number is not the same as + * primary/secondary controller. + */ + switch (ap->ioaddr.cmd_addr) { + case 0x1f0: + controller = 0; + break; + case 0x170: + controller = 1; + break; + default: + controller = ap->port_no; + } + if (!pci_test_config_bits(ap->host_set->pdev, - &piix_enable_bits[ap->port_no])) { + &piix_enable_bits[controller])) { ata_port_disable(ap); printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); return; diff -ur kernel-source-2.6.8-6/init/main.c kernel-source-2.6.8-7/init/main.c --- kernel-source-2.6.8-6/init/main.c 2004-09-12 21:28:08.000000000 -0600 +++ kernel-source-2.6.8-7/init/main.c 2004-10-03 01:33:14.000000000 -0600 @@ -93,11 +93,6 @@ extern void populate_rootfs(void); extern void driver_init(void); extern void prepare_namespace(void); -#ifdef CONFIG_ACPI -extern void acpi_early_init(void); -#else -static inline void acpi_early_init(void) { } -#endif #ifdef CONFIG_TC extern void tc_init(void); @@ -535,8 +530,6 @@ #endif check_bugs(); - acpi_early_init(); /* before LAPIC and SMP init */ - /* * We count on the initial thread going ok * Like idlers init is an unlocked kernel thread, which will diff -ur kernel-source-2.6.8-6/mm/highmem.c kernel-source-2.6.8-7/mm/highmem.c --- kernel-source-2.6.8-6/mm/highmem.c 2004-08-13 23:37:15.000000000 -0600 +++ kernel-source-2.6.8-7/mm/highmem.c 2004-10-03 01:33:14.000000000 -0600 @@ -284,7 +284,7 @@ struct bio_vec *tovec, *fromvec; int i; - bio_for_each_segment(tovec, to, i) { + __bio_for_each_segment(tovec, to, i, 0) { fromvec = from->bi_io_vec + i; /* @@ -316,7 +316,7 @@ /* * free up bounce indirect pages used */ - bio_for_each_segment(bvec, bio, i) { + __bio_for_each_segment(bvec, bio, i, 0) { org_vec = bio_orig->bi_io_vec + i; if (bvec->bv_page == org_vec->bv_page) continue; diff -ur kernel-source-2.6.8-6/net/ipv4/tcp.c kernel-source-2.6.8-7/net/ipv4/tcp.c --- kernel-source-2.6.8-6/net/ipv4/tcp.c 2004-08-13 23:36:33.000000000 -0600 +++ kernel-source-2.6.8-7/net/ipv4/tcp.c 2004-10-03 01:33:14.000000000 -0600 @@ -276,7 +276,7 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); -int sysctl_tcp_default_win_scale = 7; +int sysctl_tcp_default_win_scale = 0; int sysctl_tcp_mem[3]; int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; diff -ur kernel-source-2.6.8-6/sound/core/seq/seq_clientmgr.c kernel-source-2.6.8-7/sound/core/seq/seq_clientmgr.c --- kernel-source-2.6.8-6/sound/core/seq/seq_clientmgr.c 2004-08-13 23:36:16.000000000 -0600 +++ kernel-source-2.6.8-7/sound/core/seq/seq_clientmgr.c 2004-10-03 01:33:14.000000000 -0600 @@ -155,7 +155,10 @@ card_requested[card] = 1; snd_request_card(card); } - snd_seq_device_load_drivers(); + /* FIXME: may cause blocking when called from + * module_init(), so disable this feature + */ + /* snd_seq_device_load_drivers(); */ } } spin_lock_irqsave(&clients_lock, flags); diff -ur kernel-source-2.6.8-6/version.Debian kernel-source-2.6.8-7/version.Debian --- kernel-source-2.6.8-6/version.Debian 2004-09-12 21:28:08.000000000 -0600 +++ kernel-source-2.6.8-7/version.Debian 2004-10-03 01:33:14.000000000 -0600 @@ -1 +1 @@ -2.6.8-6 +2.6.8-7
Attachment:
signature.asc
Description: Digital signature