]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <davem@davemloft.net>
Wed, 23 Oct 2013 20:28:39 +0000 (16:28 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Oct 2013 20:49:34 +0000 (16:49 -0400)
Conflicts:
drivers/net/usb/qmi_wwan.c
include/net/dst.h

Trivial merge conflicts, both were overlapping changes.

Signed-off-by: David S. Miller <davem@davemloft.net>
43 files changed:
1  2 
MAINTAINERS
drivers/net/can/at91_can.c
drivers/net/can/flexcan.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/hamradio/yam.c
drivers/net/usb/qmi_wwan.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/cw1200/cw1200_spi.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
include/net/dst.h
include/net/ip6_route.h
init/main.c
mm/memcontrol.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/core/secure_seq.c
net/ipv4/ip_output.c
net/ipv4/ip_vti.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/route.c
net/ipv6/udp.c
net/l2tp/l2tp_ppp.c
net/mac80211/cfg.c
net/mac80211/ieee80211_i.h
net/mac80211/scan.c
net/mac80211/tx.c
net/mac80211/util.c
net/wireless/core.h
security/selinux/hooks.c

diff --combined MAINTAINERS
index f169259ccdc69a34ca94ee84f828a50c299cb78c,ebaf8bd7a570f6dd0c83db9849883f2c28b753d4..66469731e78d7a1af4ca7825bd2ec8e0c6d4e005
@@@ -237,11 -237,11 +237,11 @@@ F:      drivers/platform/x86/acer-wmi.
  
  ACPI
  M:    Len Brown <lenb@kernel.org>
- M:    Rafael J. Wysocki <rjw@sisk.pl>
+ M:    Rafael J. Wysocki <rjw@rjwysocki.net>
  L:    linux-acpi@vger.kernel.org
- W:    http://www.lesswatts.org/projects/acpi/
- Q:    http://patchwork.kernel.org/project/linux-acpi/list/
- T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
+ W:    https://01.org/linux-acpi
+ Q:    https://patchwork.kernel.org/project/linux-acpi/list/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
  S:    Supported
  F:    drivers/acpi/
  F:    drivers/pnp/pnpacpi/
@@@ -256,21 -256,21 +256,21 @@@ F:      drivers/pci/*/*/*acpi
  ACPI FAN DRIVER
  M:    Zhang Rui <rui.zhang@intel.com>
  L:    linux-acpi@vger.kernel.org
- W:    http://www.lesswatts.org/projects/acpi/
+ W:    https://01.org/linux-acpi
  S:    Supported
  F:    drivers/acpi/fan.c
  
  ACPI THERMAL DRIVER
  M:    Zhang Rui <rui.zhang@intel.com>
  L:    linux-acpi@vger.kernel.org
- W:    http://www.lesswatts.org/projects/acpi/
+ W:    https://01.org/linux-acpi
  S:    Supported
  F:    drivers/acpi/*thermal*
  
  ACPI VIDEO DRIVER
  M:    Zhang Rui <rui.zhang@intel.com>
  L:    linux-acpi@vger.kernel.org
- W:    http://www.lesswatts.org/projects/acpi/
+ W:    https://01.org/linux-acpi
  S:    Supported
  F:    drivers/acpi/video.c
  
@@@ -824,15 -824,21 +824,21 @@@ S:      Maintaine
  F:    arch/arm/mach-gemini/
  
  ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
- M:    Barry Song <baohua.song@csr.com>
+ M:    Barry Song <baohua@kernel.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git
  S:    Maintained
  F:    arch/arm/mach-prima2/
+ F:    drivers/clk/clk-prima2.c
+ F:    drivers/clocksource/timer-prima2.c
+ F:    drivers/clocksource/timer-marco.c
  F:    drivers/dma/sirf-dma.c
  F:    drivers/i2c/busses/i2c-sirf.c
+ F:    drivers/input/misc/sirfsoc-onkey.c
+ F:    drivers/irqchip/irq-sirfsoc.c
  F:    drivers/mmc/host/sdhci-sirf.c
  F:    drivers/pinctrl/sirf/
+ F:    drivers/rtc/rtc-sirfsoc.c
  F:    drivers/spi/spi-sirf.c
  
  ARM/EBSA110 MACHINE SUPPORT
@@@ -1652,9 -1658,9 +1658,9 @@@ F:      drivers/video/backlight
  F:    include/linux/backlight.h
  
  BATMAN ADVANCED
 -M:    Marek Lindner <lindner_marek@yahoo.de>
 -M:    Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
 -M:    Antonio Quartulli <ordex@autistici.org>
 +M:    Marek Lindner <mareklindner@neomailbox.ch>
 +M:    Simon Wunderlich <sw@simonwunderlich.de>
 +M:    Antonio Quartulli <antonio@meshcoding.com>
  L:    b.a.t.m.a.n@lists.open-mesh.org
  W:    http://www.open-mesh.org/
  S:    Maintained
@@@ -2295,7 -2301,7 +2301,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/ti/cpmac.c
  
  CPU FREQUENCY DRIVERS
- M:    Rafael J. Wysocki <rjw@sisk.pl>
+ M:    Rafael J. Wysocki <rjw@rjwysocki.net>
  M:    Viresh Kumar <viresh.kumar@linaro.org>
  L:    cpufreq@vger.kernel.org
  L:    linux-pm@vger.kernel.org
@@@ -2326,7 -2332,7 +2332,7 @@@ S:      Maintaine
  F:      drivers/cpuidle/cpuidle-big_little.c
  
  CPUIDLE DRIVERS
- M:    Rafael J. Wysocki <rjw@sisk.pl>
+ M:    Rafael J. Wysocki <rjw@rjwysocki.net>
  M:    Daniel Lezcano <daniel.lezcano@linaro.org>
  L:    linux-pm@vger.kernel.org
  S:    Maintained
@@@ -3548,7 -3554,7 +3554,7 @@@ F:      fs/freevxfs
  
  FREEZER
  M:    Pavel Machek <pavel@ucw.cz>
- M:    "Rafael J. Wysocki" <rjw@sisk.pl>
+ M:    "Rafael J. Wysocki" <rjw@rjwysocki.net>
  L:    linux-pm@vger.kernel.org
  S:    Supported
  F:    Documentation/power/freezing-of-tasks.txt
@@@ -3619,6 -3625,12 +3625,12 @@@ L:    linux-scsi@vger.kernel.or
  S:    Odd Fixes (e.g., new signatures)
  F:    drivers/scsi/fdomain.*
  
+ GCOV BASED KERNEL PROFILING
+ M:    Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
+ S:    Maintained
+ F:    kernel/gcov/
+ F:    Documentation/gcov.txt
  GDT SCSI DISK ARRAY CONTROLLER DRIVER
  M:    Achim Leubner <achim_leubner@adaptec.com>
  L:    linux-scsi@vger.kernel.org
@@@ -3884,7 -3896,7 +3896,7 @@@ F:      drivers/video/hgafb.
  
  HIBERNATION (aka Software Suspend, aka swsusp)
  M:    Pavel Machek <pavel@ucw.cz>
- M:    "Rafael J. Wysocki" <rjw@sisk.pl>
+ M:    "Rafael J. Wysocki" <rjw@rjwysocki.net>
  L:    linux-pm@vger.kernel.org
  S:    Supported
  F:    arch/x86/power/
@@@ -4334,7 -4346,7 +4346,7 @@@ F:      drivers/video/i810
  INTEL MENLOW THERMAL DRIVER
  M:    Sujith Thomas <sujith.thomas@intel.com>
  L:    platform-driver-x86@vger.kernel.org
- W:    http://www.lesswatts.org/projects/acpi/
+ W:    https://01.org/linux-acpi
  S:    Supported
  F:    drivers/platform/x86/intel_menlow.c
  
@@@ -4471,6 -4483,13 +4483,13 @@@ L:    linux-serial@vger.kernel.or
  S:    Maintained
  F:    drivers/tty/serial/ioc3_serial.c
  
+ IOMMU DRIVERS
+ M:    Joerg Roedel <joro@8bytes.org>
+ L:    iommu@lists.linux-foundation.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
+ S:    Maintained
+ F:    drivers/iommu/
  IP MASQUERADING
  M:    Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar>
  S:    Maintained
@@@ -6830,14 -6849,6 +6849,14 @@@ L:    linux-hexagon@vger.kernel.or
  S:    Supported
  F:    arch/hexagon/
  
 +QUALCOMM WCN36XX WIRELESS DRIVER
 +M:    Eugene Krasnikov <k.eugene.e@gmail.com>
 +L:    wcn36xx@lists.infradead.org
 +W:    http://wireless.kernel.org/en/users/Drivers/wcn36xx
 +T:    git git://github.com/KrasnikovEugene/wcn36xx.git
 +S:    Supported
 +F:    drivers/net/wireless/ath/wcn36xx/
 +
  QUICKCAM PARALLEL PORT WEBCAMS
  M:    Hans Verkuil <hverkuil@xs4all.nl>
  L:    linux-media@vger.kernel.org
@@@ -7812,6 -7823,13 +7831,13 @@@ F:    Documentation/sound/alsa/soc
  F:    sound/soc/
  F:    include/sound/soc*
  
+ SOUND - DMAENGINE HELPERS
+ M:    Lars-Peter Clausen <lars@metafoo.de>
+ S:    Supported
+ F:    include/sound/dmaengine_pcm.h
+ F:    sound/core/pcm_dmaengine.c
+ F:    sound/soc/soc-generic-dmaengine-pcm.c
  SPARC + UltraSPARC (sparc/sparc64)
  M:    "David S. Miller" <davem@davemloft.net>
  L:    sparclinux@vger.kernel.org
@@@ -8091,7 -8109,7 +8117,7 @@@ F:      drivers/sh
  SUSPEND TO RAM
  M:    Len Brown <len.brown@intel.com>
  M:    Pavel Machek <pavel@ucw.cz>
- M:    "Rafael J. Wysocki" <rjw@sisk.pl>
+ M:    "Rafael J. Wysocki" <rjw@rjwysocki.net>
  L:    linux-pm@vger.kernel.org
  S:    Supported
  F:    Documentation/power/
index 64f2efaf7638f1234d2015e6628d402eba9517ca,693d8ffe465311b6aab964c25304f4bbdd04cdf0..cf0f63e14e5339d4a6ed324076a4cad7854dfc48
@@@ -1347,7 -1347,7 +1347,7 @@@ static int at91_can_probe(struct platfo
        priv->reg_base = addr;
        priv->devtype_data = *devtype_data;
        priv->clk = clk;
 -      priv->pdata = pdev->dev.platform_data;
 +      priv->pdata = dev_get_platdata(&pdev->dev);
        priv->mb0_id = 0x7ff;
  
        netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
@@@ -1405,10 -1405,10 +1405,10 @@@ static int at91_can_remove(struct platf
  
  static const struct platform_device_id at91_can_id_table[] = {
        {
-               .name = "at91_can",
+               .name = "at91sam9x5_can",
                .driver_data = (kernel_ulong_t)&at91_at91sam9x5_data,
        }, {
-               .name = "at91sam9x5_can",
+               .name = "at91_can",
                .driver_data = (kernel_ulong_t)&at91_at91sam9263_data,
        }, {
                /* sentinel */
index df010d64ecbb9cd83e27e2ba7cbed2c8b27a49e7,8f5ce747feb57a093dc78e4a24bd9742b5ea99fc..ae08cf129ebbb0bda31f4b74893574b9703253f0
@@@ -62,7 -62,7 +62,7 @@@
  #define FLEXCAN_MCR_BCC                       BIT(16)
  #define FLEXCAN_MCR_LPRIO_EN          BIT(13)
  #define FLEXCAN_MCR_AEN                       BIT(12)
- #define FLEXCAN_MCR_MAXMB(x)          ((x) & 0xf)
+ #define FLEXCAN_MCR_MAXMB(x)          ((x) & 0x1f)
  #define FLEXCAN_MCR_IDAM_A            (0 << 8)
  #define FLEXCAN_MCR_IDAM_B            (1 << 8)
  #define FLEXCAN_MCR_IDAM_C            (2 << 8)
@@@ -735,9 -735,11 +735,11 @@@ static int flexcan_chip_start(struct ne
         *
         */
        reg_mcr = flexcan_read(&regs->mcr);
+       reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
        reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
                FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
-               FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS;
+               FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS |
+               FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
        netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
        flexcan_write(reg_mcr, &regs->mcr);
  
        netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
        flexcan_write(reg_ctrl, &regs->ctrl);
  
+       /* Abort any pending TX, mark Mailbox as INACTIVE */
+       flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+                     &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
        /* acceptance mask/acceptance code (accept everything) */
        flexcan_write(0x0, &regs->rxgmask);
        flexcan_write(0x0, &regs->rx14mask);
@@@ -979,9 -985,9 +985,9 @@@ static void unregister_flexcandev(struc
  }
  
  static const struct of_device_id flexcan_of_match[] = {
-       { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
-       { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
        { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
+       { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
+       { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
        { /* sentinel */ },
  };
  MODULE_DEVICE_TABLE(of, flexcan_of_match);
@@@ -1062,7 -1068,7 +1068,7 @@@ static int flexcan_probe(struct platfor
        priv->dev = dev;
        priv->clk_ipg = clk_ipg;
        priv->clk_per = clk_per;
 -      priv->pdata = pdev->dev.platform_data;
 +      priv->pdata = dev_get_platdata(&pdev->dev);
        priv->devtype_data = devtype_data;
  
        priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
index 5fb18cd99da20cd6a6dbe5798eaba8aa7357aa80,c5e375ddd6c09c137232ecfc8264439bc614e08e..4e01c57d8c8de349da61e80cb0e4cb0f4aece3fd
@@@ -1197,8 -1197,9 +1197,9 @@@ union cdu_context 
  /* TM (timers) host DB constants */
  #define TM_ILT_PAGE_SZ_HW     0
  #define TM_ILT_PAGE_SZ                (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */
- /* #define TM_CONN_NUM                (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */
- #define TM_CONN_NUM           1024
+ #define TM_CONN_NUM           (BNX2X_FIRST_VF_CID + \
+                                BNX2X_VF_CIDS + \
+                                CNIC_ISCSI_CID_MAX)
  #define TM_ILT_SZ             (8 * TM_CONN_NUM)
  #define TM_ILT_LINES          DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ)
  
@@@ -1527,7 -1528,6 +1528,6 @@@ struct bnx2x 
  #define PCI_32BIT_FLAG                        (1 << 1)
  #define ONE_PORT_FLAG                 (1 << 2)
  #define NO_WOL_FLAG                   (1 << 3)
- #define USING_DAC_FLAG                        (1 << 4)
  #define USING_MSIX_FLAG                       (1 << 5)
  #define USING_MSI_FLAG                        (1 << 6)
  #define DISABLE_MSI_FLAG              (1 << 7)
  #define IS_VF_FLAG                    (1 << 22)
  #define INTERRUPTS_ENABLED_FLAG               (1 << 23)
  #define BC_SUPPORTS_RMMOD_CMD         (1 << 24)
 +#define HAS_PHYS_PORT_ID              (1 << 25)
  
  #define BP_NOMCP(bp)                  ((bp)->flags & NO_MCP_FLAG)
  
        u16                     rx_ticks_int;
        u16                     rx_ticks;
  /* Maximal coalescing timeout in us */
- #define BNX2X_MAX_COALESCE_TOUT               (0xf0*12)
+ #define BNX2X_MAX_COALESCE_TOUT               (0xff*BNX2X_BTR)
  
        u32                     lin_cnt;
  
        u32 dump_preset_idx;
        bool                                    stats_started;
        struct semaphore                        stats_sema;
 +
 +      u8                                      phys_port_id[ETH_ALEN];
  };
  
  /* Tx queues may be less or equal to Rx queues */
@@@ -2075,7 -2072,8 +2075,8 @@@ u32 bnx2x_dmae_opcode(struct bnx2x *bp
  
  void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
                               u8 src_type, u8 dst_type);
- int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae);
+ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+                              u32 *comp);
  
  /* FLR related routines */
  u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp);
@@@ -2234,7 -2232,7 +2235,7 @@@ void bnx2x_igu_clear_sb_gen(struct bnx2
  #define BNX2X_NUM_TESTS_SF            7
  #define BNX2X_NUM_TESTS_MF            3
  #define BNX2X_NUM_TESTS(bp)           (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \
 -                                                   BNX2X_NUM_TESTS_SF)
 +                                           IS_VF(bp) ? 0 : BNX2X_NUM_TESTS_SF)
  
  #define BNX2X_PHY_LOOPBACK            0
  #define BNX2X_MAC_LOOPBACK            1
@@@ -2494,5 -2492,15 +2495,9 @@@ enum 
  
  #define NUM_MACS      8
  
 -enum bnx2x_pci_bus_speed {
 -      BNX2X_PCI_LINK_SPEED_2500 = 2500,
 -      BNX2X_PCI_LINK_SPEED_5000 = 5000,
 -      BNX2X_PCI_LINK_SPEED_8000 = 8000
 -};
 -
  void bnx2x_set_local_cmng(struct bnx2x *bp);
+ #define MCPR_SCRATCH_BASE(bp) \
+       (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
  #endif /* bnx2x.h */
index 0c64122aeaffe96eaa1116df01cd98da8a120cb5,4ab4c89c60cd1eeca873fad127d2702ab2a1a0d1..6e46cff5236da1b835bc7698085fb34b657e3185
@@@ -681,6 -681,7 +681,7 @@@ static void bnx2x_gro_receive(struct bn
                }
        }
  #endif
+       skb_record_rx_queue(skb, fp->rx_queue);
        napi_gro_receive(&fp->napi, skb);
  }
  
@@@ -3255,16 -3256,14 +3256,16 @@@ static u32 bnx2x_xmit_type(struct bnx2
        if (prot == IPPROTO_TCP)
                rc |= XMIT_CSUM_TCP;
  
 -      if (skb_is_gso_v6(skb)) {
 -              rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP);
 -              if (rc & XMIT_CSUM_ENC)
 -                      rc |= XMIT_GSO_ENC_V6;
 -      } else if (skb_is_gso(skb)) {
 -              rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP);
 -              if (rc & XMIT_CSUM_ENC)
 -                      rc |= XMIT_GSO_ENC_V4;
 +      if (skb_is_gso(skb)) {
 +              if (skb_is_gso_v6(skb)) {
 +                      rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP);
 +                      if (rc & XMIT_CSUM_ENC)
 +                              rc |= XMIT_GSO_ENC_V6;
 +              } else {
 +                      rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP);
 +                      if (rc & XMIT_CSUM_ENC)
 +                              rc |= XMIT_GSO_ENC_V4;
 +              }
        }
  
        return rc;
index 8213cc827aae822307e937fc72bcf6dad2d7fabe,e8efa1c93ffecdefde5183e91cbf67d7286928af..32d0f1435fb410b54c3105236c14a211f35bc0b2
@@@ -639,9 -639,6 +639,9 @@@ static int bnx2x_get_regs_len(struct ne
        struct bnx2x *bp = netdev_priv(dev);
        int regdump_len = 0;
  
 +      if (IS_VF(bp))
 +              return 0;
 +
        regdump_len = __bnx2x_get_regs_len(bp);
        regdump_len *= 4;
        regdump_len += sizeof(struct dump_header);
@@@ -894,17 -891,8 +894,8 @@@ static void bnx2x_get_regs(struct net_d
         * will re-enable parity attentions right after the dump.
         */
  
-       /* Disable parity on path 0 */
-       bnx2x_pretend_func(bp, 0);
        bnx2x_disable_blocks_parity(bp);
  
-       /* Disable parity on path 1 */
-       bnx2x_pretend_func(bp, 1);
-       bnx2x_disable_blocks_parity(bp);
-       /* Return to current function */
-       bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
        dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
        dump_hdr.preset = DUMP_ALL_PRESETS;
        dump_hdr.version = BNX2X_DUMP_VERSION;
        /* Actually read the registers */
        __bnx2x_get_regs(bp, p);
  
-       /* Re-enable parity attentions on path 0 */
-       bnx2x_pretend_func(bp, 0);
+       /* Re-enable parity attentions */
        bnx2x_clear_blocks_parity(bp);
        bnx2x_enable_blocks_parity(bp);
-       /* Re-enable parity attentions on path 1 */
-       bnx2x_pretend_func(bp, 1);
-       bnx2x_clear_blocks_parity(bp);
-       bnx2x_enable_blocks_parity(bp);
-       /* Return to current function */
-       bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
  }
  
  static int bnx2x_get_preset_regs_len(struct net_device *dev, u32 preset)
@@@ -996,17 -975,8 +978,8 @@@ static int bnx2x_get_dump_data(struct n
         * will re-enable parity attentions right after the dump.
         */
  
-       /* Disable parity on path 0 */
-       bnx2x_pretend_func(bp, 0);
        bnx2x_disable_blocks_parity(bp);
  
-       /* Disable parity on path 1 */
-       bnx2x_pretend_func(bp, 1);
-       bnx2x_disable_blocks_parity(bp);
-       /* Return to current function */
-       bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
        dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
        dump_hdr.preset = bp->dump_preset_idx;
        dump_hdr.version = BNX2X_DUMP_VERSION;
        /* Actually read the registers */
        __bnx2x_get_preset_regs(bp, p, dump_hdr.preset);
  
-       /* Re-enable parity attentions on path 0 */
-       bnx2x_pretend_func(bp, 0);
+       /* Re-enable parity attentions */
        bnx2x_clear_blocks_parity(bp);
        bnx2x_enable_blocks_parity(bp);
  
-       /* Re-enable parity attentions on path 1 */
-       bnx2x_pretend_func(bp, 1);
-       bnx2x_clear_blocks_parity(bp);
-       bnx2x_enable_blocks_parity(bp);
-       /* Return to current function */
-       bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
        return 0;
  }
  
@@@ -2903,16 -2864,9 +2867,16 @@@ static void bnx2x_self_test(struct net_
  
        memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp));
  
 +      if (bnx2x_test_nvram(bp) != 0) {
 +              if (!IS_MF(bp))
 +                      buf[4] = 1;
 +              else
 +                      buf[0] = 1;
 +              etest->flags |= ETH_TEST_FL_FAILED;
 +      }
 +
        if (!netif_running(dev)) {
 -              DP(BNX2X_MSG_ETHTOOL,
 -                 "Can't perform self-test when interface is down\n");
 +              DP(BNX2X_MSG_ETHTOOL, "Interface is down\n");
                return;
        }
  
                /* wait until link state is restored */
                bnx2x_wait_for_link(bp, link_up, is_serdes);
        }
 -      if (bnx2x_test_nvram(bp) != 0) {
 -              if (!IS_MF(bp))
 -                      buf[4] = 1;
 -              else
 -                      buf[0] = 1;
 -              etest->flags |= ETH_TEST_FL_FAILED;
 -      }
 +
        if (bnx2x_test_intr(bp) != 0) {
                if (!IS_MF(bp))
                        buf[5] = 1;
index 04b9177f46bfcba900f0de26620ebdfdbf4ff2b0,b42f89ce02ef5997fa46e57a9521b0873968d7b7..bb2f20291509392192545f495a290cec93f60e1d
@@@ -503,9 -503,9 +503,9 @@@ void bnx2x_prep_dmae_with_comp(struct b
  }
  
  /* issue a dmae command over the init-channel and wait for completion */
- int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae)
+ int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+                              u32 *comp)
  {
-       u32 *wb_comp = bnx2x_sp(bp, wb_comp);
        int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000;
        int rc = 0;
  
        spin_lock_bh(&bp->dmae_lock);
  
        /* reset completion */
-       *wb_comp = 0;
+       *comp = 0;
  
        /* post the command on the channel used for initializations */
        bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
  
        /* wait for completion */
        udelay(5);
-       while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
+       while ((*comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
  
                if (!cnt ||
                    (bp->recovery_state != BNX2X_RECOVERY_DONE &&
                cnt--;
                udelay(50);
        }
-       if (*wb_comp & DMAE_PCI_ERR_FLAG) {
+       if (*comp & DMAE_PCI_ERR_FLAG) {
                BNX2X_ERR("DMAE PCI error!\n");
                rc = DMAE_PCI_ERROR;
        }
@@@ -574,7 -574,7 +574,7 @@@ void bnx2x_write_dmae(struct bnx2x *bp
        dmae.len = len32;
  
        /* issue the command and wait for completion */
-       rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+       rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
        if (rc) {
                BNX2X_ERR("DMAE returned failure %d\n", rc);
                bnx2x_panic();
@@@ -611,7 -611,7 +611,7 @@@ void bnx2x_read_dmae(struct bnx2x *bp, 
        dmae.len = len32;
  
        /* issue the command and wait for completion */
-       rc = bnx2x_issue_dmae_with_comp(bp, &dmae);
+       rc = bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
        if (rc) {
                BNX2X_ERR("DMAE returned failure %d\n", rc);
                bnx2x_panic();
@@@ -751,6 -751,10 +751,10 @@@ static int bnx2x_mc_assert(struct bnx2
        return rc;
  }
  
+ #define MCPR_TRACE_BUFFER_SIZE        (0x800)
+ #define SCRATCH_BUFFER_SIZE(bp)       \
+       (CHIP_IS_E1(bp) ? 0x10000 : (CHIP_IS_E1H(bp) ? 0x20000 : 0x28000))
  void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl)
  {
        u32 addr, val;
                trace_shmem_base = bp->common.shmem_base;
        else
                trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr);
-       addr = trace_shmem_base - 0x800;
+       /* sanity */
+       if (trace_shmem_base < MCPR_SCRATCH_BASE(bp) + MCPR_TRACE_BUFFER_SIZE ||
+           trace_shmem_base >= MCPR_SCRATCH_BASE(bp) +
+                               SCRATCH_BUFFER_SIZE(bp)) {
+               BNX2X_ERR("Unable to dump trace buffer (mark %x)\n",
+                         trace_shmem_base);
+               return;
+       }
+       addr = trace_shmem_base - MCPR_TRACE_BUFFER_SIZE;
  
        /* validate TRCB signature */
        mark = REG_RD(bp, addr);
        /* read cyclic buffer pointer */
        addr += 4;
        mark = REG_RD(bp, addr);
-       mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
-                       + ((mark + 0x3) & ~0x3) - 0x08000000;
+       mark = MCPR_SCRATCH_BASE(bp) + ((mark + 0x3) & ~0x3) - 0x08000000;
+       if (mark >= trace_shmem_base || mark < addr + 4) {
+               BNX2X_ERR("Mark doesn't fall inside Trace Buffer\n");
+               return;
+       }
        printk("%s" "begin fw dump (mark 0x%x)\n", lvl, mark);
  
        printk("%s", lvl);
  
        /* dump buffer after the mark */
-       for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) {
+       for (offset = mark; offset < trace_shmem_base; offset += 0x8*4) {
                for (word = 0; word < 8; word++)
                        data[word] = htonl(REG_RD(bp, offset + 4*word));
                data[8] = 0x0;
@@@ -4280,65 -4297,60 +4297,60 @@@ static void _print_next_block(int idx, 
        pr_cont("%s%s", idx ? ", " : "", blk);
  }
  
- static int bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
-                                           int par_num, bool print)
+ static bool bnx2x_check_blocks_with_parity0(struct bnx2x *bp, u32 sig,
+                                           int *par_num, bool print)
  {
-       int i = 0;
-       u32 cur_bit = 0;
+       u32 cur_bit;
+       bool res;
+       int i;
+       res = false;
        for (i = 0; sig; i++) {
-               cur_bit = ((u32)0x1 << i);
+               cur_bit = (0x1UL << i);
                if (sig & cur_bit) {
-                       switch (cur_bit) {
-                       case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "BRB");
+                       res |= true; /* Each bit is real error! */
+                       if (print) {
+                               switch (cur_bit) {
+                               case AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "BRB");
                                        _print_parity(bp,
                                                      BRB1_REG_BRB1_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "PARSER");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
+                                                         "PARSER");
                                        _print_parity(bp, PRS_REG_PRS_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "TSDM");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "TSDM");
                                        _print_parity(bp,
                                                      TSDM_REG_TSDM_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++,
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
                                                          "SEARCHER");
                                        _print_parity(bp, SRC_REG_SRC_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "TCM");
-                                       _print_parity(bp,
-                                                     TCM_REG_TCM_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "TSEMI");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "TCM");
+                                       _print_parity(bp, TCM_REG_TCM_PRTY_STS);
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
+                                                         "TSEMI");
                                        _print_parity(bp,
                                                      TSEM_REG_TSEM_PRTY_STS_0);
                                        _print_parity(bp,
                                                      TSEM_REG_TSEM_PRTY_STS_1);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "XPB");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "XPB");
                                        _print_parity(bp, GRCBASE_XPB +
                                                          PB_REG_PB_PRTY_STS);
+                                       break;
                                }
-                               break;
                        }
  
                        /* Clear the bit */
                }
        }
  
-       return par_num;
+       return res;
  }
  
- static int bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
-                                           int par_num, bool *global,
+ static bool bnx2x_check_blocks_with_parity1(struct bnx2x *bp, u32 sig,
+                                           int *par_num, bool *global,
                                            bool print)
  {
-       int i = 0;
-       u32 cur_bit = 0;
+       u32 cur_bit;
+       bool res;
+       int i;
+       res = false;
        for (i = 0; sig; i++) {
-               cur_bit = ((u32)0x1 << i);
+               cur_bit = (0x1UL << i);
                if (sig & cur_bit) {
+                       res |= true; /* Each bit is real error! */
                        switch (cur_bit) {
                        case AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "PBF");
+                                       _print_next_block((*par_num)++, "PBF");
                                        _print_parity(bp, PBF_REG_PBF_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "QM");
+                                       _print_next_block((*par_num)++, "QM");
                                        _print_parity(bp, QM_REG_QM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "TM");
+                                       _print_next_block((*par_num)++, "TM");
                                        _print_parity(bp, TM_REG_TM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "XSDM");
+                                       _print_next_block((*par_num)++, "XSDM");
                                        _print_parity(bp,
                                                      XSDM_REG_XSDM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "XCM");
+                                       _print_next_block((*par_num)++, "XCM");
                                        _print_parity(bp, XCM_REG_XCM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "XSEMI");
+                                       _print_next_block((*par_num)++,
+                                                         "XSEMI");
                                        _print_parity(bp,
                                                      XSEM_REG_XSEM_PRTY_STS_0);
                                        _print_parity(bp,
                                break;
                        case AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++,
+                                       _print_next_block((*par_num)++,
                                                          "DOORBELLQ");
                                        _print_parity(bp,
                                                      DORQ_REG_DORQ_PRTY_STS);
                                break;
                        case AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "NIG");
+                                       _print_next_block((*par_num)++, "NIG");
                                        if (CHIP_IS_E1x(bp)) {
                                                _print_parity(bp,
                                                        NIG_REG_NIG_PRTY_STS);
                                break;
                        case AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR:
                                if (print)
-                                       _print_next_block(par_num++,
+                                       _print_next_block((*par_num)++,
                                                          "VAUX PCI CORE");
                                *global = true;
                                break;
                        case AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "DEBUG");
+                                       _print_next_block((*par_num)++,
+                                                         "DEBUG");
                                        _print_parity(bp, DBG_REG_DBG_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "USDM");
+                                       _print_next_block((*par_num)++, "USDM");
                                        _print_parity(bp,
                                                      USDM_REG_USDM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "UCM");
+                                       _print_next_block((*par_num)++, "UCM");
                                        _print_parity(bp, UCM_REG_UCM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "USEMI");
+                                       _print_next_block((*par_num)++,
+                                                         "USEMI");
                                        _print_parity(bp,
                                                      USEM_REG_USEM_PRTY_STS_0);
                                        _print_parity(bp,
                                break;
                        case AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "UPB");
+                                       _print_next_block((*par_num)++, "UPB");
                                        _print_parity(bp, GRCBASE_UPB +
                                                          PB_REG_PB_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "CSDM");
+                                       _print_next_block((*par_num)++, "CSDM");
                                        _print_parity(bp,
                                                      CSDM_REG_CSDM_PRTY_STS);
                                }
                                break;
                        case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR:
                                if (print) {
-                                       _print_next_block(par_num++, "CCM");
+                                       _print_next_block((*par_num)++, "CCM");
                                        _print_parity(bp, CCM_REG_CCM_PRTY_STS);
                                }
                                break;
                }
        }
  
-       return par_num;
+       return res;
  }
  
- static int bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
-                                           int par_num, bool print)
+ static bool bnx2x_check_blocks_with_parity2(struct bnx2x *bp, u32 sig,
+                                           int *par_num, bool print)
  {
-       int i = 0;
-       u32 cur_bit = 0;
+       u32 cur_bit;
+       bool res;
+       int i;
+       res = false;
        for (i = 0; sig; i++) {
-               cur_bit = ((u32)0x1 << i);
+               cur_bit = (0x1UL << i);
                if (sig & cur_bit) {
-                       switch (cur_bit) {
-                       case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "CSEMI");
+                       res |= true; /* Each bit is real error! */
+                       if (print) {
+                               switch (cur_bit) {
+                               case AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
+                                                         "CSEMI");
                                        _print_parity(bp,
                                                      CSEM_REG_CSEM_PRTY_STS_0);
                                        _print_parity(bp,
                                                      CSEM_REG_CSEM_PRTY_STS_1);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "PXP");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "PXP");
                                        _print_parity(bp, PXP_REG_PXP_PRTY_STS);
                                        _print_parity(bp,
                                                      PXP2_REG_PXP2_PRTY_STS_0);
                                        _print_parity(bp,
                                                      PXP2_REG_PXP2_PRTY_STS_1);
-                               }
-                               break;
-                       case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
-                               if (print)
-                                       _print_next_block(par_num++,
-                                       "PXPPCICLOCKCLIENT");
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "CFC");
+                                       break;
+                               case AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
+                                                         "PXPPCICLOCKCLIENT");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "CFC");
                                        _print_parity(bp,
                                                      CFC_REG_CFC_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "CDU");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "CDU");
                                        _print_parity(bp, CDU_REG_CDU_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "DMAE");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "DMAE");
                                        _print_parity(bp,
                                                      DMAE_REG_DMAE_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "IGU");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "IGU");
                                        if (CHIP_IS_E1x(bp))
                                                _print_parity(bp,
                                                        HC_REG_HC_PRTY_STS);
                                        else
                                                _print_parity(bp,
                                                        IGU_REG_IGU_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "MISC");
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "MISC");
                                        _print_parity(bp,
                                                      MISC_REG_MISC_PRTY_STS);
