Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 29 Feb 2008 16:40:21 +0000 (08:40 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 29 Feb 2008 16:40:21 +0000 (08:40 -0800)
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6:
  [XFS] If you mount an XFS filesystem with no mount options at all, then

157 files changed:
Documentation/feature-removal-schedule.txt
Documentation/ide.txt
MAINTAINERS
arch/sh/Kconfig
arch/sh/drivers/dma/dma-sh.c
arch/sh/drivers/heartbeat.c
arch/sh/drivers/pci/ops-dreamcast.c
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/clock-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/probe.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sparc/kernel/led.c
arch/sparc64/kernel/ds.c
arch/sparc64/kernel/mdesc.c
arch/sparc64/mm/fault.c
arch/sparc64/mm/init.c
drivers/char/rtc.c
drivers/connector/connector.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/ide.c
drivers/ide/legacy/qd65xx.c
drivers/ide/pci/cmd640.c
drivers/ide/pci/hpt366.c
drivers/infiniband/hw/cxgb3/iwch_mem.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes.h
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_hw.c
drivers/infiniband/hw/nes/nes_hw.h
drivers/infiniband/hw/nes/nes_verbs.c
drivers/net/Kconfig
drivers/net/bnx2x.c
drivers/net/bnx2x.h
drivers/net/bnx2x_fw_defs.h
drivers/net/bnx2x_hsi.h
drivers/net/bnx2x_init.h
drivers/net/bnx2x_reg.h
drivers/net/cs89x0.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/lib.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/phy.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/gianfar.c
drivers/net/igb/igb_main.c
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/macb.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/phy/mdio_bus.c
drivers/net/ps3_gelic_wireless.c
drivers/net/sis190.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/tlan.c
drivers/net/tulip/uli526x.c
drivers/net/via-rhine.c
drivers/net/virtio_net.c
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43legacy/Kconfig
drivers/net/wireless/bcm43xx/Kconfig
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00reg.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/s390/net/claw.c
drivers/serial/sh-sci.c
drivers/sh/maple/maple.c
drivers/ssb/Kconfig
drivers/ssb/Makefile
drivers/ssb/driver_pcicore.c
drivers/ssb/ssb_private.h
include/asm-sh/cpu-sh3/cache.h
include/asm-sh/entry-macros.S
include/linux/connector.h
include/linux/elfcore-compat.h
include/linux/maple.h
include/linux/netfilter.h
include/linux/serial_sci.h [moved from include/asm-sh/sci.h with 73% similarity]
include/linux/vmstat.h
include/net/sctp/user.h
net/8021q/vlanproc.c
net/appletalk/atalk_proc.c
net/atm/br2684.c
net/atm/clip.c
net/atm/lec.c
net/atm/mpoa_proc.c
net/atm/proc.c
net/bluetooth/l2cap.c
net/core/neighbour.c
net/core/pktgen.c
net/ipv4/devinet.c
net/ipv4/ip_gre.c
net/ipv4/ipcomp.c
net/ipv4/ipip.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipcomp6.c
net/ipv6/proc.c
net/ipv6/route.c
net/ipv6/sit.c
net/ipv6/sysctl_net_ipv6.c
net/ipx/ipx_proc.c
net/key/af_key.c
net/llc/llc_proc.c
net/mac80211/ieee80211_sta.c
net/netfilter/nf_conntrack_core.c
net/netfilter/xt_conntrack.c
net/sctp/auth.c
net/sctp/ipv6.c
net/sctp/objcnt.c
net/sctp/proc.c
net/sctp/protocol.c
net/sctp/socket.c
net/sctp/ulpevent.c
net/sunrpc/cache.c
net/sunrpc/stats.c
net/tipc/cluster.c
net/tipc/link.c
net/tipc/ref.c
net/tipc/zone.c
net/wanrouter/wanproc.c
net/x25/x25_proc.c

index 4d3aa519eadfc5cebea01e5244f0435702264319..ba899ff2a8f9b825b13808df694c6fe6c56642e0 100644 (file)
@@ -172,6 +172,16 @@ Who:       Len Brown <len.brown@intel.com>
 
 ---------------------------
 
+What:  ide-tape driver
+When:  July 2008
+Files: drivers/ide/ide-tape.c
+Why:   This driver might not have any users anymore and maintaining it for no
+       reason is an effort no one wants to make.
+Who:   Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>, Borislav Petkov
+       <petkovbb@googlemail.com>
+
+---------------------------
+
 What: libata spindown skipping and warning
 When: Dec 2008
 Why:  Some halt(8) implementations synchronize caches for and spin
index 94e2e3b9e77f03ebcb0a3d0b146e53397a6fcfc0..bcd7cd1278efd285d456fe058d1774b5181d5a7b 100644 (file)
@@ -258,8 +258,6 @@ Summary of ide driver parameters for kernel command line
                          As for VLB, it is safest to not specify it.
                          Bigger values are safer than smaller ones.
 
- "idex=noprobe"                : do not attempt to access/use this interface
  "idex=base"           : probe for an interface at the addr specified,
                          where "base" is usually 0x1f0 or 0x170
                          and "ctl" is assumed to be "base"+0x206
@@ -307,53 +305,6 @@ Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb"
 kernel paremeter to enable probing for VLB version of the chipset (PCI ones
 are detected automatically).
 
-================================================================================
-
-IDE ATAPI streaming tape driver
--------------------------------
-
-This driver is a part of the Linux ide driver and works in co-operation
-with linux/drivers/block/ide.c.
-
-The driver, in co-operation with ide.c, basically traverses the
-request-list for the block device interface. The character device
-interface, on the other hand, creates new requests, adds them
-to the request-list of the block device, and waits for their completion.
-
-Pipelined operation mode is now supported on both reads and writes.
-
-The block device major and minor numbers are determined from the
-tape's relative position in the ide interfaces, as explained in ide.c.
-
-The character device interface consists of the following devices:
-
- ht0           major 37, minor 0       first  IDE tape, rewind on close.
- ht1           major 37, minor 1       second IDE tape, rewind on close.
- ...
- nht0          major 37, minor 128     first  IDE tape, no rewind on close.
- nht1          major 37, minor 129     second IDE tape, no rewind on close.
- ...
-
-Run /dev/MAKEDEV to create the above entries.
-
-The general magnetic tape commands compatible interface, as defined by
-include/linux/mtio.h, is accessible through the character device.
-
-General ide driver configuration options, such as the interrupt-unmask
-flag, can be configured by issuing an ioctl to the block device interface,
-as any other ide device.
-
-Our own ide-tape ioctl's can be issued to either the block device or
-the character device interface.
-
-Maximal throughput with minimal bus load will usually be achieved in the
-following scenario:
-
-       1.      ide-tape is operating in the pipelined operation mode.
-       2.      No buffering is performed by the user backup program.
-
-
-
 ================================================================================
 
 Some Terminology
index 36c7bc641dba3efe58f3e78b9a51a62b7ea515b3..7990587542362113c7a1f94e7ef4202261f33adc 100644 (file)
@@ -982,6 +982,12 @@ M: mchan@broadcom.com
 L:     netdev@vger.kernel.org
 S:     Supported
 
+BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
+P:     Eliezer Tamir
+M:     eliezert@broadcom.com
+L:     netdev@vger.kernel.org
+S:     Supported
+
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 P:     Michael Chan
 M:     mchan@broadcom.com
@@ -2744,6 +2750,8 @@ S:        Maintained
 NETEFFECT IWARP RNIC DRIVER (IW_NES)
 P:     Faisal Latif
 M:     flatif@neteffect.com
+P:     Nishi Gupta
+M:     ngupta@neteffect.com
 P:     Glenn Streiff
 M:     gstreiff@neteffect.com
 L:     general@lists.openfabrics.org
@@ -3884,10 +3892,13 @@ M:      trivial@kernel.org
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
-TULIP NETWORK DRIVER
-L:     tulip-users@lists.sourceforge.net
-W:     http://sourceforge.net/projects/tulip/
-S:     Orphan
+TULIP NETWORK DRIVERS
+P:     Grant Grundler
+M:     grundler@parisc-linux.org
+P:     Kyle McMartin
+M:     kyle@parisc-linux.org
+L:     netdev@vger.kernel.org
+S:     Maintained
 
 TUN/TAP driver
 P:     Maxim Krasnyansky
index b3400b5ad5c605cface4aedcd88cd565a25b8909..783cfbbf87cad992ae388047dbdd8f60c43ebbca 100644 (file)
@@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101
 
 config CPU_SUBTYPE_SH5_103
        bool "Support SH5-103 processor"
+       select CPU_SH5
 
 endchoice
 
index 5c3359756a926fe01e1107a1af4bfc53239b25e4..71ff3d6f26e2924462de6132ca9242685c9ddacf 100644 (file)
@@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
 
 static int sh_dmac_request_dma(struct dma_channel *chan)
 {
-       if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
+       if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))
                return 0;
 
        return request_irq(get_dmte_irq(chan->chan), dma_tei,
index b76a14f12ce24dfba85431fc551cb292bee7f5ed..ab77b0e0fa0ebea7b0cef65f4fbda8f549b2483c 100644 (file)
@@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
        }
 
        hd->base = ioremap_nocache(res->start, res->end - res->start + 1);
-       if (!unlikely(hd->base)) {
+       if (unlikely(!hd->base)) {
                dev_err(&pdev->dev, "ioremap failed\n");
 
                if (!pdev->dev.platform_data)
index 0dac87b19624f5ac7dbfd15362dbe884c865b1bc..e1284fc693611a266c5b4307f569bf81fa1ff0d7 100644 (file)
@@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        switch (size) {
-               case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break;
-               case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break;
-               case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break;
+               case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break;
+               case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break;
+               case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break;
        }       
 
         return PCIBIOS_SUCCESSFUL;
@@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        switch (size) {
-               case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
-               case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
-               case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
+               case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break;
+               case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break;
+               case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break;
        }
 
         return PCIBIOS_SUCCESSFUL;
@@ -127,36 +127,36 @@ int __init gapspci_init(void)
         */
 
        for (i=0; i<16; i++)
-               idbuf[i] = ctrl_inb(GAPSPCI_REGS+i);
+               idbuf[i] = inb(GAPSPCI_REGS+i);
 
        if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16))
                return -ENODEV;
 
-       ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18);
+       outl(0x5a14a501, GAPSPCI_REGS+0x18);
 
        for (i=0; i<1000000; i++)
                ;
 
-       if (ctrl_inl(GAPSPCI_REGS+0x18) != 1)
+       if (inl(GAPSPCI_REGS+0x18) != 1)
                return -EINVAL;
 
-       ctrl_outl(0x01000000, GAPSPCI_REGS+0x20);
-       ctrl_outl(0x01000000, GAPSPCI_REGS+0x24);
+       outl(0x01000000, GAPSPCI_REGS+0x20);
+       outl(0x01000000, GAPSPCI_REGS+0x24);
 
-       ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
-       ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
+       outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28);
+       outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c);
 
-       ctrl_outl(1, GAPSPCI_REGS+0x14);
-       ctrl_outl(1, GAPSPCI_REGS+0x34);
+       outl(1, GAPSPCI_REGS+0x14);
+       outl(1, GAPSPCI_REGS+0x34);
 
        /* Setting Broadband Adapter */
-       ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
-       ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
-       ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
-       ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
-       ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
-       ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
-       ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
+       outw(0xf900, GAPSPCI_BBA_CONFIG+0x06);
+       outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30);
+       outb(0x00, GAPSPCI_BBA_CONFIG+0x3c);
+       outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d);
+       outw(0x0006, GAPSPCI_BBA_CONFIG+0x04);
+       outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10);
+       outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14);
 
        return 0;
 }