+                                       break;
                                }
-                               break;
                        }
  
                        /* Clear the bit */
                }
        }
  
-       return par_num;
+       return res;
  }
  
- static int bnx2x_check_blocks_with_parity3(u32 sig, int par_num,
-                                          bool *global, bool print)
+ static bool bnx2x_check_blocks_with_parity3(struct bnx2x *bp, u32 sig,
+                                           int *par_num, bool *global,
+                                           bool print)
  {
-       int i = 0;
-       u32 cur_bit = 0;
+       bool res = false;
+       u32 cur_bit;
+       int i;
        for (i = 0; sig; i++) {
-               cur_bit = ((u32)0x1 << i);
+               cur_bit = (0x1UL << i);
                if (sig & cur_bit) {
                        switch (cur_bit) {
                        case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY:
                                if (print)
-                                       _print_next_block(par_num++, "MCP ROM");
+                                       _print_next_block((*par_num)++,
+                                                         "MCP ROM");
                                *global = true;
+                               res |= true;
                                break;
                        case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY:
                                if (print)
-                                       _print_next_block(par_num++,
+                                       _print_next_block((*par_num)++,
                                                          "MCP UMP RX");
                                *global = true;
+                               res |= true;
                                break;
                        case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY:
                                if (print)
-                                       _print_next_block(par_num++,
+                                       _print_next_block((*par_num)++,
                                                          "MCP UMP TX");
                                *global = true;
+                               res |= true;
                                break;
                        case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY:
                                if (print)
-                                       _print_next_block(par_num++,
+                                       _print_next_block((*par_num)++,
                                                          "MCP SCPAD");
-                               *global = true;
+                               /* clear latched SCPAD PATIRY from MCP */
+                               REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
+                                      1UL << 10);
                                break;
                        }
  
                }
        }
  
-       return par_num;
+       return res;
  }
  
- static int bnx2x_check_blocks_with_parity4(struct bnx2x *bp, u32 sig,
-                                           int par_num, bool print)
+ static bool bnx2x_check_blocks_with_parity4(struct bnx2x *bp, u32 sig,
+                                           int *par_num, bool print)
  {
-       int i = 0;
-       u32 cur_bit = 0;
+       u32 cur_bit;
+       bool res;
+       int i;
+       res = false;
        for (i = 0; sig; i++) {
-               cur_bit = ((u32)0x1 << i);
+               cur_bit = (0x1UL << i);
                if (sig & cur_bit) {
-                       switch (cur_bit) {
-                       case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "PGLUE_B");
+                       res |= true; /* Each bit is real error! */
+                       if (print) {
+                               switch (cur_bit) {
+                               case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
+                                       _print_next_block((*par_num)++,
+                                                         "PGLUE_B");
                                        _print_parity(bp,
-                                               PGLUE_B_REG_PGLUE_B_PRTY_STS);
-                               }
-                               break;
-                       case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
-                               if (print) {
-                                       _print_next_block(par_num++, "ATC");
+                                                     PGLUE_B_REG_PGLUE_B_PRTY_STS);
+                                       break;
+                               case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
+                                       _print_next_block((*par_num)++, "ATC");
                                        _print_parity(bp,
                                                      ATC_REG_ATC_PRTY_STS);
+                                       break;
                                }
-                               break;
                        }
                        /* Clear the bit */
                        sig &= ~cur_bit;
                }
        }
  
-       return par_num;
+       return res;
  }
  
  static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
                              u32 *sig)
  {
+       bool res = false;
        if ((sig[0] & HW_PRTY_ASSERT_SET_0) ||
            (sig[1] & HW_PRTY_ASSERT_SET_1) ||
            (sig[2] & HW_PRTY_ASSERT_SET_2) ||
                if (print)
                        netdev_err(bp->dev,
                                   "Parity errors detected in blocks: ");
-               par_num = bnx2x_check_blocks_with_parity0(bp,
-                       sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print);
-               par_num = bnx2x_check_blocks_with_parity1(bp,
-                       sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print);
-               par_num = bnx2x_check_blocks_with_parity2(bp,
-                       sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print);
-               par_num = bnx2x_check_blocks_with_parity3(
-                       sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print);
-               par_num = bnx2x_check_blocks_with_parity4(bp,
-                       sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print);
+               res |= bnx2x_check_blocks_with_parity0(bp,
+                       sig[0] & HW_PRTY_ASSERT_SET_0, &par_num, print);
+               res |= bnx2x_check_blocks_with_parity1(bp,
+                       sig[1] & HW_PRTY_ASSERT_SET_1, &par_num, global, print);
+               res |= bnx2x_check_blocks_with_parity2(bp,
+                       sig[2] & HW_PRTY_ASSERT_SET_2, &par_num, print);
+               res |= bnx2x_check_blocks_with_parity3(bp,
+                       sig[3] & HW_PRTY_ASSERT_SET_3, &par_num, global, print);
+               res |= bnx2x_check_blocks_with_parity4(bp,
+                       sig[4] & HW_PRTY_ASSERT_SET_4, &par_num, print);
  
                if (print)
                        pr_cont("\n");
+       }
  
-               return true;
-       } else
-               return false;
+       return res;
  }
  
  /**
@@@ -7126,7 -7152,7 +7152,7 @@@ static int bnx2x_init_hw_port(struct bn
        int port = BP_PORT(bp);
        int init_phase = port ? PHASE_PORT1 : PHASE_PORT0;
        u32 low, high;
-       u32 val;
+       u32 val, reg;
  
        DP(NETIF_MSG_HW, "starting port init  port %d\n", port);
  
        val |= CHIP_IS_E1(bp) ? 0 : 0x10;
        REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val);
  
+       /* SCPAD_PARITY should NOT trigger close the gates */
+       reg = port ? MISC_REG_AEU_ENABLE4_NIG_1 : MISC_REG_AEU_ENABLE4_NIG_0;
+       REG_WR(bp, reg,
+              REG_RD(bp, reg) &
+              ~AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY);
+       reg = port ? MISC_REG_AEU_ENABLE4_PXP_1 : MISC_REG_AEU_ENABLE4_PXP_0;
+       REG_WR(bp, reg,
+              REG_RD(bp, reg) &
+              ~AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY);
        bnx2x_init_block(bp, BLOCK_NIG, init_phase);
  
        if (!CHIP_IS_E1x(bp)) {
@@@ -9879,7 -9916,7 +9916,7 @@@ static int bnx2x_prev_path_mark_eeh(str
  static bool bnx2x_prev_is_path_marked(struct bnx2x *bp)
  {
        struct bnx2x_prev_path_list *tmp_list;
 -      int rc = false;
 +      bool rc = false;
  
        if (down_trylock(&bnx2x_prev_sem))
                return false;
@@@ -11149,14 -11186,6 +11186,14 @@@ static void bnx2x_get_mac_hwinfo(struc
                        bnx2x_get_cnic_mac_hwinfo(bp);
        }
  
 +      if (!BP_NOMCP(bp)) {
 +              /* Read physical port identifier from shmem */
 +              val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
 +              val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
 +              bnx2x_set_mac_buf(bp->phys_port_id, val, val2);
 +              bp->flags |= HAS_PHYS_PORT_ID;
 +      }
 +
        memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
  
        if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr))
@@@ -11693,9 -11722,6 +11730,6 @@@ static int bnx2x_init_bp(struct bnx2x *
  static int bnx2x_open(struct net_device *dev)
  {
        struct bnx2x *bp = netdev_priv(dev);
-       bool global = false;
-       int other_engine = BP_PATH(bp) ? 0 : 1;
-       bool other_load_status, load_status;
        int rc;
  
        bp->stats_init = true;
         * Parity recovery is only relevant for PF driver.
         */
        if (IS_PF(bp)) {
+               int other_engine = BP_PATH(bp) ? 0 : 1;
+               bool other_load_status, load_status;
+               bool global = false;
                other_load_status = bnx2x_get_load_status(bp, other_engine);
                load_status = bnx2x_get_load_status(bp, BP_PATH(bp));
                if (!bnx2x_reset_is_done(bp, BP_PATH(bp)) ||
        rc = bnx2x_nic_load(bp, LOAD_OPEN);
        if (rc)
                return rc;
 -      return bnx2x_open_epilog(bp);
 +      return 0;
  }
  
  /* called with rtnl_lock */
@@@ -12052,20 -12082,6 +12090,20 @@@ static int bnx2x_validate_addr(struct n
        return 0;
  }
  
 +static int bnx2x_get_phys_port_id(struct net_device *netdev,
 +                                struct netdev_phys_port_id *ppid)
 +{
 +      struct bnx2x *bp = netdev_priv(netdev);
 +
 +      if (!(bp->flags & HAS_PHYS_PORT_ID))
 +              return -EOPNOTSUPP;
 +
 +      ppid->id_len = sizeof(bp->phys_port_id);
 +      memcpy(ppid->id, bp->phys_port_id, ppid->id_len);
 +
 +      return 0;
 +}
 +
  static const struct net_device_ops bnx2x_netdev_ops = {
        .ndo_open               = bnx2x_open,
        .ndo_stop               = bnx2x_close,
  #ifdef CONFIG_NET_RX_BUSY_POLL
        .ndo_busy_poll          = bnx2x_low_latency_recv,
  #endif
 +      .ndo_get_phys_port_id   = bnx2x_get_phys_port_id,
  };
  
  static int bnx2x_set_coherency_mask(struct bnx2x *bp)
        struct device *dev = &bp->pdev->dev;
  
        if (dma_set_mask(dev, DMA_BIT_MASK(64)) == 0) {
-               bp->flags |= USING_DAC_FLAG;
                if (dma_set_coherent_mask(dev, DMA_BIT_MASK(64)) != 0) {
                        dev_err(dev, "dma_set_coherent_mask failed, aborting\n");
                        return -EIO;
@@@ -12260,13 -12274,10 +12297,13 @@@ static int bnx2x_init_dev(struct bnx2x 
                NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO |
                NETIF_F_RXHASH | NETIF_F_HW_VLAN_CTAG_TX;
        if (!CHIP_IS_E1x(bp)) {
 -              dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
 +              dev->hw_features |= NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL |
 +                                  NETIF_F_GSO_IPIP | NETIF_F_GSO_SIT;
                dev->hw_enc_features =
                        NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
                        NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
 +                      NETIF_F_GSO_IPIP |
 +                      NETIF_F_GSO_SIT |
                        NETIF_F_GSO_GRE | NETIF_F_GSO_UDP_TUNNEL;
        }
  
                NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
  
        dev->features |= dev->hw_features | NETIF_F_HW_VLAN_CTAG_RX;
-       if (bp->flags & USING_DAC_FLAG)
-               dev->features |= NETIF_F_HIGHDMA;
+       dev->features |= NETIF_F_HIGHDMA;
  
        /* Add Loopback capability to the device */
        dev->hw_features |= NETIF_F_LOOPBACK;
@@@ -12300,11 -12310,34 +12336,11 @@@ err_out_release
  
  err_out_disable:
        pci_disable_device(pdev);
 -      pci_set_drvdata(pdev, NULL);
  
  err_out:
        return rc;
  }
  
 -static void bnx2x_get_pcie_width_speed(struct bnx2x *bp, int *width,
 -                                     enum bnx2x_pci_bus_speed *speed)
 -{
 -      u32 link_speed, val = 0;
 -
 -      pci_read_config_dword(bp->pdev, PCICFG_LINK_CONTROL, &val);
 -      *width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
 -
 -      link_speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
 -
 -      switch (link_speed) {
 -      case 3:
 -              *speed = BNX2X_PCI_LINK_SPEED_8000;
 -              break;
 -      case 2:
 -              *speed = BNX2X_PCI_LINK_SPEED_5000;
 -              break;
 -      default:
 -              *speed = BNX2X_PCI_LINK_SPEED_2500;
 -      }
 -}
 -
  static int bnx2x_check_firmware(struct bnx2x *bp)
  {
        const struct firmware *firmware = bp->firmware;
@@@ -12615,24 -12648,24 +12651,24 @@@ static int set_max_cos_est(int chip_id
                return BNX2X_MULTI_TX_COS_E1X;
        case BCM57712:
        case BCM57712_MF:
-       case BCM57712_VF:
                return BNX2X_MULTI_TX_COS_E2_E3A0;
        case BCM57800:
        case BCM57800_MF:
-       case BCM57800_VF:
        case BCM57810:
        case BCM57810_MF:
        case BCM57840_4_10:
        case BCM57840_2_20:
        case BCM57840_O:
        case BCM57840_MFO:
-       case BCM57810_VF:
        case BCM57840_MF:
-       case BCM57840_VF:
        case BCM57811:
        case BCM57811_MF:
-       case BCM57811_VF:
                return BNX2X_MULTI_TX_COS_E3B0;
+       case BCM57712_VF:
+       case BCM57800_VF:
+       case BCM57810_VF:
+       case BCM57840_VF:
+       case BCM57811_VF:
                return 1;
        default:
                pr_err("Unknown board_type (%d), aborting\n", chip_id);
@@@ -12661,8 -12694,8 +12697,8 @@@ static int bnx2x_init_one(struct pci_de
  {
        struct net_device *dev = NULL;
        struct bnx2x *bp;
 -      int pcie_width;
 -      enum bnx2x_pci_bus_speed pcie_speed;
 +      enum pcie_link_width pcie_width;
 +      enum pci_bus_speed pcie_speed;
        int rc, max_non_def_sbs;
        int rx_count, tx_count, rss_count, doorbell_size;
        int max_cos_est;
                dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN);
                rtnl_unlock();
        }
 -
 -      bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
 -      BNX2X_DEV_INFO("got pcie width %d and speed %d\n",
 -                     pcie_width, pcie_speed);
 -
 -      BNX2X_DEV_INFO("%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
 +      if (pcie_get_minimum_link(bp->pdev, &pcie_speed, &pcie_width) ||
 +          pcie_speed == PCI_SPEED_UNKNOWN ||
 +          pcie_width == PCIE_LNK_WIDTH_UNKNOWN)
 +              BNX2X_DEV_INFO("Failed to determine PCI Express Bandwidth\n");
 +      else
 +              BNX2X_DEV_INFO(
 +                     "%s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM\n",
                       board_info[ent->driver_data].name,
                       (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
                       pcie_width,
 -                     pcie_speed == BNX2X_PCI_LINK_SPEED_2500 ? "2.5GHz" :
 -                     pcie_speed == BNX2X_PCI_LINK_SPEED_5000 ? "5.0GHz" :
 -                     pcie_speed == BNX2X_PCI_LINK_SPEED_8000 ? "8.0GHz" :
 +                     pcie_speed == PCIE_SPEED_2_5GT ? "2.5GHz" :
 +                     pcie_speed == PCIE_SPEED_5_0GT ? "5.0GHz" :
 +                     pcie_speed == PCIE_SPEED_8_0GT ? "8.0GHz" :
                       "Unknown",
                       dev->base_addr, bp->pdev->irq, dev->dev_addr);
  
@@@ -12842,6 -12874,7 +12878,6 @@@ init_one_exit
                pci_release_regions(pdev);
  
        pci_disable_device(pdev);
 -      pci_set_drvdata(pdev, NULL);
  
        return rc;
  }
@@@ -12924,6 -12957,7 +12960,6 @@@ static void __bnx2x_remove(struct pci_d
                pci_release_regions(pdev);
  
        pci_disable_device(pdev);
 -      pci_set_drvdata(pdev, NULL);
  }
  
  static void bnx2x_remove_one(struct pci_dev *pdev)
index 122703d8127e6f3d8c5b8fc7d9736c8e23ea1968,bf08ad68b4052374552e376739a101af0a652cf6..71fffad94affa6ba994fcd454edba15de227b746
@@@ -470,10 -470,10 +470,10 @@@ static int bnx2x_vfop_qdtor_cmd(struct 
                                 bnx2x_vfop_qdtor, cmd->done);
                return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor,
                                             cmd->block);
+       } else {
+               BNX2X_ERR("VF[%d] failed to add a vfop\n", vf->abs_vfid);
+               return -ENOMEM;
        }
-       DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop. rc %d\n",
-          vf->abs_vfid, vfop->rc);
-       return -ENOMEM;
  }
  
  static void
@@@ -2802,7 -2802,7 +2802,7 @@@ struct set_vf_state_cookie 
        u8 state;
  };
  
 -void bnx2x_set_vf_state(void *cookie)
 +static void bnx2x_set_vf_state(void *cookie)
  {
        struct set_vf_state_cookie *p = (struct set_vf_state_cookie *)cookie;
  
@@@ -3225,9 -3225,8 +3225,9 @@@ void bnx2x_disable_sriov(struct bnx2x *
        pci_disable_sriov(bp->pdev);
  }
  
 -int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx, struct bnx2x_virtf **vf,
 -                      struct pf_vf_bulletin_content **bulletin)
 +static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx,
 +                           struct bnx2x_virtf **vf,
 +                           struct pf_vf_bulletin_content **bulletin)
  {
        if (bp->state != BNX2X_STATE_OPEN) {
                BNX2X_ERR("vf ndo called though PF is down\n");
@@@ -3391,14 -3390,16 +3391,16 @@@ int bnx2x_set_vf_mac(struct net_device 
                rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_ETH_MAC, true);
                if (rc) {
                        BNX2X_ERR("failed to delete eth macs\n");
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto out;
                }
  
                /* remove existing uc list macs */
                rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_UC_LIST_MAC, true);
                if (rc) {
                        BNX2X_ERR("failed to delete uc_list macs\n");
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto out;
                }
  
                /* configure the new mac to device */
                bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true,
                                  BNX2X_ETH_MAC, &ramrod_flags);
  
+ out:
                bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
        }
  
@@@ -3468,7 -3470,8 +3471,8 @@@ int bnx2x_set_vf_vlan(struct net_devic
                                          &ramrod_flags);
                if (rc) {
                        BNX2X_ERR("failed to delete vlans\n");
-                       return -EINVAL;
+                       rc = -EINVAL;
+                       goto out;
                }
  
                /* send queue update ramrod to configure default vlan and silent
                        rc = bnx2x_config_vlan_mac(bp, &ramrod_param);
                        if (rc) {
                                BNX2X_ERR("failed to configure vlan\n");
-                               return -EINVAL;
+                               rc =  -EINVAL;
+                               goto out;
                        }
  
                        /* configure default vlan to vf queue and set silent
                rc = bnx2x_queue_state_change(bp, &q_params);
                if (rc) {
                        BNX2X_ERR("Failed to configure default VLAN\n");
-                       return rc;
+                       goto out;
                }
  
                /* clear the flag indicating that this VF needs its vlan
-                * (will only be set if the HV configured th Vlan before vf was
-                * and we were called because the VF came up later
+                * (will only be set if the HV configured the Vlan before vf was
+                * up and we were called because the VF came up later
                 */
+ out:
                vf->cfg_flags &= ~VF_CFG_VLAN;
                bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
        }
-       return 0;
+       return rc;
  }
  
  /* crc is the first field in the bulletin board. Compute the crc over the
@@@ -3638,6 -3642,29 +3643,6 @@@ alloc_mem_err
        return -ENOMEM;
  }
  
 -int bnx2x_open_epilog(struct bnx2x *bp)
 -{
 -      /* Enable sriov via delayed work. This must be done via delayed work
 -       * because it causes the probe of the vf devices to be run, which invoke
 -       * register_netdevice which must have rtnl lock taken. As we are holding
 -       * the lock right now, that could only work if the probe would not take
 -       * the lock. However, as the probe of the vf may be called from other
 -       * contexts as well (such as passthrough to vm fails) it can't assume
 -       * the lock is being held for it. Using delayed work here allows the
 -       * probe code to simply take the lock (i.e. wait for it to be released
 -       * if it is being held). We only want to do this if the number of VFs
 -       * was set before PF driver was loaded.
 -       */
 -      if (IS_SRIOV(bp) && BNX2X_NR_VIRTFN(bp)) {
 -              smp_mb__before_clear_bit();
 -              set_bit(BNX2X_SP_RTNL_ENABLE_SRIOV, &bp->sp_rtnl_state);
 -              smp_mb__after_clear_bit();
 -              schedule_delayed_work(&bp->sp_rtnl_task, 0);
 -      }
 -
 -      return 0;
 -}
 -
  void bnx2x_iov_channel_down(struct bnx2x *bp)
  {
        int vf_idx;
index 58dc89af7c6afb5d51333230efd59cf63b72ee4a,28757dfacf0da0107576e0c8f7db3222fd5f7a1e..9199adf32d33c1639dfa2354e609ef92b638ef91
@@@ -60,30 -60,6 +60,30 @@@ void bnx2x_vfpf_finalize(struct bnx2x *
        mutex_unlock(&bp->vf2pf_mutex);
  }
  
 +/* Finds a TLV by type in a TLV buffer; If found, returns pointer to the TLV */
 +static void *bnx2x_search_tlv_list(struct bnx2x *bp, void *tlvs_list,
 +                                 enum channel_tlvs req_tlv)
 +{
 +      struct channel_tlv *tlv = (struct channel_tlv *)tlvs_list;
 +
 +      do {
 +              if (tlv->type == req_tlv)
 +                      return tlv;
 +
 +              if (!tlv->length) {
 +                      BNX2X_ERR("Found TLV with length 0\n");
 +                      return NULL;
 +              }
 +
 +              tlvs_list += tlv->length;
 +              tlv = (struct channel_tlv *)tlvs_list;
 +      } while (tlv->type != CHANNEL_TLV_LIST_END);
 +
 +      DP(BNX2X_MSG_IOV, "TLV list does not contain %d TLV\n", req_tlv);
 +
 +      return NULL;
 +}
 +
  /* list the types and lengths of the tlvs on the buffer */
  void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list)
  {
@@@ -220,7 -196,6 +220,7 @@@ int bnx2x_vfpf_acquire(struct bnx2x *bp
        int rc = 0, attempts = 0;
        struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire;
        struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp;
 +      struct vfpf_port_phys_id_resp_tlv *phys_port_resp;
        u32 vf_id;
        bool resources_acquired = false;
  
        /* pf 2 vf bulletin board address */
        req->bulletin_addr = bp->pf2vf_bulletin_mapping;
  
 +      /* Request physical port identifier */
 +      bnx2x_add_tlv(bp, req, req->first_tlv.tl.length,
 +                    CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv));
 +
        /* add list termination tlv */
 -      bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
 +      bnx2x_add_tlv(bp, req,
 +                    req->first_tlv.tl.length + sizeof(struct channel_tlv),
 +                    CHANNEL_TLV_LIST_END,
                      sizeof(struct channel_list_end_tlv));
  
        /* output tlvs list */
                }
        }
  
 +      /* Retrieve physical port id (if possible) */
 +      phys_port_resp = (struct vfpf_port_phys_id_resp_tlv *)
 +                       bnx2x_search_tlv_list(bp, resp,
 +                                             CHANNEL_TLV_PHYS_PORT_ID);
 +      if (phys_port_resp) {
 +              memcpy(bp->phys_port_id, phys_port_resp->id, ETH_ALEN);
 +              bp->flags |= HAS_PHYS_PORT_ID;
 +      }
 +
        /* get HW info */
        bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff);
        bp->link_params.chip_id = bp->common.chip_id;
@@@ -1020,62 -980,56 +1020,62 @@@ static int bnx2x_copy32_vf_dmae(struct 
        dmae.len = len32;
  
        /* issue the command and wait for completion */
-       return bnx2x_issue_dmae_with_comp(bp, &dmae);
+       return bnx2x_issue_dmae_with_comp(bp, &dmae, bnx2x_sp(bp, wb_comp));
  }
  
 -static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
 +static void bnx2x_vf_mbx_resp_single_tlv(struct bnx2x *bp,
 +                                       struct bnx2x_virtf *vf)
  {
        struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index);
 -      u64 vf_addr;
 -      dma_addr_t pf_addr;
        u16 length, type;
 -      int rc;
 -      struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp;
  
        /* prepare response */
        type = mbx->first_tlv.tl.type;
        length = type == CHANNEL_TLV_ACQUIRE ?
                sizeof(struct pfvf_acquire_resp_tlv) :
                sizeof(struct pfvf_general_resp_tlv);
 -      bnx2x_add_tlv(bp, resp, 0, type, length);
 -      resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc);
 -      bnx2x_add_tlv(bp, resp, length, CHANNEL_TLV_LIST_END,
 +      bnx2x_add_tlv(bp, &mbx->msg->resp, 0, type, length);
 +      bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END,
                      sizeof(struct channel_list_end_tlv));
 +}
 +
 +static void bnx2x_vf_mbx_resp_send_msg(struct bnx2x *bp,
 +                                     struct bnx2x_virtf *vf)
 +{
 +      struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index);
 +      struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp;
 +      dma_addr_t pf_addr;
 +      u64 vf_addr;
 +      int rc;
 +
        bnx2x_dp_tlv_list(bp, resp);
        DP(BNX2X_MSG_IOV, "mailbox vf address hi 0x%x, lo 0x%x, offset 0x%x\n",
           mbx->vf_addr_hi, mbx->vf_addr_lo, mbx->first_tlv.resp_msg_offset);
  
 +      resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc);
 +
        /* send response */
        vf_addr = HILO_U64(mbx->vf_addr_hi, mbx->vf_addr_lo) +
                  mbx->first_tlv.resp_msg_offset;
        pf_addr = mbx->msg_mapping +
                  offsetof(struct bnx2x_vf_mbx_msg, resp);
  
 -      /* copy the response body, if there is one, before the header, as the vf
 -       * is sensitive to the header being written
 +      /* Copy the response buffer. The first u64 is written afterwards, as
 +       * the vf is sensitive to the header being written
         */
 -      if (resp->hdr.tl.length > sizeof(u64)) {
 -              length = resp->hdr.tl.length - sizeof(u64);
 -              vf_addr += sizeof(u64);
 -              pf_addr += sizeof(u64);
 -              rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid,
 -                                        U64_HI(vf_addr),
 -                                        U64_LO(vf_addr),
 -                                        length/4);
 -              if (rc) {
 -                      BNX2X_ERR("Failed to copy response body to VF %d\n",
 -                                vf->abs_vfid);
 -                      goto mbx_error;
 -              }
 -              vf_addr -= sizeof(u64);
 -              pf_addr -= sizeof(u64);
 +      vf_addr += sizeof(u64);
 +      pf_addr += sizeof(u64);
 +      rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid,
 +                                U64_HI(vf_addr),
 +                                U64_LO(vf_addr),
 +                                (sizeof(union pfvf_tlvs) - sizeof(u64))/4);
 +      if (rc) {
 +              BNX2X_ERR("Failed to copy response body to VF %d\n",
 +                        vf->abs_vfid);
 +              goto mbx_error;
        }
 +      vf_addr -= sizeof(u64);
 +      pf_addr -= sizeof(u64);
  
        /* ack the FW */
        storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
@@@ -1106,36 -1060,6 +1106,36 @@@ mbx_error
        bnx2x_vf_release(bp, vf, false); /* non blocking */
  }
  
 +static void bnx2x_vf_mbx_resp(struct bnx2x *bp,
 +                                     struct bnx2x_virtf *vf)
 +{
 +      bnx2x_vf_mbx_resp_single_tlv(bp, vf);
 +      bnx2x_vf_mbx_resp_send_msg(bp, vf);
 +}
 +
 +static void bnx2x_vf_mbx_resp_phys_port(struct bnx2x *bp,
 +                                      struct bnx2x_virtf *vf,
 +                                      void *buffer,
 +                                      u16 *offset)
 +{
 +      struct vfpf_port_phys_id_resp_tlv *port_id;
 +
 +      if (!(bp->flags & HAS_PHYS_PORT_ID))
 +              return;
 +
 +      bnx2x_add_tlv(bp, buffer, *offset, CHANNEL_TLV_PHYS_PORT_ID,
 +                    sizeof(struct vfpf_port_phys_id_resp_tlv));
 +
 +      port_id = (struct vfpf_port_phys_id_resp_tlv *)
 +                (((u8 *)buffer) + *offset);
 +      memcpy(port_id->id, bp->phys_port_id, ETH_ALEN);
 +
 +      /* Offset should continue representing the offset to the tail
 +       * of TLV data (outside this function scope)
 +       */
 +      *offset += sizeof(struct vfpf_port_phys_id_resp_tlv);
 +}
 +
  static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
                                      struct bnx2x_vf_mbx *mbx, int vfop_status)
  {
        struct pfvf_acquire_resp_tlv *resp = &mbx->msg->resp.acquire_resp;
        struct pf_vf_resc *resc = &resp->resc;
        u8 status = bnx2x_pfvf_status_codes(vfop_status);
 +      u16 length;
  
        memset(resp, 0, sizeof(*resp));
  
                        resc->hw_sbs[i].sb_qid);
        DP_CONT(BNX2X_MSG_IOV, "]\n");
  
 +      /* prepare response */
 +      length = sizeof(struct pfvf_acquire_resp_tlv);
 +      bnx2x_add_tlv(bp, &mbx->msg->resp, 0, CHANNEL_TLV_ACQUIRE, length);
 +
 +      /* Handle possible VF requests for physical port identifiers.
 +       * 'length' should continue to indicate the offset of the first empty
 +       * place in the buffer (i.e., where next TLV should be inserted)
 +       */
 +      if (bnx2x_search_tlv_list(bp, &mbx->msg->req,
 +                                CHANNEL_TLV_PHYS_PORT_ID))
 +              bnx2x_vf_mbx_resp_phys_port(bp, vf, &mbx->msg->resp, &length);
 +
 +      bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END,
 +                    sizeof(struct channel_list_end_tlv));
 +
        /* send the response */
        vf->op_rc = vfop_status;
 -      bnx2x_vf_mbx_resp(bp, vf);
 +      bnx2x_vf_mbx_resp_send_msg(bp, vf);
  }
  
  static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
@@@ -1966,9 -1874,6 +1966,9 @@@ void bnx2x_vf_mbx(struct bnx2x *bp, str
        /* process the VF message header */
        mbx->first_tlv = mbx->msg->req.first_tlv;
  
 +      /* Clean response buffer to refrain from falsely seeing chains */
 +      memset(&mbx->msg->resp, 0, sizeof(union pfvf_tlvs));
 +
        /* dispatch the request (will prepare the response) */
        bnx2x_vf_mbx_request(bp, vf, mbx);
        goto mbx_done;
index be8efeea51f263481b5bcfef84d7874e9b308726,a7a941b1a655a3bbf82baa949c1fe81d17458701..7080ad6c401409199b091021aeed398dda61062c
@@@ -158,18 -158,6 +158,6 @@@ static inline board_info_t *to_dm9000_b
  
  /* DM9000 network board routine ---------------------------- */
  
- static void
- dm9000_reset(board_info_t * db)
- {
-       dev_dbg(db->dev, "resetting device\n");
-       /* RESET device */
-       writeb(DM9000_NCR, db->io_addr);
-       udelay(200);
-       writeb(NCR_RST, db->io_data);
-       udelay(200);
- }
  /*
   *   Read a byte from I/O port
   */
@@@ -191,6 -179,27 +179,27 @@@ iow(board_info_t * db, int reg, int val
        writeb(value, db->io_data);
  }
  
+ static void
+ dm9000_reset(board_info_t *db)
+ {
+       dev_dbg(db->dev, "resetting device\n");
+       /* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29
+        * The essential point is that we have to do a double reset, and the
+        * instruction is to set LBK into MAC internal loopback mode.
+        */
+       iow(db, DM9000_NCR, 0x03);
+       udelay(100); /* Application note says at least 20 us */
+       if (ior(db, DM9000_NCR) & 1)
+               dev_err(db->dev, "dm9000 did not respond to first reset\n");
+       iow(db, DM9000_NCR, 0);
+       iow(db, DM9000_NCR, 0x03);
+       udelay(100);
+       if (ior(db, DM9000_NCR) & 1)
+               dev_err(db->dev, "dm9000 did not respond to second reset\n");
+ }
  /* routines for sending block to chip */
  
  static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
@@@ -744,15 -753,20 +753,20 @@@ static const struct ethtool_ops dm9000_
  static void dm9000_show_carrier(board_info_t *db,
                                unsigned carrier, unsigned nsr)
  {
+       int lpa;
        struct net_device *ndev = db->ndev;
+       struct mii_if_info *mii = &db->mii;
        unsigned ncr = dm9000_read_locked(db, DM9000_NCR);
  
-       if (carrier)
-               dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n",
+       if (carrier) {
+               lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
+               dev_info(db->dev,
+                        "%s: link up, %dMbps, %s-duplex, lpa 0x%04X\n",
                         ndev->name, (nsr & NSR_SPEED) ? 10 : 100,
-                        (ncr & NCR_FDX) ? "full" : "half");
-       else
+                        (ncr & NCR_FDX) ? "full" : "half", lpa);
+       } else {
                dev_info(db->dev, "%s: link down\n", ndev->name);
+       }
  }
  
  static void
@@@ -890,9 -904,15 +904,15 @@@ dm9000_init_dm9000(struct net_device *d
                        (dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0);
  
        iow(db, DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
+       iow(db, DM9000_GPR, 0);
  
-       dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
-       dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
+       /* If we are dealing with DM9000B, some extra steps are required: a
+        * manual phy reset, and setting init params.
+        */
+       if (db->type == TYPE_DM9000B) {
+               dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET);
+               dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM);
+       }
  
        ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
  
@@@ -1603,7 -1623,7 +1623,7 @@@ dm9000_probe(struct platform_device *pd
  
        if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
                mac_src = "platform data";
 -              memcpy(ndev->dev_addr, pdata->dev_addr, 6);
 +              memcpy(ndev->dev_addr, pdata->dev_addr, ETH_ALEN);
        }
  
        if (!is_valid_ether_addr(ndev->dev_addr)) {
index 186dc4a489a46f2e0fcd472f73c2f187515bb848,9fbe4dda7a0e4d68d6bee463fbc6e0a18fa8c061..d6d810cb97c79b80da7991f2ee423406b89853af
@@@ -88,6 -88,7 +88,7 @@@
  
  #include <asm/io.h>
  #include <asm/reg.h>
+ #include <asm/mpc85xx.h>
  #include <asm/irq.h>
  #include <asm/uaccess.h>
  #include <linux/module.h>
@@@ -939,9 -940,8 +940,8 @@@ static void gfar_init_filer_table(struc
        }
  }
  
- static void gfar_detect_errata(struct gfar_private *priv)
+ static void __gfar_detect_errata_83xx(struct gfar_private *priv)
  {
-       struct device *dev = &priv->ofdev->dev;
        unsigned int pvr = mfspr(SPRN_PVR);
        unsigned int svr = mfspr(SPRN_SVR);
        unsigned int mod = (svr >> 16) & 0xfff6; /* w/o E suffix */
            (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
                priv->errata |= GFAR_ERRATA_76;
  
-       /* MPC8313 and MPC837x all rev */
-       if ((pvr == 0x80850010 && mod == 0x80b0) ||
-           (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0))
-               priv->errata |= GFAR_ERRATA_A002;
+       /* MPC8313 Rev < 2.0 */
+       if (pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020)
+               priv->errata |= GFAR_ERRATA_12;
+ }
  
-       /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */
-       if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) ||
-           (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020))
+ static void __gfar_detect_errata_85xx(struct gfar_private *priv)
+ {
+       unsigned int svr = mfspr(SPRN_SVR);
+       if ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20))
                priv->errata |= GFAR_ERRATA_12;
+       if (((SVR_SOC_VER(svr) == SVR_P2020) && (SVR_REV(svr) < 0x20)) ||
+           ((SVR_SOC_VER(svr) == SVR_P2010) && (SVR_REV(svr) < 0x20)))
+               priv->errata |= GFAR_ERRATA_76; /* aka eTSEC 20 */
+ }
+ static void gfar_detect_errata(struct gfar_private *priv)
+ {
+       struct device *dev = &priv->ofdev->dev;
+       /* no plans to fix */
+       priv->errata |= GFAR_ERRATA_A002;
+       if (pvr_version_is(PVR_VER_E500V1) || pvr_version_is(PVR_VER_E500V2))
+               __gfar_detect_errata_85xx(priv);
+       else /* non-mpc85xx parts, i.e. e300 core based */
+               __gfar_detect_errata_83xx(priv);
  
        if (priv->errata)
                dev_info(dev, "enabled errata workarounds, flags: 0x%x\n",
@@@ -1599,7 -1617,7 +1617,7 @@@ static int __gfar_is_rx_idle(struct gfa
        /* Normaly TSEC should not hang on GRS commands, so we should
         * actually wait for IEVENT_GRSC flag.
         */
-       if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002)))
+       if (!gfar_has_errata(priv, GFAR_ERRATA_A002))
                return 0;
  
        /* Read the eTSEC register at offset 0xD1C. If bits 7-14 are
@@@ -2900,7 -2918,7 +2918,7 @@@ static int gfar_poll(struct napi_struc
        struct gfar_priv_rx_q *rx_queue = NULL;
        int work_done = 0, work_done_per_q = 0;
        int i, budget_per_q = 0;
 -      int has_tx_work;
 +      int has_tx_work = 0;
        unsigned long rstat_rxf;
        int num_act_queues;
  
        if (num_act_queues)
                budget_per_q = budget/num_act_queues;
  
 -      while (1) {
 -              has_tx_work = 0;
 -              for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
 -                      tx_queue = priv->tx_queue[i];
 -                      /* run Tx cleanup to completion */
 -                      if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
 -                              gfar_clean_tx_ring(tx_queue);
 -                              has_tx_work = 1;
 -                      }
 +      for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) {
 +              tx_queue = priv->tx_queue[i];
 +              /* run Tx cleanup to completion */
 +              if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) {
 +                      gfar_clean_tx_ring(tx_queue);
 +                      has_tx_work = 1;
                }
 +      }
  
 -              for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
 -                      /* skip queue if not active */
 -                      if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
 -                              continue;
 -
 -                      rx_queue = priv->rx_queue[i];
 -                      work_done_per_q =
 -                              gfar_clean_rx_ring(rx_queue, budget_per_q);
 -                      work_done += work_done_per_q;
 -
 -                      /* finished processing this queue */
 -                      if (work_done_per_q < budget_per_q) {
 -                              /* clear active queue hw indication */
 -                              gfar_write(&regs->rstat,
 -                                         RSTAT_CLEAR_RXF0 >> i);
 -                              rstat_rxf &= ~(RSTAT_CLEAR_RXF0 >> i);
 -                              num_act_queues--;
 -
 -                              if (!num_act_queues)
 -                                      break;
 -                              /* recompute budget per Rx queue */
 -                              budget_per_q =
 -                                      (budget - work_done) / num_act_queues;
 -                      }
 -              }
 +      for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) {
 +              /* skip queue if not active */
 +              if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i)))
 +                      continue;
  
 -              if (work_done >= budget)
 -                      break;
 +              rx_queue = priv->rx_queue[i];
 +              work_done_per_q =
 +                      gfar_clean_rx_ring(rx_queue, budget_per_q);
 +              work_done += work_done_per_q;
 +
 +              /* finished processing this queue */
 +              if (work_done_per_q < budget_per_q) {
 +                      /* clear active queue hw indication */
 +                      gfar_write(&regs->rstat,
 +                                 RSTAT_CLEAR_RXF0 >> i);
 +                      num_act_queues--;
 +
 +                      if (!num_act_queues)
 +                              break;
 +              }
 +      }
  
 -              if (!num_act_queues && !has_tx_work) {
 +      if (!num_act_queues && !has_tx_work) {
  
 -                      napi_complete(napi);
 +              napi_complete(napi);
  
 -                      /* Clear the halt bit in RSTAT */
 -                      gfar_write(&regs->rstat, gfargrp->rstat);
 +              /* Clear the halt bit in RSTAT */
 +              gfar_write(&regs->rstat, gfargrp->rstat);
  
 -                      gfar_write(&regs->imask, IMASK_DEFAULT);
 +              gfar_write(&regs->imask, IMASK_DEFAULT);
  
 -                      /* If we are coalescing interrupts, update the timer
 -                       * Otherwise, clear it
 -                       */
 -                      gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
 -                                                gfargrp->tx_bit_map);
 -                      break;
 -              }
 +              /* If we are coalescing interrupts, update the timer
 +               * Otherwise, clear it
 +               */
 +              gfar_configure_coalescing(priv, gfargrp->rx_bit_map,
 +                                        gfargrp->tx_bit_map);
        }
  
        return work_done;
index 66355b72818c6450167289b24bddfce3f6bed91b,ff83a9fcd4c5a844955d221c9daef96772402b7a..b2a8805997ca98ccde591cd05dc0b2951470ef19
@@@ -187,8 -187,8 +187,8 @@@ static int qlcnic_dev_statistics_len(st
                return -1;
  }
  
 -#define QLCNIC_RING_REGS_COUNT        20
 -#define QLCNIC_RING_REGS_LEN  (QLCNIC_RING_REGS_COUNT * sizeof(u32))
 +#define       QLCNIC_TX_INTR_NOT_CONFIGURED   0X78563412
 +
  #define QLCNIC_MAX_EEPROM_LEN   1024
  
  static const u32 diag_registers[] = {
@@@ -219,15 -219,7 +219,15 @@@ static const u32 ext_diag_registers[] 
  };
  
  #define QLCNIC_MGMT_API_VERSION       2
 -#define QLCNIC_ETHTOOL_REGS_VER       3
 +#define QLCNIC_ETHTOOL_REGS_VER       4
 +
 +static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
 +{
 +      int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) +
 +                          (adapter->max_rds_rings * 2) +
 +                          (adapter->max_sds_rings * 3) + 5;
 +      return ring_regs_cnt * sizeof(u32);
 +}
  
  static int qlcnic_get_regs_len(struct net_device *dev)
  {
        else
                len = sizeof(ext_diag_registers) + sizeof(diag_registers);
  
 -      return QLCNIC_RING_REGS_LEN + len + QLCNIC_DEV_INFO_SIZE + 1;
 +      len += ((QLCNIC_DEV_INFO_SIZE + 2) * sizeof(u32));
 +      len += qlcnic_get_ring_regs_len(adapter);
 +      return len;
  }
  
  static int qlcnic_get_eeprom_len(struct net_device *dev)
@@@ -503,8 -493,6 +503,8 @@@ qlcnic_get_regs(struct net_device *dev
        struct qlcnic_adapter *adapter = netdev_priv(dev);
        struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
        struct qlcnic_host_sds_ring *sds_ring;
 +      struct qlcnic_host_rds_ring *rds_rings;
 +      struct qlcnic_host_tx_ring *tx_ring;
        u32 *regs_buff = p;
        int ring, i = 0;
  
        if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
                return;
  
 -      regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
 -
 -      regs_buff[i++] = 1; /* No. of tx ring */
 -      regs_buff[i++] = le32_to_cpu(*(adapter->tx_ring->hw_consumer));
 -      regs_buff[i++] = readl(adapter->tx_ring->crb_cmd_producer);
 -
 -      regs_buff[i++] = 2; /* No. of rx ring */
 -      regs_buff[i++] = readl(recv_ctx->rds_rings[0].crb_rcv_producer);
 -      regs_buff[i++] = readl(recv_ctx->rds_rings[1].crb_rcv_producer);
 +      /* Marker btw regs and TX ring count */
 +      regs_buff[i++] = 0xFFEFCDAB;
 +
 +      regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */
 +      for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
 +              tx_ring = &adapter->tx_ring[ring];
 +              regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
 +              regs_buff[i++] = tx_ring->sw_consumer;
 +              regs_buff[i++] = readl(tx_ring->crb_cmd_producer);
 +              regs_buff[i++] = tx_ring->producer;
 +              if (tx_ring->crb_intr_mask)
 +                      regs_buff[i++] = readl(tx_ring->crb_intr_mask);
 +              else
 +                      regs_buff[i++] = QLCNIC_TX_INTR_NOT_CONFIGURED;
 +      }
  
 -      regs_buff[i++] = adapter->max_sds_rings;
 +      regs_buff[i++] = adapter->max_rds_rings; /* No. of RX ring */
 +      for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 +              rds_rings = &recv_ctx->rds_rings[ring];
 +              regs_buff[i++] = readl(rds_rings->crb_rcv_producer);
 +              regs_buff[i++] = rds_rings->producer;
 +      }
  
 +      regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &(recv_ctx->sds_rings[ring]);
                regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
 +              regs_buff[i++] = sds_ring->consumer;
 +              regs_buff[i++] = readl(sds_ring->crb_intr_mask);
        }
  }
  
@@@ -691,7 -665,7 +691,7 @@@ static int qlcnic_set_channels(struct n
                        return err;
        }
  