index b230eb278cef73b7f36ce48efb849b3b0f7ca90d..cc530f4d84d679a1418571319cf3b98be02d18fd 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 enum {
        UNUSED = 0,
index 3feb95a4fcbccae462c1fda63548a33709f7bdb5..fb781329848af930b22290d452fe99a8fdc7a169 100644 (file)
@@ -21,8 +21,8 @@
 #include <asm/freq.h>
 #include <asm/io.h>
 
-const static int pll1rate[]={8,12,16,0};
-const static int pfc_divisors[]={1,2,3,4,6,8,12};
+static const int pll1rate[]={8,12,16,0};
+static const int pfc_divisors[]={1,2,3,4,6,8,12};
 #define ifc_divisors pfc_divisors
 
 #if (CONFIG_SH_CLK_MD == 0)
index db6ef5cecde14b12993f5bbce9b657ba58fa86e1..e98dc4450352c6d1a474d2edfce07c03a723c53b 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 enum {
        UNUSED = 0,
index a564425b905f6572ee710624504dc9283fd9b56b..e6d4ec445dd885d693a39e9b3c4d273ace48db6c 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 enum {
        UNUSED = 0,
index fcc80bb7bee7f9de3192d6309554e1b9642848e5..10f2a760c5ee07ae6c2d71503070bea664733602 100644 (file)
@@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
                boot_cpu_data.dcache.way_incr   = (1 << 13);
                boot_cpu_data.dcache.entry_mask = 0x1ff0;
                boot_cpu_data.dcache.sets       = 512;
-               ctrl_outl(CCR_CACHE_32KB, CCR3);
+               ctrl_outl(CCR_CACHE_32KB, CCR3_REG);
 #else
-               ctrl_outl(CCR_CACHE_16KB, CCR3);
+               ctrl_outl(CCR_CACHE_16KB, CCR3_REG);
 #endif
 #endif
        }
index dd0a20a685f716309803fcf652d47ebe4a62b7ba..f581534cb732c08163b274dc452745e957d924d5 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 #include <asm/rtc.h>
 
 enum {
index 969804bb523bab00964e6303de157e26f06b0096..d3733b13ea5298194020ee43114ce3bafe8420c4 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 enum {
        UNUSED = 0,
@@ -123,15 +123,15 @@ static struct resource rtc_resources[] = {
                .flags  = IORESOURCE_IO,
        },
        [1] =   {
-               .start  = 20,
+               .start  = 21,
                .flags  = IORESOURCE_IRQ,
        },
        [2] =   {
-               .start  = 21,
+               .start  = 22,
                .flags  = IORESOURCE_IRQ,
        },
        [3] =   {
-               .start  = 22,
+               .start  = 20,
                .flags  = IORESOURCE_IRQ,
        },
 };
index 0cc0e2bf135dd744676f3b58cf20a900c94644f1..7406c9ad92597c758cab7cecdf3102e48e72f078 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 #include <asm/rtc.h>
 
 enum {
index 3855ea4c21c8acd30ed3f3c0bbf3a4ad598f9d67..8028082527c55a82d835fc32f800a4262dc1bf06 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 #include <asm/rtc.h>
 
 #define INTC_ICR1      0xA4140010UL
index dab193293f2034c37f36090c1672540da299db0e..7371abf64f8082a902fefc675aec6579ec73b1ac 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index ae3603aca615017e2296cf094a0a822ec291006a..ec884039b914cb5d424a544da7c41bd67e8a655b 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct resource rtc_resources[] = {
        [0] = {
index 85f81579b97e54e7494e556c65c86443f3d57e8a..254c5c55ab9170b846d9a9f5b0ac52db0f31e5fa 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 enum {
        UNUSED = 0,
index c0a3f079dfdcda8565c1d3e83394d9b7930c70ac..6d4f50cd4aaf62ece55cce91bdab88c134f6e165 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index 967e8b69a2f814a1506d23ce72612d1091c295e3..f26b5cdad0d1fd0349665b30ea2c93ecef918ca1 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index 73c778d40d13f289f33b96f92945b9be49d1af6e..b98b4bc93ec9df41bfd5b61ada70a65b3bd8ba99 100644 (file)
@@ -10,9 +10,9 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
+#include <linux/serial_sci.h>
 #include <linux/mm.h>
 #include <asm/mmzone.h>
-#include <asm/sci.h>
 
 static struct resource usbf_resources[] = {
        [0] = {
index eabd5386812d089efa4084903f9244a21cdc688a..07c988dc9de6fa7bf07e7f315f294cc5e90453c0 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct resource rtc_resources[] = {
        [0] = {
index 32f4f59a837b41ca36329488597177f6aa1573ef..b9cec48b18088dc0b0239f23b120626d10c5abe3 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index 293004b526ff98eefa9c0a1f61936e3d551a3396..18dbbe23fea1b172a22532b9cd93005d2eb52562 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/io.h>
-#include <asm/sci.h>
+#include <linux/serial_sci.h>
 
 static struct resource rtc_resources[] = {
        [0] = {
index 74b60e96cdf43bf30d7b7624226116459a0bbbe8..621e7329ec63747b766301e72859a324dee8290e 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
+#include <linux/serial_sci.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <asm/mmzone.h>
-#include <asm/sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index 4dc958b6b31468a35b11d10536bb005e0d846c2f..bd35f32534b98e11a3e231a16940931915995b43 100644 (file)
@@ -10,9 +10,9 @@
 #include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/serial.h>
+#include <linux/serial_sci.h>
 #include <linux/io.h>
 #include <asm/mmzone.h>
-#include <asm/sci.h>
 
 static struct plat_sci_port sci_platform_data[] = {
        {
index 313d1620ae8ec65b3ce43c1ee8b180ec7abdeb68..59e9344e7a0da2f5f0ccc8f4586e3ef89a85debe 100644 (file)
@@ -3,6 +3,9 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/string.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/uaccess.h>
 
 #include <asm/auxio.h>
 
index eeb5a2fc788d2615e47660ae7c6962ca1777126a..bd76482077be66aa3e9e1d6e22d3523a34e4597a 100644 (file)
@@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus,
        }
 }
 
-static int dr_cpu_configure(struct ds_info *dp,
-                           struct ds_cap_state *cp,
-                           u64 req_num,
-                           cpumask_t *mask)
+static int __cpuinit dr_cpu_configure(struct ds_info *dp,
+                                     struct ds_cap_state *cp,
+                                     u64 req_num,
+                                     cpumask_t *mask)
 {
        struct ds_data *resp;
        int resp_len, ncpus, cpu;
@@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp,
        return 0;
 }
 
-static void dr_cpu_data(struct ds_info *dp,
-                       struct ds_cap_state *cp,
-                       void *buf, int len)
+static void __cpuinit dr_cpu_data(struct ds_info *dp,
+                                 struct ds_cap_state *cp,
+                                 void *buf, int len)
 {
        struct ds_data *data = buf;
        struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1);
index 856659bb13116ed7444c263ec1a9f8087c660ec7..9100835895691e1c8f93f6ac38b8bfcf42db7132 100644 (file)
@@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
        get_one_mondo_bits(val, &tb->nonresum_qmask, 2);
 }
 
-void __devinit mdesc_fill_in_cpu_data(cpumask_t mask)
+void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask)
 {
        struct mdesc_handle *hp = mdesc_grab();
        u64 mp;
index e2027f27c0fe73f2f43546aa838577e86fc6e3ba..2650d0d33ac25cbc656baa97adec4c29e1a65a93 100644 (file)
@@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
        if (regs->tstate & TSTATE_PRIV) {
                const struct exception_table_entry *entry;
 
-               if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
-                       if (insn & 0x2000)
-                               asi = (regs->tstate >> 24);
-                       else
-                               asi = (insn >> 5);
-               }
-       
-               /* Look in asi.h: All _S asis have LS bit set */
-               if ((asi & 0x1) &&
-                   (entry = search_exception_tables(regs->tpc))) {
+               entry = search_exception_tables(regs->tpc);
+               if (entry) {
                        regs->tpc = entry->fixup;
                        regs->tnpc = regs->tpc + 4;
                        return;
@@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
                unsigned long tpc = regs->tpc;
 
                /* Sanity check the PC. */
-               if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
+               if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
                    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
                        /* Valid, no problems... */
                } else {
index 9e6bca266d88338df73baf4dd1079a5c17672b69..b5c30416fdac221e9bc31c4d720865769c988e85 100644 (file)
@@ -1010,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata;
 static int pall_ents __initdata;
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
-static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
+static unsigned long __ref kernel_map_range(unsigned long pstart,
+                                           unsigned long pend, pgprot_t prot)
 {
        unsigned long vstart = PAGE_OFFSET + pstart;
        unsigned long vend = PAGE_OFFSET + pend;
index 78b151c4d20f94b0bccecc1acb3540e14b77cdc9..5c3142b6f1fcdf102a92b79dec3b9d000b4d4a3b 100644 (file)
@@ -110,8 +110,8 @@ static int rtc_has_irq = 1;
 #define hpet_set_rtc_irq_bit(arg)              0
 #define hpet_rtc_timer_init()                  do { } while (0)
 #define hpet_rtc_dropped_irq()                 0
-#define hpet_register_irq_handler(h)           0
-#define hpet_unregister_irq_handler(h)         0
+#define hpet_register_irq_handler(h)           ({ 0; })
+#define hpet_unregister_irq_handler(h)         ({ 0; })
 #ifdef RTC_IRQ
 static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
 {
index fea2d3ed9cbdacd57661f5a1a5227a1bde2ffeb2..85e2ba7fcfbab1b4533079da8bd812f22203952d 100644 (file)
@@ -47,7 +47,7 @@ static LIST_HEAD(notify_list);
 
 static struct cn_dev cdev;
 
-int cn_already_initialized = 0;
+static int cn_already_initialized;
 
 /*
  * msg->seq and msg->ack are used to determine message genealogy.
index 310e497b58380d5d348c29d9d890204e1cf47edf..c8d0e8715997475abe51e683ee5b5aff2f44109c 100644 (file)
@@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
  * and attempt to recover if there are problems.  Returns  0 if everything's
  * ok; nonzero if the request has been terminated.
  */
-static
-int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
+static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
+                               int len, int ireason, int rw)
 {
        /*
         * ireason == 0: the drive wants to receive data from us
@@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw)
                                drive->name, __FUNCTION__, ireason);
        }
 
+       if (rq->cmd_type == REQ_TYPE_ATA_PC)
+               rq->cmd_flags |= REQ_FAILED;
+
        cdrom_end_request(drive, 0);
        return -1;
 }
@@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        /*
         * check which way to transfer data
         */
-       if (blk_fs_request(rq) || blk_pc_request(rq)) {
-               if (ide_cd_check_ireason(drive, len, ireason, write))
-                       return ide_stopped;
+       if (ide_cd_check_ireason(drive, rq, len, ireason, write))
+               return ide_stopped;
 
-               if (blk_fs_request(rq) && write == 0) {
+       if (blk_fs_request(rq)) {
+               if (write == 0) {
                        int nskip;
 
                        if (ide_cd_check_transfer_size(drive, len)) {
@@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        if (ireason == 0) {
                write = 1;
                xferfunc = HWIF(drive)->atapi_output_bytes;
-       } else if (ireason == 2 || (ireason == 1 &&
-                  (blk_fs_request(rq) || blk_pc_request(rq)))) {
+       } else {
                write = 0;
                xferfunc = HWIF(drive)->atapi_input_bytes;
-       } else {
-               printk(KERN_ERR "%s: %s: The drive "
-                               "appears confused (ireason = 0x%02x). "
-                               "Trying to recover by ending request.\n",
-                               drive->name, __FUNCTION__, ireason);
-               goto end_request;
        }
 
        /*
@@ -1182,11 +1178,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                        else
                                rq->data += blen;
                }
+               if (!write && blk_sense_request(rq))
+                       rq->sense_len += blen;
        }
 
-       if (write && blk_sense_request(rq))
-               rq->sense_len += thislen;
-
        /*
         * pad, if necessary
         */
@@ -1931,6 +1926,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = {
        { "MATSHITADVD-ROM SR-8186", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
        { "MATSHITADVD-ROM SR-8176", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
        { "MATSHITADVD-ROM SR-8174", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
+       { "Optiarc DVD RW AD-5200A", NULL,   IDE_CD_FLAG_PLAY_AUDIO_OK      },
        { NULL, NULL, 0 }
 };
 
index 8f5bed471050d955713f5d5230aa7327ad993dec..39501d130256109ad50d06a6b904249e9163f08a 100644 (file)
@@ -867,7 +867,7 @@ static void idedisk_setup (ide_drive_t *drive)
 
        /* Only print cache size when it was specified */
        if (id->buf_size)
-               printk (" w/%dKiB Cache", id->buf_size/2);
+               printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2);
 
        printk(KERN_CONT ", CHS=%d/%d/%d\n",
                         drive->bios_cyl, drive->bios_head, drive->bios_sect);
@@ -949,7 +949,8 @@ static void ide_device_shutdown(ide_drive_t *drive)
                return;
        }
 
-       printk("Shutdown: %s\n", drive->name);
+       printk(KERN_INFO "Shutdown: %s\n", drive->name);
+
        drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
 }
 
index d0e7b537353e38ea1bb23ff6f0604f0d93777752..2de99e4be5c9b963ebfbf263884d6f55f1d82d56 100644 (file)
@@ -1,9 +1,13 @@
 /*
+ *  IDE DMA support (including IDE PCI BM-DMA).
+ *
  *  Copyright (C) 1995-1998   Mark Lord
  *  Copyright (C) 1999-2000   Andre Hedrick <andre@linux-ide.org>
  *  Copyright (C) 2004, 2007  Bartlomiej Zolnierkiewicz
  *
  *  May be copied or modified under the terms of the GNU General Public License
+ *
+ *  DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies).
  */
 
 /*
  */
 
 /*
- * This module provides support for the bus-master IDE DMA functions
- * of various PCI chipsets, including the Intel PIIX (i82371FB for
- * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and 
- * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset)
- * ("PIIX" stands for "PCI ISA IDE Xcellerator").
- *
- * Pretty much the same code works for other IDE PCI bus-mastering chipsets.
- *
- * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies).
- *
- * By default, DMA support is prepared for use, but is currently enabled only
- * for drives which already have DMA enabled (UltraDMA or mode 2 multi/single),
- * or which are recognized as "good" (see table below).  Drives with only mode0
- * or mode1 (multi/single) DMA should also work with this chipset/driver
- * (eg. MC2112A) but are not enabled by default.
- *
- * Use "hdparm -i" to view modes supported by a given drive.
- *
- * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling
- * DMA support, but must be (re-)compiled against this kernel version or later.
- *
- * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting.
- * If problems arise, ide.c will disable DMA operation after a few retries.
- * This error recovery mechanism works and has been extremely well exercised.
- *
- * IDE drives, depending on their vintage, may support several different modes
- * of DMA operation.  The boot-time modes are indicated with a "*" in
- * the "hdparm -i" listing, and can be changed with *knowledgeable* use of
- * the "hdparm -X" feature.  There is seldom a need to do this, as drives
- * normally power-up with their "best" PIO/DMA modes enabled.
- *
- * Testing has been done with a rather extensive number of drives,
- * with Quantum & Western Digital models generally outperforming the pack,
- * and Fujitsu & Conner (and some Seagate which are really Conner) drives
- * showing more lackluster throughput.
- *
- * Keep an eye on /var/adm/messages for "DMA disabled" messages.
- *
- * Some people have reported trouble with Intel Zappa motherboards.
- * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0,
- * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
- * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
- *
  * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for
  * fixing the problem with the BIOS on some Acer motherboards.
  *
  *
  * Most importantly, thanks to Robert Bringman <rob@mars.trion.com>
  * for supplying a Promise UDMA board & WD UDMA drive for this work!
- *
- * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
- *
- * ATA-66/100 and recovery functions, I forgot the rest......
- *
  */
 
 #include <linux/module.h>
index 4a2cb28682263d6a3c3a861490dfbe770d96c2d6..194ecb0049eb1ed37c3dde4c00d3a83273c1dc88 100644 (file)
@@ -756,7 +756,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
 
        BUG_ON(hwif->present);
 
-       if (hwif->noprobe)
+       if (hwif->noprobe ||
+           (hwif->drives[0].noprobe && hwif->drives[1].noprobe))
                return -EACCES;
 
        /*
index 0598ecfd5f3706b0402182875f324474361bbf5b..43e0e05577763b4bcd166dc4d14128dd94dac9d2 100644 (file)
@@ -3765,6 +3765,11 @@ static int ide_tape_probe(ide_drive_t *drive)
        g->fops = &idetape_block_ops;
        ide_register_region(g);
 
+       printk(KERN_WARNING "It is possible that this driver does not have any"
+               " users anymore and, as a result, it will be REMOVED soon."
+               " Please notify Bart <bzolnier@gmail.com> or Boris"
+               " <petkovbb@gmail.com> in case you still need it.\n");
+
        return 0;
 
 out_free_tape:
index 477833f0daf501cbb1a67150e6523818a1fc38f6..fa16bc30bbc985efe4efc4ad9c91d93b3d7b0ed7 100644 (file)
@@ -590,11 +590,6 @@ void ide_unregister(unsigned int index, int init_default, int restore)
                hwif->extra_ports = 0;
        }
 
-       /*
-        * Note that we only release the standard ports,
-        * and do not even try to handle any extra ports
-        * allocated for weird IDE interface chipsets.
-        */
        ide_hwif_release_regions(hwif);
 
        /* copy original settings */
@@ -1036,10 +1031,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
                        drive->nice1 = (arg >> IDE_NICE_1) & 1;
                        return 0;
                case HDIO_DRIVE_RESET:
-               {
-                       unsigned long flags;
-                       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-                       
+                       if (!capable(CAP_SYS_ADMIN))
+                               return -EACCES;
+
                        /*
                         *      Abort the current command on the
                         *      group if there is one, taking
@@ -1058,17 +1052,15 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
                        ide_abort(drive, "drive reset");
 
                        BUG_ON(HWGROUP(drive)->handler);
-                               
+
                        /* Ensure nothing gets queued after we
                           drop the lock. Reset will clear the busy */
-                  
+
                        HWGROUP(drive)->busy = 1;
                        spin_unlock_irqrestore(&ide_lock, flags);
                        (void) ide_do_reset(drive);
 
                        return 0;
-               }
-
                case HDIO_GET_BUSSTATE:
                        if (!capable(CAP_SYS_ADMIN))
                                return -EACCES;
@@ -1449,7 +1441,7 @@ static int __init ide_setup(char *s)
 
                        case -1: /* "noprobe" */
                                hwif->noprobe = 1;
-                               goto done;
+                               goto obsolete_option;
 
                        case 1: /* base */
                                vals[1] = vals[0] + 0x206; /* default ctl */
index bba29df5f21d6094660c777724c38ef9d2de454b..2f4f47ad602f61ca8ec3614d484dcc5939a46c05 100644 (file)
@@ -334,43 +334,6 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif)
        hwif->drives[1].drive_data = t2;
 }
 
-/*
- * qd_unsetup:
- *
- * called to unsetup an ata channel : back to default values, unlinks tuning
- */
-/*
-static void __exit qd_unsetup(ide_hwif_t *hwif)
-{
-       u8 config = hwif->config_data;
-       int base = hwif->select_data;
-       void *set_pio_mode = (void *)hwif->set_pio_mode;
-
-       if (hwif->chipset != ide_qd65xx)
-               return;
-
-       printk(KERN_NOTICE "%s: back to defaults\n", hwif->name);
-
-       hwif->selectproc = NULL;
-       hwif->set_pio_mode = NULL;
-
-       if (set_pio_mode == (void *)qd6500_set_pio_mode) {
-               // will do it for both
-               outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
-       } else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
-               if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
-                       outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
-                       outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
-               } else {
-                       outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
-               }
-       } else {
-               printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
-               printk(KERN_WARNING "keeping settings !\n");
-       }
-}
-*/
-
 static const struct ide_port_info qd65xx_port_info __initdata = {
        .chipset                = ide_qd65xx,
        .host_flags             = IDE_HFLAG_IO_32BIT |
@@ -444,6 +407,8 @@ static int __init qd_probe(int base)
                printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
                        config, control, QD_ID3);
 
+               outb(QD_DEF_CONTR, QD_CONTROL_PORT);
+
                if (control & QD_CONTR_SEC_DISABLED) {
                        /* secondary disabled */
 
@@ -460,8 +425,6 @@ static int __init qd_probe(int base)
 
                        ide_device_add(idx, &qd65xx_port_info);
 
-                       outb(QD_DEF_CONTR, QD_CONTROL_PORT);
-
                        return 1;
                } else {
                        ide_hwif_t *mate;
@@ -487,8 +450,6 @@ static int __init qd_probe(int base)
 
                        ide_device_add(idx, &qd65xx_port_info);
 
-                       outb(QD_DEF_CONTR, QD_CONTROL_PORT);
-
                        return 0; /* no other qd65xx possible */
                }
        }
index bd24dad3cfc6b2a82c990120ff7e10ac567599ab..ec667982809c18ae8ddf59bc5023190134cb33c1 100644 (file)
@@ -787,7 +787,8 @@ static int __init cmd640x_init(void)
        /*
         * Try to enable the secondary interface, if not already enabled
         */
-       if (cmd_hwif1->noprobe) {
+       if (cmd_hwif1->noprobe ||
+           (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) {
                port2 = "not probed";
        } else {
                b = get_cmd640_reg(CNTRL);
index d0f7bb8b8adf1d881fe4d2f7c5f86106dc4b63d1..6357bb6269ab42bfc14623006e0fef089484ae08 100644 (file)
@@ -1570,10 +1570,12 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
                if (rev < 3)
                        info = &hpt36x;
                else {
-                       static const struct hpt_info *hpt37x_info[] =
-                               { &hpt370, &hpt370a, &hpt372, &hpt372n };
-
-                       info = hpt37x_info[min_t(u8, rev, 6) - 3];
+                       switch (min_t(u8, rev, 6)) {
+                       case 3: info = &hpt370;  break;
+                       case 4: info = &hpt370a; break;
+                       case 5: info = &hpt372;  break;
+                       case 6: info = &hpt372n; break;
+                       }
                        idx++;
                }
                break;
@@ -1626,7 +1628,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
        return ide_setup_pci_device(dev, &d);
 }
 
-static const struct pci_device_id hpt366_pci_tbl[] = {
+static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = {
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366),  0 },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372),  1 },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302),  2 },
index 73bfd1656f86434bae2c36215a6d073607a07a7c..b8797c66676d6837b265f816e55d923d450047be 100644 (file)
@@ -136,14 +136,8 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list,
 
        /* Find largest page shift we can use to cover buffers */
        for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
-               if (num_phys_buf > 1) {
-                       if ((1ULL << *shift) & mask)
-                               break;
-               } else
-                       if (1ULL << *shift >=
-                           buffer_list[0].size +
-                           (buffer_list[0].addr & ((1ULL << *shift) - 1)))
-                               break;
+               if ((1ULL << *shift) & mask)
+                       break;
 
        buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
        buffer_list[0].addr &= ~0ull << *shift;
index 7f8853b44ee173579d2af89d54c09acfa5117ff9..b2112f5a422fbd8bcf6d993f707a0b8b604ad5e1 100644 (file)
@@ -567,12 +567,12 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
 
        /* Init the adapter */
        nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev);
-       nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
        if (!nesdev->nesadapter) {
                printk(KERN_ERR PFX "Unable to initialize adapter.\n");
                ret = -ENOMEM;
                goto bail5;
        }
+       nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval;
 
        /* nesdev->base_doorbell_index =
                        nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */
index fd57e8a1582f210383044ab7748eabbccdcf662d..a48b288618ece5d569644915455e51251e4d5e97 100644 (file)
@@ -285,6 +285,21 @@ struct nes_device {
 };
 
 
+static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad)
+{
+       u32 crc_value;
+       crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad));
+
+       /*
+        * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc
+        * state in cpu order"), behavior of crc32c changes on
+        * big-endian platforms.  Our algorithm expects the previous
+        * behavior; otherwise we have RDMA connection establishment
+        * issue on big-endian.
+        */
+       return cpu_to_le32(crc_value);
+}
+
 static inline void
 set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value)
 {
index bd5cfeaac203df2da0f09ea63ff2fc5e5c9b0c0f..39adb267fb1553fb45d96104b361eb6442ba8658 100644 (file)
@@ -370,11 +370,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
        int ret = 0;
        u32 was_timer_set;
 
+       if (!cm_node)
+               return -EINVAL;
        new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
        if (!new_send)
                return -1;
-       if (!cm_node)
-               return -EINVAL;
 
        /* new_send->timetosend = currenttime */
        new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -947,6 +947,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
                nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener);
 
                kfree(listener);
+               listener = NULL;
                ret = 0;
                cm_listens_destroyed++;
        } else {
@@ -2319,6 +2320,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        struct iw_cm_event cm_event;
        struct nes_hw_qp_wqe *wqe;
        struct nes_v4_quad nes_quad;
+       u32 crc_value;
        int ret;
 
        ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
@@ -2435,8 +2437,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        nes_quad.TcpPorts[1]   = cm_id->local_addr.sin_port;
 
        /* Produce hash key */
-       nesqp->hte_index = cpu_to_be32(
-                       crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff);
+       crc_value = get_crc_value(&nes_quad);
+       nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
        nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n",
                        nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask);
 
@@ -2750,6 +2752,7 @@ void cm_event_connected(struct nes_cm_event *event)
        struct iw_cm_event cm_event;
        struct nes_hw_qp_wqe *wqe;
        struct nes_v4_quad nes_quad;
+       u32 crc_value;
        int ret;
 
        /* get all our handles */
@@ -2827,8 +2830,8 @@ void cm_event_connected(struct nes_cm_event *event)
        nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
 
        /* Produce hash key */
-       nesqp->hte_index = cpu_to_be32(
-                       crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff);
+       crc_value = get_crc_value(&nes_quad);
+       nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
        nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n",
                        nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask);
 
index 7c4c0fbf0abd3ff9322a07888afe5cb00d4c34d2..49e53e4c1ebef475bf5337bb346472c98a8ec72f 100644 (file)
@@ -156,15 +156,14 @@ static void nes_nic_tune_timer(struct nes_device *nesdev)
 
        spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags);
 
-       if (shared_timer->cq_count_old < cq_count) {
-               if (cq_count > shared_timer->threshold_low)
-                       shared_timer->cq_direction_downward=0;
-       }
-       if (shared_timer->cq_count_old >= cq_count)
+       if (shared_timer->cq_count_old <= cq_count)
+               shared_timer->cq_direction_downward = 0;
+       else
                shared_timer->cq_direction_downward++;
        shared_timer->cq_count_old = cq_count;
        if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) {
-               if (cq_count <= shared_timer->threshold_low) {
+               if (cq_count <= shared_timer->threshold_low &&
+                   shared_timer->threshold_low > 4) {
                        shared_timer->threshold_low = shared_timer->threshold_low/2;
                        shared_timer->cq_direction_downward=0;
                        nesdev->currcq_count = 0;
@@ -1728,7 +1727,6 @@ int nes_napi_isr(struct nes_device *nesdev)
                        nesdev->int_req &= ~NES_INT_TIMER;
                        nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
                        nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
-                       nesadapter->tune_timer.timer_in_use_old = 0;
                }
                nesdev->deepcq_count = 0;
                return 1;
@@ -1867,7 +1865,6 @@ void nes_dpc(unsigned long param)
                                        nesdev->int_req &= ~NES_INT_TIMER;
                                        nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req));
                                        nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req);
-                                       nesdev->nesadapter->tune_timer.timer_in_use_old = 0;
                                } else {
                                        nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req));
                                }
index 1e10df550c9ea49e3a2f04414a61bbb941f97ac2..b7e2844f096b620489c0b338e65e400937c16c4a 100644 (file)
@@ -962,7 +962,7 @@ struct nes_arp_entry {
 #define DEFAULT_JUMBO_NES_QL_LOW    12
 #define DEFAULT_JUMBO_NES_QL_TARGET 40
 #define DEFAULT_JUMBO_NES_QL_HIGH   128
-#define NES_NIC_CQ_DOWNWARD_TREND   8
+#define NES_NIC_CQ_DOWNWARD_TREND   16
 
 struct nes_hw_tune_timer {
     //u16 cq_count;
index 4dafbe16e82a8366aed841269c3d54535c091cfc..a651e9d9f0efdba6e38612b738f9455ccf2a1bcf 100644 (file)
@@ -929,7 +929,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
                                NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db);
                nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n",
                                nespd->mmap_db_index, nespd->pd_id);
-               if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) {
+               if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) {
                        nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n");
                        nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num);
                        kfree(nespd);
@@ -1327,7 +1327,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
                                                                  (long long unsigned int)req.user_wqe_buffers);
                                                        nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
                                                        kfree(nesqp->allocated_buffer);
-                                                       return ERR_PTR(-ENOMEM);
+                                                       return ERR_PTR(-EFAULT);
                                                }
                                        }
 