-       if (channel->tx_count) {
+       if (qlcnic_82xx_check(adapter) && channel->tx_count) {
                err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count);
                if (err)
                        return err;
index 24e6b1123d86e4ba9ebd032378d38c3332e0a03e,9e61eb8674524575481d0f1158d75353ea4ef724..dcf4a4e7ce23d49073b949b2275f8192b09a0c97
@@@ -819,7 -819,7 +819,7 @@@ static bool qlcnic_port_eswitch_cfg_cap
  int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
  {
        struct qlcnic_pci_info *pci_info;
 -      int i, ret = 0, j = 0;
 +      int i, id = 0, ret = 0, j = 0;
        u16 act_pci_func;
        u8 pfn;
  
                        continue;
  
                if (qlcnic_port_eswitch_cfg_capability(adapter)) {
 -                      if (!qlcnic_83xx_enable_port_eswitch(adapter, pfn))
 +                      if (!qlcnic_83xx_set_port_eswitch_status(adapter, pfn,
 +                                                               &id))
                                adapter->npars[j].eswitch_status = true;
                        else
                                continue;
                adapter->npars[j].min_bw = pci_info[i].tx_min_bw;
                adapter->npars[j].max_bw = pci_info[i].tx_max_bw;
  
 +              memcpy(&adapter->npars[j].mac, &pci_info[i].mac, ETH_ALEN);
                j++;
        }
  
 -      if (qlcnic_82xx_check(adapter)) {
 +      /* Update eSwitch status for adapters without per port eSwitch
 +       * configuration capability
 +       */
 +      if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
                for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
                        adapter->eswitch[i].flags |= QLCNIC_SWITCH_ENABLE;
 -      } else if (!qlcnic_port_eswitch_cfg_capability(adapter)) {
 -              for (i = 0; i < QLCNIC_NIU_MAX_XG_PORTS; i++)
 -                      qlcnic_enable_eswitch(adapter, i, 1);
        }
  
        kfree(pci_info);
@@@ -2071,7 -2069,7 +2071,7 @@@ qlcnic_setup_netdev(struct qlcnic_adapt
                return err;
        }
  
 -      qlcnic_dcb_init_dcbnl_ops(adapter);
 +      qlcnic_dcb_init_dcbnl_ops(adapter->dcb);
  
        return 0;
  }
@@@ -2166,6 -2164,17 +2166,6 @@@ void qlcnic_set_drv_version(struct qlcn
                qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd);
  }
  
 -static int qlcnic_register_dcb(struct qlcnic_adapter *adapter)
 -{
 -      return __qlcnic_register_dcb(adapter);
 -}
 -
 -void qlcnic_clear_dcb_ops(struct qlcnic_adapter *adapter)
 -{
 -      kfree(adapter->dcb);
 -      adapter->dcb = NULL;
 -}
 -
  static int
  qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  {
        struct qlcnic_hardware_context *ahw;
        int err, pci_using_dac = -1;
        char board_name[QLCNIC_MAX_BOARD_NAME_LEN + 19]; /* MAC + ": " + name */
 +      struct qlcnic_dcb *dcb;
  
        if (pdev->is_virtfn)
                return -ENODEV;
  
                adapter->flags |= QLCNIC_NEED_FLR;
  
 -              if (adapter->dcb && qlcnic_dcb_attach(adapter))
 -                      qlcnic_clear_dcb_ops(adapter);
 +              dcb = adapter->dcb;
 +
 +              if (dcb && qlcnic_dcb_attach(dcb))
 +                      qlcnic_clear_dcb_ops(dcb);
  
        } else if (qlcnic_83xx_check(adapter)) {
                adapter->max_drv_tx_rings = 1;
@@@ -2406,6 -2412,7 +2406,6 @@@ err_out_free_res
        pci_release_regions(pdev);
  
  err_out_disable_pdev:
 -      pci_set_drvdata(pdev, NULL);
        pci_disable_device(pdev);
        return err;
  
@@@ -2442,7 -2449,7 +2442,7 @@@ static void qlcnic_remove(struct pci_de
        qlcnic_cancel_idc_work(adapter);
        ahw = adapter->ahw;
  
 -      qlcnic_dcb_free(adapter);
 +      qlcnic_dcb_free(adapter->dcb);
  
        unregister_netdev(netdev);
        qlcnic_sriov_cleanup(adapter);
        pci_disable_pcie_error_reporting(pdev);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
 -      pci_set_drvdata(pdev, NULL);
  
        if (adapter->qlcnic_wq) {
                destroy_workqueue(adapter->qlcnic_wq);
@@@ -3319,7 -3327,7 +3319,7 @@@ qlcnic_attach_work(struct work_struct *
                return;
        }
  attach:
 -      qlcnic_dcb_get_info(adapter);
 +      qlcnic_dcb_get_info(adapter->dcb);
  
        if (netif_running(netdev)) {
                if (qlcnic_up(adapter, netdev))
@@@ -3344,8 -3352,6 +3344,8 @@@ done
  static int
  qlcnic_check_health(struct qlcnic_adapter *adapter)
  {
 +      struct qlcnic_hardware_context *ahw = adapter->ahw;
 +      struct qlcnic_fw_dump *fw_dump = &ahw->fw_dump;
        u32 state = 0, heartbeat;
        u32 peg_status;
        int err = 0;
                if (adapter->need_fw_reset)
                        goto detach;
  
 -              if (adapter->ahw->reset_context && qlcnic_auto_fw_reset)
 +              if (ahw->reset_context && qlcnic_auto_fw_reset)
                        qlcnic_reset_hw_context(adapter);
  
                return 0;
@@@ -3413,9 -3419,6 +3413,9 @@@ detach
  
                qlcnic_schedule_work(adapter, qlcnic_detach_work, 0);
                QLCDB(adapter, DRV, "fw recovery scheduled.\n");
 +      } else if (!qlcnic_auto_fw_reset && fw_dump->enable &&
 +                 adapter->flags & QLCNIC_FW_RESET_OWNER) {
 +              qlcnic_dump_fw(adapter);
        }
  
        return 1;
@@@ -3648,11 -3651,6 +3648,6 @@@ int qlcnic_validate_max_tx_rings(struc
        u8 max_hw = QLCNIC_MAX_TX_RINGS;
        u32 max_allowed;
  
-       if (!qlcnic_82xx_check(adapter)) {
-               netdev_err(netdev, "No Multi TX-Q support\n");
-               return -EINVAL;
-       }
        if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
                netdev_err(netdev, "No Multi TX-Q support in INT-x mode\n");
                return -EINVAL;
@@@ -3692,8 -3690,7 +3687,7 @@@ int qlcnic_validate_max_rss(struct qlcn
        u8 max_hw = adapter->ahw->max_rx_ques;
        u32 max_allowed;
  
-       if (qlcnic_82xx_check(adapter) && !qlcnic_use_msi_x &&
-           !qlcnic_use_msi) {
+       if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
                netdev_err(netdev, "No RSS support in INT-x mode\n");
                return -EINVAL;
        }
index ee8df999494c86dbdae9623c17d75d66385fa16b,b57c278d3b46b2eeb1d9b56b3cc9ca312ba67f61..7258366f7e0b2bdfdc368a62db27636b17efe472
@@@ -620,16 -620,12 +620,12 @@@ static struct sh_eth_cpu_data sh7734_da
        .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
                          EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
                          EESR_TDE | EESR_ECI,
-       .fdr_value      = 0x0000070f,
-       .rmcr_value     = 0x00000001,
  
        .apr            = 1,
        .mpr            = 1,
        .tpauser        = 1,
        .bculr          = 1,
        .hw_swap        = 1,
-       .rpadir         = 1,
-       .rpadir_value   = 2 << 16,
        .no_trimd       = 1,
        .no_ade         = 1,
        .tsu            = 1,
@@@ -692,12 -688,16 +688,16 @@@ static struct sh_eth_cpu_data r8a7740_d
        .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
                          EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
                          EESR_TDE | EESR_ECI,
+       .fdr_value      = 0x0000070f,
+       .rmcr_value     = 0x00000001,
  
        .apr            = 1,
        .mpr            = 1,
        .tpauser        = 1,
        .bculr          = 1,
        .hw_swap        = 1,
+       .rpadir         = 1,
+       .rpadir_value   = 2 << 16,
        .no_trimd       = 1,
        .no_ade         = 1,
        .tsu            = 1,
@@@ -872,7 -872,7 +872,7 @@@ static void update_mac_address(struct n
  static void read_mac_address(struct net_device *ndev, unsigned char *mac)
  {
        if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
 -              memcpy(ndev->dev_addr, mac, 6);
 +              memcpy(ndev->dev_addr, mac, ETH_ALEN);
        } else {
                ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
                ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
index 1fd8125e58a896061628ffe713c544285f9d3aa8,cc3ce557e4aa62074873ee34e348ec24a0719ccf..90d41d26ec6d8c37f04682aa05b8731a4d4c3002
@@@ -367,6 -367,8 +367,6 @@@ struct cpsw_priv 
        spinlock_t                      lock;
        struct platform_device          *pdev;
        struct net_device               *ndev;
 -      struct resource                 *cpsw_res;
 -      struct resource                 *cpsw_wr_res;
        struct napi_struct              napi;
        struct device                   *dev;
        struct cpsw_platform_data       data;
@@@ -637,13 -639,6 +637,6 @@@ void cpsw_rx_handler(void *token, int l
  static irqreturn_t cpsw_interrupt(int irq, void *dev_id)
  {
        struct cpsw_priv *priv = dev_id;
-       u32 rx, tx, rx_thresh;
-       rx_thresh = __raw_readl(&priv->wr_regs->rx_thresh_stat);
-       rx = __raw_readl(&priv->wr_regs->rx_stat);
-       tx = __raw_readl(&priv->wr_regs->tx_stat);
-       if (!rx_thresh && !rx && !tx)
-               return IRQ_NONE;
  
        cpsw_intr_disable(priv);
        if (priv->irq_enabled == true) {
@@@ -1021,10 -1016,6 +1014,10 @@@ static void cpsw_slave_open(struct cpsw
                dev_info(priv->dev, "phy found : id is : 0x%x\n",
                         slave->phy->phy_id);
                phy_start(slave->phy);
 +
 +              /* Configure GMII_SEL register */
 +              cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface,
 +                           slave->slave_num);
        }
  }
  
@@@ -1171,9 -1162,9 +1164,9 @@@ static int cpsw_ndo_open(struct net_dev
                }
        }
  
+       napi_enable(&priv->napi);
        cpdma_ctlr_start(priv->dma);
        cpsw_intr_enable(priv);
-       napi_enable(&priv->napi);
        cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX);
        cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX);
  
@@@ -1714,55 -1705,62 +1707,55 @@@ static int cpsw_probe_dt(struct cpsw_pl
  
        if (of_property_read_u32(node, "active_slave", &prop)) {
                pr_err("Missing active_slave property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->active_slave = prop;
  
        if (of_property_read_u32(node, "cpts_clock_mult", &prop)) {
                pr_err("Missing cpts_clock_mult property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->cpts_clock_mult = prop;
  
        if (of_property_read_u32(node, "cpts_clock_shift", &prop)) {
                pr_err("Missing cpts_clock_shift property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->cpts_clock_shift = prop;
  
 -      data->slave_data = kcalloc(data->slaves, sizeof(struct cpsw_slave_data),
 -                                 GFP_KERNEL);
 +      data->slave_data = devm_kzalloc(&pdev->dev, data->slaves
 +                                      * sizeof(struct cpsw_slave_data),
 +                                      GFP_KERNEL);
        if (!data->slave_data)
 -              return -EINVAL;
 +              return -ENOMEM;
  
        if (of_property_read_u32(node, "cpdma_channels", &prop)) {
                pr_err("Missing cpdma_channels property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->channels = prop;
  
        if (of_property_read_u32(node, "ale_entries", &prop)) {
                pr_err("Missing ale_entries property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->ale_entries = prop;
  
        if (of_property_read_u32(node, "bd_ram_size", &prop)) {
                pr_err("Missing bd_ram_size property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->bd_ram_size = prop;
  
        if (of_property_read_u32(node, "rx_descs", &prop)) {
                pr_err("Missing rx_descs property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->rx_descs = prop;
  
        if (of_property_read_u32(node, "mac_control", &prop)) {
                pr_err("Missing mac_control property in the DT.\n");
 -              ret = -EINVAL;
 -              goto error_ret;
 +              return -EINVAL;
        }
        data->mac_control = prop;
  
                parp = of_get_property(slave_node, "phy_id", &lenp);
                if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
                        pr_err("Missing slave[%d] phy_id property\n", i);
 -                      ret = -EINVAL;
 -                      goto error_ret;
 +                      return -EINVAL;
                }
                mdio_node = of_find_node_by_phandle(be32_to_cpup(parp));
                phyid = be32_to_cpup(parp+1);
        }
  
        return 0;
 -
 -error_ret:
 -      kfree(data->slave_data);
 -      return ret;
  }
  
  static int cpsw_probe_dual_emac(struct platform_device *pdev,
        priv_sl2->coal_intvl = 0;
        priv_sl2->bus_freq_mhz = priv->bus_freq_mhz;
  
 -      priv_sl2->cpsw_res = priv->cpsw_res;
        priv_sl2->regs = priv->regs;
        priv_sl2->host_port = priv->host_port;
        priv_sl2->host_port_regs = priv->host_port_regs;
@@@ -1907,8 -1911,8 +1900,8 @@@ static int cpsw_probe(struct platform_d
        struct cpsw_priv                *priv;
        struct cpdma_params             dma_params;
        struct cpsw_ale_params          ale_params;
 -      void __iomem                    *ss_regs, *wr_regs;
 -      struct resource                 *res;
 +      void __iomem                    *ss_regs;
 +      struct resource                 *res, *ss_res;
        u32 slave_offset, sliver_offset, slave_size;
        int ret = 0, i, k = 0;
  
        if (cpsw_probe_dt(&priv->data, pdev)) {
                pr_err("cpsw: platform data missing\n");
                ret = -ENODEV;
 -              goto clean_ndev_ret;
 +              goto clean_runtime_disable_ret;
        }
        data = &priv->data;
  
  
        memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
  
 -      priv->slaves = kzalloc(sizeof(struct cpsw_slave) * data->slaves,
 -                             GFP_KERNEL);
 +      priv->slaves = devm_kzalloc(&pdev->dev,
 +                                  sizeof(struct cpsw_slave) * data->slaves,
 +                                  GFP_KERNEL);
        if (!priv->slaves) {
 -              ret = -EBUSY;
 -              goto clean_ndev_ret;
 +              ret = -ENOMEM;
 +              goto clean_runtime_disable_ret;
        }
        for (i = 0; i < data->slaves; i++)
                priv->slaves[i].slave_num = i;
        priv->slaves[0].ndev = ndev;
        priv->emac_port = 0;
  
 -      priv->clk = clk_get(&pdev->dev, "fck");
 +      priv->clk = devm_clk_get(&pdev->dev, "fck");
        if (IS_ERR(priv->clk)) {
 -              dev_err(&pdev->dev, "fck is not found\n");
 +              dev_err(priv->dev, "fck is not found\n");
                ret = -ENODEV;
 -              goto clean_slave_ret;
 +              goto clean_runtime_disable_ret;
        }
        priv->coal_intvl = 0;
        priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000;
  
 -      priv->cpsw_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!priv->cpsw_res) {
 -              dev_err(priv->dev, "error getting i/o resource\n");
 -              ret = -ENOENT;
 -              goto clean_clk_ret;
 -      }
 -      if (!request_mem_region(priv->cpsw_res->start,
 -                              resource_size(priv->cpsw_res), ndev->name)) {
 -              dev_err(priv->dev, "failed request i/o region\n");
 -              ret = -ENXIO;
 -              goto clean_clk_ret;
 -      }
 -      ss_regs = ioremap(priv->cpsw_res->start, resource_size(priv->cpsw_res));
 -      if (!ss_regs) {
 -              dev_err(priv->dev, "unable to map i/o region\n");
 -              goto clean_cpsw_iores_ret;
 +      ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      ss_regs = devm_ioremap_resource(&pdev->dev, ss_res);
 +      if (IS_ERR(ss_regs)) {
 +              ret = PTR_ERR(ss_regs);
 +              goto clean_runtime_disable_ret;
        }
        priv->regs = ss_regs;
        priv->version = __raw_readl(&priv->regs->id_ver);
        priv->host_port = HOST_PORT_NUM;
  
 -      priv->cpsw_wr_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 -      if (!priv->cpsw_wr_res) {
 -              dev_err(priv->dev, "error getting i/o resource\n");
 -              ret = -ENOENT;
 -              goto clean_iomap_ret;
 -      }
 -      if (!request_mem_region(priv->cpsw_wr_res->start,
 -                      resource_size(priv->cpsw_wr_res), ndev->name)) {
 -              dev_err(priv->dev, "failed request i/o region\n");
 -              ret = -ENXIO;
 -              goto clean_iomap_ret;
 +      res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 +      priv->wr_regs = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(priv->wr_regs)) {
 +              ret = PTR_ERR(priv->wr_regs);
 +              goto clean_runtime_disable_ret;
        }
 -      wr_regs = ioremap(priv->cpsw_wr_res->start,
 -                              resource_size(priv->cpsw_wr_res));
 -      if (!wr_regs) {
 -              dev_err(priv->dev, "unable to map i/o region\n");
 -              goto clean_cpsw_wr_iores_ret;
 -      }
 -      priv->wr_regs = wr_regs;
  
        memset(&dma_params, 0, sizeof(dma_params));
        memset(&ale_params, 0, sizeof(ale_params));
                slave_size           = CPSW2_SLAVE_SIZE;
                sliver_offset        = CPSW2_SLIVER_OFFSET;
                dma_params.desc_mem_phys =
 -                      (u32 __force) priv->cpsw_res->start + CPSW2_BD_OFFSET;
 +                      (u32 __force) ss_res->start + CPSW2_BD_OFFSET;
                break;
        default:
                dev_err(priv->dev, "unknown version 0x%08x\n", priv->version);
                ret = -ENODEV;
 -              goto clean_cpsw_wr_iores_ret;
 +              goto clean_runtime_disable_ret;
        }
        for (i = 0; i < priv->data.slaves; i++) {
                struct cpsw_slave *slave = &priv->slaves[i];
        if (!priv->dma) {
                dev_err(priv->dev, "error initializing dma\n");
                ret = -ENOMEM;
 -              goto clean_wr_iomap_ret;
 +              goto clean_runtime_disable_ret;
        }
  
        priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0),
  
        while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
                for (i = res->start; i <= res->end; i++) {
 -                      if (request_irq(i, cpsw_interrupt, 0,
 -                                      dev_name(&pdev->dev), priv)) {
 +                      if (devm_request_irq(&pdev->dev, i, cpsw_interrupt, 0,
 +                                           dev_name(priv->dev), priv)) {
                                dev_err(priv->dev, "error attaching irq\n");
                                goto clean_ale_ret;
                        }
        if (ret) {
                dev_err(priv->dev, "error registering net device\n");
                ret = -ENODEV;
 -              goto clean_irq_ret;
 +              goto clean_ale_ret;
        }
  
        if (cpts_register(&pdev->dev, priv->cpts,
                dev_err(priv->dev, "error registering cpts device\n");
  
        cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n",
 -                priv->cpsw_res->start, ndev->irq);
 +                  ss_res->start, ndev->irq);
  
        if (priv->data.dual_emac) {
                ret = cpsw_probe_dual_emac(pdev, priv);
                if (ret) {
                        cpsw_err(priv, probe, "error probe slave 2 emac interface\n");
 -                      goto clean_irq_ret;
 +                      goto clean_ale_ret;
                }
        }
  
        return 0;
  
 -clean_irq_ret:
 -      for (i = 0; i < priv->num_irqs; i++)
 -              free_irq(priv->irqs_table[i], priv);
  clean_ale_ret:
        cpsw_ale_destroy(priv->ale);
  clean_dma_ret:
        cpdma_chan_destroy(priv->txch);
        cpdma_chan_destroy(priv->rxch);
        cpdma_ctlr_destroy(priv->dma);
 -clean_wr_iomap_ret:
 -      iounmap(priv->wr_regs);
 -clean_cpsw_wr_iores_ret:
 -      release_mem_region(priv->cpsw_wr_res->start,
 -                         resource_size(priv->cpsw_wr_res));
 -clean_iomap_ret:
 -      iounmap(priv->regs);
 -clean_cpsw_iores_ret:
 -      release_mem_region(priv->cpsw_res->start,
 -                         resource_size(priv->cpsw_res));
 -clean_clk_ret:
 -      clk_put(priv->clk);
 -clean_slave_ret:
 +clean_runtime_disable_ret:
        pm_runtime_disable(&pdev->dev);
 -      kfree(priv->slaves);
  clean_ndev_ret:
 -      kfree(priv->data.slave_data);
        free_netdev(priv->ndev);
        return ret;
  }
@@@ -2154,18 -2198,30 +2147,18 @@@ static int cpsw_remove(struct platform_
  {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct cpsw_priv *priv = netdev_priv(ndev);
 -      int i;
  
        if (priv->data.dual_emac)
                unregister_netdev(cpsw_get_slave_ndev(priv, 1));
        unregister_netdev(ndev);
  
        cpts_unregister(priv->cpts);
 -      for (i = 0; i < priv->num_irqs; i++)
 -              free_irq(priv->irqs_table[i], priv);
  
        cpsw_ale_destroy(priv->ale);
        cpdma_chan_destroy(priv->txch);
        cpdma_chan_destroy(priv->rxch);
        cpdma_ctlr_destroy(priv->dma);
 -      iounmap(priv->regs);
 -      release_mem_region(priv->cpsw_res->start,
 -                         resource_size(priv->cpsw_res));
 -      iounmap(priv->wr_regs);
 -      release_mem_region(priv->cpsw_wr_res->start,
 -                         resource_size(priv->cpsw_wr_res));
        pm_runtime_disable(&pdev->dev);
 -      clk_put(priv->clk);
 -      kfree(priv->slaves);
 -      kfree(priv->data.slave_data);
        if (priv->data.dual_emac)
                free_netdev(cpsw_get_slave_ndev(priv, 1));
        free_netdev(ndev);
@@@ -2221,7 -2277,7 +2214,7 @@@ static struct platform_driver cpsw_driv
                .name    = "cpsw",
                .owner   = THIS_MODULE,
                .pm      = &cpsw_pm_ops,
 -              .of_match_table = of_match_ptr(cpsw_of_mtable),
 +              .of_match_table = cpsw_of_mtable,
        },
        .probe = cpsw_probe,
        .remove = cpsw_remove,
index fba1c489a91112dce8eaaf705bbf7513355bf734,6a32ef9d63ae2500d5a397a3d6837be525ff7d6f..41ba974bf37cb9175c74ab40bba1817e890749e7
@@@ -876,8 -876,7 +876,7 @@@ static void emac_dev_mcast_set(struct n
                    netdev_mc_count(ndev) > EMAC_DEF_MAX_MULTICAST_ADDRESSES) {
                        mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
                        emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL);
-               }
-               if (!netdev_mc_empty(ndev)) {
+               } else if (!netdev_mc_empty(ndev)) {
                        struct netdev_hw_addr *ha;
  
                        mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
@@@ -1853,7 -1852,7 +1852,7 @@@ static int davinci_emac_probe(struct pl
        }
  
        /* MAC addr and PHY mask , RMII enable info from platform_data */
 -      memcpy(priv->mac_addr, pdata->mac_addr, 6);
 +      memcpy(priv->mac_addr, pdata->mac_addr, ETH_ALEN);
        priv->phy_id = pdata->phy_id;
        priv->rmii_en = pdata->rmii_en;
        priv->version = pdata->version;
index ff31ff0e0c43be8efcbde99abd14836b4bc5ba05,5af1c3e5032addd1441722899d3ab1fb0b010ae9..1971411574db1c7ae2dd6549490ab6975e816cd1
@@@ -888,7 -888,7 +888,7 @@@ static int yam_open(struct net_device *
                goto out_release_base;
        }
        outb(0, IER(dev->base_addr));
 -      if (request_irq(dev->irq, yam_interrupt, IRQF_DISABLED | IRQF_SHARED, dev->name, dev)) {
 +      if (request_irq(dev->irq, yam_interrupt, IRQF_SHARED, dev->name, dev)) {
                printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq);
                ret = -EBUSY;
                goto out_release_base;
@@@ -975,7 -975,6 +975,6 @@@ static int yam_ioctl(struct net_device 
                        return -EINVAL;         /* Cannot change this parameter when up */
                if ((ym = kmalloc(sizeof(struct yamdrv_ioctl_mcs), GFP_KERNEL)) == NULL)
                        return -ENOBUFS;
-               ym->bitrate = 9600;
                if (copy_from_user(ym, ifr->ifr_data, sizeof(struct yamdrv_ioctl_mcs))) {
                        kfree(ym);
                        return -EFAULT;
index d03b6b6c64c0baaa925714b88847861a5313981e,818ce90185b5dee9e736923cee09d2b7a0a8d840..e0a4a2b08e4526a14fc20e64346af85e88623ed2
@@@ -143,22 -143,16 +143,22 @@@ static const struct net_device_ops qmi_
        .ndo_validate_addr      = eth_validate_addr,
  };
  
 -/* using a counter to merge subdriver requests with our own into a combined state */
 +/* using a counter to merge subdriver requests with our own into a
 + * combined state
 + */
  static int qmi_wwan_manage_power(struct usbnet *dev, int on)
  {
        struct qmi_wwan_state *info = (void *)&dev->data;
        int rv = 0;
  
 -      dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on);
 +      dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__,
 +              atomic_read(&info->pmcount), on);
  
 -      if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) {
 -              /* need autopm_get/put here to ensure the usbcore sees the new value */
 +      if ((on && atomic_add_return(1, &info->pmcount) == 1) ||
 +          (!on && atomic_dec_and_test(&info->pmcount))) {
 +              /* need autopm_get/put here to ensure the usbcore sees
 +               * the new value
 +               */
                rv = usb_autopm_get_interface(dev->intf);
                if (rv < 0)
                        goto err;
@@@ -205,8 -199,7 +205,8 @@@ static int qmi_wwan_register_subdriver(
        atomic_set(&info->pmcount, 0);
  
        /* register subdriver */
 -      subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc, 4096, &qmi_wwan_cdc_wdm_manage_power);
 +      subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc,
 +                                       4096, &qmi_wwan_cdc_wdm_manage_power);
        if (IS_ERR(subdriver)) {
                dev_err(&info->control->dev, "subdriver registration failed\n");
                rv = PTR_ERR(subdriver);
@@@ -235,8 -228,7 +235,8 @@@ static int qmi_wwan_bind(struct usbnet 
        struct usb_driver *driver = driver_of(intf);
        struct qmi_wwan_state *info = (void *)&dev->data;
  
 -      BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state)));
 +      BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) <
 +                    sizeof(struct qmi_wwan_state)));
  
        /* set up initial state */
        info->control = intf;
                                goto err;
                        }
                        if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
 -                              dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength);
 +                              dev_dbg(&intf->dev, "CDC header len %u\n",
 +                                      h->bLength);
                                goto err;
                        }
                        break;
                                goto err;
                        }
                        if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
 -                              dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength);
 +                              dev_dbg(&intf->dev, "CDC union len %u\n",
 +                                      h->bLength);
                                goto err;
                        }
                        cdc_union = (struct usb_cdc_union_desc *)buf;
                                goto err;
                        }
                        if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
 -                              dev_dbg(&intf->dev, "CDC ether len %u\n",  h->bLength);
 +                              dev_dbg(&intf->dev, "CDC ether len %u\n",
 +                                      h->bLength);
                                goto err;
                        }
                        cdc_ether = (struct usb_cdc_ether_desc *)buf;
                        break;
                }
  
 -              /*
 -               * Remember which CDC functional descriptors we've seen.  Works
 +              /* Remember which CDC functional descriptors we've seen.  Works
                 * for all types we care about, of which USB_CDC_ETHERNET_TYPE
                 * (0x0f) is the highest numbered
                 */
@@@ -303,14 -293,10 +303,14 @@@ next_desc
  
        /* Use separate control and data interfaces if we found a CDC Union */
        if (cdc_union) {
 -              info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0);
 -              if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) {
 -                      dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n",
 -                              cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0);
 +              info->data = usb_ifnum_to_if(dev->udev,
 +                                           cdc_union->bSlaveInterface0);
 +              if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 ||
 +                  !info->data) {
 +                      dev_err(&intf->dev,
 +                              "bogus CDC Union: master=%u, slave=%u\n",
 +                              cdc_union->bMasterInterface0,
 +                              cdc_union->bSlaveInterface0);
                        goto err;
                }
        }
@@@ -388,7 -374,8 +388,7 @@@ static int qmi_wwan_suspend(struct usb_
        struct qmi_wwan_state *info = (void *)&dev->data;
        int ret;
  
 -      /*
 -       * Both usbnet_suspend() and subdriver->suspend() MUST return 0
 +      /* Both usbnet_suspend() and subdriver->suspend() MUST return 0
         * in system sleep context, otherwise, the resume callback has
         * to recover device from previous suspend failure.
         */
        if (ret < 0)
                goto err;
  
 -      if (intf == info->control && info->subdriver && info->subdriver->suspend)
 +      if (intf == info->control && info->subdriver &&
 +          info->subdriver->suspend)
                ret = info->subdriver->suspend(intf, message);
        if (ret < 0)
                usbnet_resume(intf);
@@@ -410,8 -396,7 +410,8 @@@ static int qmi_wwan_resume(struct usb_i
        struct usbnet *dev = usb_get_intfdata(intf);
        struct qmi_wwan_state *info = (void *)&dev->data;
        int ret = 0;
 -      bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume);
 +      bool callsub = (intf == info->control && info->subdriver &&
 +                      info->subdriver->resume);
  
        if (callsub)
                ret = info->subdriver->resume(intf);
@@@ -729,7 -714,7 +729,8 @@@ static const struct usb_device_id produ
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
        {QMI_FIXED_INTF(0x2357, 0x9000, 4)},    /* TP-LINK MA260 */
        {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
 +      {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)},    /* Telit LE920 */
+       {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)},    /* Olivetti Olicard 200 */
        {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)},    /* Cinterion PLxx */
  
        /* 4. Gobi 1000 devices */
  };
  MODULE_DEVICE_TABLE(usb, products);
  
 -static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod)
 +static int qmi_wwan_probe(struct usb_interface *intf,
 +                        const struct usb_device_id *prod)
  {
        struct usb_device_id *id = (struct usb_device_id *)prod;
  
index c42b55c1face8808f944d00068cce539f22d065a,709301f88dcd26210a18db4d6eb1f8e230905608..20a2fbc1e34ff27a00a3d6de2739da45181bf32f
@@@ -208,6 -208,7 +208,7 @@@ static bool ath_complete_reset(struct a
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        unsigned long flags;
+       int i;
  
        if (ath_startrecv(sc) != 0) {
                ath_err(common, "Unable to restart recv logic\n");
                }
        work:
                ath_restart_work(sc);
+               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+                       if (!ATH_TXQ_SETUP(sc, i))
+                               continue;
+                       spin_lock_bh(&sc->tx.txq[i].axq_lock);
+                       ath_txq_schedule(sc, &sc->tx.txq[i]);
+                       spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+               }
        }
  
        ieee80211_wake_queues(sc->hw);
@@@ -302,91 -312,17 +312,91 @@@ out
   * by reseting the chip.  To accomplish this we must first cleanup any pending
   * DMA, then restart stuff.
  */
 -static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
 -                  struct ath9k_channel *hchan)
 +static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
  {
 +      struct ath_hw *ah = sc->sc_ah;
 +      struct ath_common *common = ath9k_hw_common(ah);
 +      struct ieee80211_hw *hw = sc->hw;
 +      struct ath9k_channel *hchan;
 +      struct ieee80211_channel *chan = chandef->chan;
 +      unsigned long flags;
 +      bool offchannel;
 +      int pos = chan->hw_value;
 +      int old_pos = -1;
        int r;
  
        if (test_bit(SC_OP_INVALID, &sc->sc_flags))
                return -EIO;
  
 +      offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
 +
 +      if (ah->curchan)
 +              old_pos = ah->curchan - &ah->channels[0];
 +
 +      ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
 +              chan->center_freq, chandef->width);
 +
 +      /* update survey stats for the old channel before switching */
 +      spin_lock_irqsave(&common->cc_lock, flags);
 +      ath_update_survey_stats(sc);
 +      spin_unlock_irqrestore(&common->cc_lock, flags);
 +
 +      ath9k_cmn_get_channel(hw, ah, chandef);
 +
 +      /*
 +       * If the operating channel changes, change the survey in-use flags
 +       * along with it.
 +       * Reset the survey data for the new channel, unless we're switching
 +       * back to the operating channel from an off-channel operation.
 +       */
 +      if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
 +              if (sc->cur_survey)
 +                      sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
 +
 +              sc->cur_survey = &sc->survey[pos];
 +
 +              memset(sc->cur_survey, 0, sizeof(struct survey_info));
 +              sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
 +      } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
 +              memset(&sc->survey[pos], 0, sizeof(struct survey_info));
 +      }
 +
 +      hchan = &sc->sc_ah->channels[pos];
        r = ath_reset_internal(sc, hchan);
 +      if (r)
 +              return r;
  
 -      return r;
 +      /*
 +       * The most recent snapshot of channel->noisefloor for the old
 +       * channel is only available after the hardware reset. Copy it to
 +       * the survey stats now.
 +       */
 +      if (old_pos >= 0)
 +              ath_update_survey_nf(sc, old_pos);
 +
 +      /*
 +       * Enable radar pulse detection if on a DFS channel. Spectral
 +       * scanning and radar detection can not be used concurrently.
 +       */
 +      if (hw->conf.radar_enabled) {
 +              u32 rxfilter;
 +
 +              /* set HW specific DFS configuration */
 +              ath9k_hw_set_radar_params(ah);
 +              rxfilter = ath9k_hw_getrxfilter(ah);
 +              rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
 +                              ATH9K_RX_FILTER_PHYERR;
 +              ath9k_hw_setrxfilter(ah, rxfilter);
 +              ath_dbg(common, DFS, "DFS enabled at freq %d\n",
 +                      chan->center_freq);
 +      } else {
 +              /* perform spectral scan if requested. */
 +              if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
 +                      sc->spectral_mode == SPECTRAL_CHANSCAN)
 +                      ath9k_spectral_scan_trigger(hw);
 +      }
 +
 +      return 0;
  }
  
  static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
@@@ -436,13 -372,6 +446,13 @@@ void ath9k_tasklet(unsigned long data
                        type = RESET_TYPE_BB_WATCHDOG;
  
                ath9k_queue_reset(sc, type);
 +
 +              /*
 +               * Increment the ref. counter here so that
 +               * interrupts are enabled in the reset routine.
 +               */
 +              atomic_inc(&ah->intr_ref_cnt);
 +              ath_dbg(common, ANY, "FATAL: Skipping interrupts\n");
                goto out;
        }
  
  
        ath9k_btcoex_handle_interrupt(sc, status);
  
 -out:
        /* re-enable hardware interrupt */
        ath9k_hw_enable_interrupts(ah);
 -
 +out:
        spin_unlock(&sc->sc_pcu_lock);
        ath9k_ps_restore(sc);
  }
@@@ -619,21 -549,10 +629,10 @@@ chip_reset
  
  static int ath_reset(struct ath_softc *sc)
  {
-       int i, r;
+       int r;
  
        ath9k_ps_wakeup(sc);
        r = ath_reset_internal(sc, NULL);
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (!ATH_TXQ_SETUP(sc, i))
-                       continue;
-               spin_lock_bh(&sc->tx.txq[i].axq_lock);
-               ath_txq_schedule(sc, &sc->tx.txq[i]);
-               spin_unlock_bh(&sc->tx.txq[i].axq_lock);
-       }
        ath9k_ps_restore(sc);
  
        return r;
@@@ -675,7 -594,7 +674,7 @@@ static int ath9k_start(struct ieee80211
        ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
  
 -      init_channel = ath9k_cmn_get_curchannel(hw, ah);
 +      init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
  
        /* Reset SERDES registers */
        ath9k_hw_configpcipowersave(ah, false);
@@@ -878,7 -797,7 +877,7 @@@ static void ath9k_stop(struct ieee80211
        }
  
        if (!ah->curchan)
 -              ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
 +              ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
  
        ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
        ath9k_hw_phy_disable(ah);
        ath_dbg(common, CONFIG, "Driver halt\n");
  }
  
 -bool ath9k_uses_beacons(int type)
 +static bool ath9k_uses_beacons(int type)
  {
        switch (type) {
        case NL80211_IFTYPE_AP:
@@@ -1282,12 -1201,81 +1281,12 @@@ static int ath9k_config(struct ieee8021
        }
  
        if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
 -              struct ieee80211_channel *curchan = hw->conf.chandef.chan;
 -              int pos = curchan->hw_value;
 -              int old_pos = -1;
 -              unsigned long flags;
 -
 -              if (ah->curchan)
 -                      old_pos = ah->curchan - &ah->channels[0];
 -
 -              ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
 -                      curchan->center_freq, hw->conf.chandef.width);
 -
 -              /* update survey stats for the old channel before switching */
 -              spin_lock_irqsave(&common->cc_lock, flags);
 -              ath_update_survey_stats(sc);
 -              spin_unlock_irqrestore(&common->cc_lock, flags);
 -
 -              ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
 -                                        &conf->chandef);
 -
 -              /*
 -               * If the operating channel changes, change the survey in-use flags
 -               * along with it.
 -               * Reset the survey data for the new channel, unless we're switching
 -               * back to the operating channel from an off-channel operation.
 -               */
 -              if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
 -                  sc->cur_survey != &sc->survey[pos]) {
 -
 -                      if (sc->cur_survey)
 -                              sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
 -
 -                      sc->cur_survey = &sc->survey[pos];
 -
 -                      memset(sc->cur_survey, 0, sizeof(struct survey_info));
 -                      sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
 -              } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
 -                      memset(&sc->survey[pos], 0, sizeof(struct survey_info));
 -              }
 -
 -              if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
 +              if (ath_set_channel(sc, &hw->conf.chandef) < 0) {
                        ath_err(common, "Unable to set channel\n");
                        mutex_unlock(&sc->mutex);
                        ath9k_ps_restore(sc);
                        return -EINVAL;
                }
 -
 -              /*
 -               * The most recent snapshot of channel->noisefloor for the old
 -               * channel is only available after the hardware reset. Copy it to
 -               * the survey stats now.
 -               */
 -              if (old_pos >= 0)
 -                      ath_update_survey_nf(sc, old_pos);
 -
 -              /*
 -               * Enable radar pulse detection if on a DFS channel. Spectral
 -               * scanning and radar detection can not be used concurrently.
 -               */
 -              if (hw->conf.radar_enabled) {
 -                      u32 rxfilter;
 -
 -                      /* set HW specific DFS configuration */
 -                      ath9k_hw_set_radar_params(ah);
 -                      rxfilter = ath9k_hw_getrxfilter(ah);
 -                      rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
 -                                  ATH9K_RX_FILTER_PHYERR;
 -                      ath9k_hw_setrxfilter(ah, rxfilter);
 -                      ath_dbg(common, DFS, "DFS enabled at freq %d\n",
 -                              curchan->center_freq);
 -              } else {
 -                      /* perform spectral scan if requested. */
 -                      if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
 -                          sc->spectral_mode == SPECTRAL_CHANSCAN)
 -                              ath9k_spectral_scan_trigger(hw);
 -              }
        }
  
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
index 8057143849cee40b6fd20c45dd161f81f2546f02,755a0c8edfe1235e73180b8b45d6143afa582547..40078f5f932ec6b1ea3a26af5453f2bc5d2206ec
@@@ -237,7 -237,9 +237,9 @@@ static irqreturn_t cw1200_spi_irq_handl
        struct hwbus_priv *self = dev_id;
  
        if (self->core) {
+               cw1200_spi_lock(self);
                cw1200_irq_handler(self->core);
+               cw1200_spi_unlock(self);
                return IRQ_HANDLED;
        } else {
                return IRQ_NONE;
@@@ -363,7 -365,7 +365,7 @@@ static struct hwbus_ops cw1200_spi_hwbu
  static int cw1200_spi_probe(struct spi_device *func)
  {
        const struct cw1200_platform_data_spi *plat_data =
 -              func->dev.platform_data;
 +              dev_get_platdata(&func->dev);
        struct hwbus_priv *self;
        int status;
  
@@@ -441,7 -443,7 +443,7 @@@ static int cw1200_spi_disconnect(struc
                }
                kfree(self);
        }
 -      cw1200_spi_off(func->dev.platform_data);
 +      cw1200_spi_off(dev_get_platdata(&func->dev));
  
        return 0;
  }
index 717fbe2e0e5aea2b5d86482da86cce7b3ccc393d,37f873bb342f5043046b18c3fe3b573ebdedac64..4e4686e6ac092b3ce23282c575eadc2b40071eff
@@@ -621,7 -621,7 +621,7 @@@ int mwifiex_ret_802_11_associate(struc
        int ret = 0;
        struct ieee_types_assoc_rsp *assoc_rsp;
        struct mwifiex_bssdescriptor *bss_desc;
 -      u8 enable_data = true;
 +      bool enable_data = true;
        u16 cap_info, status_code;
  
        assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
@@@ -1422,13 -1422,19 +1422,19 @@@ static int mwifiex_deauthenticate_infra
   */
  int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
  {
+       int ret = 0;
        if (!priv->media_connected)
                return 0;
  
        switch (priv->bss_mode) {
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
-               return mwifiex_deauthenticate_infra(priv, mac);
+               ret = mwifiex_deauthenticate_infra(priv, mac);
+               if (ret)
+                       cfg80211_disconnected(priv->netdev, 0, NULL, 0,
+                                             GFP_KERNEL);
+               break;
        case NL80211_IFTYPE_ADHOC:
                return mwifiex_send_cmd_sync(priv,
                                             HostCmd_CMD_802_11_AD_HOC_STOP,
                break;
        }
  
-       return 0;
+       return ret;
  }
  EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
  
index 04c7e57dbce2f5165626c15344c23b348f58abbf,5a060e537fbe99171f234c29a6320f75ad22a1f3..25e50ffc44ec8b42fd35b4ab0b60a08ee09edd7d
@@@ -343,12 -343,14 +343,13 @@@ bool rtl92cu_rx_query_desc(struct ieee8
                                        (bool)GET_RX_DESC_PAGGR(pdesc));
        rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
        if (phystatus) {
-               p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE);
+               p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
+                                                    stats->rx_bufshift);
                rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
                                                 p_drvinfo);
        }
        /*rx_status->qual = stats->signal; */
        rx_status->signal = stats->rssi + 10;
 -      /*rx_status->noise = -stats->noise; */
        return true;
  }
  
@@@ -363,6 -365,7 +364,6 @@@ static void _rtl_rx_process(struct ieee
        u8 *rxdesc;
        struct rtl_stats stats = {
                .signal = 0,
 -              .noise = -98,
                .rate = 0,
        };
        struct rx_fwinfo_92c *p_drvinfo;
diff --combined include/net/dst.h
index 211dcf1e758e1acdcabd7cf4cd371bbd250bc48d,3c4c944096c9e5133695a415b530c80908980f39..44995c13e941df814db2433819d2934869df4d0f
@@@ -106,7 -106,7 +106,7 @@@ struct dst_entry 
        };
  };
  
 -extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
 +u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
  extern const u32 dst_default_metrics[];
  
  #define DST_METRICS_READ_ONLY 0x1UL
@@@ -119,7 -119,7 +119,7 @@@ static inline bool dst_metrics_read_onl
        return dst->_metrics & DST_METRICS_READ_ONLY;
  }
  
 -extern void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
 +void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
  
  static inline void dst_destroy_metrics_generic(struct dst_entry *dst)
  {
@@@ -262,7 -262,7 +262,7 @@@ static inline struct dst_entry *dst_clo
        return dst;
  }
  
 -extern void dst_release(struct dst_entry *dst);
 +void dst_release(struct dst_entry *dst);
  
  static inline void refdst_drop(unsigned long refdst)
  {
@@@ -362,11 -362,12 +362,11 @@@ static inline struct dst_entry *skb_dst
        return child;
  }
  
 -extern int dst_discard(struct sk_buff *skb);
 -extern void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
 -                     int initial_ref, int initial_obsolete,
 -                     unsigned short flags);
 -extern void __dst_free(struct dst_entry *dst);
 -extern struct dst_entry *dst_destroy(struct dst_entry *dst);
 +int dst_discard(struct sk_buff *skb);
 +void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
 +              int initial_obsolete, unsigned short flags);
 +void __dst_free(struct dst_entry *dst);
 +struct dst_entry *dst_destroy(struct dst_entry *dst);
  
  static inline void dst_free(struct dst_entry *dst)
  {
@@@ -462,7 -463,7 +462,7 @@@ static inline struct dst_entry *dst_che
        return dst;
  }
  
 -extern void           dst_init(void);
 +void dst_init(void);
  
  /* Flags for xfrm_lookup flags argument. */
  enum {
@@@ -478,10 -479,22 +478,22 @@@ static inline struct dst_entry *xfrm_lo
  {
        return dst_orig;
  } 
+ static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
+ {
+       return NULL;
+ }
  #else
 -extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
 -                                   const struct flowi *fl, struct sock *sk,
 -                                   int flags);
 +struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
 +                            const struct flowi *fl, struct sock *sk,
 +                            int flags);
+ /* skb attached with this dst needs transformation if dst->xfrm is valid */
+ static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
+ {
+       return dst->xfrm;
+ }
  #endif
  
  #endif /* _NET_DST_H */
diff --combined include/net/ip6_route.h
index 02e220dc4cf57960948c19f6cf77774558f4eefd,2b786b7e35850fe4b4b147a8a0cdcf0b010d2cb9..733747ce163c1a08a91a24eb5277832f5c04d6ee
@@@ -51,7 -51,7 +51,7 @@@ static inline unsigned int rt6_flags2sr
        return (flags >> 3) & 7;
  }
  
 -extern void rt6_bind_peer(struct rt6_info *rt, int create);
 +void rt6_bind_peer(struct rt6_info *rt, int create);
  
  static inline struct inet_peer *__rt6_get_peer(struct rt6_info *rt, int create)
  {
@@@ -72,58 -72,70 +72,58 @@@ static inline struct inet_peer *rt6_get
        return __rt6_get_peer(rt, 1);
  }
  
 -extern void                   ip6_route_input(struct sk_buff *skb);
 +void ip6_route_input(struct sk_buff *skb);
  
 -extern struct dst_entry *     ip6_route_output(struct net *net,
 -                                               const struct sock *sk,
 -                                               struct flowi6 *fl6);
 -extern struct dst_entry *     ip6_route_lookup(struct net *net,
 -                                               struct flowi6 *fl6, int flags);
 +struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
 +                                 struct flowi6 *fl6);
 +struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
 +                                 int flags);
  
 -extern int                    ip6_route_init(void);
 -extern void                   ip6_route_cleanup(void);
 +int ip6_route_init(void);
 +void ip6_route_cleanup(void);
  
 -extern int                    ipv6_route_ioctl(struct net *net,
 -                                               unsigned int cmd,
 -                                               void __user *arg);
 +int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);
  
 -extern int                    ip6_route_add(struct fib6_config *cfg);
 -extern int                    ip6_ins_rt(struct rt6_info *);
 -extern int                    ip6_del_rt(struct rt6_info *);
 +int ip6_route_add(struct fib6_config *cfg);
 +int ip6_ins_rt(struct rt6_info *);
 +int ip6_del_rt(struct rt6_info *);
  
 -extern int                    ip6_route_get_saddr(struct net *net,
 -                                                  struct rt6_info *rt,
 -                                                  const struct in6_addr *daddr,
 -                                                  unsigned int prefs,
 -                                                  struct in6_addr *saddr);
 +int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
 +                      const struct in6_addr *daddr, unsigned int prefs,
 +                      struct in6_addr *saddr);
  
 -extern struct rt6_info                *rt6_lookup(struct net *net,
 -                                          const struct in6_addr *daddr,
 -                                          const struct in6_addr *saddr,
 -                                          int oif, int flags);
 +struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
 +                          const struct in6_addr *saddr, int oif, int flags);
  
 -extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
 -                                       struct flowi6 *fl6);
 -extern int icmp6_dst_gc(void);
 +struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);
 +int icmp6_dst_gc(void);
  
 -extern void fib6_force_start_gc(struct net *net);
 +void fib6_force_start_gc(struct net *net);
  
 -extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 -                                         const struct in6_addr *addr,
 -                                         bool anycast);
 +struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 +                                  const struct in6_addr *addr, bool anycast);
  
  /*
   *    support functions for ND
   *
   */
 -extern struct rt6_info *      rt6_get_dflt_router(const struct in6_addr *addr,
 -                                                  struct net_device *dev);
 -extern struct rt6_info *      rt6_add_dflt_router(const struct in6_addr *gwaddr,
 -                                                  struct net_device *dev,
 -                                                  unsigned int pref);
 -
 -extern void                   rt6_purge_dflt_routers(struct net *net);
 -
 -extern int                    rt6_route_rcv(struct net_device *dev,
 -                                            u8 *opt, int len,
 -                                            const struct in6_addr *gwaddr);
 -
 -extern void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
 -                          int oif, u32 mark);
 -extern void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk,
 -                             __be32 mtu);
 -extern void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark);
 -extern void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
 -                                 u32 mark);
 -extern void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
 +struct rt6_info *rt6_get_dflt_router(const struct in6_addr *addr,
 +                                   struct net_device *dev);
 +struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
 +                                   struct net_device *dev, unsigned int pref);
 +
 +void rt6_purge_dflt_routers(struct net *net);
 +
 +int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
 +                const struct in6_addr *gwaddr);
 +
 +void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, int oif,
 +                   u32 mark);
 +void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu);
 +void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark);
 +void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
 +                          u32 mark);
 +void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
  
  struct netlink_callback;
  
@@@ -133,10 -145,10 +133,10 @@@ struct rt6_rtnl_dump_arg 
        struct net *net;
  };
  
 -extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
 -extern void rt6_ifdown(struct net *net, struct net_device *dev);
 -extern void rt6_mtu_change(struct net_device *dev, unsigned int mtu);
 -extern void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
 +int rt6_dump_route(struct rt6_info *rt, void *p_arg);
 +void rt6_ifdown(struct net *net, struct net_device *dev);
 +void rt6_mtu_change(struct net_device *dev, unsigned int mtu);
 +void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
  
  
  /*
@@@ -182,11 -194,9 +182,9 @@@ static inline int ip6_skb_dst_mtu(struc
               skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
  }
  
- static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest)
+ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt)
  {
-       if (rt->rt6i_flags & RTF_GATEWAY)
-               return &rt->rt6i_gateway;
-       return dest;
+       return &rt->rt6i_gateway;
  }
  
  #endif
diff --combined init/main.c
index 27bbec1a5b35d56c8f93107efaf116bfe76bf946,63d3e8f2970c1377ec822bcb9db8ee306faecee6..edee99f735746f4bb3b6a8fb17794919469f4888
@@@ -76,6 -76,7 +76,7 @@@
  #include <linux/elevator.h>
  #include <linux/sched_clock.h>
  #include <linux/context_tracking.h>
+ #include <linux/random.h>
  
  #include <asm/io.h>
  #include <asm/bugs.h>
@@@ -135,13 -136,6 +136,13 @@@ static char *static_command_line
  static char *execute_command;
  static char *ramdisk_execute_command;
  
 +/*
 + * Used to generate warnings if static_key manipulation functions are used
 + * before jump_label_init is called.
 + */
 +bool static_key_initialized __read_mostly = false;
 +EXPORT_SYMBOL_GPL(static_key_initialized);
 +
  /*
   * If set, this is an indication to the drivers that reset the underlying
   * device before going ahead with the initialization otherwise driver might
@@@ -787,6 -781,7 +788,7 @@@ static void __init do_basic_setup(void
        do_ctors();
        usermodehelper_enable();
        do_initcalls();
+       random_int_secret_init();
  }
  
  static void __init do_pre_smp_initcalls(void)
diff --combined mm/memcontrol.c
index 28243f7d9c230a9dbb7dcd6aaf4dfe850f1206fc,34d3ca9572d6baed85499d099a0050af3b9bdf66..9c9c685e4ddca665c11b878bd5a19ed1199f8eca
@@@ -311,7 -311,7 +311,7 @@@ struct mem_cgroup 
  
        atomic_t        dead_count;
  #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET)
 -      struct tcp_memcontrol tcp_mem;
 +      struct cg_proto tcp_mem;
  #endif
  #if defined(CONFIG_MEMCG_KMEM)
        /* analogous to slab_common's slab_caches list. per-memcg */
@@@ -550,13 -550,13 +550,13 @@@ struct cg_proto *tcp_proto_cgroup(struc
        if (!memcg || mem_cgroup_is_root(memcg))
                return NULL;
  
 -      return &memcg->tcp_mem.cg_proto;
 +      return &memcg->tcp_mem;
  }
  EXPORT_SYMBOL(tcp_proto_cgroup);
  
  static void disarm_sock_keys(struct mem_cgroup *memcg)
  {
 -      if (!memcg_proto_activated(&memcg->tcp_mem.cg_proto))
 +      if (!memcg_proto_activated(&memcg->tcp_mem))
                return;
        static_key_slow_dec(&memcg_socket_limit_enabled);
  }
@@@ -866,6 -866,7 +866,7 @@@ static unsigned long mem_cgroup_read_ev
        unsigned long val = 0;
        int cpu;
  
+       get_online_cpus();
        for_each_online_cpu(cpu)
                val += per_cpu(memcg->stat->events[idx], cpu);
  #ifdef CONFIG_HOTPLUG_CPU
        val += memcg->nocpu_base.events[idx];
        spin_unlock(&memcg->pcp_counter_lock);
  #endif
+       put_online_cpus();
        return val;
  }
  
@@@ -2159,110 -2161,59 +2161,59 @@@ static void memcg_oom_recover(struct me
                memcg_wakeup_oom(memcg);
  }
  
- /*
-  * try to call OOM killer
-  */
  static void mem_cgroup_oom(struct mem_cgroup *memcg, gfp_t mask, int order)
  {
-       bool locked;
-       int wakeups;
        if (!current->memcg_oom.may_oom)
                return;
-       current->memcg_oom.in_memcg_oom = 1;
        /*
-        * As with any blocking lock, a contender needs to start
-        * listening for wakeups before attempting the trylock,
-        * otherwise it can miss the wakeup from the unlock and sleep
-        * indefinitely.  This is just open-coded because our locking
-        * is so particular to memcg hierarchies.
+        * We are in the middle of the charge context here, so we
+        * don't want to block when potentially sitting on a callstack
+        * that holds all kinds of filesystem and mm locks.
+        *
+        * Also, the caller may handle a failed allocation gracefully
+        * (like optional page cache readahead) and so an OOM killer
+        * invocation might not even be necessary.
+        *
+        * That's why we don't do anything here except remember the
+        * OOM context and then deal with it at the end of the page
+        * fault when the stack is unwound, the locks are released,
+        * and when we know whether the fault was overall successful.
         */
-       wakeups = atomic_read(&memcg->oom_wakeups);
-       mem_cgroup_mark_under_oom(memcg);
-       locked = mem_cgroup_oom_trylock(memcg);
-       if (locked)
-               mem_cgroup_oom_notify(memcg);
-       if (locked && !memcg->oom_kill_disable) {
-               mem_cgroup_unmark_under_oom(memcg);
-               mem_cgroup_out_of_memory(memcg, mask, order);
-               mem_cgroup_oom_unlock(memcg);
-               /*
-                * There is no guarantee that an OOM-lock contender
-                * sees the wakeups triggered by the OOM kill
-                * uncharges.  Wake any sleepers explicitely.
-                */
-               memcg_oom_recover(memcg);
-       } else {
-               /*
-                * A system call can just return -ENOMEM, but if this
-                * is a page fault and somebody else is handling the
-                * OOM already, we need to sleep on the OOM waitqueue
-                * for this memcg until the situation is resolved.
-                * Which can take some time because it might be
-                * handled by a userspace task.
-                *
-                * However, this is the charge context, which means
-                * that we may sit on a large call stack and hold
-                * various filesystem locks, the mmap_sem etc. and we
-                * don't want the OOM handler to deadlock on them
-                * while we sit here and wait.  Store the current OOM
-                * context in the task_struct, then return -ENOMEM.
-                * At the end of the page fault handler, with the
-                * stack unwound, pagefault_out_of_memory() will check
-                * back with us by calling
-                * mem_cgroup_oom_synchronize(), possibly putting the
-                * task to sleep.
-                */
-               current->memcg_oom.oom_locked = locked;
-               current->memcg_oom.wakeups = wakeups;
-               css_get(&memcg->css);
-               current->memcg_oom.wait_on_memcg = memcg;
-       }
+       css_get(&memcg->css);
+       current->memcg_oom.memcg = memcg;
+       current->memcg_oom.gfp_mask = mask;
+       current->memcg_oom.order = order;
  }
  
  /**
   * mem_cgroup_oom_synchronize - complete memcg OOM handling
+  * @handle: actually kill/wait or just clean up the OOM state
   *
-  * This has to be called at the end of a page fault if the the memcg
-  * OOM handler was enabled and the fault is returning %VM_FAULT_OOM.
+  * This has to be called at the end of a page fault if the memcg OOM
+  * handler was enabled.
   *
-  * Memcg supports userspace OOM handling, so failed allocations must
+  * Memcg supports userspace OOM handling where failed allocations must
   * sleep on a waitqueue until the userspace task resolves the
   * situation.  Sleeping directly in the charge context with all kinds
   * of locks held is not a good idea, instead we remember an OOM state
   * in the task and mem_cgroup_oom_synchronize() has to be called at
-  * the end of the page fault to put the task to sleep and clean up the
-  * OOM state.
+  * the end of the page fault to complete the OOM handling.
   *
   * Returns %true if an ongoing memcg OOM situation was detected and
-  * finalized, %false otherwise.
+  * completed, %false otherwise.
   */
- bool mem_cgroup_oom_synchronize(void)
+ bool mem_cgroup_oom_synchronize(bool handle)
  {
+       struct mem_cgroup *memcg = current->memcg_oom.memcg;
        struct oom_wait_info owait;
-       struct mem_cgroup *memcg;
+       bool locked;
  
        /* OOM is global, do not handle */
-       if (!current->memcg_oom.in_memcg_oom)
-               return false;
-       /*
-        * We invoked the OOM killer but there is a chance that a kill
-        * did not free up any charges.  Everybody else might already
-        * be sleeping, so restart the fault and keep the rampage
-        * going until some charges are released.
-        */
-       memcg = current->memcg_oom.wait_on_memcg;
        if (!memcg)
-               goto out;
+               return false;
  
-       if (test_thread_flag(TIF_MEMDIE) || fatal_signal_pending(current))
-               goto out_memcg;
+       if (!handle)
+               goto cleanup;
  
        owait.memcg = memcg;
        owait.wait.flags = 0;
        INIT_LIST_HEAD(&owait.wait.task_list);
  
        prepare_to_wait(&memcg_oom_waitq, &owait.wait, TASK_KILLABLE);
-       /* Only sleep if we didn't miss any wakeups since OOM */
-       if (atomic_read(&memcg->oom_wakeups) == current->memcg_oom.wakeups)
+       mem_cgroup_mark_under_oom(memcg);
+       locked = mem_cgroup_oom_trylock(memcg);
+       if (locked)
+               mem_cgroup_oom_notify(memcg);
+       if (locked && !memcg->oom_kill_disable) {
+               mem_cgroup_unmark_under_oom(memcg);
+               finish_wait(&memcg_oom_waitq, &owait.wait);
+               mem_cgroup_out_of_memory(memcg, current->memcg_oom.gfp_mask,
+                                        current->memcg_oom.order);
+       } else {
                schedule();
-       finish_wait(&memcg_oom_waitq, &owait.wait);
- out_memcg:
-       mem_cgroup_unmark_under_oom(memcg);
-       if (current->memcg_oom.oom_locked) {
+               mem_cgroup_unmark_under_oom(memcg);
+               finish_wait(&memcg_oom_waitq, &owait.wait);
+       }
+       if (locked) {
                mem_cgroup_oom_unlock(memcg);
                /*
                 * There is no guarantee that an OOM-lock contender
                 */
                memcg_oom_recover(memcg);
        }
+ cleanup:
+       current->memcg_oom.memcg = NULL;
        css_put(&memcg->css);
-       current->memcg_oom.wait_on_memcg = NULL;
- out:
-       current->memcg_oom.in_memcg_oom = 0;
        return true;
  }
  
@@@ -2703,6 -2665,9 +2665,9 @@@ static int __mem_cgroup_try_charge(stru
                     || fatal_signal_pending(current)))
                goto bypass;
  
+       if (unlikely(task_in_memcg_oom(current)))
+               goto bypass;
        /*
         * We always charge the cgroup the mm_struct belongs to.
         * The mm_struct's mem_cgroup changes on task migration if the
@@@ -2801,6 -2766,8 +2766,8 @@@ done
        return 0;
  nomem:
        *ptr = NULL;
+       if (gfp_mask & __GFP_NOFAIL)
+               return 0;
        return -ENOMEM;
  bypass:
        *ptr = root_mem_cgroup;
index 005d876dd86cc89f8e7cf0f43d369661fcd6834e,8b0b610ca2c9a3cb8eb14ead723198783db35659..0513ef3ce6673dbc62ab4ff8dd8d28af6a0f6478
@@@ -272,7 -272,7 +272,7 @@@ static void br_multicast_del_pg(struct 
                del_timer(&p->timer);
                call_rcu_bh(&p->rcu, br_multicast_free_pg);
  
-               if (!mp->ports && !mp->mglist && mp->timer_armed &&
+               if (!mp->ports && !mp->mglist &&
                    netif_running(br->dev))
                        mod_timer(&mp->timer, jiffies);
  
@@@ -363,7 -363,7 +363,7 @@@ static struct sk_buff *br_ip4_multicast
        skb_reset_mac_header(skb);
        eth = eth_hdr(skb);
  
 -      memcpy(eth->h_source, br->dev->dev_addr, 6);
 +      memcpy(eth->h_source, br->dev->dev_addr, ETH_ALEN);
        eth->h_dest[0] = 1;
        eth->h_dest[1] = 0;
        eth->h_dest[2] = 0x5e;
@@@ -433,7 -433,7 +433,7 @@@ static struct sk_buff *br_ip6_multicast
        skb_reset_mac_header(skb);
        eth = eth_hdr(skb);
  
 -      memcpy(eth->h_source, br->dev->dev_addr, 6);
 +      memcpy(eth->h_source, br->dev->dev_addr, ETH_ALEN);
        eth->h_proto = htons(ETH_P_IPV6);
        skb_put(skb, sizeof(*eth));
  
@@@ -620,7 -620,6 +620,6 @@@ rehash
  
        mp->br = br;
        mp->addr = *group;
        setup_timer(&mp->timer, br_multicast_group_expired,
                    (unsigned long)mp);
  
@@@ -660,6 -659,7 +659,7 @@@ static int br_multicast_add_group(struc
        struct net_bridge_mdb_entry *mp;
        struct net_bridge_port_group *p;
        struct net_bridge_port_group __rcu **pp;
+       unsigned long now = jiffies;
        int err;
  
        spin_lock(&br->multicast_lock);
  
        if (!port) {
                mp->mglist = true;
+               mod_timer(&mp->timer, now + br->multicast_membership_interval);
                goto out;
        }
  
             (p = mlock_dereference(*pp, br)) != NULL;
             pp = &p->next) {
                if (p->port == port)
-                       goto out;
+                       goto found;
                if ((unsigned long)p->port < (unsigned long)port)
                        break;
        }
        rcu_assign_pointer(*pp, p);
        br_mdb_notify(br->dev, port, group, RTM_NEWMDB);
  
+ found:
+       mod_timer(&p->timer, now + br->multicast_membership_interval);
  out:
        err = 0;
  
@@@ -1191,9 -1194,6 +1194,6 @@@ static int br_ip4_multicast_query(struc
        if (!mp)
                goto out;
  
-       mod_timer(&mp->timer, now + br->multicast_membership_interval);
-       mp->timer_armed = true;
        max_delay *= br->multicast_last_member_count;
  
        if (mp->mglist &&
@@@ -1270,9 -1270,6 +1270,6 @@@ static int br_ip6_multicast_query(struc
        if (!mp)
                goto out;
  
-       mod_timer(&mp->timer, now + br->multicast_membership_interval);
-       mp->timer_armed = true;
        max_delay *= br->multicast_last_member_count;
        if (mp->mglist &&
            (timer_pending(&mp->timer) ?
@@@ -1358,7 -1355,7 +1355,7 @@@ static void br_multicast_leave_group(st
                        call_rcu_bh(&p->rcu, br_multicast_free_pg);
                        br_mdb_notify(br->dev, port, group, RTM_DELMDB);
  
-                       if (!mp->ports && !mp->mglist && mp->timer_armed &&
+                       if (!mp->ports && !mp->mglist &&
                            netif_running(br->dev))
                                mod_timer(&mp->timer, jiffies);
                }
                     br->multicast_last_member_interval;
  
        if (!port) {
-               if (mp->mglist && mp->timer_armed &&
+               if (mp->mglist &&
                    (timer_pending(&mp->timer) ?
                     time_after(mp->timer.expires, time) :
                     try_to_del_timer_sync(&mp->timer) >= 0)) {
                        mod_timer(&mp->timer, time);
                }
+               goto out;
+       }
+       for (p = mlock_dereference(mp->ports, br);
+            p != NULL;
+            p = mlock_dereference(p->next, br)) {
+               if (p->port != port)
+                       continue;
+               if (!hlist_unhashed(&p->mglist) &&
+                   (timer_pending(&p->timer) ?
+                    time_after(p->timer.expires, time) :
+                    try_to_del_timer_sync(&p->timer) >= 0)) {
+                       mod_timer(&p->timer, time);
+               }
+               break;
        }
  out:
        spin_unlock(&br->multicast_lock);
@@@ -1798,7 -1813,6 +1813,6 @@@ void br_multicast_stop(struct net_bridg
                hlist_for_each_entry_safe(mp, n, &mdb->mhash[i],
                                          hlist[ver]) {
                        del_timer(&mp->timer);
-                       mp->timer_armed = false;
                        call_rcu_bh(&mp->rcu, br_multicast_free_group);
                }
        }
diff --combined net/bridge/br_private.h
index 767c4dad85042cb7350dfeed4a4e558a206e9ca4,e14c33b42f75c3d1f4b6bb095b32efdb9218683e..d1ca6d9566332055591b96979805748a4c76e6c5
@@@ -126,7 -126,6 +126,6 @@@ struct net_bridge_mdb_entr
        struct timer_list               timer;
        struct br_ip                    addr;
        bool                            mglist;
-       bool                            timer_armed;
  };
  
  struct net_bridge_mdb_htable
@@@ -344,9 -343,10 +343,9 @@@ static inline int br_is_root_bridge(con
  }
  
  /* br_device.c */
 -extern void br_dev_setup(struct net_device *dev);
 -extern void br_dev_delete(struct net_device *dev, struct list_head *list);
 -extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
 -                             struct net_device *dev);
 +void br_dev_setup(struct net_device *dev);
 +void br_dev_delete(struct net_device *dev, struct list_head *list);
 +netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
  #ifdef CONFIG_NET_POLL_CONTROLLER
  static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
                                       struct sk_buff *skb)
                netpoll_send_skb(np, skb);
  }
  
 -extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
 -extern void br_netpoll_disable(struct net_bridge_port *p);
 +int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
 +void br_netpoll_disable(struct net_bridge_port *p);
  #else
  static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
                                       struct sk_buff *skb)