@@ -1674,6 +1674,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
                }
                nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n",
                                (unsigned long)req.user_cq_buffer, entries);
+               err = 1;
                list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) {
                        if (nespbl->user_base == (unsigned long )req.user_cq_buffer) {
                                list_del(&nespbl->list);
@@ -1686,7 +1687,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
                if (err) {
                        nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num);
                        kfree(nescq);
-                       return ERR_PTR(err);
+                       return ERR_PTR(-EFAULT);
                }
 
                pbl_entries = nespbl->pbl_size >> 3;
@@ -1831,9 +1832,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,
                                spin_unlock_irqrestore(&nesdev->cqp.lock, flags);
                        }
                }
-               nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X,"
-                               " minor code = 0x%04X\n",
-                               nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code);
                if (!context)
                        pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem,
                                        nescq->hw_cq.cq_pbase);
index f337800076c0fdba7fe986e8dd27d897f8cce1ef..a0f0e605d630389bbed8450c1446905002e1a836 100644 (file)
@@ -90,6 +90,11 @@ config MACVLAN
          This allows one to create virtual interfaces that map packets to
          or from specific MAC addresses to a particular interface.
 
+         Macvlan devices can be added using the "ip" command from the
+         iproute2 package starting with the iproute2-2.6.23 release:
+
+         "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
+
          To compile this driver as a module, choose M here: the module
          will be called macvlan.
 
@@ -2363,6 +2368,7 @@ config GELIC_NET
 config GELIC_WIRELESS
        bool "PS3 Wireless support"
        depends on GELIC_NET
+       select WIRELESS_EXT
        help
         This option adds the support for the wireless feature of PS3.
         If you have the wireless-less model of PS3 or have no plan to
index afc7f34b1dcf3afbf8dd6eb02b272abe94c8edf5..8af142ccf373feb060b82fae91e7a5fe9adae10b 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2x.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007 Broadcom Corporation
+ * Copyright (c) 2007-2008 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Based on code from Michael Chan's bnx2 driver
  * UDP CSUM errata workaround by Arik Gendelman
  * Slowpath rework by Vladislav Zolotarov
- * Statistics and Link managment by Yitchak Gertner
+ * Statistics and Link management by Yitchak Gertner
  *
  */
 
 /* define this to make the driver freeze on error
  * to allow getting debug info
- * (you will need to reboot afterwords)
+ * (you will need to reboot afterwards)
  */
 /*#define BNX2X_STOP_ON_ERROR*/
 
 #include "bnx2x.h"
 #include "bnx2x_init.h"
 
-#define DRV_MODULE_VERSION      "0.40.15"
-#define DRV_MODULE_RELDATE      "$DateTime: 2007/11/15 07:28:37 $"
-#define BNX2X_BC_VER           0x040009
+#define DRV_MODULE_VERSION      "1.40.22"
+#define DRV_MODULE_RELDATE      "2007/11/27"
+#define BNX2X_BC_VER           0x040200
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT             (5*HZ)
 
 static char version[] __devinitdata =
-       "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver "
+       "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver "
        DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>");
 MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
-MODULE_INFO(cvs_version, "$Revision: #356 $");
 
 static int use_inta;
 static int poll;
@@ -94,8 +93,8 @@ module_param(debug, int, 0);
 MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
 MODULE_PARM_DESC(poll, "use polling (for debug)");
 MODULE_PARM_DESC(onefunc, "enable only first function");
-MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)");
-MODULE_PARM_DESC(debug, "defualt debug msglevel");
+MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)");
+MODULE_PARM_DESC(debug, "default debug msglevel");
 
 #ifdef BNX2X_MULTI
 module_param(use_multi, int, 0);
@@ -298,8 +297,7 @@ static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 
 static int bnx2x_mc_assert(struct bnx2x *bp)
 {
-       int i, j;
-       int rc = 0;
+       int i, j, rc = 0;
        char last_idx;
        const char storm[] = {"XTCU"};
        const u32 intmem_base[] = {
@@ -313,8 +311,9 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
        for (i = 0; i < 4; i++) {
                last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
                                   intmem_base[i]);
-               BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
-                         storm[i], last_idx);
+               if (last_idx)
+                       BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
+                                 storm[i], last_idx);
 
                /* print the asserts */
                for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
@@ -330,7 +329,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
                                      intmem_base[i]);
 
                        if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
-                               BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x ="
+                               BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x ="
                                          " 0x%08x 0x%08x 0x%08x 0x%08x\n",
                                          storm[i], j, row3, row2, row1, row0);
                                rc++;
@@ -341,6 +340,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
        }
        return rc;
 }
+
 static void bnx2x_fw_dump(struct bnx2x *bp)
 {
        u32 mark, offset;
@@ -348,21 +348,22 @@ static void bnx2x_fw_dump(struct bnx2x *bp)
        int word;
 
        mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
-       printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+       mark = ((mark + 0x3) & ~0x3);
+       printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
 
        for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
                for (word = 0; word < 8; word++)
                        data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
                                                  offset + 4*word));
                data[8] = 0x0;
-               printk(KERN_ERR PFX "%s", (char *)data);
+               printk(KERN_CONT "%s", (char *)data);
        }
        for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
                for (word = 0; word < 8; word++)
                        data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
                                                  offset + 4*word));
                data[8] = 0x0;
-               printk(KERN_ERR PFX "%s", (char *)data);
+               printk(KERN_CONT "%s", (char *)data);
        }
        printk("\n" KERN_ERR PFX "end of fw dump\n");
 }
@@ -427,10 +428,10 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
                }
        }
 
-       BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_t_idx(%u)"
-                 "  def_x_idx(%u)  def_att_idx(%u)  attn_state(%u)"
+       BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_x_idx(%u)"
+                 "  def_t_idx(%u)  def_att_idx(%u)  attn_state(%u)"
                  "  spq_prod_idx(%u)\n",
-                 bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx,
+                 bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
                  bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
 
 
@@ -441,7 +442,7 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
        DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
 }
 
-static void bnx2x_enable_int(struct bnx2x *bp)
+static void bnx2x_int_enable(struct bnx2x *bp)
 {
        int port = bp->port;
        u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -454,18 +455,26 @@ static void bnx2x_enable_int(struct bnx2x *bp)
                        HC_CONFIG_0_REG_ATTN_BIT_EN_0);
        } else {
                val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+                       HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
                        HC_CONFIG_0_REG_INT_LINE_EN_0 |
                        HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+               /* Errata A0.158 workaround */
+               DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  MSI-X %d\n",
+                  val, port, addr, msix);
+
+               REG_WR(bp, addr, val);
+
                val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
        }
 
-       DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  msi %d\n",
+       DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  MSI-X %d\n",
           val, port, addr, msix);
 
        REG_WR(bp, addr, val);
 }
 
-static void bnx2x_disable_int(struct bnx2x *bp)
+static void bnx2x_int_disable(struct bnx2x *bp)
 {
        int port = bp->port;
        u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
@@ -484,15 +493,15 @@ static void bnx2x_disable_int(struct bnx2x *bp)
                BNX2X_ERR("BUG! proper val not read from IGU!\n");
 }
 
-static void bnx2x_disable_int_sync(struct bnx2x *bp)
+static void bnx2x_int_disable_sync(struct bnx2x *bp)
 {
 
        int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
        int i;
 
        atomic_inc(&bp->intr_sem);
-       /* prevent the HW from sending interrupts*/
-       bnx2x_disable_int(bp);
+       /* prevent the HW from sending interrupts */
+       bnx2x_int_disable(bp);
 
        /* make sure all ISRs are done */
        if (msix) {
@@ -775,6 +784,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
                mb(); /* force bnx2x_wait_ramrod to see the change */
                return;
        }
+
        switch (command | bp->state) {
        case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
                DP(NETIF_MSG_IFUP, "got setup ramrod\n");
@@ -787,20 +797,20 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
                fp->state = BNX2X_FP_STATE_HALTED;
                break;
 
-       case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE):
-               DP(NETIF_MSG_IFDOWN, "got delete ramrod\n");
-               bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
-               break;
-
        case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
-               DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
-               bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED;
+               DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n",
+                  cid);
+               bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
                break;
 
        case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
                DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
                break;
 
+       case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
+               DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
+               break;
+
        default:
                BNX2X_ERR("unexpected ramrod (%d)  state is %x\n",
                          command, bp->state);
@@ -1179,12 +1189,175 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
        return val;
 }
 
+static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
+{
+       u32 cnt;
+       u32 lock_status;
+       u32 resource_bit = (1 << resource);
+       u8 func = bp->port;
+
+       /* Validating that the resource is within range */
+       if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+               DP(NETIF_MSG_HW,
+                  "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+                  resource, HW_LOCK_MAX_RESOURCE_VALUE);
+               return -EINVAL;
+       }
+
+       /* Validating that the resource is not already taken */
+       lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+       if (lock_status & resource_bit) {
+               DP(NETIF_MSG_HW, "lock_status 0x%x  resource_bit 0x%x\n",
+                  lock_status, resource_bit);
+               return -EEXIST;
+       }
+
+       /* Try for 1 second every 5ms */
+       for (cnt = 0; cnt < 200; cnt++) {
+               /* Try to acquire the lock */
+               REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4,
+                      resource_bit);
+               lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+               if (lock_status & resource_bit)
+                       return 0;
+
+               msleep(5);
+       }
+       DP(NETIF_MSG_HW, "Timeout\n");
+       return -EAGAIN;
+}
+
+static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
+{
+       u32 lock_status;
+       u32 resource_bit = (1 << resource);
+       u8 func = bp->port;
+
+       /* Validating that the resource is within range */
+       if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+               DP(NETIF_MSG_HW,
+                  "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+                  resource, HW_LOCK_MAX_RESOURCE_VALUE);
+               return -EINVAL;
+       }
+
+       /* Validating that the resource is currently taken */
+       lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
+       if (!(lock_status & resource_bit)) {
+               DP(NETIF_MSG_HW, "lock_status 0x%x  resource_bit 0x%x\n",
+                  lock_status, resource_bit);
+               return -EFAULT;
+       }
+
+       REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit);
+       return 0;
+}
+
+static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
+{
+       /* The GPIO should be swapped if swap register is set and active */
+       int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+                        REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
+       int gpio_shift = gpio_num +
+                       (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+       u32 gpio_mask = (1 << gpio_shift);
+       u32 gpio_reg;
+
+       if (gpio_num > MISC_REGISTERS_GPIO_3) {
+               BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+               return -EINVAL;
+       }
+
+       bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+       /* read GPIO and mask except the float bits */
+       gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
+
+       switch (mode) {
+       case MISC_REGISTERS_GPIO_OUTPUT_LOW:
+               DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
+                  gpio_num, gpio_shift);
+               /* clear FLOAT and set CLR */
+               gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+               gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
+               break;
+
+       case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
+               DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
+                  gpio_num, gpio_shift);
+               /* clear FLOAT and set SET */
+               gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+               gpio_reg |=  (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
+               break;
+
+       case MISC_REGISTERS_GPIO_INPUT_HI_Z :
+               DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
+                  gpio_num, gpio_shift);
+               /* set FLOAT */
+               gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+               break;
+
+       default:
+               break;
+       }
+
+       REG_WR(bp, MISC_REG_GPIO, gpio_reg);
+       bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
+
+       return 0;
+}
+
+static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
+{
+       u32 spio_mask = (1 << spio_num);
+       u32 spio_reg;
+
+       if ((spio_num < MISC_REGISTERS_SPIO_4) ||
+           (spio_num > MISC_REGISTERS_SPIO_7)) {
+               BNX2X_ERR("Invalid SPIO %d\n", spio_num);
+               return -EINVAL;
+       }
+
+       bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
+       /* read SPIO and mask except the float bits */
+       spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
+
+       switch (mode) {
+       case MISC_REGISTERS_SPIO_OUTPUT_LOW :
+               DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
+               /* clear FLOAT and set CLR */
+               spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+               spio_reg |=  (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
+               break;
+
+       case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
+               DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
+               /* clear FLOAT and set SET */
+               spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+               spio_reg |=  (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
+               break;
+
+       case MISC_REGISTERS_SPIO_INPUT_HI_Z:
+               DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
+               /* set FLOAT */
+               spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+               break;
+
+       default:
+               break;
+       }
+
+       REG_WR(bp, MISC_REG_SPIO, spio_reg);
+       bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
+
+       return 0;
+}
+
 static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
 {
-       int rc;
-       u32 tmp, i;
        int port = bp->port;
        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+       u32 tmp;
+       int i, rc;
 
 /*      DP(NETIF_MSG_HW, "phy_addr 0x%x  reg 0x%x  val 0x%08x\n",
           bp->phy_addr, reg, val); */
@@ -1236,8 +1409,8 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
 {
        int port = bp->port;
        u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-       u32 val, i;
-       int rc;
+       u32 val;
+       int i, rc;
 
        if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
 
@@ -1286,58 +1459,54 @@ static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
        return rc;
 }
 
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
+                                  u32 phy_addr, u32 reg, u32 addr, u32 val)
 {
-       int rc = 0;
-       u32 tmp, i;
-       int port = bp->port;
-       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+       u32 tmp;
+       int i, rc = 0;
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
-               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-               tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
-               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-               udelay(40);
-       }
-
-       /* set clause 45 mode */
-       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-       tmp |= EMAC_MDIO_MODE_CLAUSE_45;
-       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+       /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+        * (a value of 49==0x31) and make sure that the AUTO poll is off
+        */
+       tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+       tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
+               (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+       REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       udelay(40);
 
        /* address */
-       tmp = ((bp->phy_addr << 21) | (reg << 16) | addr |
+       tmp = ((phy_addr << 21) | (reg << 16) | addr |
               EMAC_MDIO_COMM_COMMAND_ADDRESS |
               EMAC_MDIO_COMM_START_BUSY);
-       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
 
        for (i = 0; i < 50; i++) {
                udelay(10);
 
-               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
                if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
                        udelay(5);
                        break;
                }
        }
-
        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
                BNX2X_ERR("write phy register failed\n");
 
                rc = -EBUSY;
+
        } else {
                /* data */
-               tmp = ((bp->phy_addr << 21) | (reg << 16) | val |
+               tmp = ((phy_addr << 21) | (reg << 16) | val |
                       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
                       EMAC_MDIO_COMM_START_BUSY);
-               EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+               REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
 
                for (i = 0; i < 50; i++) {
                        udelay(10);
 
-                       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+                       tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
                        if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
                                udelay(5);
                                break;
@@ -1351,75 +1520,78 @@ static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
                }
        }
 
-       /* unset clause 45 mode */
-       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-       tmp &= ~EMAC_MDIO_MODE_CLAUSE_45;
-       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
-               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       /* unset clause 45 mode, set the MDIO clock to a faster value
+        * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+        */
+       tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+       tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
                tmp |= EMAC_MDIO_MODE_AUTO_POLL;
-               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
-       }
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
 
        return rc;
 }
 
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
-                            u32 *ret_val)
+static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
+                             u32 addr, u32 val)
 {
-       int port = bp->port;
-       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-       u32 val, i;
-       int rc = 0;
+       u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+       return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
+                                      reg, addr, val);
+}
 
-               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-               val &= ~EMAC_MDIO_MODE_AUTO_POLL;
-               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-               udelay(40);
-       }
+static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl,
+                                 u32 phy_addr, u32 reg, u32 addr,
+                                 u32 *ret_val)
+{
+       u32 val;
+       int i, rc = 0;
 
-       /* set clause 45 mode */
-       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-       val |= EMAC_MDIO_MODE_CLAUSE_45;
-       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+       /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+        * (a value of 49==0x31) and make sure that the AUTO poll is off
+        */
+       val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
+       val |= (EMAC_MDIO_MODE_CLAUSE_45 |
+               (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+       REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       udelay(40);
 
        /* address */
-       val = ((bp->phy_addr << 21) | (reg << 16) | addr |
+       val = ((phy_addr << 21) | (reg << 16) | addr |
               EMAC_MDIO_COMM_COMMAND_ADDRESS |
               EMAC_MDIO_COMM_START_BUSY);
-       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
 
        for (i = 0; i < 50; i++) {
                udelay(10);
 
-               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
                if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
                        udelay(5);
                        break;
                }
        }
-
        if (val & EMAC_MDIO_COMM_START_BUSY) {
                BNX2X_ERR("read phy register failed\n");
 
                *ret_val = 0;
                rc = -EBUSY;
+
        } else {
                /* data */
-               val = ((bp->phy_addr << 21) | (reg << 16) |
+               val = ((phy_addr << 21) | (reg << 16) |
                       EMAC_MDIO_COMM_COMMAND_READ_45 |
                       EMAC_MDIO_COMM_START_BUSY);
-               EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+               REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
 
                for (i = 0; i < 50; i++) {
                        udelay(10);
 
-                       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+                       val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
                        if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
                                val &= EMAC_MDIO_COMM_DATA;
                                break;
@@ -1436,31 +1608,39 @@ static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
                *ret_val = val;
        }
 
-       /* unset clause 45 mode */
-       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
-       val &= ~EMAC_MDIO_MODE_CLAUSE_45;
-       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
-               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       /* unset clause 45 mode, set the MDIO clock to a faster value
+        * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
+        */
+       val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+       val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
+       val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
                val |= EMAC_MDIO_MODE_AUTO_POLL;
-               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
-       }
+       REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
 
        return rc;
 }
 
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg,
+                            u32 addr, u32 *ret_val)
+{
+       u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+       return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr,
+                                     reg, addr, ret_val);
+}
+
+static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg,
+                              u32 addr, u32 val)
 {
        int i;
        u32 rd_val;
 
        might_sleep();
        for (i = 0; i < 10; i++) {
-               bnx2x_mdio45_write(bp, reg, addr, val);
+               bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
                msleep(5);
-               bnx2x_mdio45_read(bp, reg, addr, &rd_val);
+               bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val);
                /* if the read value is not the same as the value we wrote,
                   we should write it again */
                if (rd_val == val)
@@ -1471,18 +1651,81 @@ static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
 }
 
 /*
- * link managment
+ * link management
  */
 
+static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result)
+{
+       switch (pause_result) {                 /* ASYM P ASYM P */
+       case 0xb:                               /*   1  0   1  1 */
+               bp->flow_ctrl = FLOW_CTRL_TX;
+               break;
+
+       case 0xe:                               /*   1  1   1  0 */
+               bp->flow_ctrl = FLOW_CTRL_RX;
+               break;
+
+       case 0x5:                               /*   0  1   0  1 */
+       case 0x7:                               /*   0  1   1  1 */
+       case 0xd:                               /*   1  1   0  1 */
+       case 0xf:                               /*   1  1   1  1 */
+               bp->flow_ctrl = FLOW_CTRL_BOTH;
+               break;
+
+       default:
+               break;
+       }
+}
+
+static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp)
+{
+       u32 ext_phy_addr;
+       u32 ld_pause;   /* local */
+       u32 lp_pause;   /* link partner */
+       u32 an_complete; /* AN complete */
+       u32 pause_result;
+       u8 ret = 0;
+
+       ext_phy_addr = ((bp->ext_phy_config &
+                        PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+       /* read twice */
+       bnx2x_mdio45_read(bp, ext_phy_addr,
+                         EXT_PHY_KR_AUTO_NEG_DEVAD,
+                         EXT_PHY_KR_STATUS, &an_complete);
+       bnx2x_mdio45_read(bp, ext_phy_addr,
+                         EXT_PHY_KR_AUTO_NEG_DEVAD,
+                         EXT_PHY_KR_STATUS, &an_complete);
+
+       if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) {
+               ret = 1;
+               bnx2x_mdio45_read(bp, ext_phy_addr,
+                                 EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                 EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause);
+               bnx2x_mdio45_read(bp, ext_phy_addr,
+                                 EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                 EXT_PHY_KR_LP_AUTO_NEG, &lp_pause);
+               pause_result = (ld_pause &
+                               EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8;
+               pause_result |= (lp_pause &
+                                EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10;
+               DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
+                  pause_result);
+               bnx2x_pause_resolve(bp, pause_result);
+       }
+       return ret;
+}
+
 static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
 {
-       u32 ld_pause;   /* local driver */
-       u32 lp_pause;   /* link partner */
+       u32 ld_pause;   /* local driver */
+       u32 lp_pause;   /* link partner */
        u32 pause_result;
 
        bp->flow_ctrl = 0;
 
-       /* reolve from gp_status in case of AN complete and not sgmii */
+       /* resolve from gp_status in case of AN complete and not sgmii */
        if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
            (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
            (!(bp->phy_flags & PHY_SGMII_FLAG)) &&
@@ -1499,45 +1742,57 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
                pause_result |= (lp_pause &
                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
                DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+               bnx2x_pause_resolve(bp, pause_result);
+       } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) ||
+                  !(bnx2x_ext_phy_resove_fc(bp))) {
+               /* forced speed */
+               if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+                       switch (bp->req_flow_ctrl) {
+                       case FLOW_CTRL_AUTO:
+                               if (bp->dev->mtu <= 4500)
+                                       bp->flow_ctrl = FLOW_CTRL_BOTH;
+                               else
+                                       bp->flow_ctrl = FLOW_CTRL_TX;
+                               break;
 
-               switch (pause_result) {                 /* ASYM P ASYM P */
-               case 0xb:                               /*   1  0   1  1 */
-                       bp->flow_ctrl = FLOW_CTRL_TX;
-                       break;
-
-               case 0xe:                               /*   1  1   1  0 */
-                       bp->flow_ctrl = FLOW_CTRL_RX;
-                       break;
+                       case FLOW_CTRL_TX:
+                               bp->flow_ctrl = FLOW_CTRL_TX;
+                               break;
 
-               case 0x5:                               /*   0  1   0  1 */
-               case 0x7:                               /*   0  1   1  1 */
-               case 0xd:                               /*   1  1   0  1 */
-               case 0xf:                               /*   1  1   1  1 */
-                       bp->flow_ctrl = FLOW_CTRL_BOTH;
-                       break;
+                       case FLOW_CTRL_RX:
+                               if (bp->dev->mtu <= 4500)
+                                       bp->flow_ctrl = FLOW_CTRL_RX;
+                               break;
 
-               default:
-                       break;
-               }
+                       case FLOW_CTRL_BOTH:
+                               if (bp->dev->mtu <= 4500)
+                                       bp->flow_ctrl = FLOW_CTRL_BOTH;
+                               else
+                                       bp->flow_ctrl = FLOW_CTRL_TX;
+                               break;
 
-       } else { /* forced mode */
-               switch (bp->req_flow_ctrl) {
-               case FLOW_CTRL_AUTO:
-                       if (bp->dev->mtu <= 4500)
-                               bp->flow_ctrl = FLOW_CTRL_BOTH;
-                       else
-                               bp->flow_ctrl = FLOW_CTRL_TX;
-                       break;
+                       case FLOW_CTRL_NONE:
+                       default:
+                               break;
+                       }
+               } else { /* forced mode */
+                       switch (bp->req_flow_ctrl) {
+                       case FLOW_CTRL_AUTO:
+                               DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+                                                  " req_autoneg 0x%x\n",
+                                  bp->req_flow_ctrl, bp->req_autoneg);
+                               break;
 
-               case FLOW_CTRL_TX:
-               case FLOW_CTRL_RX:
-               case FLOW_CTRL_BOTH:
-                       bp->flow_ctrl = bp->req_flow_ctrl;
-                       break;
+                       case FLOW_CTRL_TX:
+                       case FLOW_CTRL_RX:
+                       case FLOW_CTRL_BOTH:
+                               bp->flow_ctrl = bp->req_flow_ctrl;
+                               break;
 
-               case FLOW_CTRL_NONE:
-               default:
-                       break;
+                       case FLOW_CTRL_NONE:
+                       default:
+                               break;
+                       }
                }
        }
        DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
@@ -1548,9 +1803,9 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
        bp->link_status = 0;
 
        if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
-               DP(NETIF_MSG_LINK, "link up\n");
+               DP(NETIF_MSG_LINK, "phy link up\n");
 
-               bp->link_up = 1;
+               bp->phy_link_up = 1;
                bp->link_status |= LINK_STATUS_LINK_UP;
 
                if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
@@ -1659,20 +1914,20 @@ static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
                       bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
 
        } else { /* link_down */
-               DP(NETIF_MSG_LINK, "link down\n");
+               DP(NETIF_MSG_LINK, "phy link down\n");
 
-               bp->link_up = 0;
+               bp->phy_link_up = 0;
 
                bp->line_speed = 0;
                bp->duplex = DUPLEX_FULL;
                bp->flow_ctrl = 0;
        }
 
-       DP(NETIF_MSG_LINK, "gp_status 0x%x  link_up %d\n"
+       DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %d\n"
           DP_LEVEL "  line_speed %d  duplex %d  flow_ctrl 0x%x"
                    "  link_status 0x%x\n",
-          gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl,
-          bp->link_status);
+          gp_status, bp->phy_link_up, bp->line_speed, bp->duplex,
+          bp->flow_ctrl, bp->link_status);
 }
 
 static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
@@ -1680,40 +1935,40 @@ static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
        int port = bp->port;
 
        /* first reset all status
-        * we asume only one line will be change at a time */
+        * we assume only one line will be change at a time */
        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-                      (NIG_XGXS0_LINK_STATUS |
-                       NIG_SERDES0_LINK_STATUS |
-                       NIG_STATUS_INTERRUPT_XGXS0_LINK10G));
-       if (bp->link_up) {
+                      (NIG_STATUS_XGXS0_LINK10G |
+                       NIG_STATUS_XGXS0_LINK_STATUS |
+                       NIG_STATUS_SERDES0_LINK_STATUS));
+       if (bp->phy_link_up) {
                if (is_10g) {
                        /* Disable the 10G link interrupt
                         * by writing 1 to the status register
                         */
-                       DP(NETIF_MSG_LINK, "10G XGXS link up\n");
+                       DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
                        bnx2x_bits_en(bp,
                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-                                     NIG_STATUS_INTERRUPT_XGXS0_LINK10G);
+                                     NIG_STATUS_XGXS0_LINK10G);
 
                } else if (bp->phy_flags & PHY_XGXS_FLAG) {
                        /* Disable the link interrupt
                         * by writing 1 to the relevant lane
                         * in the status register
                         */
-                       DP(NETIF_MSG_LINK, "1G XGXS link up\n");
+                       DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
                        bnx2x_bits_en(bp,
                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
                                      ((1 << bp->ser_lane) <<
-                                      NIG_XGXS0_LINK_STATUS_SIZE));
+                                      NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
 
                } else { /* SerDes */
-                       DP(NETIF_MSG_LINK, "SerDes link up\n");
+                       DP(NETIF_MSG_LINK, "SerDes phy link up\n");
                        /* Disable the link interrupt
                         * by writing 1 to the status register
                         */
                        bnx2x_bits_en(bp,
                                      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-                                     NIG_SERDES0_LINK_STATUS);
+                                     NIG_STATUS_SERDES0_LINK_STATUS);
                }
 
        } else { /* link_down */
@@ -1724,91 +1979,182 @@ static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp)
 {
        u32 ext_phy_type;
        u32 ext_phy_addr;
-       u32 local_phy;
-       u32 val = 0;
+       u32 val1 = 0, val2;
        u32 rx_sd, pcs_status;
 
        if (bp->phy_flags & PHY_XGXS_FLAG) {
-               local_phy = bp->phy_addr;
                ext_phy_addr = ((bp->ext_phy_config &
                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
                                PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-               bp->phy_addr = (u8)ext_phy_addr;
 
                ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
                switch (ext_phy_type) {
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
                        DP(NETIF_MSG_LINK, "XGXS Direct\n");
-                       val = 1;
+                       val1 = 1;
                        break;
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
                        DP(NETIF_MSG_LINK, "XGXS 8705\n");
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
-                                         EXT_PHY_OPT_LASI_STATUS, &val);
-                       DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
-                                         EXT_PHY_OPT_LASI_STATUS, &val);
-                       DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
-
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_WIS_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_WIS_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
                                          EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
-                       val = (rx_sd & 0x1);
+                       DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
+                       val1 = (rx_sd & 0x1);
                        break;
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
                        DP(NETIF_MSG_LINK, "XGXS 8706\n");
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-                                         EXT_PHY_OPT_LASI_STATUS, &val);
-                       DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-                                         EXT_PHY_OPT_LASI_STATUS, &val);
-                       DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
-
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
                                          EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
-                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD,
-                                        EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PCS_DEVAD,
+                                         EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_AUTO_NEG_DEVAD,
+                                         EXT_PHY_OPT_AN_LINK_STATUS, &val2);
+
                        DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
-                          "  pcs_status 0x%x\n", rx_sd, pcs_status);
-                       /* link is up if both bit 0 of pmd_rx and
-                        * bit 0 of pcs_status are set
+                          "  pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n",
+                          rx_sd, pcs_status, val2, (val2 & (1<<1)));
+                       /* link is up if both bit 0 of pmd_rx_sd and
+                        * bit 0 of pcs_status are set, or if the autoneg bit
+                          1 is set
+                        */
+                       val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+                       bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+                       /* clear the interrupt LASI status register */
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                              ext_phy_addr,
+                                              EXT_PHY_KR_PCS_DEVAD,
+                                              EXT_PHY_KR_LASI_STATUS, &val2);
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                              ext_phy_addr,
+                                              EXT_PHY_KR_PCS_DEVAD,
+                                              EXT_PHY_KR_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n",
+                          val2, val1);
+                       /* Check the LASI */
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                              ext_phy_addr,
+                                              EXT_PHY_KR_PMA_PMD_DEVAD,
+                                              0x9003, &val2);
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                              ext_phy_addr,
+                                              EXT_PHY_KR_PMA_PMD_DEVAD,
+                                              0x9003, &val1);
+                       DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
+                          val2, val1);
+                       /* Check the link status */
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                              ext_phy_addr,
+                                              EXT_PHY_KR_PCS_DEVAD,
+                                              EXT_PHY_KR_PCS_STATUS, &val2);
+                       DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+                       /* Check the link status on 1.1.2 */
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                         ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_KR_STATUS, &val2);
+                       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                         ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_KR_STATUS, &val1);
+                       DP(NETIF_MSG_LINK,
+                          "KR PMA status 0x%x->0x%x\n", val2, val1);
+                       val1 = ((val1 & 4) == 4);
+                       /* If 1G was requested assume the link is up */
+                       if (!(bp->req_autoneg & AUTONEG_SPEED) &&
+                           (bp->req_line_speed == SPEED_1000))
+                               val1 = 1;
+                       bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val2);
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val1);
+                       DP(NETIF_MSG_LINK,
+                          "10G-base-T LASI status 0x%x->0x%x\n", val2, val1);
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_KR_STATUS, &val2);
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_KR_STATUS, &val1);
+                       DP(NETIF_MSG_LINK,
+                          "10G-base-T PMA status 0x%x->0x%x\n", val2, val1);
+                       val1 = ((val1 & 4) == 4);
+                       /* if link is up
+                        * print the AN outcome of the SFX7101 PHY
                         */
-                       val = (rx_sd & pcs_status);
+                       if (val1) {
+                               bnx2x_mdio45_read(bp, ext_phy_addr,
+                                                 EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                                 0x21, &val2);
+                               DP(NETIF_MSG_LINK,
+                                  "SFX7101 AN status 0x%x->%s\n", val2,
+                                  (val2 & (1<<14)) ? "Master" : "Slave");
+                       }
                        break;
 
                default:
                        DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
                           bp->ext_phy_config);
-                       val = 0;
+                       val1 = 0;
                        break;
                }
-               bp->phy_addr = local_phy;
 
        } else { /* SerDes */
                ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
                switch (ext_phy_type) {
                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
                        DP(NETIF_MSG_LINK, "SerDes Direct\n");
-                       val = 1;
+                       val1 = 1;
                        break;
 
                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
                        DP(NETIF_MSG_LINK, "SerDes 5482\n");
-                       val = 1;
+                       val1 = 1;
                        break;
 
                default:
                        DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
                           bp->ext_phy_config);
-                       val = 0;
+                       val1 = 0;
                        break;
                }
        }
 
-       return val;
+       return val1;
 }
 
 static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
@@ -1819,7 +2165,7 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
        u32 wb_write[2];
        u32 val;
 
-       DP(NETIF_MSG_LINK, "enableing BigMAC\n");
+       DP(NETIF_MSG_LINK, "enabling BigMAC\n");
        /* reset and unreset the BigMac */
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
               (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -1933,6 +2279,35 @@ static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
        bp->stats_state = STATS_STATE_ENABLE;
 }
 
+static void bnx2x_bmac_rx_disable(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+                              NIG_REG_INGRESS_BMAC0_MEM;
+       u32 wb_write[2];
+
+       /* Only if the bmac is out of reset */
+       if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+                       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) {
+               /* Clear Rx Enable bit in BMAC_CONTROL register */
+#ifdef BNX2X_DMAE_RD
+               bnx2x_read_dmae(bp, bmac_addr +
+                               BIGMAC_REGISTER_BMAC_CONTROL, 2);
+               wb_write[0] = *bnx2x_sp(bp, wb_data[0]);
+               wb_write[1] = *bnx2x_sp(bp, wb_data[1]);
+#else
+               wb_write[0] = REG_RD(bp,
+                               bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL);
+               wb_write[1] = REG_RD(bp,
+                               bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4);
+#endif
+               wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE;
+               REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+                           wb_write, 2);
+               msleep(1);
+       }
+}
+
 static void bnx2x_emac_enable(struct bnx2x *bp)
 {
        int port = bp->port;
@@ -1940,7 +2315,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
        u32 val;
        int timeout;
 
-       DP(NETIF_MSG_LINK, "enableing EMAC\n");
+       DP(NETIF_MSG_LINK, "enabling EMAC\n");
        /* reset and unreset the emac core */
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
               (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
@@ -2033,7 +2408,7 @@ static void bnx2x_emac_enable(struct bnx2x *bp)
                                      EMAC_TX_MODE_EXT_PAUSE_EN);
        }
 
-       /* KEEP_VLAN_TAG, promiscous */
+       /* KEEP_VLAN_TAG, promiscuous */
        val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
        val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
        EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
@@ -2161,7 +2536,6 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
        u32 count = 1000;
        u32 pause = 0;
 
-
        /* disable port */
        REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
 
@@ -2232,7 +2606,7 @@ static void bnx2x_pbf_update(struct bnx2x *bp)
 static void bnx2x_update_mng(struct bnx2x *bp)
 {
        if (!nomcp)
-               SHMEM_WR(bp, drv_fw_mb[bp->port].link_status,
+               SHMEM_WR(bp, port_mb[bp->port].link_status,
                         bp->link_status);
 }
 
@@ -2294,19 +2668,19 @@ static void bnx2x_link_down(struct bnx2x *bp)
                DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
        }
 
-       /* indicate link down */
+       /* indicate no mac active */
        bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
 
-       /* reset BigMac */
-       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
-              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+       /* update shared memory */
+       bnx2x_update_mng(bp);
 
-       /* ignore drain flag interrupt */
        /* activate nig drain */
        NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
 
-       /* update shared memory */
-       bnx2x_update_mng(bp);
+       /* reset BigMac */
+       bnx2x_bmac_rx_disable(bp);
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 
        /* indicate link down */
        bnx2x_link_report(bp);
@@ -2317,14 +2691,15 @@ static void bnx2x_init_mac_stats(struct bnx2x *bp);
 /* This function is called upon link interrupt */
 static void bnx2x_link_update(struct bnx2x *bp)
 {
-       u32 gp_status;
        int port = bp->port;
        int i;
+       u32 gp_status;
        int link_10g;
 
-       DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x,"
+       DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
           " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
-          " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG),
+          " 10G %x, XGXS_LINK %x\n", port,
+          (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
           REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
           REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
           REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
@@ -2336,7 +2711,7 @@ static void bnx2x_link_update(struct bnx2x *bp)
        might_sleep();
        MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
        /* avoid fast toggling */
-       for (i = 0 ; i < 10 ; i++) {
+       for (i = 0; i < 10; i++) {
                msleep(10);
                bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
                                  &gp_status);
@@ -2351,7 +2726,8 @@ static void bnx2x_link_update(struct bnx2x *bp)
        bnx2x_link_int_ack(bp, link_10g);
 
        /* link is up only if both local phy and external phy are up */
-       if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) {
+       bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp));
+       if (bp->link_up) {
                if (link_10g) {
                        bnx2x_bmac_enable(bp, 0);
                        bnx2x_leds_set(bp, SPEED_10000);
@@ -2427,7 +2803,9 @@ static void bnx2x_reset_unicore(struct bnx2x *bp)
                }
        }
 
-       BNX2X_ERR("BUG! unicore is still in reset!\n");
+       BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n",
+                 (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+                 bp->phy_addr);
 }
 
 static void bnx2x_set_swap_lanes(struct bnx2x *bp)
@@ -2475,12 +2853,12 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
                MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
 
                bnx2x_mdio22_write(bp,
-                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
 
                bnx2x_mdio22_read(bp,
-                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
-                                 &control2);
+                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+                               &control2);
 
                if (bp->autoneg & AUTONEG_PARALLEL) {
                        control2 |=
@@ -2490,8 +2868,14 @@ static void bnx2x_set_parallel_detection(struct bnx2x *bp)
                   ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
                }
                bnx2x_mdio22_write(bp,
-                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
-                                  control2);
+                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+                               control2);
+
+               /* Disable parallel detection of HiG */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+               bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
+                               MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
+                               MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
        }
 }
 