@@@ -376,99 -376,116 +375,99 @@@ static inline void br_netpoll_disable(s
  #endif
  
  /* br_fdb.c */
 -extern int br_fdb_init(void);
 -extern void br_fdb_fini(void);
 -extern void br_fdb_flush(struct net_bridge *br);
 -extern void br_fdb_changeaddr(struct net_bridge_port *p,
 -                            const unsigned char *newaddr);
 -extern void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
 -extern void br_fdb_cleanup(unsigned long arg);
 -extern void br_fdb_delete_by_port(struct net_bridge *br,
 -                                const struct net_bridge_port *p, int do_all);
 -extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
 -                                               const unsigned char *addr,
 -                                               __u16 vid);
 -extern int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
 -extern int br_fdb_fillbuf(struct net_bridge *br, void *buf,
 -                        unsigned long count, unsigned long off);
 -extern int br_fdb_insert(struct net_bridge *br,
 -                       struct net_bridge_port *source,
 -                       const unsigned char *addr,
 -                       u16 vid);
 -extern void br_fdb_update(struct net_bridge *br,
 -                        struct net_bridge_port *source,
 -                        const unsigned char *addr,
 -                        u16 vid);
 -extern int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vid);
 -
 -extern int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
 -                       struct net_device *dev,
 -                       const unsigned char *addr);
 -extern int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[],
 -                    struct net_device *dev,
 -                    const unsigned char *addr,
 -                    u16 nlh_flags);
 -extern int br_fdb_dump(struct sk_buff *skb,
 -                     struct netlink_callback *cb,
 -                     struct net_device *dev,
 -                     int idx);
 +int br_fdb_init(void);
 +void br_fdb_fini(void);
 +void br_fdb_flush(struct net_bridge *br);
 +void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr);
 +void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
 +void br_fdb_cleanup(unsigned long arg);
 +void br_fdb_delete_by_port(struct net_bridge *br,
 +                         const struct net_bridge_port *p, int do_all);
 +struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
 +                                        const unsigned char *addr, __u16 vid);
 +int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
 +int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
 +                 unsigned long off);
 +int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
 +                const unsigned char *addr, u16 vid);
 +void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
 +                 const unsigned char *addr, u16 vid);
 +int fdb_delete_by_addr(struct net_bridge *br, const u8 *addr, u16 vid);
 +
 +int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
 +                struct net_device *dev, const unsigned char *addr);
 +int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
 +             const unsigned char *addr, u16 nlh_flags);
 +int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
 +              struct net_device *dev, int idx);
  
  /* br_forward.c */
 -extern void br_deliver(const struct net_bridge_port *to,
 -              struct sk_buff *skb);
 -extern int br_dev_queue_push_xmit(struct sk_buff *skb);
 -extern void br_forward(const struct net_bridge_port *to,
 +void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb);
 +int br_dev_queue_push_xmit(struct sk_buff *skb);
 +void br_forward(const struct net_bridge_port *to,
                struct sk_buff *skb, struct sk_buff *skb0);
 -extern int br_forward_finish(struct sk_buff *skb);
 -extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb,
 -                           bool unicast);
 -extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
 -                           struct sk_buff *skb2, bool unicast);
 +int br_forward_finish(struct sk_buff *skb);
 +void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb, bool unicast);
 +void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
 +                    struct sk_buff *skb2, bool unicast);
  
  /* br_if.c */
 -extern void br_port_carrier_check(struct net_bridge_port *p);
 -extern int br_add_bridge(struct net *net, const char *name);
 -extern int br_del_bridge(struct net *net, const char *name);
 -extern void br_net_exit(struct net *net);
 -extern int br_add_if(struct net_bridge *br,
 -            struct net_device *dev);
 -extern int br_del_if(struct net_bridge *br,
 -            struct net_device *dev);
 -extern int br_min_mtu(const struct net_bridge *br);
 -extern netdev_features_t br_features_recompute(struct net_bridge *br,
 -      netdev_features_t features);
 +void br_port_carrier_check(struct net_bridge_port *p);
 +int br_add_bridge(struct net *net, const char *name);
 +int br_del_bridge(struct net *net, const char *name);
 +void br_net_exit(struct net *net);
 +int br_add_if(struct net_bridge *br, struct net_device *dev);
 +int br_del_if(struct net_bridge *br, struct net_device *dev);
 +int br_min_mtu(const struct net_bridge *br);
 +netdev_features_t br_features_recompute(struct net_bridge *br,
 +                                      netdev_features_t features);
  
  /* br_input.c */
 -extern int br_handle_frame_finish(struct sk_buff *skb);
 -extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
 +int br_handle_frame_finish(struct sk_buff *skb);
 +rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
  
  /* br_ioctl.c */
 -extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 -extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);
 +int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 +int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd,
 +                           void __user *arg);
  
  /* br_multicast.c */
  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  extern unsigned int br_mdb_rehash_seq;
 -extern int br_multicast_rcv(struct net_bridge *br,
 -                          struct net_bridge_port *port,
 -                          struct sk_buff *skb);
 -extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
 -                                             struct sk_buff *skb, u16 vid);
 -extern void br_multicast_add_port(struct net_bridge_port *port);
 -extern void br_multicast_del_port(struct net_bridge_port *port);
 -extern void br_multicast_enable_port(struct net_bridge_port *port);
 -extern void br_multicast_disable_port(struct net_bridge_port *port);
 -extern void br_multicast_init(struct net_bridge *br);
 -extern void br_multicast_open(struct net_bridge *br);
 -extern void br_multicast_stop(struct net_bridge *br);
 -extern void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
 -                               struct sk_buff *skb);
 -extern void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
 -                               struct sk_buff *skb, struct sk_buff *skb2);
 -extern int br_multicast_set_router(struct net_bridge *br, unsigned long val);
 -extern int br_multicast_set_port_router(struct net_bridge_port *p,
 -                                      unsigned long val);
 -extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
 -extern int br_multicast_set_querier(struct net_bridge *br, unsigned long val);
 -extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
 -extern struct net_bridge_mdb_entry *br_mdb_ip_get(
 -                              struct net_bridge_mdb_htable *mdb,
 -                              struct br_ip *dst);
 -extern struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
 -                              struct net_bridge_port *port, struct br_ip *group);
 -extern void br_multicast_free_pg(struct rcu_head *head);
 -extern struct net_bridge_port_group *br_multicast_new_port_group(
 -                              struct net_bridge_port *port,
 -                              struct br_ip *group,
 -                              struct net_bridge_port_group __rcu *next,
 -                              unsigned char state);
 -extern void br_mdb_init(void);
 -extern void br_mdb_uninit(void);
 -extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 -                        struct br_ip *group, int type);
 +int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
 +                   struct sk_buff *skb);
 +struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
 +                                      struct sk_buff *skb, u16 vid);
 +void br_multicast_add_port(struct net_bridge_port *port);
 +void br_multicast_del_port(struct net_bridge_port *port);
 +void br_multicast_enable_port(struct net_bridge_port *port);
 +void br_multicast_disable_port(struct net_bridge_port *port);
 +void br_multicast_init(struct net_bridge *br);
 +void br_multicast_open(struct net_bridge *br);
 +void br_multicast_stop(struct net_bridge *br);
 +void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
 +                        struct sk_buff *skb);
 +void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
 +                        struct sk_buff *skb, struct sk_buff *skb2);
 +int br_multicast_set_router(struct net_bridge *br, unsigned long val);
 +int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val);
 +int br_multicast_toggle(struct net_bridge *br, unsigned long val);
 +int br_multicast_set_querier(struct net_bridge *br, unsigned long val);
 +int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
 +struct net_bridge_mdb_entry *
 +br_mdb_ip_get(struct net_bridge_mdb_htable *mdb, struct br_ip *dst);
 +struct net_bridge_mdb_entry *
 +br_multicast_new_group(struct net_bridge *br, struct net_bridge_port *port,
 +                     struct br_ip *group);
 +void br_multicast_free_pg(struct rcu_head *head);
 +struct net_bridge_port_group *
 +br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
 +                          struct net_bridge_port_group __rcu *next,
 +                          unsigned char state);
 +void br_mdb_init(void);
 +void br_mdb_uninit(void);
 +void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 +                 struct br_ip *group, int type);
  
  #define mlock_dereference(X, br) \
        rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
@@@ -573,21 -590,22 +572,21 @@@ static inline void br_mdb_uninit(void
  
  /* br_vlan.c */
  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
 -extern bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
 -                             struct sk_buff *skb, u16 *vid);
 -extern bool br_allowed_egress(struct net_bridge *br,
 -                            const struct net_port_vlans *v,
 -                            const struct sk_buff *skb);
 -extern struct sk_buff *br_handle_vlan(struct net_bridge *br,
 -                                    const struct net_port_vlans *v,
 -                                    struct sk_buff *skb);
 -extern int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags);
 -extern int br_vlan_delete(struct net_bridge *br, u16 vid);
 -extern void br_vlan_flush(struct net_bridge *br);
 -extern int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
 -extern int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
 -extern int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
 -extern void nbp_vlan_flush(struct net_bridge_port *port);
 -extern bool nbp_vlan_find(struct net_bridge_port *port, u16 vid);
 +bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
 +                      struct sk_buff *skb, u16 *vid);
 +bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v,
 +                     const struct sk_buff *skb);
 +struct sk_buff *br_handle_vlan(struct net_bridge *br,
 +                             const struct net_port_vlans *v,
 +                             struct sk_buff *skb);
 +int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags);
 +int br_vlan_delete(struct net_bridge *br, u16 vid);
 +void br_vlan_flush(struct net_bridge *br);
 +int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
 +int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags);
 +int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
 +void nbp_vlan_flush(struct net_bridge_port *port);
 +bool nbp_vlan_find(struct net_bridge_port *port, u16 vid);
  
  static inline struct net_port_vlans *br_get_vlan_info(
                                                const struct net_bridge *br)
@@@ -624,9 -642,7 +623,7 @@@ static inline u16 br_get_pvid(const str
         * vid wasn't set
         */
        smp_rmb();
-       return (v->pvid & VLAN_TAG_PRESENT) ?
-                       (v->pvid & ~VLAN_TAG_PRESENT) :
-                       VLAN_N_VID;
+       return v->pvid ?: VLAN_N_VID;
  }
  
  #else
@@@ -708,9 -724,9 +705,9 @@@ static inline u16 br_get_pvid(const str
  
  /* br_netfilter.c */
  #ifdef CONFIG_BRIDGE_NETFILTER
 -extern int br_netfilter_init(void);
 -extern void br_netfilter_fini(void);
 -extern void br_netfilter_rtable_init(struct net_bridge *);
 +int br_netfilter_init(void);
 +void br_netfilter_fini(void);
 +void br_netfilter_rtable_init(struct net_bridge *);
  #else
  #define br_netfilter_init()   (0)
  #define br_netfilter_fini()   do { } while(0)
  #endif
  
  /* br_stp.c */
 -extern void br_log_state(const struct net_bridge_port *p);
 -extern struct net_bridge_port *br_get_port(struct net_bridge *br,
 -                                         u16 port_no);
 -extern void br_init_port(struct net_bridge_port *p);
 -extern void br_become_designated_port(struct net_bridge_port *p);
 +void br_log_state(const struct net_bridge_port *p);
 +struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no);
 +void br_init_port(struct net_bridge_port *p);
 +void br_become_designated_port(struct net_bridge_port *p);
  
 -extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t);
 -extern int br_set_forward_delay(struct net_bridge *br, unsigned long x);
 -extern int br_set_hello_time(struct net_bridge *br, unsigned long x);
 -extern int br_set_max_age(struct net_bridge *br, unsigned long x);
 +void __br_set_forward_delay(struct net_bridge *br, unsigned long t);
 +int br_set_forward_delay(struct net_bridge *br, unsigned long x);
 +int br_set_hello_time(struct net_bridge *br, unsigned long x);
 +int br_set_max_age(struct net_bridge *br, unsigned long x);
  
  
  /* br_stp_if.c */
 -extern void br_stp_enable_bridge(struct net_bridge *br);
 -extern void br_stp_disable_bridge(struct net_bridge *br);
 -extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val);
 -extern void br_stp_enable_port(struct net_bridge_port *p);
 -extern void br_stp_disable_port(struct net_bridge_port *p);
 -extern bool br_stp_recalculate_bridge_id(struct net_bridge *br);
 -extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
 -extern void br_stp_set_bridge_priority(struct net_bridge *br,
 -                                     u16 newprio);
 -extern int br_stp_set_port_priority(struct net_bridge_port *p,
 -                                  unsigned long newprio);
 -extern int br_stp_set_path_cost(struct net_bridge_port *p,
 -                              unsigned long path_cost);
 -extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
 +void br_stp_enable_bridge(struct net_bridge *br);
 +void br_stp_disable_bridge(struct net_bridge *br);
 +void br_stp_set_enabled(struct net_bridge *br, unsigned long val);
 +void br_stp_enable_port(struct net_bridge_port *p);
 +void br_stp_disable_port(struct net_bridge_port *p);
 +bool br_stp_recalculate_bridge_id(struct net_bridge *br);
 +void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
 +void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio);
 +int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio);
 +int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost);
 +ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
  
  /* br_stp_bpdu.c */
  struct stp_proto;
 -extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
 -                     struct net_device *dev);
 +void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
 +              struct net_device *dev);
  
  /* br_stp_timer.c */
 -extern void br_stp_timer_init(struct net_bridge *br);
 -extern void br_stp_port_timer_init(struct net_bridge_port *p);
 -extern unsigned long br_timer_value(const struct timer_list *timer);
 +void br_stp_timer_init(struct net_bridge *br);
 +void br_stp_port_timer_init(struct net_bridge_port *p);
 +unsigned long br_timer_value(const struct timer_list *timer);
  
  /* br.c */
  #if IS_ENABLED(CONFIG_ATM_LANE)
@@@ -759,23 -779,23 +756,23 @@@ extern int (*br_fdb_test_addr_hook)(str
  
  /* br_netlink.c */
  extern struct rtnl_link_ops br_link_ops;
 -extern int br_netlink_init(void);
 -extern void br_netlink_fini(void);
 -extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
 -extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
 -extern int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg);
 -extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 -                    struct net_device *dev, u32 filter_mask);
 +int br_netlink_init(void);
 +void br_netlink_fini(void);
 +void br_ifinfo_notify(int event, struct net_bridge_port *port);
 +int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
 +int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg);
 +int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
 +             u32 filter_mask);
  
  #ifdef CONFIG_SYSFS
  /* br_sysfs_if.c */
  extern const struct sysfs_ops brport_sysfs_ops;
 -extern int br_sysfs_addif(struct net_bridge_port *p);
 -extern int br_sysfs_renameif(struct net_bridge_port *p);
 +int br_sysfs_addif(struct net_bridge_port *p);
 +int br_sysfs_renameif(struct net_bridge_port *p);
  
  /* br_sysfs_br.c */
 -extern int br_sysfs_addbr(struct net_device *dev);
 -extern void br_sysfs_delbr(struct net_device *dev);
 +int br_sysfs_addbr(struct net_device *dev);
 +void br_sysfs_delbr(struct net_device *dev);
  
  #else
  
diff --combined net/core/secure_seq.c
index 90e8a825025595c2340ee86af0af67ab6e5bc638,8d9d05edd2eb1e66024311c62c6b7679c52bdc7d..897da56f3affae13161d4610989667a82244c308
@@@ -7,18 -7,30 +7,20 @@@
  #include <linux/hrtimer.h>
  #include <linux/ktime.h>
  #include <linux/string.h>
 +#include <linux/net.h>
  
  #include <net/secure_seq.h>
  
+ #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET)
  #define NET_SECRET_SIZE (MD5_MESSAGE_BYTES / 4)
  
  static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned;
  
 -static void net_secret_init(void)
 +static __always_inline void net_secret_init(void)
  {
 -      u32 tmp;
 -      int i;
 -
 -      if (likely(net_secret[0]))
 -              return;
 -
 -      for (i = NET_SECRET_SIZE; i > 0;) {
 -              do {
 -                      get_random_bytes(&tmp, sizeof(tmp));
 -              } while (!tmp);
 -              cmpxchg(&net_secret[--i], 0, tmp);
 -      }
 +      net_get_random_once(net_secret, sizeof(net_secret));
  }
+ #endif
  
  #ifdef CONFIG_INET
  static u32 seq_scale(u32 seq)
diff --combined net/ipv4/ip_output.c
index 7d8357bb2ba654a88fbf564897beb88e412f4974,3982eabf61e126060fc7c5b48042bea2f0417135..8fbac7de1e1b731e14aa485e75c1212618cace55
@@@ -772,15 -772,20 +772,20 @@@ static inline int ip_ufo_append_data(st
                /* initialize protocol header pointer */
                skb->transport_header = skb->network_header + fragheaderlen;
  
-               skb->ip_summed = CHECKSUM_PARTIAL;
                skb->csum = 0;
  
-               /* specify the length of each IP datagram fragment */
-               skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
-               skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
                __skb_queue_tail(queue, skb);
+       } else if (skb_is_gso(skb)) {
+               goto append;
        }
  
+       skb->ip_summed = CHECKSUM_PARTIAL;
+       /* specify the length of each IP datagram fragment */
+       skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
+       skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ append:
        return skb_append_datato_frags(sk, skb, getfrag, from,
                                       (length - transhdrlen));
  }
@@@ -1060,9 -1065,6 +1065,9 @@@ static int ip_setup_cork(struct sock *s
                         rt->dst.dev->mtu : dst_mtu(&rt->dst);
        cork->dst = &rt->dst;
        cork->length = 0;
 +      cork->ttl = ipc->ttl;
 +      cork->tos = ipc->tos;
 +      cork->priority = ipc->priority;
        cork->tx_flags = ipc->tx_flags;
  
        return 0;
@@@ -1314,9 -1316,7 +1319,9 @@@ struct sk_buff *__ip_make_skb(struct so
        if (cork->flags & IPCORK_OPT)
                opt = cork->opt;
  
 -      if (rt->rt_type == RTN_MULTICAST)
 +      if (cork->ttl != 0)
 +              ttl = cork->ttl;
 +      else if (rt->rt_type == RTN_MULTICAST)
                ttl = inet->mc_ttl;
        else
                ttl = ip_select_ttl(inet, &rt->dst);
        iph = ip_hdr(skb);
        iph->version = 4;
        iph->ihl = 5;
 -      iph->tos = inet->tos;
 +      iph->tos = (cork->tos != -1) ? cork->tos : inet->tos;
        iph->frag_off = df;
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
                ip_options_build(skb, opt, cork->addr, rt, 0);
        }
  
 -      skb->priority = sk->sk_priority;
 +      skb->priority = (cork->tos != -1) ? cork->priority: sk->sk_priority;
        skb->mark = sk->sk_mark;
        /*
         * Steal rt from cork.dst to avoid a pair of atomic_inc/atomic_dec
@@@ -1486,8 -1486,6 +1491,8 @@@ void ip_send_unicast_reply(struct net *
        ipc.addr = daddr;
        ipc.opt = NULL;
        ipc.tx_flags = 0;
 +      ipc.ttl = 0;
 +      ipc.tos = -1;
  
        if (replyopts.opt.opt.optlen) {
                ipc.opt = &replyopts.opt;
diff --combined net/ipv4/ip_vti.c
index 91f69bc883fe80cc97df0e34744caa6d40186bf8,6e87f853d03334567906c8782250049c568e4280..5d9c845d288a3d8cce3eb96aeb65384e4a56edbc
@@@ -49,6 -49,70 +49,6 @@@ static struct rtnl_link_ops vti_link_op
  static int vti_net_id __read_mostly;
  static int vti_tunnel_init(struct net_device *dev);
  
 -static int vti_err(struct sk_buff *skb, u32 info)
 -{
 -
 -      /* All the routers (except for Linux) return only
 -       * 8 bytes of packet payload. It means, that precise relaying of
 -       * ICMP in the real Internet is absolutely infeasible.
 -       */
 -      struct net *net = dev_net(skb->dev);
 -      struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
 -      struct iphdr *iph = (struct iphdr *)skb->data;
 -      const int type = icmp_hdr(skb)->type;
 -      const int code = icmp_hdr(skb)->code;
 -      struct ip_tunnel *t;
 -      int err;
 -
 -      switch (type) {
 -      default:
 -      case ICMP_PARAMETERPROB:
 -              return 0;
 -
 -      case ICMP_DEST_UNREACH:
 -              switch (code) {
 -              case ICMP_SR_FAILED:
 -              case ICMP_PORT_UNREACH:
 -                      /* Impossible event. */
 -                      return 0;
 -              default:
 -                      /* All others are translated to HOST_UNREACH. */
 -                      break;
 -              }
 -              break;
 -      case ICMP_TIME_EXCEEDED:
 -              if (code != ICMP_EXC_TTL)
 -                      return 0;
 -              break;
 -      }
 -
 -      err = -ENOENT;
 -
 -      t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
 -                           iph->daddr, iph->saddr, 0);
 -      if (t == NULL)
 -              goto out;
 -
 -      if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
 -              ipv4_update_pmtu(skb, dev_net(skb->dev), info,
 -                               t->parms.link, 0, IPPROTO_IPIP, 0);
 -              err = 0;
 -              goto out;
 -      }
 -
 -      err = 0;
 -      if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
 -              goto out;
 -
 -      if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
 -              t->err_count++;
 -      else
 -              t->err_count = 1;
 -      t->err_time = jiffies;
 -out:
 -      return err;
 -}
 -
  /* We dont digest the packet therefore let the packet pass */
  static int vti_rcv(struct sk_buff *skb)
  {
                                  iph->saddr, iph->daddr, 0);
        if (tunnel != NULL) {
                struct pcpu_tstats *tstats;
+               u32 oldmark = skb->mark;
+               int ret;
  
-               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+               /* temporarily mark the skb with the tunnel o_key, to
+                * only match policies with this mark.
+                */
+               skb->mark = be32_to_cpu(tunnel->parms.o_key);
+               ret = xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb);
+               skb->mark = oldmark;
+               if (!ret)
                        return -1;
  
                tstats = this_cpu_ptr(tunnel->dev->tstats);
                tstats->rx_bytes += skb->len;
                u64_stats_update_end(&tstats->syncp);
  
-               skb->mark = 0;
                secpath_reset(skb);
                skb->dev = tunnel->dev;
                return 1;
@@@ -103,7 -175,7 +111,7 @@@ static netdev_tx_t vti_tunnel_xmit(stru
  
        memset(&fl4, 0, sizeof(fl4));
        flowi4_init_output(&fl4, tunnel->parms.link,
-                          be32_to_cpu(tunnel->parms.i_key), RT_TOS(tos),
+                          be32_to_cpu(tunnel->parms.o_key), RT_TOS(tos),
                           RT_SCOPE_UNIVERSE,
                           IPPROTO_IPIP, 0,
                           dst, tiph->saddr, 0, 0);
@@@ -232,8 -304,9 +240,8 @@@ static void __net_init vti_fb_tunnel_in
        iph->ihl                = 5;
  }
  
 -static struct xfrm_tunnel vti_handler __read_mostly = {
 +static struct xfrm_tunnel_notifier vti_handler __read_mostly = {
        .handler        =       vti_rcv,
 -      .err_handler    =       vti_err,
        .priority       =       1,
  };
  
diff --combined net/ipv4/tcp_input.c
index eb651a069a6c7b585ce3e5e1740e1b2be207c6c5,a16b01b537baa1e0e2b63e606f96fb37571d7638..b935397c703c569bf01e6ebfd85e6bfd1b474227
@@@ -267,31 -267,11 +267,31 @@@ static bool TCP_ECN_rcv_ecn_echo(const 
   * 1. Tuning sk->sk_sndbuf, when connection enters established state.
   */
  
 -static void tcp_fixup_sndbuf(struct sock *sk)
 +static void tcp_sndbuf_expand(struct sock *sk)
  {
 -      int sndmem = SKB_TRUESIZE(tcp_sk(sk)->rx_opt.mss_clamp + MAX_TCP_HEADER);
 +      const struct tcp_sock *tp = tcp_sk(sk);
 +      int sndmem, per_mss;
 +      u32 nr_segs;
 +
 +      /* Worst case is non GSO/TSO : each frame consumes one skb
 +       * and skb->head is kmalloced using power of two area of memory
 +       */
 +      per_mss = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) +
 +                MAX_TCP_HEADER +
 +                SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 +
 +      per_mss = roundup_pow_of_two(per_mss) +
 +                SKB_DATA_ALIGN(sizeof(struct sk_buff));
 +
 +      nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd);
 +      nr_segs = max_t(u32, nr_segs, tp->reordering + 1);
 +
 +      /* Fast Recovery (RFC 5681 3.2) :
 +       * Cubic needs 1.7 factor, rounded to 2 to include
 +       * extra cushion (application might react slowly to POLLOUT)
 +       */
 +      sndmem = 2 * nr_segs * per_mss;
  
 -      sndmem *= TCP_INIT_CWND;
        if (sk->sk_sndbuf < sndmem)
                sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]);
  }
@@@ -375,12 -355,6 +375,12 @@@ static void tcp_fixup_rcvbuf(struct soc
        rcvmem = 2 * SKB_TRUESIZE(mss + MAX_TCP_HEADER) *
                 tcp_default_init_rwnd(mss);
  
 +      /* Dynamic Right Sizing (DRS) has 2 to 3 RTT latency
 +       * Allow enough cushion so that sender is not limited by our window
 +       */
 +      if (sysctl_tcp_moderate_rcvbuf)
 +              rcvmem <<= 2;
 +
        if (sk->sk_rcvbuf < rcvmem)
                sk->sk_rcvbuf = min(rcvmem, sysctl_tcp_rmem[2]);
  }
@@@ -396,11 -370,9 +396,11 @@@ void tcp_init_buffer_space(struct sock 
        if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK))
                tcp_fixup_rcvbuf(sk);
        if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK))
 -              tcp_fixup_sndbuf(sk);
 +              tcp_sndbuf_expand(sk);
  
        tp->rcvq_space.space = tp->rcv_wnd;
 +      tp->rcvq_space.time = tcp_time_stamp;
 +      tp->rcvq_space.seq = tp->copied_seq;
  
        maxwin = tcp_full_space(sk);
  