@@ -2625,7 +3009,7 @@ static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp)
        MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
 
        /* set extended capabilities */
-       if (bp->advertising & ADVERTISED_2500baseT_Full)
+       if (bp->advertising & ADVERTISED_2500baseX_Full)
                val |= MDIO_OVER_1G_UP1_2_5G;
        if (bp->advertising & ADVERTISED_10000baseT_Full)
                val |= MDIO_OVER_1G_UP1_10G;
@@ -2638,23 +3022,94 @@ static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp)
 {
        u32 an_adv;
 
-       /* for AN, we are always publishing full duplex */
-       an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
+       /* for AN, we are always publishing full duplex */
+       an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
+
+       /* resolve pause mode and advertisement
+        * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+       if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
+               switch (bp->req_flow_ctrl) {
+               case FLOW_CTRL_AUTO:
+                       if (bp->dev->mtu <= 4500) {
+                               an_adv |=
+                                    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+                               bp->advertising |= (ADVERTISED_Pause |
+                                                   ADVERTISED_Asym_Pause);
+                       } else {
+                               an_adv |=
+                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                               bp->advertising |= ADVERTISED_Asym_Pause;
+                       }
+                       break;
+
+               case FLOW_CTRL_TX:
+                       an_adv |=
+                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                       bp->advertising |= ADVERTISED_Asym_Pause;
+                       break;
+
+               case FLOW_CTRL_RX:
+                       if (bp->dev->mtu <= 4500) {
+                               an_adv |=
+                                    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+                               bp->advertising |= (ADVERTISED_Pause |
+                                                   ADVERTISED_Asym_Pause);
+                       } else {
+                               an_adv |=
+                                    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+                               bp->advertising &= ~(ADVERTISED_Pause |
+                                                    ADVERTISED_Asym_Pause);
+                       }
+                       break;
+
+               case FLOW_CTRL_BOTH:
+                       if (bp->dev->mtu <= 4500) {
+                               an_adv |=
+                                    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+                               bp->advertising |= (ADVERTISED_Pause |
+                                                   ADVERTISED_Asym_Pause);
+                       } else {
+                               an_adv |=
+                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                               bp->advertising |= ADVERTISED_Asym_Pause;
+                       }
+                       break;
+
+               case FLOW_CTRL_NONE:
+               default:
+                       an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+                       bp->advertising &= ~(ADVERTISED_Pause |
+                                            ADVERTISED_Asym_Pause);
+                       break;
+               }
+       } else { /* forced mode */
+               switch (bp->req_flow_ctrl) {
+               case FLOW_CTRL_AUTO:
+                       DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
+                                          " req_autoneg 0x%x\n",
+                          bp->req_flow_ctrl, bp->req_autoneg);
+                       break;
+
+               case FLOW_CTRL_TX:
+                       an_adv |=
+                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                       bp->advertising |= ADVERTISED_Asym_Pause;
+                       break;
 
-       /* set pause */
-       switch (bp->pause_mode) {
-       case PAUSE_SYMMETRIC:
-               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
-               break;
-       case PAUSE_ASYMMETRIC:
-               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
-               break;
-       case PAUSE_BOTH:
-               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
-               break;
-       case PAUSE_NONE:
-               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
-               break;
+               case FLOW_CTRL_RX:
+               case FLOW_CTRL_BOTH:
+                       an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+                       bp->advertising |= (ADVERTISED_Pause |
+                                           ADVERTISED_Asym_Pause);
+                       break;
+
+               case FLOW_CTRL_NONE:
+               default:
+                       an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+                       bp->advertising &= ~(ADVERTISED_Pause |
+                                            ADVERTISED_Asym_Pause);
+                       break;
+               }
        }
 
        MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
@@ -2752,47 +3207,162 @@ static void bnx2x_initialize_sgmii_process(struct bnx2x *bp)
 static void bnx2x_link_int_enable(struct bnx2x *bp)
 {
        int port = bp->port;
+       u32 ext_phy_type;
+       u32 mask;
 
        /* setting the status to report on link up
           for either XGXS or SerDes */
        bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
-                      (NIG_XGXS0_LINK_STATUS |
-                       NIG_STATUS_INTERRUPT_XGXS0_LINK10G |
-                       NIG_SERDES0_LINK_STATUS));
+                      (NIG_STATUS_XGXS0_LINK10G |
+                       NIG_STATUS_XGXS0_LINK_STATUS |
+                       NIG_STATUS_SERDES0_LINK_STATUS));
 
        if (bp->phy_flags & PHY_XGXS_FLAG) {
-               /* TBD -
-                * in force mode (not AN) we can enable just the relevant
-                * interrupt
-                * Even in AN we might enable only one according to the AN
-                * speed mask
-                */
-               bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-                             (NIG_MASK_XGXS0_LINK_STATUS |
-                              NIG_MASK_XGXS0_LINK10G));
-               DP(NETIF_MSG_LINK, "enable XGXS interrupt\n");
+               mask = (NIG_MASK_XGXS0_LINK10G |
+                       NIG_MASK_XGXS0_LINK_STATUS);
+               DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+               ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+                   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+                   (ext_phy_type !=
+                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
+                       mask |= NIG_MASK_MI_INT;
+                       DP(NETIF_MSG_LINK, "enabled external phy int\n");
+               }
 
        } else { /* SerDes */
-               bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-                             NIG_MASK_SERDES0_LINK_STATUS);
-               DP(NETIF_MSG_LINK, "enable SerDes interrupt\n");
+               mask = NIG_MASK_SERDES0_LINK_STATUS;
+               DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+               ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+               if ((ext_phy_type !=
+                               PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
+                   (ext_phy_type !=
+                               PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
+                       mask |= NIG_MASK_MI_INT;
+                       DP(NETIF_MSG_LINK, "enabled external phy int\n");
+               }
        }
+       bnx2x_bits_en(bp,
+                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                     mask);
+       DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
+          " int_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
+          " 10G %x, XGXS_LINK %x\n", port,
+          (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
+          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
+          REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+          REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+          REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
+          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
+       );
+}
+
+static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp)
+{
+       u32 ext_phy_addr = ((bp->ext_phy_config &
+                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                           PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+       u32 fw_ver1, fw_ver2;
+
+       /* Need to wait 200ms after reset */
+       msleep(200);
+       /* Boot port from external ROM
+        * Set ser_boot_ctl bit in the MISC_CTRL1 register
+        */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD,
+                               EXT_PHY_KR_MISC_CTRL1, 0x0001);
+
+       /* Reset internal microprocessor */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+                               EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+       /* set micro reset = 0 */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+                               EXT_PHY_KR_ROM_MICRO_RESET);
+       /* Reset internal microprocessor */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
+                               EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
+       /* wait for 100ms for code download via SPI port */
+       msleep(100);
+
+       /* Clear ser_boot_ctl bit */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD,
+                               EXT_PHY_KR_MISC_CTRL1, 0x0000);
+       /* Wait 100ms */
+       msleep(100);
+
+       /* Print the PHY FW version */
+       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+                              EXT_PHY_KR_PMA_PMD_DEVAD,
+                              0xca19, &fw_ver1);
+       bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
+                              EXT_PHY_KR_PMA_PMD_DEVAD,
+                              0xca1a, &fw_ver2);
+       DP(NETIF_MSG_LINK,
+          "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+}
+
+static void bnx2x_bcm8072_force_10G(struct bnx2x *bp)
+{
+       u32 ext_phy_addr = ((bp->ext_phy_config &
+                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                           PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+       /* Force KR or KX */
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL,
+                               0x2040);
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2,
+                               0x000b);
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL,
+                               0x0000);
+       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
+                               EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL,
+                               0x0000);
 }
 
 static void bnx2x_ext_phy_init(struct bnx2x *bp)
 {
-       int port = bp->port;
        u32 ext_phy_type;
        u32 ext_phy_addr;
-       u32 local_phy;
+       u32 cnt;
+       u32 ctrl;
+       u32 val = 0;
 
        if (bp->phy_flags & PHY_XGXS_FLAG) {
-               local_phy = bp->phy_addr;
                ext_phy_addr = ((bp->ext_phy_config &
                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
                                PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
 
                ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               /* Make sure that the soft reset is off (expect for the 8072:
+                * due to the lock, it will be done inside the specific
+                * handling)
+                */
+               if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+                   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+                  (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
+                   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) {
+                       /* Wait for soft reset to get cleared upto 1 sec */
+                       for (cnt = 0; cnt < 1000; cnt++) {
+                               bnx2x_mdio45_read(bp, ext_phy_addr,
+                                                 EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                                 EXT_PHY_OPT_CNTL, &ctrl);
+                               if (!(ctrl & (1<<15)))
+                                       break;
+                               msleep(1);
+                       }
+                       DP(NETIF_MSG_LINK,
+                          "control reg 0x%x (after %d ms)\n", ctrl, cnt);
+               }
+
                switch (ext_phy_type) {
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
                        DP(NETIF_MSG_LINK, "XGXS Direct\n");
@@ -2800,49 +3370,235 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
                        DP(NETIF_MSG_LINK, "XGXS 8705\n");
-                       bnx2x_bits_en(bp,
-                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-                                     NIG_MASK_MI_INT);
-                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
 
-                       bp->phy_addr = ext_phy_type;
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_PMA_PMD_DEVAD,
                                            EXT_PHY_OPT_PMD_MISC_CNTL,
                                            0x8288);
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_PMA_PMD_DEVAD,
                                            EXT_PHY_OPT_PHY_IDENTIFIER,
                                            0x7fbf);
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_PMA_PMD_DEVAD,
                                            EXT_PHY_OPT_CMU_PLL_BYPASS,
                                            0x0100);
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD,
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_WIS_DEVAD,
                                            EXT_PHY_OPT_LASI_CNTL, 0x1);
                        break;
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
                        DP(NETIF_MSG_LINK, "XGXS 8706\n");
-                       bnx2x_bits_en(bp,
-                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-                                     NIG_MASK_MI_INT);
-                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
-
-                       bp->phy_addr = ext_phy_type;
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
-                                           EXT_PHY_OPT_PMD_DIGITAL_CNT,
-                                           0x400);
-                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+
+                       if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+                               /* Force speed */
+                               if (bp->req_line_speed == SPEED_10000) {
+                                       DP(NETIF_MSG_LINK,
+                                          "XGXS 8706 force 10Gbps\n");
+                                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                               EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                               EXT_PHY_OPT_PMD_DIGITAL_CNT,
+                                               0x400);
+                               } else {
+                                       /* Force 1Gbps */
+                                       DP(NETIF_MSG_LINK,
+                                          "XGXS 8706 force 1Gbps\n");
+
+                                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                               EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                               EXT_PHY_OPT_CNTL,
+                                               0x0040);
+
+                                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                               EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                               EXT_PHY_OPT_CNTL2,
+                                               0x000D);
+                               }
+
+                               /* Enable LASI */
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                                   EXT_PHY_OPT_LASI_CNTL,
+                                                   0x1);
+                       } else {
+                               /* AUTONEG */
+                               /* Allow CL37 through CL73 */
+                               DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_AUTO_NEG_DEVAD,
+                                                   EXT_PHY_OPT_AN_CL37_CL73,
+                                                   0x040c);
+
+                               /* Enable Full-Duplex advertisment on CL37 */
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_AUTO_NEG_DEVAD,
+                                                   EXT_PHY_OPT_AN_CL37_FD,
+                                                   0x0020);
+                               /* Enable CL37 AN */
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_AUTO_NEG_DEVAD,
+                                                   EXT_PHY_OPT_AN_CL37_AN,
+                                                   0x1000);
+                               /* Advertise 10G/1G support */
+                               if (bp->advertising &
+                                   ADVERTISED_1000baseT_Full)
+                                       val = (1<<5);
+                               if (bp->advertising &
+                                   ADVERTISED_10000baseT_Full)
+                                       val |= (1<<7);
+
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_AUTO_NEG_DEVAD,
+                                                   EXT_PHY_OPT_AN_ADV, val);
+                               /* Enable LASI */
+                               bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                                   EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                                   EXT_PHY_OPT_LASI_CNTL,
+                                                   0x1);
+
+                               /* Enable clause 73 AN */
+                               bnx2x_mdio45_write(bp, ext_phy_addr,
+                                                  EXT_PHY_AUTO_NEG_DEVAD,
+                                                  EXT_PHY_OPT_CNTL,
+                                                  0x1200);
+                       }
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+                       bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+                       /* Wait for soft reset to get cleared upto 1 sec */
+                       for (cnt = 0; cnt < 1000; cnt++) {
+                               bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                               EXT_PHY_OPT_CNTL, &ctrl);
+                               if (!(ctrl & (1<<15)))
+                                       break;
+                               msleep(1);
+                       }
+                       DP(NETIF_MSG_LINK,
+                          "8072 control reg 0x%x (after %d ms)\n",
+                          ctrl, cnt);
+
+                       bnx2x_bcm8072_external_rom_boot(bp);
+                       DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n");
+
+                       /* enable LASI */
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_PMA_PMD_DEVAD,
+                                               0x9000, 0x0400);
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_PMA_PMD_DEVAD,
+                                               EXT_PHY_KR_LASI_CNTL, 0x0004);
+
+                       /* If this is forced speed, set to KR or KX
+                        * (all other are not supported)
+                        */
+                       if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+                               if (bp->req_line_speed == SPEED_10000) {
+                                       bnx2x_bcm8072_force_10G(bp);
+                                       DP(NETIF_MSG_LINK,
+                                          "Forced speed 10G on 8072\n");
+                                       /* unlock */
+                                       bnx2x_hw_unlock(bp,
+                                               HW_LOCK_RESOURCE_8072_MDIO);
+                                       break;
+                               } else
+                                       val = (1<<5);
+                       } else {
+
+                               /* Advertise 10G/1G support */
+                               if (bp->advertising &
+                                               ADVERTISED_1000baseT_Full)
+                                       val = (1<<5);
+                               if (bp->advertising &
+                                               ADVERTISED_10000baseT_Full)
+                                       val |= (1<<7);
+                       }
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                       ext_phy_addr,
+                                       EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                       0x11, val);
+                       /* Add support for CL37 ( passive mode ) I */
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                               0x8370, 0x040c);
+                       /* Add support for CL37 ( passive mode ) II */
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                               0xffe4, 0x20);
+                       /* Add support for CL37 ( passive mode ) III */
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                               0xffe0, 0x1000);
+                       /* Restart autoneg */
+                       msleep(500);
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                       ext_phy_addr,
+                                       EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                       EXT_PHY_KR_CTRL, 0x1200);
+                       DP(NETIF_MSG_LINK, "8072 Autoneg Restart: "
+                          "1G %ssupported  10G %ssupported\n",
+                          (val & (1<<5)) ? "" : "not ",
+                          (val & (1<<7)) ? "" : "not ");
+
+                       /* unlock */
+                       bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+                       DP(NETIF_MSG_LINK,
+                          "Setting the SFX7101 LASI indication\n");
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_PMA_PMD_DEVAD,
                                            EXT_PHY_OPT_LASI_CNTL, 0x1);
+                       DP(NETIF_MSG_LINK,
+                          "Setting the SFX7101 LED to blink on traffic\n");
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           0xC007, (1<<3));
+
+                       /* read modify write pause advertizing */
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                         EXT_PHY_KR_AUTO_NEG_ADVERT, &val);
+                       val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH;
+                       /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+                       if (bp->advertising & ADVERTISED_Pause)
+                               val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE;
+
+                       if (bp->advertising & ADVERTISED_Asym_Pause) {
+                               val |=
+                                EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC;
+                       }
+                       DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val);
+                       bnx2x_mdio45_vwrite(bp, ext_phy_addr,
+                                           EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                           EXT_PHY_KR_AUTO_NEG_ADVERT, val);
+                       /* Restart autoneg */
+                       bnx2x_mdio45_read(bp, ext_phy_addr,
+                                         EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                         EXT_PHY_KR_CTRL, &val);
+                       val |= 0x200;
+                       bnx2x_mdio45_write(bp, ext_phy_addr,
+                                           EXT_PHY_KR_AUTO_NEG_DEVAD,
+                                           EXT_PHY_KR_CTRL, val);
                        break;
 
                default:
-                       DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
-                          bp->ext_phy_config);
+                       BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n",
+                                 bp->ext_phy_config);
                        break;
                }
-               bp->phy_addr = local_phy;
 
        } else { /* SerDes */
-/*             ext_phy_addr = ((bp->ext_phy_config &
+/*             ext_phy_addr = ((bp->ext_phy_config &
                                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
                                PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
 */
@@ -2854,10 +3610,6 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
 
                case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
                        DP(NETIF_MSG_LINK, "SerDes 5482\n");
-                       bnx2x_bits_en(bp,
-                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
-                                     NIG_MASK_MI_INT);
-                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
                        break;
 
                default:
@@ -2871,8 +3623,22 @@ static void bnx2x_ext_phy_init(struct bnx2x *bp)
 static void bnx2x_ext_phy_reset(struct bnx2x *bp)
 {
        u32 ext_phy_type;
-       u32 ext_phy_addr;
-       u32 local_phy;
+       u32 ext_phy_addr = ((bp->ext_phy_config &
+                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                           PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+       u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+       /* The PHY reset is controled by GPIO 1
+        * Give it 1ms of reset pulse
+        */
+       if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+           (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+               bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+                              MISC_REGISTERS_GPIO_OUTPUT_LOW);
+               msleep(1);
+               bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+                              MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+       }
 
        if (bp->phy_flags & PHY_XGXS_FLAG) {
                ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
@@ -2883,15 +3649,24 @@ static void bnx2x_ext_phy_reset(struct bnx2x *bp)
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-                       DP(NETIF_MSG_LINK, "XGXS 8705/6\n");
-                       local_phy = bp->phy_addr;
-                       ext_phy_addr = ((bp->ext_phy_config &
-                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-                       bp->phy_addr = (u8)ext_phy_addr;
-                       bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                       DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+                       bnx2x_mdio45_write(bp, ext_phy_addr,
+                                          EXT_PHY_OPT_PMA_PMD_DEVAD,
                                           EXT_PHY_OPT_CNTL, 0xa040);
-                       bp->phy_addr = local_phy;
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+                       DP(NETIF_MSG_LINK, "XGXS 8072\n");
+                       bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+                       bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
+                                               ext_phy_addr,
+                                               EXT_PHY_KR_PMA_PMD_DEVAD,
+                                               0, 1<<15);
+                       bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+                       DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
                        break;
 
                default:
@@ -2930,6 +3705,7 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
                        NIG_MASK_SERDES0_LINK_STATUS |
                        NIG_MASK_MI_INT));
 
+       /* Activate the external PHY */
        bnx2x_ext_phy_reset(bp);
 
        bnx2x_set_aer_mmd(bp);
@@ -2994,13 +3770,13 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
                        /* AN enabled */
                        bnx2x_set_brcm_cl37_advertisment(bp);
 
-                       /* program duplex & pause advertisment (for aneg) */
+                       /* program duplex & pause advertisement (for aneg) */
                        bnx2x_set_ieee_aneg_advertisment(bp);
 
                        /* enable autoneg */
                        bnx2x_set_autoneg(bp);
 
-                       /* enalbe and restart AN */
+                       /* enable and restart AN */
                        bnx2x_restart_autoneg(bp);
                }
 
@@ -3010,11 +3786,11 @@ static void bnx2x_link_initialize(struct bnx2x *bp)
                bnx2x_initialize_sgmii_process(bp);
        }
 
-       /* enable the interrupt */
-       bnx2x_link_int_enable(bp);
-
        /* init ext phy and enable link state int */
        bnx2x_ext_phy_init(bp);
+
+       /* enable the interrupt */
+       bnx2x_link_int_enable(bp);
 }
 
 static void bnx2x_phy_deassert(struct bnx2x *bp)