@@@ -540,62 -512,48 +540,62 @@@ void tcp_rcv_space_adjust(struct sock *
  {
        struct tcp_sock *tp = tcp_sk(sk);
        int time;
 -      int space;
 -
 -      if (tp->rcvq_space.time == 0)
 -              goto new_measure;
 +      int copied;
  
        time = tcp_time_stamp - tp->rcvq_space.time;
        if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
                return;
  
 -      space = 2 * (tp->copied_seq - tp->rcvq_space.seq);
 +      /* Number of bytes copied to user in last RTT */
 +      copied = tp->copied_seq - tp->rcvq_space.seq;
 +      if (copied <= tp->rcvq_space.space)
 +              goto new_measure;
  
 -      space = max(tp->rcvq_space.space, space);
 +      /* A bit of theory :
 +       * copied = bytes received in previous RTT, our base window
 +       * To cope with packet losses, we need a 2x factor
 +       * To cope with slow start, and sender growing its cwin by 100 %
 +       * every RTT, we need a 4x factor, because the ACK we are sending
 +       * now is for the next RTT, not the current one :
 +       * <prev RTT . ><current RTT .. ><next RTT .... >
 +       */
  
 -      if (tp->rcvq_space.space != space) {
 -              int rcvmem;
 +      if (sysctl_tcp_moderate_rcvbuf &&
 +          !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
 +              int rcvwin, rcvmem, rcvbuf;
  
 -              tp->rcvq_space.space = space;
 +              /* minimal window to cope with packet losses, assuming
 +               * steady state. Add some cushion because of small variations.
 +               */
 +              rcvwin = (copied << 1) + 16 * tp->advmss;
  
 -              if (sysctl_tcp_moderate_rcvbuf &&
 -                  !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) {
 -                      int new_clamp = space;
 +              /* If rate increased by 25%,
 +               *      assume slow start, rcvwin = 3 * copied
 +               * If rate increased by 50%,
 +               *      assume sender can use 2x growth, rcvwin = 4 * copied
 +               */
 +              if (copied >=
 +                  tp->rcvq_space.space + (tp->rcvq_space.space >> 2)) {
 +                      if (copied >=
 +                          tp->rcvq_space.space + (tp->rcvq_space.space >> 1))
 +                              rcvwin <<= 1;
 +                      else
 +                              rcvwin += (rcvwin >> 1);
 +              }
  
 -                      /* Receive space grows, normalize in order to
 -                       * take into account packet headers and sk_buff
 -                       * structure overhead.
 -                       */
 -                      space /= tp->advmss;
 -                      if (!space)
 -                              space = 1;
 -                      rcvmem = SKB_TRUESIZE(tp->advmss + MAX_TCP_HEADER);
 -                      while (tcp_win_from_space(rcvmem) < tp->advmss)
 -                              rcvmem += 128;
 -                      space *= rcvmem;
 -                      space = min(space, sysctl_tcp_rmem[2]);
 -                      if (space > sk->sk_rcvbuf) {
 -                              sk->sk_rcvbuf = space;
 -
 -                              /* Make the window clamp follow along.  */
 -                              tp->window_clamp = new_clamp;
 -                      }
 +              rcvmem = SKB_TRUESIZE(tp->advmss + MAX_TCP_HEADER);
 +              while (tcp_win_from_space(rcvmem) < tp->advmss)
 +                      rcvmem += 128;
 +
 +              rcvbuf = min(rcvwin / tp->advmss * rcvmem, sysctl_tcp_rmem[2]);
 +              if (rcvbuf > sk->sk_rcvbuf) {
 +                      sk->sk_rcvbuf = rcvbuf;
 +
 +                      /* Make the window clamp follow along.  */
 +                      tp->window_clamp = rcvwin;
                }
        }
 +      tp->rcvq_space.space = copied;
  
  new_measure:
        tp->rcvq_space.seq = tp->copied_seq;
@@@ -755,12 -713,7 +755,12 @@@ static void tcp_update_pacing_rate(stru
        if (tp->srtt > 8 + 2)
                do_div(rate, tp->srtt);
  
 -      sk->sk_pacing_rate = min_t(u64, rate, ~0U);
 +      /* ACCESS_ONCE() is needed because sch_fq fetches sk_pacing_rate
 +       * without any lock. We want to make sure compiler wont store
 +       * intermediate values in this location.
 +       */
 +      ACCESS_ONCE(sk->sk_pacing_rate) = min_t(u64, rate,
 +                                              sk->sk_max_pacing_rate);
  }
  
  /* Calculate rto without backoff.  This is the second half of Van Jacobson's
@@@ -3020,7 -2973,7 +3020,7 @@@ static int tcp_clean_rtx_queue(struct s
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct sk_buff *skb;
        u32 now = tcp_time_stamp;
 -      int fully_acked = true;
 +      bool fully_acked = true;
        int flag = 0;
        u32 pkts_acked = 0;
        u32 reord = tp->packets_out;
@@@ -3338,7 -3291,7 +3338,7 @@@ static void tcp_process_tlp_ack(struct 
                        tcp_init_cwnd_reduction(sk, true);
                        tcp_set_ca_state(sk, TCP_CA_CWR);
                        tcp_end_cwnd_reduction(sk);
-                       tcp_set_ca_state(sk, TCP_CA_Open);
+                       tcp_try_keep_open(sk);
                        NET_INC_STATS_BH(sock_net(sk),
                                         LINUX_MIB_TCPLOSSPROBERECOVERY);
                }
@@@ -4751,7 -4704,15 +4751,7 @@@ static void tcp_new_space(struct sock *
        struct tcp_sock *tp = tcp_sk(sk);
  
        if (tcp_should_expand_sndbuf(sk)) {
 -              int sndmem = SKB_TRUESIZE(max_t(u32,
 -                                              tp->rx_opt.mss_clamp,
 -                                              tp->mss_cache) +
 -                                        MAX_TCP_HEADER);
 -              int demanded = max_t(unsigned int, tp->snd_cwnd,
 -                                   tp->reordering + 1);
 -              sndmem *= 2 * demanded;
 -              if (sndmem > sk->sk_sndbuf)
 -                      sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]);
 +              tcp_sndbuf_expand(sk);
                tp->snd_cwnd_stamp = tcp_time_stamp;
        }
  
@@@ -5716,8 -5677,8 +5716,8 @@@ int tcp_rcv_state_process(struct sock *
                        tcp_init_congestion_control(sk);
  
                        tcp_mtup_init(sk);
 -                      tcp_init_buffer_space(sk);
                        tp->copied_seq = tp->rcv_nxt;
 +                      tcp_init_buffer_space(sk);
                }
                smp_mb();
                tcp_set_state(sk, TCP_ESTABLISHED);
                } else
                        tcp_init_metrics(sk);
  
+               tcp_update_pacing_rate(sk);
                /* Prevent spurious tcp_cwnd_restart() on first data packet */
                tp->lsndtime = tcp_time_stamp;
  
diff --combined net/ipv4/tcp_output.c
index ce7c4d9d9195f02921b353e6a1ac2fd134d766d9,d46f2143305c2632e7703f2677310dd177d67208..672854664ff5c1d36783ac1bfb72fea481648ca1
@@@ -850,15 -850,15 +850,15 @@@ static int tcp_transmit_skb(struct soc
  
        BUG_ON(!skb || !tcp_skb_pcount(skb));
  
 -      /* If congestion control is doing timestamping, we must
 -       * take such a timestamp before we potentially clone/copy.
 -       */
 -      if (icsk->icsk_ca_ops->flags & TCP_CONG_RTT_STAMP)
 -              __net_timestamp(skb);
 -
 -      if (likely(clone_it)) {
 +      if (clone_it) {
                const struct sk_buff *fclone = skb + 1;
  
 +              /* If congestion control is doing timestamping, we must
 +               * take such a timestamp before we potentially clone/copy.
 +               */
 +              if (icsk->icsk_ca_ops->flags & TCP_CONG_RTT_STAMP)
 +                      __net_timestamp(skb);
 +
                if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
                             fclone->fclone == SKB_FCLONE_CLONE))
                        NET_INC_STATS_BH(sock_net(sk),
@@@ -986,8 -986,10 +986,10 @@@ static void tcp_queue_skb(struct sock *
  static void tcp_set_skb_tso_segs(const struct sock *sk, struct sk_buff *skb,
                                 unsigned int mss_now)
  {
-       if (skb->len <= mss_now || !sk_can_gso(sk) ||
-           skb->ip_summed == CHECKSUM_NONE) {
+       /* Make sure we own this skb before messing gso_size/gso_segs */
+       WARN_ON_ONCE(skb_cloned(skb));
+       if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) {
                /* Avoid the costly divide in the normal
                 * non-TSO case.
                 */
@@@ -1067,9 -1069,7 +1069,7 @@@ int tcp_fragment(struct sock *sk, struc
        if (nsize < 0)
                nsize = 0;
  
-       if (skb_cloned(skb) &&
-           skb_is_nonlinear(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_unclone(skb, GFP_ATOMIC))
                return -ENOMEM;
  
        /* Get a new skb... force flag on. */
@@@ -2344,6 -2344,8 +2344,8 @@@ int __tcp_retransmit_skb(struct sock *s
                int oldpcount = tcp_skb_pcount(skb);
  
                if (unlikely(oldpcount > 1)) {
+                       if (skb_unclone(skb, GFP_ATOMIC))
+                               return -ENOMEM;
                        tcp_init_tso_segs(sk, skb, cur_mss);
                        tcp_adjust_pcount(sk, skb, oldpcount - tcp_skb_pcount(skb));
                }
  
        tcp_retrans_try_collapse(sk, skb, cur_mss);
  
 -      /* Some Solaris stacks overoptimize and ignore the FIN on a
 -       * retransmit when old data is attached.  So strip it off
 -       * since it is cheap to do so and saves bytes on the network.
 -       */
 -      if (skb->len > 0 &&
 -          (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) &&
 -          tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
 -              if (!pskb_trim(skb, 0)) {
 -                      /* Reuse, even though it does some unnecessary work */
 -                      tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1,
 -                                           TCP_SKB_CB(skb)->tcp_flags);
 -                      skb->ip_summed = CHECKSUM_NONE;
 -              }
 -      }
 -
        /* Make a copy, if the first transmission SKB clone we made
         * is still in somebody's hands, else make a clone.
         */
@@@ -2719,8 -2736,8 +2721,8 @@@ struct sk_buff *tcp_make_synack(struct 
        th->syn = 1;
        th->ack = 1;
        TCP_ECN_make_synack(req, th);
 -      th->source = ireq->loc_port;
 -      th->dest = ireq->rmt_port;
 +      th->source = htons(ireq->ir_num);
 +      th->dest = ireq->ir_rmt_port;
        /* Setting of flags are superfluous here for callers (and ECE is
         * not even correctly set)
         */
diff --combined net/ipv6/route.c
index c3130ffc3bca6af51e8126fcf4541a52a20b2a2a,f54e3a1010989ac93619d4984df4ed9b32aed521..5dc6ca6b66863a981b807df51341b35bfd93d2b6
@@@ -476,6 -476,24 +476,24 @@@ out
  }
  
  #ifdef CONFIG_IPV6_ROUTER_PREF
+ struct __rt6_probe_work {
+       struct work_struct work;
+       struct in6_addr target;
+       struct net_device *dev;
+ };
+ static void rt6_probe_deferred(struct work_struct *w)
+ {
+       struct in6_addr mcaddr;
+       struct __rt6_probe_work *work =
+               container_of(w, struct __rt6_probe_work, work);
+       addrconf_addr_solict_mult(&work->target, &mcaddr);
+       ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL);
+       dev_put(work->dev);
+       kfree(w);
+ }
  static void rt6_probe(struct rt6_info *rt)
  {
        struct neighbour *neigh;
  
        if (!neigh ||
            time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) {
-               struct in6_addr mcaddr;
-               struct in6_addr *target;
+               struct __rt6_probe_work *work;
  
-               if (neigh) {
+               work = kmalloc(sizeof(*work), GFP_ATOMIC);
+               if (neigh && work)
                        neigh->updated = jiffies;
+               if (neigh)
                        write_unlock(&neigh->lock);
-               }
  
-               target = (struct in6_addr *)&rt->rt6i_gateway;
-               addrconf_addr_solict_mult(target, &mcaddr);
-               ndisc_send_ns(rt->dst.dev, NULL, target, &mcaddr, NULL);
+               if (work) {
+                       INIT_WORK(&work->work, rt6_probe_deferred);
+                       work->target = rt->rt6i_gateway;
+                       dev_hold(rt->dst.dev);
+                       work->dev = rt->dst.dev;
+                       schedule_work(&work->work);
+               }
        } else {
  out:
                write_unlock(&neigh->lock);
@@@ -851,7 -875,6 +875,6 @@@ static struct rt6_info *rt6_alloc_cow(s
                        if (ort->rt6i_dst.plen != 128 &&
                            ipv6_addr_equal(&ort->rt6i_dst.addr, daddr))
                                rt->rt6i_flags |= RTF_ANYCAST;
-                       rt->rt6i_gateway = *daddr;
                }
  
                rt->rt6i_flags |= RTF_CACHE;
@@@ -1137,6 -1160,7 +1160,6 @@@ void ip6_update_pmtu(struct sk_buff *sk
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
        fl6.flowi6_mark = mark;
 -      fl6.flowi6_flags = 0;
        fl6.daddr = iph->daddr;
        fl6.saddr = iph->saddr;
        fl6.flowlabel = ip6_flowinfo(iph);
@@@ -1235,6 -1259,7 +1258,6 @@@ void ip6_redirect(struct sk_buff *skb, 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
        fl6.flowi6_mark = mark;
 -      fl6.flowi6_flags = 0;
        fl6.daddr = iph->daddr;
        fl6.saddr = iph->saddr;
        fl6.flowlabel = ip6_flowinfo(iph);
@@@ -1256,6 -1281,7 +1279,6 @@@ void ip6_redirect_no_header(struct sk_b
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
        fl6.flowi6_mark = mark;
 -      fl6.flowi6_flags = 0;
        fl6.daddr = msg->dest;
        fl6.saddr = iph->daddr;
  
@@@ -1335,6 -1361,7 +1358,7 @@@ struct dst_entry *icmp6_dst_alloc(struc
        rt->dst.flags |= DST_HOST;
        rt->dst.output  = ip6_output;
        atomic_set(&rt->dst.__refcnt, 1);
+       rt->rt6i_gateway  = fl6->daddr;
        rt->rt6i_dst.addr = fl6->daddr;
        rt->rt6i_dst.plen = 128;
        rt->rt6i_idev     = idev;
@@@ -1870,7 -1897,10 +1894,10 @@@ static struct rt6_info *ip6_rt_copy(str
                        in6_dev_hold(rt->rt6i_idev);
                rt->dst.lastuse = jiffies;
  
-               rt->rt6i_gateway = ort->rt6i_gateway;
+               if (ort->rt6i_flags & RTF_GATEWAY)
+                       rt->rt6i_gateway = ort->rt6i_gateway;
+               else
+                       rt->rt6i_gateway = *dest;
                rt->rt6i_flags = ort->rt6i_flags;
                if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ==
                    (RTF_DEFAULT | RTF_ADDRCONF))
@@@ -2157,6 -2187,7 +2184,7 @@@ struct rt6_info *addrconf_dst_alloc(str
        else
                rt->rt6i_flags |= RTF_LOCAL;
  
+       rt->rt6i_gateway  = *addr;
        rt->rt6i_dst.addr = *addr;
        rt->rt6i_dst.plen = 128;
        rt->rt6i_table = fib6_get_table(net, RT6_TABLE_LOCAL);
@@@ -2797,12 -2828,56 +2825,12 @@@ static int ip6_route_dev_notify(struct 
  
  #ifdef CONFIG_PROC_FS
  
 -struct rt6_proc_arg
 -{
 -      char *buffer;
 -      int offset;
 -      int length;
 -      int skip;
 -      int len;
 -};
 -
 -static int rt6_info_route(struct rt6_info *rt, void *p_arg)
 -{
 -      struct seq_file *m = p_arg;
 -
 -      seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
 -
 -#ifdef CONFIG_IPV6_SUBTREES
 -      seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen);
 -#else
 -      seq_puts(m, "00000000000000000000000000000000 00 ");
 -#endif
 -      if (rt->rt6i_flags & RTF_GATEWAY) {
 -              seq_printf(m, "%pi6", &rt->rt6i_gateway);
 -      } else {
 -              seq_puts(m, "00000000000000000000000000000000");
 -      }
 -      seq_printf(m, " %08x %08x %08x %08x %8s\n",
 -                 rt->rt6i_metric, atomic_read(&rt->dst.__refcnt),
 -                 rt->dst.__use, rt->rt6i_flags,
 -                 rt->dst.dev ? rt->dst.dev->name : "");
 -      return 0;
 -}
 -
 -static int ipv6_route_show(struct seq_file *m, void *v)
 -{
 -      struct net *net = (struct net *)m->private;
 -      fib6_clean_all_ro(net, rt6_info_route, 0, m);
 -      return 0;
 -}
 -
 -static int ipv6_route_open(struct inode *inode, struct file *file)
 -{
 -      return single_open_net(inode, file, ipv6_route_show);
 -}
 -
  static const struct file_operations ipv6_route_proc_fops = {
        .owner          = THIS_MODULE,
        .open           = ipv6_route_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
 -      .release        = single_release_net,
 +      .release        = seq_release_net,
  };
  
  static int rt6_stats_seq_show(struct seq_file *seq, void *v)
diff --combined net/ipv6/udp.c
index 44fc4e3d661fc342cc4cea555823c69694039d5c,18786098fd412dd5fa95a9fc096195f387b53fa0..f3893e897f721aa4345c82f0ea2b899c44fa0ae4
  #include <trace/events/skb.h>
  #include "udp_impl.h"
  
 +static unsigned int udp6_ehashfn(struct net *net,
 +                                const struct in6_addr *laddr,
 +                                const u16 lport,
 +                                const struct in6_addr *faddr,
 +                                const __be16 fport)
 +{
 +      static u32 udp6_ehash_secret __read_mostly;
 +      static u32 udp_ipv6_hash_secret __read_mostly;
 +
 +      u32 lhash, fhash;
 +
 +      net_get_random_once(&udp6_ehash_secret,
 +                          sizeof(udp6_ehash_secret));
 +      net_get_random_once(&udp_ipv6_hash_secret,
 +                          sizeof(udp_ipv6_hash_secret));
 +
 +      lhash = (__force u32)laddr->s6_addr32[3];
 +      fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
 +
 +      return __inet6_ehashfn(lhash, lport, fhash, fport,
 +                             udp_ipv6_hash_secret + net_hash_mix(net));
 +}
 +
  int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
  {
 -      const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
        const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
 -      __be32 sk1_rcv_saddr = sk_rcv_saddr(sk);
 -      __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2);
        int sk_ipv6only = ipv6_only_sock(sk);
        int sk2_ipv6only = inet_v6_ipv6only(sk2);
 -      int addr_type = ipv6_addr_type(sk_rcv_saddr6);
 +      int addr_type = ipv6_addr_type(&sk->sk_v6_rcv_saddr);
        int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
  
        /* if both are mapped, treat as IPv4 */
        if (addr_type == IPV6_ADDR_MAPPED && addr_type2 == IPV6_ADDR_MAPPED)
                return (!sk2_ipv6only &&
 -                      (!sk1_rcv_saddr || !sk2_rcv_saddr ||
 -                        sk1_rcv_saddr == sk2_rcv_saddr));
 +                      (!sk->sk_rcv_saddr || !sk2->sk_rcv_saddr ||
 +                        sk->sk_rcv_saddr == sk2->sk_rcv_saddr));
  
        if (addr_type2 == IPV6_ADDR_ANY &&
            !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
@@@ -99,7 -79,7 +99,7 @@@
                return 1;
  
        if (sk2_rcv_saddr6 &&
 -          ipv6_addr_equal(sk_rcv_saddr6, sk2_rcv_saddr6))
 +          ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6))
                return 1;
  
        return 0;
@@@ -127,7 -107,7 +127,7 @@@ int udp_v6_get_port(struct sock *sk, un
        unsigned int hash2_nulladdr =
                udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
        unsigned int hash2_partial =
 -              udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0);
 +              udp6_portaddr_hash(sock_net(sk), &sk->sk_v6_rcv_saddr, 0);
  
        /* precompute partial secondary hash */
        udp_sk(sk)->udp_portaddr_hash = hash2_partial;
  static void udp_v6_rehash(struct sock *sk)
  {
        u16 new_hash = udp6_portaddr_hash(sock_net(sk),
 -                                        &inet6_sk(sk)->rcv_saddr,
 +                                        &sk->sk_v6_rcv_saddr,
                                          inet_sk(sk)->inet_num);
  
        udp_lib_rehash(sk, new_hash);
@@@ -153,6 -133,7 +153,6 @@@ static inline int compute_score(struct 
  
        if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
                        sk->sk_family == PF_INET6) {
 -              struct ipv6_pinfo *np = inet6_sk(sk);
                struct inet_sock *inet = inet_sk(sk);
  
                score = 0;
                                return -1;
                        score++;
                }
 -              if (!ipv6_addr_any(&np->rcv_saddr)) {
 -                      if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
 +              if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
 +                      if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
                                return -1;
                        score++;
                }
 -              if (!ipv6_addr_any(&np->daddr)) {
 -                      if (!ipv6_addr_equal(&np->daddr, saddr))
 +              if (!ipv6_addr_any(&sk->sk_v6_daddr)) {
 +                      if (!ipv6_addr_equal(&sk->sk_v6_daddr, saddr))
                                return -1;
                        score++;
                }
@@@ -190,9 -171,10 +190,9 @@@ static inline int compute_score2(struc
  
        if (net_eq(sock_net(sk), net) && udp_sk(sk)->udp_port_hash == hnum &&
                        sk->sk_family == PF_INET6) {
 -              struct ipv6_pinfo *np = inet6_sk(sk);
                struct inet_sock *inet = inet_sk(sk);
  
 -              if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
 +              if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr))
                        return -1;
                score = 0;
                if (inet->inet_dport) {
                                return -1;
                        score++;
                }
 -              if (!ipv6_addr_any(&np->daddr)) {
 -                      if (!ipv6_addr_equal(&np->daddr, saddr))
 +              if (!ipv6_addr_any(&sk->sk_v6_daddr)) {
 +                      if (!ipv6_addr_equal(&sk->sk_v6_daddr, saddr))
                                return -1;
                        score++;
                }
@@@ -237,8 -219,8 +237,8 @@@ begin
                        badness = score;
                        reuseport = sk->sk_reuseport;
                        if (reuseport) {
 -                              hash = inet6_ehashfn(net, daddr, hnum,
 -                                                   saddr, sport);
 +                              hash = udp6_ehashfn(net, daddr, hnum,
 +                                                  saddr, sport);
                                matches = 1;
                        } else if (score == SCORE2_MAX)
                                goto exact_match;
@@@ -318,8 -300,8 +318,8 @@@ begin
                        badness = score;
                        reuseport = sk->sk_reuseport;
                        if (reuseport) {
 -                              hash = inet6_ehashfn(net, daddr, hnum,
 -                                                   saddr, sport);
 +                              hash = udp6_ehashfn(net, daddr, hnum,
 +                                                  saddr, sport);
                                matches = 1;
                        }
                } else if (score == badness && reuseport) {
@@@ -569,10 -551,8 +569,10 @@@ static int __udpv6_queue_rcv_skb(struc
  {
        int rc;
  
 -      if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
 +      if (!ipv6_addr_any(&sk->sk_v6_daddr)) {
                sock_rps_save_rxhash(sk, skb);
 +              sk_mark_napi_id(sk, skb);
 +      }
  
        rc = sock_queue_rcv_skb(sk, skb);
        if (rc < 0) {
@@@ -710,19 -690,20 +710,19 @@@ static struct sock *udp_v6_mcast_next(s
  
                if (udp_sk(s)->udp_port_hash == num &&
                    s->sk_family == PF_INET6) {
 -                      struct ipv6_pinfo *np = inet6_sk(s);
                        if (inet->inet_dport) {
                                if (inet->inet_dport != rmt_port)
                                        continue;
                        }
 -                      if (!ipv6_addr_any(&np->daddr) &&
 -                          !ipv6_addr_equal(&np->daddr, rmt_addr))
 +                      if (!ipv6_addr_any(&sk->sk_v6_daddr) &&
 +                          !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
                                continue;
  
                        if (s->sk_bound_dev_if && s->sk_bound_dev_if != dif)
                                continue;
  
 -                      if (!ipv6_addr_any(&np->rcv_saddr)) {
 -                              if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr))
 +                      if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
 +                              if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr))
                                        continue;
                        }
                        if (!inet6_mc_check(s, loc_addr, rmt_addr))
@@@ -865,6 -846,7 +865,6 @@@ int __udp6_lib_rcv(struct sk_buff *skb
        if (sk != NULL) {
                int ret;
  
 -              sk_mark_napi_id(sk, skb);
                ret = udpv6_queue_rcv_skb(sk, skb);
                sock_put(sk);
  
@@@ -1082,7 -1064,7 +1082,7 @@@ int udpv6_sendmsg(struct kiocb *iocb, s
        } else if (!up->pending) {
                if (sk->sk_state != TCP_ESTABLISHED)
                        return -EDESTADDRREQ;
 -              daddr = &np->daddr;
 +              daddr = &sk->sk_v6_daddr;
        } else
                daddr = NULL;
  
@@@ -1152,8 -1134,8 +1152,8 @@@ do_udp_sendmsg
                 * sk->sk_dst_cache.
                 */
                if (sk->sk_state == TCP_ESTABLISHED &&
 -                  ipv6_addr_equal(daddr, &np->daddr))
 -                      daddr = &np->daddr;
 +                  ipv6_addr_equal(daddr, &sk->sk_v6_daddr))
 +                      daddr = &sk->sk_v6_daddr;
  
                if (addr_len >= sizeof(struct sockaddr_in6) &&
                    sin6->sin6_scope_id &&
                        return -EDESTADDRREQ;
  
                fl6.fl6_dport = inet->inet_dport;
 -              daddr = &np->daddr;
 +              daddr = &sk->sk_v6_daddr;
                fl6.flowlabel = np->flow_label;
                connected = 1;
        }
        if (tclass < 0)
                tclass = np->tclass;
  
-       if (dontfrag < 0)
-               dontfrag = np->dontfrag;
        if (msg->msg_flags&MSG_CONFIRM)
                goto do_confirm;
  back_from_confirm:
        up->pending = AF_INET6;
  
  do_append_data:
+       if (dontfrag < 0)
+               dontfrag = np->dontfrag;
        up->len += ulen;
        getfrag  =  is_udplite ?  udplite_getfrag : ip_generic_getfrag;
        err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
        if (dst) {
                if (connected) {
                        ip6_dst_store(sk, dst,
 -                                    ipv6_addr_equal(&fl6.daddr, &np->daddr) ?
 -                                    &np->daddr : NULL,
 +                                    ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
 +                                    &sk->sk_v6_daddr : NULL,
  #ifdef CONFIG_IPV6_SUBTREES
                                      ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
                                      &np->saddr :
diff --combined net/l2tp/l2tp_ppp.c
index f0a7adaef2ea59d60c07f5b37c06ed9cd696f81c,8c46b271064a43607190198e76c1e1ff4c540396..ffda81ef1a709df605ef128ebc866cb00c75fe32
@@@ -353,7 -353,9 +353,9 @@@ static int pppol2tp_sendmsg(struct kioc
                goto error_put_sess_tun;
        }
  
+       local_bh_disable();
        l2tp_xmit_skb(session, skb, session->hdr_len);
+       local_bh_enable();
  
        sock_put(ps->tunnel_sock);
        sock_put(sk);
@@@ -422,7 -424,9 +424,9 @@@ static int pppol2tp_xmit(struct ppp_cha
        skb->data[0] = ppph[0];
        skb->data[1] = ppph[1];
  
+       local_bh_disable();
        l2tp_xmit_skb(session, skb, session->hdr_len);
+       local_bh_enable();
  
        sock_put(sk_tun);
        sock_put(sk);
@@@ -906,8 -910,8 +910,8 @@@ static int pppol2tp_getname(struct sock
  #if IS_ENABLED(CONFIG_IPV6)
        } else if ((tunnel->version == 2) &&
                   (tunnel->sock->sk_family == AF_INET6)) {
 -              struct ipv6_pinfo *np = inet6_sk(tunnel->sock);
                struct sockaddr_pppol2tpin6 sp;
 +
                len = sizeof(sp);
                memset(&sp, 0, len);
                sp.sa_family    = AF_PPPOX;
                sp.pppol2tp.d_session = session->peer_session_id;
                sp.pppol2tp.addr.sin6_family = AF_INET6;
                sp.pppol2tp.addr.sin6_port = inet->inet_dport;
 -              memcpy(&sp.pppol2tp.addr.sin6_addr, &np->daddr,
 -                     sizeof(np->daddr));
 +              memcpy(&sp.pppol2tp.addr.sin6_addr, &tunnel->sock->sk_v6_daddr,
 +                     sizeof(tunnel->sock->sk_v6_daddr));
                memcpy(uaddr, &sp, len);
        } else if ((tunnel->version == 3) &&
                   (tunnel->sock->sk_family == AF_INET6)) {
 -              struct ipv6_pinfo *np = inet6_sk(tunnel->sock);
                struct sockaddr_pppol2tpv3in6 sp;
 +
                len = sizeof(sp);
                memset(&sp, 0, len);
                sp.sa_family    = AF_PPPOX;
                sp.pppol2tp.d_session = session->peer_session_id;
                sp.pppol2tp.addr.sin6_family = AF_INET6;
                sp.pppol2tp.addr.sin6_port = inet->inet_dport;
 -              memcpy(&sp.pppol2tp.addr.sin6_addr, &np->daddr,
 -                     sizeof(np->daddr));
 +              memcpy(&sp.pppol2tp.addr.sin6_addr, &tunnel->sock->sk_v6_daddr,
 +                     sizeof(tunnel->sock->sk_v6_daddr));
                memcpy(uaddr, &sp, len);
  #endif
        } else if (tunnel->version == 3) {
diff --combined net/mac80211/cfg.c
index ac28af74a41410abceed9884a9388d9cb37784cb,629dee7ec9bfbae6dc0f00cdaf91b58968980c99..b0a651cc389fdab807b2a8b800f63144d0eaeb2f
@@@ -2865,43 -2865,30 +2865,43 @@@ void ieee80211_csa_finalize_work(struc
        if (!ieee80211_sdata_running(sdata))
                return;
  
 -      if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP))
 -              return;
 -
        sdata->radar_required = sdata->csa_radar_required;
        err = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
                                           &changed);
        if (WARN_ON(err < 0))
                return;
  
 -      err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
 -      if (err < 0)
 -              return;
 +      if (!local->use_chanctx) {
 +              local->_oper_chandef = local->csa_chandef;
 +              ieee80211_hw_config(local, 0);
 +      }
  
 -      changed |= err;
 -      kfree(sdata->u.ap.next_beacon);
 -      sdata->u.ap.next_beacon = NULL;
 +      ieee80211_bss_info_change_notify(sdata, changed);
 +
 +      switch (sdata->vif.type) {
 +      case NL80211_IFTYPE_AP:
 +              err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
 +              if (err < 0)
 +                      return;
 +              changed |= err;
 +              kfree(sdata->u.ap.next_beacon);
 +              sdata->u.ap.next_beacon = NULL;
 +
 +              ieee80211_bss_info_change_notify(sdata, err);
 +              break;
 +      case NL80211_IFTYPE_ADHOC:
 +              ieee80211_ibss_finish_csa(sdata);
 +              break;
 +      default:
 +              WARN_ON(1);
 +              return;
 +      }
        sdata->vif.csa_active = false;
  
        ieee80211_wake_queues_by_reason(&sdata->local->hw,
                                        IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_CSA);
  
 -      ieee80211_bss_info_change_notify(sdata, changed);
 -
        cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef);
  }
  
@@@ -2949,56 -2936,20 +2949,56 @@@ static int ieee80211_channel_switch(str
        if (sdata->vif.csa_active)
                return -EBUSY;
  
 -      /* only handle AP for now. */
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_AP:
 +              sdata->csa_counter_offset_beacon =
 +                      params->counter_offset_beacon;
 +              sdata->csa_counter_offset_presp = params->counter_offset_presp;
 +              sdata->u.ap.next_beacon =
 +                      cfg80211_beacon_dup(&params->beacon_after);
 +              if (!sdata->u.ap.next_beacon)
 +                      return -ENOMEM;
 +
 +              err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
 +              if (err < 0) {
 +                      kfree(sdata->u.ap.next_beacon);
 +                      return err;
 +              }
 +              break;
 +      case NL80211_IFTYPE_ADHOC:
 +              if (!sdata->vif.bss_conf.ibss_joined)
 +                      return -EINVAL;
 +
 +              if (params->chandef.width != sdata->u.ibss.chandef.width)
 +                      return -EINVAL;
 +
 +              switch (params->chandef.width) {
 +              case NL80211_CHAN_WIDTH_40:
 +                      if (cfg80211_get_chandef_type(&params->chandef) !=
 +                          cfg80211_get_chandef_type(&sdata->u.ibss.chandef))
 +                              return -EINVAL;
 +              case NL80211_CHAN_WIDTH_5:
 +              case NL80211_CHAN_WIDTH_10:
 +              case NL80211_CHAN_WIDTH_20_NOHT:
 +              case NL80211_CHAN_WIDTH_20:
 +                      break;
 +              default:
 +                      return -EINVAL;
 +              }
 +
 +              /* changes into another band are not supported */
 +              if (sdata->u.ibss.chandef.chan->band !=
 +                  params->chandef.chan->band)
 +                      return -EINVAL;
 +
 +              err = ieee80211_ibss_csa_beacon(sdata, params);
 +              if (err < 0)
 +                      return err;
                break;
        default:
                return -EOPNOTSUPP;
        }
  
 -      sdata->u.ap.next_beacon = cfg80211_beacon_dup(&params->beacon_after);
 -      if (!sdata->u.ap.next_beacon)
 -              return -ENOMEM;
 -
 -      sdata->csa_counter_offset_beacon = params->counter_offset_beacon;
 -      sdata->csa_counter_offset_presp = params->counter_offset_presp;
        sdata->csa_radar_required = params->radar_required;
  
        if (params->block_tx)
                                IEEE80211_MAX_QUEUE_MAP,
                                IEEE80211_QUEUE_STOP_REASON_CSA);
  
 -      err = ieee80211_assign_beacon(sdata, &params->beacon_csa);
 -      if (err < 0)
 -              return err;
 -
        local->csa_chandef = params->chandef;
        sdata->vif.csa_active = true;
  
@@@ -3059,8 -3014,7 +3059,8 @@@ static int ieee80211_mgmt_tx(struct wip
                        need_offchan = true;
                if (!ieee80211_is_action(mgmt->frame_control) ||
                    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
 -                  mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED)
 +                  mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED ||
 +                  mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT)
                        break;
                rcu_read_lock();
                sta = sta_info_get(sdata, mgmt->da);
@@@ -3564,7 -3518,7 +3564,7 @@@ static int ieee80211_probe_client(struc
                return -EINVAL;
        }
        band = chanctx_conf->def.chan->band;
-       sta = sta_info_get(sdata, peer);
+       sta = sta_info_get_bss(sdata, peer);
        if (sta) {
                qos = test_sta_flag(sta, WLAN_STA_WME);
        } else {
index 3a87c8976a320473a5155f5963109b4319954f7f,611abfcfb5ebba3c135edbcf8b2efb4a47f38374..e73cd0637f3b754bc1e2755f3c5aea211a175918
@@@ -322,6 -322,7 +322,6 @@@ struct ieee80211_roc_work 
  
  /* flags used in struct ieee80211_if_managed.flags */
  enum ieee80211_sta_flags {
 -      IEEE80211_STA_BEACON_POLL       = BIT(0),
        IEEE80211_STA_CONNECTION_POLL   = BIT(1),
        IEEE80211_STA_CONTROL_PORT      = BIT(2),
        IEEE80211_STA_DISABLE_HT        = BIT(4),
@@@ -486,7 -487,6 +486,7 @@@ struct ieee80211_if_managed 
  
  struct ieee80211_if_ibss {
        struct timer_list timer;
 +      struct work_struct csa_connection_drop_work;
  
        unsigned long last_scan_completed;
  
@@@ -893,6 -893,8 +893,8 @@@ struct tpt_led_trigger 
   *    that the scan completed.
   * @SCAN_ABORTED: Set for our scan work function when the driver reported
   *    a scan complete for an aborted scan.
+  * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
+  *    cancelled.
   */
  enum {
        SCAN_SW_SCANNING,
        SCAN_ONCHANNEL_SCANNING,
        SCAN_COMPLETED,
        SCAN_ABORTED,
+       SCAN_HW_CANCELLED,
  };
  
  /**
@@@ -1330,10 -1333,6 +1333,10 @@@ int ieee80211_ibss_leave(struct ieee802
  void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
  void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                                   struct sk_buff *skb);
 +int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
 +                            struct cfg80211_csa_settings *csa_settings);
 +int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata);
 +void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
  
  /* mesh code */
  void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
@@@ -1485,29 -1484,6 +1488,29 @@@ void ieee80211_apply_vhtcap_overrides(s
  void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
                                       struct ieee80211_mgmt *mgmt,
                                       size_t len);
 +/**
 + * ieee80211_parse_ch_switch_ie - parses channel switch IEs
 + * @sdata: the sdata of the interface which has received the frame
 + * @elems: parsed 802.11 elements received with the frame
 + * @beacon: indicates if the frame was a beacon or probe response
 + * @current_band: indicates the current band
 + * @sta_flags: contains information about own capabilities and restrictions
 + *    to decide which channel switch announcements can be accepted. Only the
 + *    following subset of &enum ieee80211_sta_flags are evaluated:
 + *    %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
 + *    %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
 + *    %IEEE80211_STA_DISABLE_160MHZ.
 + * @count: to be filled with the counter until the switch (on success only)
 + * @bssid: the currently connected bssid (for reporting)
 + * @mode: to be filled with CSA mode (on success only)
 + * @new_chandef: to be filled with destination chandef (on success only)
 + * Return: 0 on success, <0 on error and >0 if there is nothing to parse.
 + */
 +int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
 +                               struct ieee802_11_elems *elems, bool beacon,
 +                               enum ieee80211_band current_band,
 +                               u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
 +                               struct cfg80211_chan_def *new_chandef);
  
  /* Suspend/resume and hw reconfiguration */
  int ieee80211_reconfig(struct ieee80211_local *local);
@@@ -1681,7 -1657,6 +1684,7 @@@ int ieee80211_add_ext_srates_ie(struct 
  void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
                                  const struct ieee80211_ht_operation *ht_oper,
                                  struct cfg80211_chan_def *chandef);
 +u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c);
  
  int __must_check
  ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
diff --combined net/mac80211/scan.c
index ecb57b0bf74a19153ab0ed196fe1ae4f7e272c64,d2d17a4492245953413c5742d22d2af9e15fd74d..5ad66a83ef7f4d4525de163c2c2f1fe9d6931a04
@@@ -238,6 -238,9 +238,9 @@@ static bool ieee80211_prep_hw_scan(stru
        enum ieee80211_band band;
        int i, ielen, n_chans;
  
+       if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
+               return false;
        do {
                if (local->hw_scan_band == IEEE80211_NUM_BANDS)
                        return false;
@@@ -391,7 -394,8 +394,7 @@@ static bool ieee80211_can_scan(struct i
                return false;
  
        if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 -          sdata->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
 -                                IEEE80211_STA_CONNECTION_POLL))
 +          sdata->u.mgd.flags & IEEE80211_STA_CONNECTION_POLL)
                return false;
  
        return true;
@@@ -939,7 -943,23 +942,23 @@@ void ieee80211_scan_cancel(struct ieee8
        if (!local->scan_req)
                goto out;
  
+       /*
+        * We have a scan running and the driver already reported completion,
+        * but the worker hasn't run yet or is stuck on the mutex - mark it as
+        * cancelled.
+        */
+       if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
+           test_bit(SCAN_COMPLETED, &local->scanning)) {
+               set_bit(SCAN_HW_CANCELLED, &local->scanning);
+               goto out;
+       }
        if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
+               /*
+                * Make sure that __ieee80211_scan_completed doesn't trigger a
+                * scan on another band.
+                */
+               set_bit(SCAN_HW_CANCELLED, &local->scanning);
                if (local->ops->cancel_hw_scan)
                        drv_cancel_hw_scan(local,
                                rcu_dereference_protected(local->scan_sdata,
diff --combined net/mac80211/tx.c
index 4fcbf634b54863387f85b42d5f47f82de861e995,70b5a05c0a4e12b8cb36252465171ffbc7ef1686..9993fcb19ecdd8b97ea0c1fe1221f916dfd24e7f
@@@ -1120,7 -1120,8 +1120,8 @@@ ieee80211_tx_prepare(struct ieee80211_s
                tx->sta = rcu_dereference(sdata->u.vlan.sta);
                if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
                        return TX_DROP;
-       } else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
+       } else if (info->flags & (IEEE80211_TX_CTL_INJECTED |
+                                 IEEE80211_TX_INTFL_NL80211_FRAME_TX) ||
                   tx->sdata->control_port_protocol == tx->skb->protocol) {
                tx->sta = sta_info_get_bss(sdata, hdr->addr1);
        }
@@@ -1981,7 -1982,7 +1982,7 @@@ netdev_tx_t ieee80211_subif_start_xmit(
         * EAPOL frames from the local station.
         */
        if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
 -                   !is_multicast_ether_addr(hdr.addr1) && !authorized &&
 +                   !multicast && !authorized &&
                     (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
                      !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
  #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@@ -2357,31 -2358,15 +2358,31 @@@ static void ieee80211_update_csa(struc
        struct probe_resp *resp;
        int counter_offset_beacon = sdata->csa_counter_offset_beacon;
        int counter_offset_presp = sdata->csa_counter_offset_presp;
 +      u8 *beacon_data;
 +      size_t beacon_data_len;
 +
 +      switch (sdata->vif.type) {
 +      case NL80211_IFTYPE_AP:
 +              beacon_data = beacon->tail;
 +              beacon_data_len = beacon->tail_len;
 +              break;
 +      case NL80211_IFTYPE_ADHOC:
 +              beacon_data = beacon->head;
 +              beacon_data_len = beacon->head_len;
 +              break;
 +      default:
 +              return;
 +      }
 +      if (WARN_ON(counter_offset_beacon >= beacon_data_len))
 +              return;
  
        /* warn if the driver did not check for/react to csa completeness */
 -      if (WARN_ON(((u8 *)beacon->tail)[counter_offset_beacon] == 0))
 +      if (WARN_ON(beacon_data[counter_offset_beacon] == 0))
                return;
  
 -      ((u8 *)beacon->tail)[counter_offset_beacon]--;
 +      beacon_data[counter_offset_beacon]--;
  
 -      if (sdata->vif.type == NL80211_IFTYPE_AP &&
 -          counter_offset_presp) {
 +      if (sdata->vif.type == NL80211_IFTYPE_AP && counter_offset_presp) {
                rcu_read_lock();
                resp = rcu_dereference(sdata->u.ap.probe_resp);
  
@@@ -2416,15 -2401,6 +2417,15 @@@ bool ieee80211_csa_is_complete(struct i
                        goto out;
                beacon_data = beacon->tail;
                beacon_data_len = beacon->tail_len;
 +      } else if (vif->type == NL80211_IFTYPE_ADHOC) {
 +              struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 +
 +              beacon = rcu_dereference(ifibss->presp);
 +              if (!beacon)
 +                      goto out;
 +
 +              beacon_data = beacon->head;
 +              beacon_data_len = beacon->head_len;
        } else {
                WARN_ON(1);
                goto out;
@@@ -2509,10 -2485,6 +2510,10 @@@ struct sk_buff *ieee80211_beacon_get_ti
                if (!presp)
                        goto out;
  
 +              if (sdata->vif.csa_active)
 +                      ieee80211_update_csa(sdata, presp);
 +
 +
                skb = dev_alloc_skb(local->tx_headroom + presp->head_len);
                if (!skb)
                        goto out;
diff --combined net/mac80211/util.c
index 1220f5afdb7e9c787506310810d1e18b280bb16e,69e4ef5348a0e916b76fa87de9d83402ec99a5e4..aefb9d5b962023eb59b750f867de6733eb1c142b
@@@ -567,15 -567,18 +567,15 @@@ void ieee80211_flush_queues(struct ieee
                                        IEEE80211_QUEUE_STOP_REASON_FLUSH);
  }
  
 -void ieee80211_iterate_active_interfaces(
 -      struct ieee80211_hw *hw, u32 iter_flags,
 -      void (*iterator)(void *data, u8 *mac,
 -                       struct ieee80211_vif *vif),
 -      void *data)
 +static void __iterate_active_interfaces(struct ieee80211_local *local,
 +                                      u32 iter_flags,
 +                                      void (*iterator)(void *data, u8 *mac,
 +                                              struct ieee80211_vif *vif),
 +                                      void *data)
  {
 -      struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
  
 -      mutex_lock(&local->iflist_mtx);
 -
 -      list_for_each_entry(sdata, &local->interfaces, list) {
 +      list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_MONITOR:
                        if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
                                 &sdata->vif);
        }
  
 -      sdata = rcu_dereference_protected(local->monitor_sdata,
 -                                        lockdep_is_held(&local->iflist_mtx));
 +      sdata = rcu_dereference_check(local->monitor_sdata,
 +                                    lockdep_is_held(&local->iflist_mtx) ||
 +                                    lockdep_rtnl_is_held());
        if (sdata &&
            (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
             sdata->flags & IEEE80211_SDATA_IN_DRIVER))
                iterator(data, sdata->vif.addr, &sdata->vif);
 +}
 +
 +void ieee80211_iterate_active_interfaces(
 +      struct ieee80211_hw *hw, u32 iter_flags,
 +      void (*iterator)(void *data, u8 *mac,
 +                       struct ieee80211_vif *vif),
 +      void *data)
 +{
 +      struct ieee80211_local *local = hw_to_local(hw);
  
 +      mutex_lock(&local->iflist_mtx);
 +      __iterate_active_interfaces(local, iter_flags, iterator, data);
        mutex_unlock(&local->iflist_mtx);
  }
  EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
@@@ -624,26 -615,38 +624,26 @@@ void ieee80211_iterate_active_interface
        void *data)
  {
        struct ieee80211_local *local = hw_to_local(hw);
 -      struct ieee80211_sub_if_data *sdata;
  
        rcu_read_lock();
 +      __iterate_active_interfaces(local, iter_flags, iterator, data);
 +      rcu_read_unlock();
 +}
 +EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
  
 -      list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 -              switch (sdata->vif.type) {
 -              case NL80211_IFTYPE_MONITOR:
 -                      if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
 -                              continue;
 -                      break;
 -              case NL80211_IFTYPE_AP_VLAN:
 -                      continue;
 -              default:
 -                      break;
 -              }
 -              if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
 -                  !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
 -                      continue;
 -              if (ieee80211_sdata_running(sdata))
 -                      iterator(data, sdata->vif.addr,
 -                               &sdata->vif);
 -      }
 +void ieee80211_iterate_active_interfaces_rtnl(
 +      struct ieee80211_hw *hw, u32 iter_flags,
 +      void (*iterator)(void *data, u8 *mac,
 +                       struct ieee80211_vif *vif),
 +      void *data)
 +{
 +      struct ieee80211_local *local = hw_to_local(hw);
  
 -      sdata = rcu_dereference(local->monitor_sdata);
 -      if (sdata &&
 -          (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL ||
 -           sdata->flags & IEEE80211_SDATA_IN_DRIVER))
 -              iterator(data, sdata->vif.addr, &sdata->vif);
 +      ASSERT_RTNL();
  
 -      rcu_read_unlock();
 +      __iterate_active_interfaces(local, iter_flags, iterator, data);
  }
 -EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
 +EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
  
  /*
   * Nothing should have been stuffed into the workqueue during
@@@ -1004,21 -1007,14 +1004,21 @@@ void ieee80211_set_wmm_default(struct i
         */
        enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION);
  
 -      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 -              /* Set defaults according to 802.11-2007 Table 7-37 */
 -              aCWmax = 1023;
 -              if (use_11b)
 -                      aCWmin = 31;
 -              else
 -                      aCWmin = 15;
 +      /* Set defaults according to 802.11-2007 Table 7-37 */
 +      aCWmax = 1023;
 +      if (use_11b)
 +              aCWmin = 31;
 +      else
 +              aCWmin = 15;
 +
 +      /* Confiure old 802.11b/g medium access rules. */
 +      qparam.cw_max = aCWmax;
 +      qparam.cw_min = aCWmin;
 +      qparam.txop = 0;
 +      qparam.aifs = 2;
  
 +      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 +              /* Update if QoS is enabled. */
                if (enable_qos) {
                        switch (ac) {
                        case IEEE80211_AC_BK:
                                qparam.aifs = 2;
                                break;
                        }
 -              } else {
 -                      /* Confiure old 802.11b/g medium access rules. */
 -                      qparam.cw_max = aCWmax;
 -                      qparam.cw_min = aCWmin;
 -                      qparam.txop = 0;
 -                      qparam.aifs = 2;
                }
  
                qparam.uapsd = false;
@@@ -1082,8 -1084,8 +1082,8 @@@ void ieee80211_send_auth(struct ieee802
        struct ieee80211_mgmt *mgmt;
        int err;
  
 -      skb = dev_alloc_skb(local->hw.extra_tx_headroom +
 -                          sizeof(*mgmt) + 6 + extra_len);
 +      /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
 +      skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24 + 6 + extra_len);
        if (!skb)
                return;
  
@@@ -2236,6 -2238,10 +2236,10 @@@ u64 ieee80211_calculate_rx_timestamp(st
        }
  
        rate = cfg80211_calculate_bitrate(&ri);
+       if (WARN_ONCE(!rate,
+                     "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+                     status->flag, status->rate_idx, status->vht_nss))
+               return 0;
  
        /* rewind from end of MPDU */
        if (status->flag & RX_FLAG_MACTIME_END)
@@@ -2290,63 -2296,3 +2294,63 @@@ void ieee80211_radar_detected(struct ie
        ieee80211_queue_work(hw, &local->radar_detected_work);
  }
  EXPORT_SYMBOL(ieee80211_radar_detected);
 +
 +u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
 +{
 +      u32 ret;
 +      int tmp;
 +
 +      switch (c->width) {
 +      case NL80211_CHAN_WIDTH_20:
 +              c->width = NL80211_CHAN_WIDTH_20_NOHT;
 +              ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
 +              break;
 +      case NL80211_CHAN_WIDTH_40:
 +              c->width = NL80211_CHAN_WIDTH_20;
 +              c->center_freq1 = c->chan->center_freq;
 +              ret = IEEE80211_STA_DISABLE_40MHZ |
 +                    IEEE80211_STA_DISABLE_VHT;
 +              break;
 +      case NL80211_CHAN_WIDTH_80:
 +              tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
 +              /* n_P40 */
 +              tmp /= 2;
 +              /* freq_P40 */
 +              c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
 +              c->width = NL80211_CHAN_WIDTH_40;
 +              ret = IEEE80211_STA_DISABLE_VHT;
 +              break;
 +      case NL80211_CHAN_WIDTH_80P80:
 +              c->center_freq2 = 0;
 +              c->width = NL80211_CHAN_WIDTH_80;
 +              ret = IEEE80211_STA_DISABLE_80P80MHZ |
 +                    IEEE80211_STA_DISABLE_160MHZ;
 +              break;
 +      case NL80211_CHAN_WIDTH_160:
 +              /* n_P20 */
 +              tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
 +              /* n_P80 */
 +              tmp /= 4;
 +              c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
 +              c->width = NL80211_CHAN_WIDTH_80;
 +              ret = IEEE80211_STA_DISABLE_80P80MHZ |
 +                    IEEE80211_STA_DISABLE_160MHZ;
 +              break;
 +      default:
 +      case NL80211_CHAN_WIDTH_20_NOHT:
 +              WARN_ON_ONCE(1);
 +              c->width = NL80211_CHAN_WIDTH_20_NOHT;
 +              ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
 +              break;
 +      case NL80211_CHAN_WIDTH_5:
 +      case NL80211_CHAN_WIDTH_10:
 +              WARN_ON_ONCE(1);
 +              /* keep c->width */
 +              ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
 +              break;
 +      }
 +
 +      WARN_ON_ONCE(!cfg80211_chandef_valid(c));
 +
 +      return ret;
 +}
diff --combined net/wireless/core.h
index 74beff1e926f732bf11679e802638ab20467ed2b,3159e9c284c5b10c3b7cd0cf4d384d278b0a6245..af10e59af2d86f418bd7cc4e69914c9bb31831c7
@@@ -234,10 -234,10 +234,10 @@@ struct cfg80211_beacon_registration 
  };
  
  /* free object */
 -extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
 +void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
  
 -extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 -                             char *newname);
 +int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 +                      char *newname);
  
  void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
  
@@@ -382,6 -382,15 +382,6 @@@ int cfg80211_can_use_iftype_chan(struc
                                 enum cfg80211_chan_mode chanmode,
                                 u8 radar_detect);
  
 -/**
 - * cfg80211_chandef_dfs_required - checks if radar detection is required
 - * @wiphy: the wiphy to validate against
 - * @chandef: the channel definition to check
 - * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
 - */
 -int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 -                                const struct cfg80211_chan_def *c);
 -
  void cfg80211_set_dfs_state(struct wiphy *wiphy,
                            const struct cfg80211_chan_def *chandef,
                            enum nl80211_dfs_state dfs_state);
@@@ -402,6 -411,9 +402,9 @@@ static inline in
  cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
                           enum nl80211_iftype iftype)
  {
+       if (rfkill_blocked(rdev->rfkill))
+               return -ERFKILL;
        return cfg80211_can_change_interface(rdev, NULL, iftype);
  }
  
diff --combined security/selinux/hooks.c
index 3f224d7795f5996850e47463a2a8f6381cb4509d,5b5231068516e46bb529efb3df38051124d2ef85..c540795fb3f2647619cb4705281872e93592e21e
@@@ -1502,7 -1502,7 +1502,7 @@@ static int cred_has_capability(const st
  
        rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
        if (audit == SECURITY_CAP_AUDIT) {
-               int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
+               int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad);
                if (rc2)
                        return rc2;
        }
@@@ -1525,8 -1525,7 +1525,7 @@@ static int task_has_system(struct task_
  static int inode_has_perm(const struct cred *cred,
                          struct inode *inode,
                          u32 perms,
-                         struct common_audit_data *adp,
-                         unsigned flags)
+                         struct common_audit_data *adp)
  {
        struct inode_security_struct *isec;
        u32 sid;
        sid = cred_sid(cred);
        isec = inode->i_security;
  
-       return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
+       return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
  }
  
  /* Same as inode_has_perm, but pass explicit audit data containing
@@@ -1554,7 -1553,7 +1553,7 @@@ static inline int dentry_has_perm(cons
  
        ad.type = LSM_AUDIT_DATA_DENTRY;
        ad.u.dentry = dentry;
-       return inode_has_perm(cred, inode, av, &ad, 0);
+       return inode_has_perm(cred, inode, av, &ad);
  }
  
  /* Same as inode_has_perm, but pass explicit audit data containing
@@@ -1569,7 -1568,7 +1568,7 @@@ static inline int path_has_perm(const s
  
        ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = *path;
-       return inode_has_perm(cred, inode, av, &ad, 0);
+       return inode_has_perm(cred, inode, av, &ad);
  }
  
  /* Same as path_has_perm, but uses the inode from the file struct. */
@@@ -1581,7 -1580,7 +1580,7 @@@ static inline int file_path_has_perm(co
  
        ad.type = LSM_AUDIT_DATA_PATH;
        ad.u.path = file->f_path;
-       return inode_has_perm(cred, file_inode(file), av, &ad, 0);
+       return inode_has_perm(cred, file_inode(file), av, &ad);
  }
  
  /* Check whether a task can use an open file descriptor to
@@@ -1617,7 -1616,7 +1616,7 @@@ static int file_has_perm(const struct c
        /* av is zero if only checking access to the descriptor. */
        rc = 0;
        if (av)
-               rc = inode_has_perm(cred, inode, av, &ad, 0);
+               rc = inode_has_perm(cred, inode, av, &ad);
  
  out:
        return rc;
@@@ -3929,7 -3928,7 +3928,7 @@@ static int selinux_socket_bind(struct s
                if (snum) {
                        int low, high;
  
 -                      inet_get_local_port_range(&low, &high);
 +                      inet_get_local_port_range(sock_net(sk), &low, &high);
  
                        if (snum < max(PROT_SOCK, low) || snum > high) {
                                err = sel_netport_sid(sk->sk_protocol,
@@@ -4668,7 -4667,7 +4667,7 @@@ static unsigned int selinux_ip_forward(
        return NF_ACCEPT;
  }
  
 -static unsigned int selinux_ipv4_forward(unsigned int hooknum,
 +static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
                                         struct sk_buff *skb,
                                         const struct net_device *in,
                                         const struct net_device *out,
  }
  
  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 -static unsigned int selinux_ipv6_forward(unsigned int hooknum,
 +static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
                                         struct sk_buff *skb,
                                         const struct net_device *in,
                                         const struct net_device *out,
@@@ -4710,7 -4709,7 +4709,7 @@@ static unsigned int selinux_ip_output(s
        return NF_ACCEPT;
  }
  
 -static unsigned int selinux_ipv4_output(unsigned int hooknum,
 +static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops,
                                        struct sk_buff *skb,
                                        const struct net_device *in,
                                        const struct net_device *out,
@@@ -4837,7 -4836,7 +4836,7 @@@ static unsigned int selinux_ip_postrout
        return NF_ACCEPT;
  }
  
 -static unsigned int selinux_ipv4_postroute(unsigned int hooknum,
 +static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
                                           struct sk_buff *skb,
                                           const struct net_device *in,
                                           const struct net_device *out,
  }
  
  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 -static unsigned int selinux_ipv6_postroute(unsigned int hooknum,
 +static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
                                           struct sk_buff *skb,
                                           const struct net_device *in,
                                           const struct net_device *out,