@@ -3073,6 +3849,11 @@ static int bnx2x_phy_init(struct bnx2x *bp)
 static void bnx2x_link_reset(struct bnx2x *bp)
 {
        int port = bp->port;
+       u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
+
+       /* update shared memory */
+       bp->link_status = 0;
+       bnx2x_update_mng(bp);
 
        /* disable attentions */
        bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
@@ -3081,21 +3862,45 @@ static void bnx2x_link_reset(struct bnx2x *bp)
                        NIG_MASK_SERDES0_LINK_STATUS |
                        NIG_MASK_MI_INT));
 
-       bnx2x_ext_phy_reset(bp);
+       /* activate nig drain */
+       NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+       /* disable nig egress interface */
+       NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+       NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+       /* Stop BigMac rx */
+       bnx2x_bmac_rx_disable(bp);
+
+       /* disable emac */
+       NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+       msleep(10);
+
+       /* The PHY reset is controled by GPIO 1
+        * Hold it as output low
+        */
+       if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
+           (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
+               bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+                              MISC_REGISTERS_GPIO_OUTPUT_LOW);
+               DP(NETIF_MSG_LINK, "reset external PHY\n");
+       }
 
        /* reset the SerDes/XGXS */
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
               (0x1ff << (port*16)));
 
-       /* reset EMAC / BMAC and disable NIG interfaces */
-       NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
-       NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+       /* reset BigMac */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
 
-       NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+       /* disable nig ingress interface */
+       NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
        NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
-       NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
 
-       NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+       /* set link down */
+       bp->link_up = 0;
 }
 
 #ifdef BNX2X_XGXS_LB
@@ -3158,7 +3963,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
        int port = bp->port;
 
        DP(NETIF_MSG_TIMER,
-          "spe (%x:%x)  command %x  hw_cid %x  data (%x:%x)  left %x\n",
+          "spe (%x:%x)  command %d  hw_cid %x  data (%x:%x)  left %x\n",
           (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
           (void *)bp->spq_prod_bd - (void *)bp->spq), command,
           HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
@@ -3176,6 +3981,7 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
                bnx2x_panic();
                return -EBUSY;
        }
+
        /* CID needs port number to be encoded int it */
        bp->spq_prod_bd->hdr.conn_and_cmd_data =
                        cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
@@ -3282,8 +4088,8 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
        u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8;
        u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
                              MISC_REG_AEU_MASK_ATTN_FUNC_0;
-       u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
-                                  NIG_REG_MASK_INTERRUPT_PORT0;
+       u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
+                                      NIG_REG_MASK_INTERRUPT_PORT0;
 
        if (~bp->aeu_mask & (asserted & 0xff))
                BNX2X_ERR("IGU ERROR\n");
@@ -3301,15 +4107,11 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
 
        if (asserted & ATTN_HARD_WIRED_MASK) {
                if (asserted & ATTN_NIG_FOR_FUNC) {
-                       u32 nig_status_port;
-                       u32 nig_int_addr = port ?
-                                       NIG_REG_STATUS_INTERRUPT_PORT1 :
-                                       NIG_REG_STATUS_INTERRUPT_PORT0;
 
-                       bp->nig_mask = REG_RD(bp, nig_mask_addr);
-                       REG_WR(bp, nig_mask_addr, 0);
+                       /* save nig interrupt mask */
+                       bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+                       REG_WR(bp, nig_int_mask_addr, 0);
 
-                       nig_status_port = REG_RD(bp, nig_int_addr);
                        bnx2x_link_update(bp);
 
                        /* handle unicore attn? */
@@ -3362,15 +4164,132 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
 
        /* now set back the mask */
        if (asserted & ATTN_NIG_FOR_FUNC)
-               REG_WR(bp, nig_mask_addr, bp->nig_mask);
+               REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
 }
 
-static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
 {
        int port = bp->port;
-       int index;
+       int reg_offset;
+       u32 val;
+
+       if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
+
+               reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+                                    MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+               val = REG_RD(bp, reg_offset);
+               val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
+               REG_WR(bp, reg_offset, val);
+
+               BNX2X_ERR("SPIO5 hw attention\n");
+
+               switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+               case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+                       /* Fan failure attention */
+
+                       /* The PHY reset is controled by GPIO 1 */
+                       bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+                                      MISC_REGISTERS_GPIO_OUTPUT_LOW);
+                       /* Low power mode is controled by GPIO 2 */
+                       bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+                                      MISC_REGISTERS_GPIO_OUTPUT_LOW);
+                       /* mark the failure */
+                       bp->ext_phy_config &=
+                                       ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+                       bp->ext_phy_config |=
+                                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+                       SHMEM_WR(bp,
+                                dev_info.port_hw_config[port].
+                                                       external_phy_config,
+                                bp->ext_phy_config);
+                       /* log the failure */
+                       printk(KERN_ERR PFX "Fan Failure on Network"
+                              " Controller %s has caused the driver to"
+                              " shutdown the card to prevent permanent"
+                              " damage.  Please contact Dell Support for"
+                              " assistance\n", bp->dev->name);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+}
+
+static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
+{
+       u32 val;
+
+       if (attn & BNX2X_DOORQ_ASSERT) {
+
+               val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
+               BNX2X_ERR("DB hw attention 0x%x\n", val);
+               /* DORQ discard attention */
+               if (val & 0x2)
+                       BNX2X_ERR("FATAL error from DORQ\n");
+       }
+}
+
+static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
+{
+       u32 val;
+
+       if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
+
+               val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
+               BNX2X_ERR("CFC hw attention 0x%x\n", val);
+               /* CFC error attention */
+               if (val & 0x2)
+                       BNX2X_ERR("FATAL error from CFC\n");
+       }
+
+       if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
+
+               val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
+               BNX2X_ERR("PXP hw attention 0x%x\n", val);
+               /* RQ_USDMDP_FIFO_OVERFLOW */
+               if (val & 0x18000)
+                       BNX2X_ERR("FATAL error from PXP\n");
+       }
+}
+
+static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
+{
+       if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
+
+               if (attn & BNX2X_MC_ASSERT_BITS) {
+
+                       BNX2X_ERR("MC assert!\n");
+                       REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
+                       REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
+                       REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
+                       REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
+                       bnx2x_panic();
+
+               } else if (attn & BNX2X_MCP_ASSERT) {
+
+                       BNX2X_ERR("MCP assert!\n");
+                       REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
+                       bnx2x_mc_assert(bp);
+
+               } else
+                       BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
+       }
+
+       if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
+
+               REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
+               BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn);
+       }
+}
+
+static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+{
        struct attn_route attn;
        struct attn_route group_mask;
+       int port = bp->port;
+       int index;
        u32 reg_addr;
        u32 val;
 
@@ -3391,64 +4310,14 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
                        DP(NETIF_MSG_HW, "group[%d]: %llx\n", index,
                           (unsigned long long)group_mask.sig[0]);
 
-                       if (attn.sig[3] & group_mask.sig[3] &
-                           EVEREST_GEN_ATTN_IN_USE_MASK) {
-
-                               if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) {
-
-                                       BNX2X_ERR("MC assert!\n");
-                                       bnx2x_panic();
-
-                               } else if (attn.sig[3] & BNX2X_MCP_ASSERT) {
-
-                                       BNX2X_ERR("MCP assert!\n");
-                                       REG_WR(bp,
-                                            MISC_REG_AEU_GENERAL_ATTN_11, 0);
-                                       bnx2x_mc_assert(bp);
-
-                               } else {
-                                       BNX2X_ERR("UNKOWEN HW ASSERT!\n");
-                               }
-                       }
-
-                       if (attn.sig[1] & group_mask.sig[1] &
-                           BNX2X_DOORQ_ASSERT) {
-
-                               val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
-                               BNX2X_ERR("DB hw attention 0x%x\n", val);
-                               /* DORQ discard attention */
-                               if (val & 0x2)
-                                       BNX2X_ERR("FATAL error from DORQ\n");
-                       }
-
-                       if (attn.sig[2] & group_mask.sig[2] &
-                           AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
-
-                               val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
-                               BNX2X_ERR("CFC hw attention 0x%x\n", val);
-                               /* CFC error attention */
-                               if (val & 0x2)
-                                       BNX2X_ERR("FATAL error from CFC\n");
-                       }
-
-                       if (attn.sig[2] & group_mask.sig[2] &
-                           AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
-
-                               val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
-                               BNX2X_ERR("PXP hw attention 0x%x\n", val);
-                               /* RQ_USDMDP_FIFO_OVERFLOW */
-                               if (val & 0x18000)
-                                       BNX2X_ERR("FATAL error from PXP\n");
-                       }
-
-                       if (attn.sig[3] & group_mask.sig[3] &
-                           EVEREST_LATCHED_ATTN_IN_USE_MASK) {
-
-                               REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
-                                      0x7ff);
-                               DP(NETIF_MSG_HW, "got latched bits 0x%x\n",
-                                  attn.sig[3]);
-                       }
+                       bnx2x_attn_int_deasserted3(bp,
+                                       attn.sig[3] & group_mask.sig[3]);
+                       bnx2x_attn_int_deasserted1(bp,
+                                       attn.sig[1] & group_mask.sig[1]);
+                       bnx2x_attn_int_deasserted2(bp,
+                                       attn.sig[2] & group_mask.sig[2]);
+                       bnx2x_attn_int_deasserted0(bp,
+                                       attn.sig[0] & group_mask.sig[0]);
 
                        if ((attn.sig[0] & group_mask.sig[0] &
                                                HW_INTERRUT_ASSERT_SET_0) ||
@@ -3456,7 +4325,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
                                                HW_INTERRUT_ASSERT_SET_1) ||
                            (attn.sig[2] & group_mask.sig[2] &
                                                HW_INTERRUT_ASSERT_SET_2))
-                               BNX2X_ERR("FATAL HW block attention\n");
+                               BNX2X_ERR("FATAL HW block attention"
+                                         "  set0 0x%x  set1 0x%x"
+                                         "  set2 0x%x\n",
+                                         (attn.sig[0] & group_mask.sig[0] &
+                                          HW_INTERRUT_ASSERT_SET_0),
+                                         (attn.sig[1] & group_mask.sig[1] &
+                                          HW_INTERRUT_ASSERT_SET_1),
+                                         (attn.sig[2] & group_mask.sig[2] &
+                                          HW_INTERRUT_ASSERT_SET_2));
 
                        if ((attn.sig[0] & group_mask.sig[0] &
                                                HW_PRTY_ASSERT_SET_0) ||
@@ -3464,7 +4341,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
                                                HW_PRTY_ASSERT_SET_1) ||
                            (attn.sig[2] & group_mask.sig[2] &
                                                HW_PRTY_ASSERT_SET_2))
-                               BNX2X_ERR("FATAL HW block parity atention\n");
+                              BNX2X_ERR("FATAL HW block parity attention\n");
                }
        }
 
@@ -3529,7 +4406,7 @@ static void bnx2x_sp_task(struct work_struct *work)
 
        /* Return here if interrupt is disabled */
        if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
-               DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+               DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
                return;
        }
 
@@ -3539,12 +4416,11 @@ static void bnx2x_sp_task(struct work_struct *work)
 
        DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
 
-       if (status & 0x1) {
-               /* HW attentions */
+       /* HW attentions */
+       if (status & 0x1)
                bnx2x_attn_int(bp);
-       }
 
-       /* CStorm events: query_stats, cfc delete ramrods */
+       /* CStorm events: query_stats, port delete ramrod */
        if (status & 0x2)
                bp->stat_pending = 0;
 
@@ -3558,6 +4434,7 @@ static void bnx2x_sp_task(struct work_struct *work)
                     IGU_INT_NOP, 1);
        bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
                     IGU_INT_ENABLE, 1);
+
 }
 
 static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
@@ -3567,11 +4444,11 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
 
        /* Return here if interrupt is disabled */
        if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
-               DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+               DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
                return IRQ_HANDLED;
        }
 
-       bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+       bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
 
 #ifdef BNX2X_STOP_ON_ERROR
        if (unlikely(bp->panic))
@@ -3906,7 +4783,7 @@ static void bnx2x_stop_stats(struct bnx2x *bp)
 
                while (bp->stats_state != STATS_STATE_DISABLE) {
                        if (!timeout) {
-                               BNX2X_ERR("timeout wating for stats stop\n");
+                               BNX2X_ERR("timeout waiting for stats stop\n");
                                break;
                        }
                        timeout--;
@@ -4173,39 +5050,37 @@ static void bnx2x_update_net_stats(struct bnx2x *bp)
 
        nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
 
-       nstats->tx_bytes =
-               bnx2x_hilo(&estats->total_bytes_transmitted_hi);
+       nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
 
-       nstats->rx_dropped = estats->checksum_discard +
-                                  estats->mac_discard;
+       nstats->rx_dropped = estats->checksum_discard + estats->mac_discard;
        nstats->tx_dropped = 0;
 
        nstats->multicast =
                bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
 
-       nstats->collisions =
-               estats->single_collision_transmit_frames +
-               estats->multiple_collision_transmit_frames +
-               estats->late_collision_frames +
-               estats->excessive_collision_frames;
+       nstats->collisions = estats->single_collision_transmit_frames +
+                            estats->multiple_collision_transmit_frames +
+                            estats->late_collision_frames +
+                            estats->excessive_collision_frames;
 
        nstats->rx_length_errors = estats->runt_packets_received +
                                   estats->jabber_packets_received;
-       nstats->rx_over_errors = estats->no_buff_discard;
+       nstats->rx_over_errors = estats->brb_discard +
+                                estats->brb_truncate_discard;
        nstats->rx_crc_errors = estats->crc_receive_errors;
        nstats->rx_frame_errors = estats->alignment_errors;
-       nstats->rx_fifo_errors = estats->brb_discard +
-                                      estats->brb_truncate_discard;
+       nstats->rx_fifo_errors = estats->no_buff_discard;
        nstats->rx_missed_errors = estats->xxoverflow_discard;
 
        nstats->rx_errors = nstats->rx_length_errors +
                            nstats->rx_over_errors +
                            nstats->rx_crc_errors +
                            nstats->rx_frame_errors +
-                           nstats->rx_fifo_errors;
+                           nstats->rx_fifo_errors +
+                           nstats->rx_missed_errors;
 
        nstats->tx_aborted_errors = estats->late_collision_frames +
-                                         estats->excessive_collision_frames;
+                                   estats->excessive_collision_frames;
        nstats->tx_carrier_errors = estats->false_carrier_detections;
        nstats->tx_fifo_errors = 0;
        nstats->tx_heartbeat_errors = 0;
@@ -4334,7 +5209,7 @@ static void bnx2x_timer(unsigned long data)
                return;
 
        if (atomic_read(&bp->intr_sem) != 0)
-               goto bnx2x_restart_timer;
+               goto timer_restart;
 
        if (poll) {
                struct bnx2x_fastpath *fp = &bp->fp[0];
@@ -4344,7 +5219,7 @@ static void bnx2x_timer(unsigned long data)
                rc = bnx2x_rx_int(fp, 1000);
        }
 
-       if (!nomcp && (bp->bc_ver >= 0x040003)) {
+       if (!nomcp) {
                int port = bp->port;
                u32 drv_pulse;
                u32 mcp_pulse;
@@ -4353,9 +5228,9 @@ static void bnx2x_timer(unsigned long data)
                bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
                /* TBD - add SYSTEM_TIME */
                drv_pulse = bp->fw_drv_pulse_wr_seq;
-               SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse);
+               SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse);
 
-               mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) &
+               mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) &
                             MCP_PULSE_SEQ_MASK);
                /* The delta between driver pulse and mcp response
                 * should be 1 (before mcp response) or 0 (after mcp response)
@@ -4369,11 +5244,11 @@ static void bnx2x_timer(unsigned long data)
        }
 
        if (bp->stats_state == STATS_STATE_DISABLE)
-               goto bnx2x_restart_timer;
+               goto timer_restart;
 
        bnx2x_update_stats(bp);
 
-bnx2x_restart_timer:
+timer_restart:
        mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
 
@@ -4438,6 +5313,9 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                                            atten_status_block);
        def_sb->atten_status_block.status_block_id = id;
 
+       bp->def_att_idx = 0;
+       bp->attn_state = 0;
+
        reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
                             MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
 
@@ -4472,6 +5350,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                                            u_def_status_block);
        def_sb->u_def_status_block.status_block_id = id;
 
+       bp->def_u_idx = 0;
+
        REG_WR(bp, BAR_USTRORM_INTMEM +
               USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
        REG_WR(bp, BAR_USTRORM_INTMEM +
@@ -4489,6 +5369,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                                            c_def_status_block);
        def_sb->c_def_status_block.status_block_id = id;
 
+       bp->def_c_idx = 0;
+
        REG_WR(bp, BAR_CSTRORM_INTMEM +
               CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
        REG_WR(bp, BAR_CSTRORM_INTMEM +
@@ -4506,6 +5388,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                                            t_def_status_block);
        def_sb->t_def_status_block.status_block_id = id;
 
+       bp->def_t_idx = 0;
+
        REG_WR(bp, BAR_TSTRORM_INTMEM +
               TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
        REG_WR(bp, BAR_TSTRORM_INTMEM +
@@ -4523,6 +5407,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                                            x_def_status_block);
        def_sb->x_def_status_block.status_block_id = id;
 
+       bp->def_x_idx = 0;
+
        REG_WR(bp, BAR_XSTRORM_INTMEM +
               XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
        REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -4535,6 +5421,8 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
                REG_WR16(bp, BAR_XSTRORM_INTMEM +
                         XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
 
+       bp->stat_pending = 0;
+
        bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
 }
 
@@ -4626,7 +5514,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
                fp->rx_bd_prod = fp->rx_comp_prod = ring_prod;
                fp->rx_pkt = fp->rx_calls = 0;
 
-               /* Warning! this will genrate an interrupt (to the TSTORM) */
+               /* Warning! this will generate an interrupt (to the TSTORM) */
                /* must only be done when chip is initialized */
                REG_WR(bp, BAR_TSTRORM_INTMEM +
                       TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod);
@@ -4678,7 +5566,6 @@ static void bnx2x_init_sp_ring(struct bnx2x *bp)
 
        bp->spq_left = MAX_SPQ_PENDING;
        bp->spq_prod_idx = 0;
-       bp->dsb_sp_prod_idx = 0;
        bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
        bp->spq_prod_bd = bp->spq;
        bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
@@ -4755,6 +5642,42 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
        REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
 }
 
+static void bnx2x_set_client_config(struct bnx2x *bp)
+{
+#ifdef BCM_VLAN
+       int mode = bp->rx_mode;
+#endif
+       int i, port = bp->port;
+       struct tstorm_eth_client_config tstorm_client = {0};
+
+       tstorm_client.mtu = bp->dev->mtu;
+       tstorm_client.statistics_counter_id = 0;
+       tstorm_client.config_flags =
+                               TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+#ifdef BCM_VLAN
+       if (mode && bp->vlgrp) {
+               tstorm_client.config_flags |=
+                               TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+               DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+       }
+#endif
+       if (mode != BNX2X_RX_MODE_PROMISC)
+               tstorm_client.drop_flags =
+                               TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR;
+
+       for_each_queue(bp, i) {
+               REG_WR(bp, BAR_TSTRORM_INTMEM +
+                      TSTORM_CLIENT_CONFIG_OFFSET(port, i),
+                      ((u32 *)&tstorm_client)[0]);
+               REG_WR(bp, BAR_TSTRORM_INTMEM +
+                      TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4,
+                      ((u32 *)&tstorm_client)[1]);
+       }
+
+/*     DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
+          ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+}
+
 static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 {
        int mode = bp->rx_mode;
@@ -4794,41 +5717,9 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 /*             DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
                   ((u32 *)&tstorm_mac_filter)[i]); */
        }
-}
-
-static void bnx2x_set_client_config(struct bnx2x *bp, int client_id)
-{
-#ifdef BCM_VLAN
-       int mode = bp->rx_mode;
-#endif
-       int port = bp->port;
-       struct tstorm_eth_client_config tstorm_client = {0};
-
-       tstorm_client.mtu = bp->dev->mtu;
-       tstorm_client.statistics_counter_id = 0;
-       tstorm_client.config_flags =
-               TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
-#ifdef BCM_VLAN
-       if (mode && bp->vlgrp) {
-               tstorm_client.config_flags |=
-                               TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
-               DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
-       }
-#endif
-       tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR |
-                                   TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR |
-                                   TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR |
-                                   TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR);
-
-       REG_WR(bp, BAR_TSTRORM_INTMEM +
-              TSTORM_CLIENT_CONFIG_OFFSET(port, client_id),
-              ((u32 *)&tstorm_client)[0]);
-       REG_WR(bp, BAR_TSTRORM_INTMEM +
-              TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4,
-              ((u32 *)&tstorm_client)[1]);
 
-/*      DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
-          ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+       if (mode != BNX2X_RX_MODE_NONE)
+               bnx2x_set_client_config(bp);
 }
 
 static void bnx2x_init_internal(struct bnx2x *bp)
@@ -4836,7 +5727,6 @@ static void bnx2x_init_internal(struct bnx2x *bp)
        int port = bp->port;
        struct tstorm_eth_function_common_config tstorm_config = {0};
        struct stats_indication_flags stats_flags = {0};
-       int i;
 
        if (is_multi(bp)) {
                tstorm_config.config_flags = MULTI_FLAGS;
@@ -4850,13 +5740,9 @@ static void bnx2x_init_internal(struct bnx2x *bp)
 /*      DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
           (*(u32 *)&tstorm_config)); */
 
-       bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */
+       bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
        bnx2x_set_storm_rx_mode(bp);
 
-       for_each_queue(bp, i)
-               bnx2x_set_client_config(bp, i);
-
-
        stats_flags.collect_eth = cpu_to_le32(1);
 
        REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
@@ -4902,7 +5788,7 @@ static void bnx2x_nic_init(struct bnx2x *bp)
        bnx2x_init_internal(bp);
        bnx2x_init_stats(bp);
        bnx2x_init_ind_table(bp);
-       bnx2x_enable_int(bp);
+       bnx2x_int_enable(bp);
 
 }
 
@@ -5265,8 +6151,10 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
        if (mode & 0x1) {       /* init common */
                DP(BNX2X_MSG_MCP, "starting common init  func %d  mode %x\n",
                   func, mode);
-               REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff);
-               REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc);
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+                      0xffffffff);
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+                      0xfffc);
                bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
 
                REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
@@ -5359,7 +6247,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
                REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8);
 #endif
                bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
-               /* softrest pulse */
+               /* soft reset pulse */
                REG_WR(bp, QM_REG_SOFT_RESET, 1);
                REG_WR(bp, QM_REG_SOFT_RESET, 0);
 
@@ -5413,7 +6301,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
                REG_WR(bp, SRC_REG_SOFT_RST, 1);
                for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
                        REG_WR(bp, i, 0xc0cac01a);
-                       /* TODO: repleace with something meaningfull */
+                       /* TODO: replace with something meaningful */
                }
                /* SRCH COMMON comes here */
                REG_WR(bp, SRC_REG_SOFT_RST, 0);
@@ -5486,6 +6374,28 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
                enable_blocks_attention(bp);
                /* enable_blocks_parity(bp); */
 
+               switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+               case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+                       /* Fan failure is indicated by SPIO 5 */
+                       bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+                                      MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+                       /* set to active low mode */
+                       val = REG_RD(bp, MISC_REG_SPIO_INT);
+                       val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+                                       MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+                       REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+                       /* enable interrupt to signal the IGU */
+                       val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+                       val |= (1 << MISC_REGISTERS_SPIO_5);
+                       REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+                       break;
+
+               default:
+                       break;
+               }
+
        } /* end of common init */
 
        /* per port init */
@@ -5645,9 +6555,21 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
        /* Port MCP comes here */
        /* Port DMAE comes here */
 
+       switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+       case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+               /* add SPIO 5 to group 0 */
+               val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+               val |= AEU_INPUTS_ATTN_BITS_SPIO5;
+               REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+               break;
+
+       default:
+               break;
+       }
+
        bnx2x_link_reset(bp);
 
-       /* Reset pciex errors for debug */
+       /* Reset PCIE errors for debug */
        REG_WR(bp, 0x2114, 0xffffffff);
        REG_WR(bp, 0x2120, 0xffffffff);
        REG_WR(bp, 0x2814, 0xffffffff);
@@ -5669,9 +6591,9 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
                port = bp->port;
 
                bp->fw_drv_pulse_wr_seq =
-                               (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) &
+                               (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) &
                                 DRV_PULSE_SEQ_MASK);
-               bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param);
+               bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param);
                DP(BNX2X_MSG_MCP, "drv_pulse 0x%x  fw_mb 0x%x\n",
                   bp->fw_drv_pulse_wr_seq, bp->fw_mb);
        } else {
@@ -5681,16 +6603,15 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
        return 0;
 }
 
-
-/* send the MCP a request, block untill there is a reply */
+/* send the MCP a request, block until there is a reply */
 static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
 {
-       u32 rc = 0;
-       u32 seq = ++bp->fw_seq;
        int port = bp->port;
+       u32 seq = ++bp->fw_seq;
+       u32 rc = 0;
 
-       SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq);
-       DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq);
+       SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq));
+       DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
 
        /* let the FW do it's magic ... */
        msleep(100); /* TBD */
@@ -5698,19 +6619,20 @@ static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
        if (CHIP_REV_IS_SLOW(bp))
                msleep(900);
 
-       rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header);
-
+       rc = SHMEM_RD(bp, func_mb[port].fw_mb_header);
        DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
 
        /* is this a reply to our command? */
        if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
                rc &= FW_MSG_CODE_MASK;
+
        } else {
                /* FW BUG! */
                BNX2X_ERR("FW failed to respond!\n");
                bnx2x_fw_dump(bp);
                rc = 0;
        }
+
        return rc;
 }
 
@@ -5869,7 +6791,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
        for (i = 0; i < 16*1024; i += 64)
                * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
 
-       /* now sixup the last line in the block to point to the next block */
+       /* now fixup the last line in the block to point to the next block */
        *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
 
        /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
@@ -5950,22 +6872,19 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
        int i;
 
        free_irq(bp->msix_table[0].vector, bp->dev);
-       DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n",
+       DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
           bp->msix_table[0].vector);
 
        for_each_queue(bp, i) {
-               DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq  "
+               DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq  "
                   "state(%x)\n", i, bp->msix_table[i + 1].vector,
                   bnx2x_fp(bp, i, state));
 
-               if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) {
-
-                       free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
-                       bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED;
-
-               } else
-                       DP(NETIF_MSG_IFDOWN, "irq not freed\n");
+               if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
+                       BNX2X_ERR("IRQ of fp #%d being freed while "
+                                 "state != closed\n", i);
 
+               free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
        }
 
 }
@@ -5995,7 +6914,7 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
 
        if (pci_enable_msix(bp->pdev, &bp->msix_table[0],
                                     bp->num_queues + 1)){
-               BNX2X_ERR("failed to enable msix\n");
+               BNX2X_LOG("failed to enable MSI-X\n");
                return -1;
 
        }
@@ -6010,11 +6929,8 @@ static int bnx2x_enable_msix(struct bnx2x *bp)
 static int bnx2x_req_msix_irqs(struct bnx2x *bp)
 {
 
-
        int i, rc;
 
-       DP(NETIF_MSG_IFUP, "about to request sp irq\n");
-
        rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
                         bp->dev->name, bp->dev);
 
@@ -6029,7 +6945,8 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
                                 bp->dev->name, &bp->fp[i]);
 
                if (rc) {
-                       BNX2X_ERR("request fp #%d irq failed\n", i);
+                       BNX2X_ERR("request fp #%d irq failed  "
+                                 "rc %d\n", i, rc);
                        bnx2x_free_msix_irqs(bp);
                        return -EBUSY;
                }
@@ -6109,8 +7026,8 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
        /* can take a while if any port is running */
        int timeout = 500;
 
-       /* DP("waiting for state to become %d on IDX [%d]\n",
-       state, sb_idx); */
+       DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
+          poll ? "polling" : "waiting", state, idx);
 
        might_sleep();
 
@@ -6128,7 +7045,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
 
                mb(); /* state is changed by bnx2x_sp_event()*/
 
-               if (*state_p != state)
+               if (*state_p == state)
                        return 0;
 
                timeout--;
@@ -6136,17 +7053,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
 
        }
 
-
        /* timeout! */
-       BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx);
-       return -EBUSY;
+       BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
+                 poll ? "polling" : "waiting", state, idx);
 
+       return -EBUSY;
 }
 
 static int bnx2x_setup_leading(struct bnx2x *bp)
 {
 
-       /* reset IGU staae */
+       /* reset IGU state */
        bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
 
        /* SETUP ramrod */
@@ -6162,12 +7079,13 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index)
        /* reset IGU state */
        bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
 
+       /* SETUP ramrod */
        bp->fp[index].state = BNX2X_FP_STATE_OPENING;
        bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
 
        /* Wait for completion */
        return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
-                                &(bp->fp[index].state), 1);
+                                &(bp->fp[index].state), 0);
 
 }
 
@@ -6177,8 +7095,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev);
 
 static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
 {
-       int rc;
-       int i = 0;
+       u32 load_code;
+       int i;
 
        bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
@@ -6188,26 +7106,28 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
           initialized, otherwise - not.
        */
        if (!nomcp) {
-               rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
-               if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+               load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+               if (!load_code) {
+                       BNX2X_ERR("MCP response failure, unloading\n");
+                       return -EBUSY;
+               }
+               if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+                       BNX2X_ERR("MCP refused load request, unloading\n");
                        return -EBUSY; /* other port in diagnostic mode */
                }
        } else {
-               rc = FW_MSG_CODE_DRV_LOAD_COMMON;
+               load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
        }
 
-       DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
-
        /* if we can't use msix we only need one fp,
         * so try to enable msix with the requested number of fp's
         * and fallback to inta with one fp
         */
        if (req_irq) {
-
                if (use_inta) {
                        bp->num_queues = 1;
                } else {
-                       if (use_multi > 1 && use_multi <= 16)
+                       if ((use_multi > 1) && (use_multi <= 16))
                                /* user requested number */
                                bp->num_queues = use_multi;
                        else if (use_multi == 1)
@@ -6216,15 +7136,17 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
                                bp->num_queues = 1;
 
                        if (bnx2x_enable_msix(bp)) {
-                               /* faild to enable msix */
+                               /* failed to enable msix */
                                bp->num_queues = 1;
                                if (use_multi)
-                                       BNX2X_ERR("Muti requested but failed"
+                                       BNX2X_ERR("Multi requested but failed"
                                                  " to enable MSI-X\n");
                        }
                }
        }
 
+       DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
+
        if (bnx2x_alloc_mem(bp))
                return -ENOMEM;
 
@@ -6232,13 +7154,13 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
                if (bp->flags & USING_MSIX_FLAG) {
                        if (bnx2x_req_msix_irqs(bp)) {
                                pci_disable_msix(bp->pdev);
-                               goto out_error;
+                               goto load_error;
                        }
 
                } else {
                        if (bnx2x_req_irq(bp)) {
                                BNX2X_ERR("IRQ request failed, aborting\n");
-                               goto out_error;
+                               goto load_error;
                        }
                }
        }
@@ -6249,31 +7171,25 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
 
 
        /* Initialize HW */
-       if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) {
+       if (bnx2x_function_init(bp,
+                               (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) {
                BNX2X_ERR("HW init failed, aborting\n");
-               goto out_error;
+               goto load_error;
        }
 
 
        atomic_set(&bp->intr_sem, 0);
 
-       /* Reenable SP tasklet */
-       /*if (bp->sp_task_en) {                */
-       /*        tasklet_enable(&bp->sp_task);*/
-       /*} else {                             */
-       /*        bp->sp_task_en = 1;          */
-       /*}                                    */
 
        /* Setup NIC internals and enable interrupts */
        bnx2x_nic_init(bp);
 
        /* Send LOAD_DONE command to MCP */
        if (!nomcp) {
-               rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
-               DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc);
-               if (!rc) {
+               load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+               if (!load_code) {
                        BNX2X_ERR("MCP response failure, unloading\n");
-                       goto int_disable;
+                       goto load_int_disable;
                }
        }
 
@@ -6285,11 +7201,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
                napi_enable(&bnx2x_fp(bp, i, napi));
 
        if (bnx2x_setup_leading(bp))
-               goto stop_netif;
+               goto load_stop_netif;
 
        for_each_nondefault_queue(bp, i)
                if (bnx2x_setup_multi(bp, i))
-                       goto stop_netif;
+                       goto load_stop_netif;
 
        bnx2x_set_mac_addr(bp);
 
@@ -6313,42 +7229,24 @@ static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
 
        return 0;
 
-stop_netif:
+load_stop_netif:
        for_each_queue(bp, i)
                napi_disable(&bnx2x_fp(bp, i, napi));
 
-int_disable:
-       bnx2x_disable_int_sync(bp);
+load_int_disable:
+       bnx2x_int_disable_sync(bp);
 
        bnx2x_free_skbs(bp);
        bnx2x_free_irq(bp);
 
-out_error:
+load_error:
        bnx2x_free_mem(bp);
 
        /* TBD we really need to reset the chip
           if we want to recover from this */
-       return rc;
+       return -EBUSY;
 }
 
-static void bnx2x_netif_stop(struct bnx2x *bp)
-{
-       int i;
-
-       bp->rx_mode = BNX2X_RX_MODE_NONE;
-       bnx2x_set_storm_rx_mode(bp);
-
-       bnx2x_disable_int_sync(bp);
-       bnx2x_link_reset(bp);
-
-       for_each_queue(bp, i)
-               napi_disable(&bnx2x_fp(bp, i, napi));
-
-       if (netif_running(bp->dev)) {
-               netif_tx_disable(bp->dev);
-               bp->dev->trans_start = jiffies; /* prevent tx timeout */
-       }
-}
 
 static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
 {
@@ -6401,20 +7299,20 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
 
        int rc;
 
-       /* halt the connnection */
+       /* halt the connection */
        bp->fp[index].state = BNX2X_FP_STATE_HALTING;
        bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
 
 
        rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
                                       &(bp->fp[index].state), 1);
-       if (rc) /* timout */
+       if (rc) /* timeout */
                return rc;
 
        /* delete cfc entry */
        bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
 
-       return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index,
+       return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
                                 &(bp->fp[index].state), 1);
 
 }
@@ -6422,8 +7320,8 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
 
 static void bnx2x_stop_leading(struct bnx2x *bp)
 {
-
-       /* if the other port is hadling traffic,
+       u16 dsb_sp_prod_idx;
+       /* if the other port is handling traffic,
           this can take a lot of time */
        int timeout = 500;
 
@@ -6437,52 +7335,71 @@ static void bnx2x_stop_leading(struct bnx2x *bp)
                               &(bp->fp[0].state), 1))
                return;
 
-       bp->dsb_sp_prod_idx = *bp->dsb_sp_prod;
+       dsb_sp_prod_idx = *bp->dsb_sp_prod;
 
-       /* Send CFC_DELETE ramrod */
+       /* Send PORT_DELETE ramrod */
        bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
 
-       /*
-          Wait for completion.
+       /* Wait for completion to arrive on default status block
           we are going to reset the chip anyway
           so there is not much to do if this times out
         */
-       while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) {
-                       timeout--;
-                       msleep(1);
+       while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) {
+               timeout--;
+               msleep(1);
        }
-
+       if (!timeout) {
+               DP(NETIF_MSG_IFDOWN, "timeout polling for completion "
+                  "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
+                  *bp->dsb_sp_prod, dsb_sp_prod_idx);
+       }
+       bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+       bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
 }
 
-static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
+
+static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq)
 {
        u32 reset_code = 0;
-       int rc;
-       int i;
+       int i, timeout;
 
        bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
 
-       /* Calling flush_scheduled_work() may deadlock because
-        * linkwatch_event() may be on the workqueue and it will try to get
-        * the rtnl_lock which we are holding.
-        */
+       del_timer_sync(&bp->timer);
 
-       while (bp->in_reset_task)
-               msleep(1);
+       bp->rx_mode = BNX2X_RX_MODE_NONE;
+       bnx2x_set_storm_rx_mode(bp);
 
-       /* Delete the timer: do it before disabling interrupts, as it
-          may be stil STAT_QUERY ramrod pending after stopping the timer */
-       del_timer_sync(&bp->timer);
+       if (netif_running(bp->dev)) {
+               netif_tx_disable(bp->dev);
+               bp->dev->trans_start = jiffies; /* prevent tx timeout */
+       }
+
+       /* Wait until all fast path tasks complete */
+       for_each_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               timeout = 1000;
+               while (bnx2x_has_work(fp) && (timeout--))
+                       msleep(1);
+               if (!timeout)
+                       BNX2X_ERR("timeout waiting for queue[%d]\n", i);
+       }
 
        /* Wait until stat ramrod returns and all SP tasks complete */
-       while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING))
+       timeout = 1000;
+       while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) &&
+              (timeout--))
                msleep(1);
 
-       /* Stop fast path, disable MAC, disable interrupts, disable napi */
-       bnx2x_netif_stop(bp);
+       for_each_queue(bp, i)
+               napi_disable(&bnx2x_fp(bp, i, napi));
+       /* Disable interrupts after Tx and Rx are disabled on stack level */
+       bnx2x_int_disable_sync(bp);
 
        if (bp->flags & NO_WOL_FLAG)
                reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
+
        else if (bp->wol) {
                u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
                u8 *mac_addr = bp->dev->dev_addr;
@@ -6499,28 +7416,37 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
                EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
 
                reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
+
        } else
                reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
 
+       /* Close multi and leading connections */
        for_each_nondefault_queue(bp, i)
                if (bnx2x_stop_multi(bp, i))
-                       goto error;
-
+                       goto unload_error;
 
        bnx2x_stop_leading(bp);
+       if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
+           (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
+               DP(NETIF_MSG_IFDOWN, "failed to close leading properly!"
+                  "state 0x%x  fp[0].state 0x%x",
+                  bp->state, bp->fp[0].state);
+       }
+
+unload_error:
+       bnx2x_link_reset(bp);
 
-error:
        if (!nomcp)
-               rc = bnx2x_fw_command(bp, reset_code);
+               reset_code = bnx2x_fw_command(bp, reset_code);
        else
-               rc = FW_MSG_CODE_DRV_UNLOAD_COMMON;
+               reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
 
        /* Release IRQs */
-       if (fre_irq)
+       if (free_irq)
                bnx2x_free_irq(bp);
 
        /* Reset the chip */
-       bnx2x_reset_chip(bp, rc);
+       bnx2x_reset_chip(bp, reset_code);
 
        /* Report UNLOAD_DONE to MCP */
        if (!nomcp)
@@ -6531,8 +7457,7 @@ error:
        bnx2x_free_mem(bp);
 
        bp->state = BNX2X_STATE_CLOSED;
-       /* Set link down */
-       bp->link_up = 0;
+
        netif_carrier_off(bp->dev);
 
        return 0;
@@ -6568,7 +7493,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
                                          SUPPORTED_100baseT_Half |
                                          SUPPORTED_100baseT_Full |
                                          SUPPORTED_1000baseT_Full |
-                                         SUPPORTED_2500baseT_Full |
+                                         SUPPORTED_2500baseX_Full |
                                          SUPPORTED_TP | SUPPORTED_FIBRE |
                                          SUPPORTED_Autoneg |
                                          SUPPORTED_Pause |
@@ -6581,10 +7506,10 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
 
                        bp->phy_flags |= PHY_SGMII_FLAG;
 
-                       bp->supported |= (/* SUPPORTED_10baseT_Half |
-                                            SUPPORTED_10baseT_Full |
-                                            SUPPORTED_100baseT_Half |
-                                            SUPPORTED_100baseT_Full |*/
+                       bp->supported |= (SUPPORTED_10baseT_Half |
+                                         SUPPORTED_10baseT_Full |
+                                         SUPPORTED_100baseT_Half |
+                                         SUPPORTED_100baseT_Full |
                                          SUPPORTED_1000baseT_Full |
                                          SUPPORTED_TP | SUPPORTED_FIBRE |
                                          SUPPORTED_Autoneg |
@@ -6620,7 +7545,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
                                          SUPPORTED_100baseT_Half |
                                          SUPPORTED_100baseT_Full |
                                          SUPPORTED_1000baseT_Full |
-                                         SUPPORTED_2500baseT_Full |
+                                         SUPPORTED_2500baseX_Full |
                                          SUPPORTED_10000baseT_Full |
                                          SUPPORTED_TP | SUPPORTED_FIBRE |
                                          SUPPORTED_Autoneg |
@@ -6629,12 +7554,46 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
                        break;
 
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+                                       ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_FIBRE |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
                case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-                       BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n",
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+                                      ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_1000baseT_Full |
+                                         SUPPORTED_Autoneg |
+                                         SUPPORTED_FIBRE |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
                                       ext_phy_type);
 
                        bp->supported |= (SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_1000baseT_Full |
                                          SUPPORTED_FIBRE |
+                                         SUPPORTED_Autoneg |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
+                                      ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_TP |
+                                         SUPPORTED_Autoneg |
                                          SUPPORTED_Pause |
                                          SUPPORTED_Asym_Pause);
                        break;
@@ -6691,7 +7650,7 @@ static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
                                   SUPPORTED_1000baseT_Full);
 
        if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
-               bp->supported &= ~SUPPORTED_2500baseT_Full;
+               bp->supported &= ~SUPPORTED_2500baseX_Full;
 
        if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
                bp->supported &= ~SUPPORTED_10000baseT_Full;
@@ -6711,13 +7670,8 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                        bp->req_line_speed = 0;
                        bp->advertising = bp->supported;
                } else {
-                       u32 ext_phy_type;
-
-                       ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
-                       if ((ext_phy_type ==
-                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
-                           (ext_phy_type ==
-                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+                       if (XGXS_EXT_PHY_TYPE(bp) ==
+                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) {
                                /* force 10G, no AN */
                                bp->req_line_speed = SPEED_10000;
                                bp->advertising =
@@ -6734,8 +7688,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_10M_FULL:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
+               if (bp->supported & SUPPORTED_10baseT_Full) {
                        bp->req_line_speed = SPEED_10;
                        bp->advertising = (ADVERTISED_10baseT_Full |
                                           ADVERTISED_TP);
@@ -6749,8 +7702,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_10M_HALF:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
+               if (bp->supported & SUPPORTED_10baseT_Half) {
                        bp->req_line_speed = SPEED_10;
                        bp->req_duplex = DUPLEX_HALF;
                        bp->advertising = (ADVERTISED_10baseT_Half |
@@ -6765,8 +7717,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_100M_FULL:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
+               if (bp->supported & SUPPORTED_100baseT_Full) {
                        bp->req_line_speed = SPEED_100;
                        bp->advertising = (ADVERTISED_100baseT_Full |
                                           ADVERTISED_TP);
@@ -6780,8 +7731,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_100M_HALF:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
+               if (bp->supported & SUPPORTED_100baseT_Half) {
                        bp->req_line_speed = SPEED_100;
                        bp->req_duplex = DUPLEX_HALF;
                        bp->advertising = (ADVERTISED_100baseT_Half |
@@ -6796,8 +7746,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_1G:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+               if (bp->supported & SUPPORTED_1000baseT_Full) {
                        bp->req_line_speed = SPEED_1000;
                        bp->advertising = (ADVERTISED_1000baseT_Full |
                                           ADVERTISED_TP);
@@ -6811,10 +7760,9 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                break;
 
        case PORT_FEATURE_LINK_SPEED_2_5G:
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) {
+               if (bp->supported & SUPPORTED_2500baseX_Full) {
                        bp->req_line_speed = SPEED_2500;
-                       bp->advertising = (ADVERTISED_2500baseT_Full |
+                       bp->advertising = (ADVERTISED_2500baseX_Full |
                                           ADVERTISED_TP);
                } else {
                        BNX2X_ERR("NVRAM config error. "
@@ -6828,15 +7776,7 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
        case PORT_FEATURE_LINK_SPEED_10G_CX4:
        case PORT_FEATURE_LINK_SPEED_10G_KX4:
        case PORT_FEATURE_LINK_SPEED_10G_KR:
-               if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
-                       BNX2X_ERR("NVRAM config error. "
-                                 "Invalid link_config 0x%x"
-                                 "  phy_flags 0x%x\n",
-                                 bp->link_config, bp->phy_flags);
-                       return;
-               }
-               if (bp->speed_cap_mask &
-                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+               if (bp->supported & SUPPORTED_10000baseT_Full) {
                        bp->req_line_speed = SPEED_10000;
                        bp->advertising = (ADVERTISED_10000baseT_Full |
                                           ADVERTISED_FIBRE);
@@ -6863,43 +7803,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
 
        bp->req_flow_ctrl = (bp->link_config &
                             PORT_FEATURE_FLOW_CONTROL_MASK);
-       /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
-       switch (bp->req_flow_ctrl) {
-       case FLOW_CTRL_AUTO:
+       if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+           (bp->supported & SUPPORTED_Autoneg))
                bp->req_autoneg |= AUTONEG_FLOW_CTRL;
-               if (bp->dev->mtu <= 4500) {
-                       bp->pause_mode = PAUSE_BOTH;
-                       bp->advertising |= (ADVERTISED_Pause |
-                                           ADVERTISED_Asym_Pause);
-               } else {
-                       bp->pause_mode = PAUSE_ASYMMETRIC;
-                       bp->advertising |= ADVERTISED_Asym_Pause;
-               }
-               break;
-
-       case FLOW_CTRL_TX:
-               bp->pause_mode = PAUSE_ASYMMETRIC;
-               bp->advertising |= ADVERTISED_Asym_Pause;
-               break;
-
-       case FLOW_CTRL_RX:
-       case FLOW_CTRL_BOTH:
-               bp->pause_mode = PAUSE_BOTH;
-               bp->advertising |= (ADVERTISED_Pause |
-                                   ADVERTISED_Asym_Pause);
-               break;
 
-       case FLOW_CTRL_NONE:
-       default:
-               bp->pause_mode = PAUSE_NONE;
-               bp->advertising &= ~(ADVERTISED_Pause |
-                                    ADVERTISED_Asym_Pause);
-               break;
-       }
-       BNX2X_DEV_INFO("req_autoneg 0x%x  req_flow_ctrl 0x%x\n"
-            KERN_INFO "  pause_mode %d  advertising 0x%x\n",
-                      bp->req_autoneg, bp->req_flow_ctrl,
-                      bp->pause_mode, bp->advertising);
+       BNX2X_DEV_INFO("req_autoneg 0x%x  req_flow_ctrl 0x%x"
+                      "  advertising 0x%x\n",
+                      bp->req_autoneg, bp->req_flow_ctrl, bp->advertising);
 }
 
 static void bnx2x_get_hwinfo(struct bnx2x *bp)
@@ -6933,15 +7843,15 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
        val = SHMEM_RD(bp, validity_map[port]);
        if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
                != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-               BNX2X_ERR("MCP validity signature bad\n");
+               BNX2X_ERR("BAD MCP validity signature\n");
 
-       bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) &
+       bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) &
                      DRV_MSG_SEQ_NUMBER_MASK);
 
        bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
-
+       bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
        bp->serdes_config =
-               SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config);
+               SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
        bp->lane_config =
                SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
        bp->ext_phy_config =
@@ -6954,13 +7864,13 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
        bp->link_config =
                SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
 
-       BNX2X_DEV_INFO("hw_config (%08x)  serdes_config (%08x)\n"
+       BNX2X_DEV_INFO("hw_config (%08x) board (%08x)  serdes_config (%08x)\n"
             KERN_INFO "  lane_config (%08x)  ext_phy_config (%08x)\n"
             KERN_INFO "  speed_cap_mask (%08x)  link_config (%08x)"
                       "  fw_seq (%08x)\n",
-                      bp->hw_config, bp->serdes_config, bp->lane_config,
-                      bp->ext_phy_config, bp->speed_cap_mask,
-                      bp->link_config, bp->fw_seq);
+                      bp->hw_config, bp->board, bp->serdes_config,
+                      bp->lane_config, bp->ext_phy_config,
+                      bp->speed_cap_mask, bp->link_config, bp->fw_seq);
 
        switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
        bnx2x_link_settings_supported(bp, switch_cfg);
@@ -7014,14 +7924,8 @@ static void bnx2x_get_hwinfo(struct bnx2x *bp)
        return;
 
 set_mac: /* only supposed to happen on emulation/FPGA */
-       BNX2X_ERR("warning constant MAC workaround active\n");
-       bp->dev->dev_addr[0] = 0;
-       bp->dev->dev_addr[1] = 0x50;
-       bp->dev->dev_addr[2] = 0xc2;
-       bp->dev->dev_addr[3] = 0x2c;
-       bp->dev->dev_addr[4] = 0x71;
-       bp->dev->dev_addr[5] = port ? 0x0d : 0x0e;
-
+       BNX2X_ERR("warning rendom MAC workaround active\n");
+       random_ether_addr(bp->dev->dev_addr);
        memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
 
 }
@@ -7048,19 +7952,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        }
 
        if (bp->phy_flags & PHY_XGXS_FLAG) {
-               cmd->port = PORT_FIBRE;
-       } else {
+               u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+                       cmd->port = PORT_FIBRE;
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+                       cmd->port = PORT_TP;
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+               }
+       } else
                cmd->port = PORT_TP;
-       }
 
        cmd->phy_address = bp->phy_addr;
        cmd->transceiver = XCVR_INTERNAL;
 
-       if (bp->req_autoneg & AUTONEG_SPEED) {
+       if (bp->req_autoneg & AUTONEG_SPEED)
                cmd->autoneg = AUTONEG_ENABLE;
-       } else {
+       else
                cmd->autoneg = AUTONEG_DISABLE;
-       }
 
        cmd->maxtxpkt = 0;
        cmd->maxrxpkt = 0;
@@ -7091,8 +8010,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        switch (cmd->port) {
        case PORT_TP:
-               if (!(bp->supported & SUPPORTED_TP))
+               if (!(bp->supported & SUPPORTED_TP)) {
+                       DP(NETIF_MSG_LINK, "TP not supported\n");
                        return -EINVAL;
+               }
 
                if (bp->phy_flags & PHY_XGXS_FLAG) {
                        bnx2x_link_reset(bp);
@@ -7102,8 +8023,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                break;
 
        case PORT_FIBRE:
-               if (!(bp->supported & SUPPORTED_FIBRE))
+               if (!(bp->supported & SUPPORTED_FIBRE)) {
+                       DP(NETIF_MSG_LINK, "FIBRE not supported\n");
                        return -EINVAL;
+               }
 
                if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
                        bnx2x_link_reset(bp);
@@ -7113,12 +8036,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                break;
 
        default:
+               DP(NETIF_MSG_LINK, "Unknown port type\n");
                return -EINVAL;
        }
 
        if (cmd->autoneg == AUTONEG_ENABLE) {
-               if (!(bp->supported & SUPPORTED_Autoneg))
+               if (!(bp->supported & SUPPORTED_Autoneg)) {
+                       DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
                        return -EINVAL;
+               }
 
                /* advertise the requested speed and duplex if supported */
                cmd->advertising &= bp->supported;
@@ -7133,14 +8059,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                switch (cmd->speed) {
                case SPEED_10:
                        if (cmd->duplex == DUPLEX_FULL) {
-                               if (!(bp->supported & SUPPORTED_10baseT_Full))
+                               if (!(bp->supported &
+                                     SUPPORTED_10baseT_Full)) {
+                                       DP(NETIF_MSG_LINK,
+                                          "10M full not supported\n");
                                        return -EINVAL;
+                               }
 
                                advertising = (ADVERTISED_10baseT_Full |
                                               ADVERTISED_TP);
                        } else {
-                               if (!(bp->supported & SUPPORTED_10baseT_Half))
+                               if (!(bp->supported &
+                                     SUPPORTED_10baseT_Half)) {
+                                       DP(NETIF_MSG_LINK,
+                                          "10M half not supported\n");
                                        return -EINVAL;
+                               }
 
                                advertising = (ADVERTISED_10baseT_Half |
                                               ADVERTISED_TP);
@@ -7150,15 +8084,21 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                case SPEED_100:
                        if (cmd->duplex == DUPLEX_FULL) {
                                if (!(bp->supported &
-                                               SUPPORTED_100baseT_Full))
+                                               SUPPORTED_100baseT_Full)) {
+                                       DP(NETIF_MSG_LINK,
+                                          "100M full not supported\n");
                                        return -EINVAL;
+                               }
 
                                advertising = (ADVERTISED_100baseT_Full |
                                               ADVERTISED_TP);
                        } else {
                                if (!(bp->supported &
-                                               SUPPORTED_100baseT_Half))
+                                               SUPPORTED_100baseT_Half)) {
+                                       DP(NETIF_MSG_LINK,
+                                          "100M half not supported\n");
                                        return -EINVAL;
+                               }
 
                                advertising = (ADVERTISED_100baseT_Half |
                                               ADVERTISED_TP);
@@ -7166,39 +8106,54 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        break;
 
                case SPEED_1000:
-                       if (cmd->duplex != DUPLEX_FULL)
+                       if (cmd->duplex != DUPLEX_FULL) {
+                               DP(NETIF_MSG_LINK, "1G half not supported\n");
                                return -EINVAL;
+                       }
 
-                       if (!(bp->supported & SUPPORTED_1000baseT_Full))
+                       if (!(bp->supported & SUPPORTED_1000baseT_Full)) {
+                               DP(NETIF_MSG_LINK, "1G full not supported\n");
                                return -EINVAL;
+                       }
 
                        advertising = (ADVERTISED_1000baseT_Full |
                                       ADVERTISED_TP);
                        break;
 
                case SPEED_2500:
-                       if (cmd->duplex != DUPLEX_FULL)
+                       if (cmd->duplex != DUPLEX_FULL) {
+                               DP(NETIF_MSG_LINK,
+                                  "2.5G half not supported\n");
                                return -EINVAL;
+                       }
 
-                       if (!(bp->supported & SUPPORTED_2500baseT_Full))
+                       if (!(bp->supported & SUPPORTED_2500baseX_Full)) {
+                               DP(NETIF_MSG_LINK,
+                                  "2.5G full not supported\n");
                                return -EINVAL;
+                       }
 
-                       advertising = (ADVERTISED_2500baseT_Full |
+                       advertising = (ADVERTISED_2500baseX_Full |
                                       ADVERTISED_TP);
                        break;
 
                case SPEED_10000:
-                       if (cmd->duplex != DUPLEX_FULL)
+                       if (cmd->duplex != DUPLEX_FULL) {
+                               DP(NETIF_MSG_LINK, "10G half not supported\n");
                                return -EINVAL;
+                       }
 
-                       if (!(bp->supported & SUPPORTED_10000baseT_Full))
+                       if (!(bp->supported & SUPPORTED_10000baseT_Full)) {
+                               DP(NETIF_MSG_LINK, "10G full not supported\n");
                                return -EINVAL;
+                       }
 
                        advertising = (ADVERTISED_10000baseT_Full |
                                       ADVERTISED_FIBRE);
                        break;
 
                default:
+                       DP(NETIF_MSG_LINK, "Unsupported speed\n");
                        return -EINVAL;
                }
 
@@ -7398,8 +8353,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
 static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
                                  u32 cmd_flags)
 {
-       int rc;
-       int count, i;
+       int count, i, rc;
        u32 val;
 
        /* build the command word */
@@ -7452,13 +8406,13 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
 
        if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
                DP(NETIF_MSG_NVM,
-                  "Invalid paramter: offset 0x%x  buf_size 0x%x\n",
+                  "Invalid parameter: offset 0x%x  buf_size 0x%x\n",
                   offset, buf_size);
                return -EINVAL;
        }
 
        if (offset + buf_size > bp->flash_size) {
-               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+               DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
                                  " buf_size (0x%x) > flash_size (0x%x)\n",
                   offset, buf_size, bp->flash_size);
                return -EINVAL;
@@ -7519,8 +8473,7 @@ static int bnx2x_get_eeprom(struct net_device *dev,
 static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
                                   u32 cmd_flags)
 {
-       int rc;
-       int count, i;
+       int count, i, rc;
 
        /* build the command word */
        cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
@@ -7557,7 +8510,7 @@ static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
        return rc;
 }
 
-#define BYTE_OFFSET(offset)            (8 * (offset & 0x03))
+#define BYTE_OFFSET(offset)            (8 * (offset & 0x03))
 
 static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
                              int buf_size)
@@ -7568,7 +8521,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
        u32 val;
 
        if (offset + buf_size > bp->flash_size) {
-               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+               DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
                                  " buf_size (0x%x) > flash_size (0x%x)\n",
                   offset, buf_size, bp->flash_size);
                return -EINVAL;
@@ -7621,13 +8574,13 @@ static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
 
        if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
                DP(NETIF_MSG_NVM,
-                  "Invalid paramter: offset 0x%x  buf_size 0x%x\n",
+                  "Invalid parameter: offset 0x%x  buf_size 0x%x\n",
                   offset, buf_size);
                return -EINVAL;
        }
 
        if (offset + buf_size > bp->flash_size) {
-               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+               DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
                                  " buf_size (0x%x) > flash_size (0x%x)\n",
                   offset, buf_size, bp->flash_size);
                return -EINVAL;
@@ -7788,52 +8741,29 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
           DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
           epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
 
-       bp->req_flow_ctrl = FLOW_CTRL_AUTO;
        if (epause->autoneg) {
-               bp->req_autoneg |= AUTONEG_FLOW_CTRL;
-               if (bp->dev->mtu <= 4500) {
-                       bp->pause_mode = PAUSE_BOTH;
-                       bp->advertising |= (ADVERTISED_Pause |
-                        &n