]> exis.tech > repos - linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <davem@davemloft.net>
Thu, 5 Sep 2013 18:58:52 +0000 (14:58 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 5 Sep 2013 18:58:52 +0000 (14:58 -0400)
Conflicts:
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
net/bridge/br_multicast.c
net/ipv6/sit.c

The conflicts were minor:

1) sit.c changes overlap with change to ip_tunnel_xmit() signature.

2) br_multicast.c had an overlap between computing max_delay using
   msecs_to_jiffies and turning MLDV2_MRC() into an inline function
   with a name using lowercase instead of uppercase letters.

3) stmmac had two overlapping changes, one which conditionally allocated
   and hooked up a dma_cfg based upon the presence of the pbl OF property,
   and another one handling store-and-forward DMA made.  The latter of
   which should not go into the new of_find_property() basic block.

Signed-off-by: David S. Miller <davem@davemloft.net>
33 files changed:
1  2 
MAINTAINERS
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
include/net/xfrm.h
net/bridge/br_device.c
net/bridge/br_mdb.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/core/flow_dissector.c
net/ipv4/ipip.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/icmp.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ndisc.c
net/ipv6/raw.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c

diff --combined MAINTAINERS
index ecb83cdf06c06b160b226bd0e26a625497abbcc7,b140c8123098324996ea813226eec34377ee651f..2e1be9906d0a90a2351755f811fce3cc7da05fe1
@@@ -2076,8 -2076,7 +2076,8 @@@ F:      drivers/usb/chipidea
  
  CISCO VIC ETHERNET NIC DRIVER
  M:    Christian Benvenuti <benve@cisco.com>
 -M:    Roopa Prabhu <roprabhu@cisco.com>
 +M:    Sujith Sankar <ssujith@cisco.com>
 +M:    Govindarajulu Varadarajan <govindarajulu90@gmail.com>
  M:    Neel Patel <neepatel@cisco.com>
  M:    Nishank Trivedi <nistrive@cisco.com>
  S:    Supported
@@@ -4366,7 -4365,7 +4366,7 @@@ F:      drivers/net/wireless/iwlegacy
  
  INTEL WIRELESS WIFI LINK (iwlwifi)
  M:    Johannes Berg <johannes.berg@intel.com>
 -M:    Wey-Yi Guy <wey-yi.w.guy@intel.com>
 +M:    Emmanuel Grumbach <emmanuel.grumbach@intel.com>
  M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
  W:    http://intellinuxwireless.org
@@@ -5793,7 -5792,7 +5793,7 @@@ M:      Aloisio Almeida Jr <aloisio.almeida@
  M:    Samuel Ortiz <sameo@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
  L:    linux-nfc@lists.01.org (moderated for non-subscribers)
 -S:    Maintained
 +S:    Supported
  F:    net/nfc/
  F:    include/net/nfc/
  F:    include/uapi/linux/nfc.h
@@@ -6067,7 -6066,7 +6067,7 @@@ M:      Rob Herring <rob.herring@calxeda.com
  M:    Pawel Moll <pawel.moll@arm.com>
  M:    Mark Rutland <mark.rutland@arm.com>
  M:    Stephen Warren <swarren@wwwdotorg.org>
- M:    Ian Campbell <ian.campbell@citrix.com>
+ M:    Ian Campbell <ijc+devicetree@hellion.org.uk>
  L:    devicetree@vger.kernel.org
  S:    Maintained
  F:    Documentation/devicetree/
@@@ -7237,7 -7236,6 +7237,7 @@@ W:      http://lksctp.sourceforge.ne
  S:    Maintained
  F:    Documentation/networking/sctp.txt
  F:    include/linux/sctp.h
 +F:    include/uapi/linux/sctp.h
  F:    include/net/sctp/
  F:    net/sctp/
  
@@@ -7974,12 -7972,6 +7974,12 @@@ F:    arch/m68k/sun3*
  F:    arch/m68k/include/asm/sun3*
  F:    drivers/net/ethernet/i825xx/sun3*
  
 +SUNDANCE NETWORK DRIVER
 +M:    Denis Kirjanov <kda@linux-powerpc.org>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/ethernet/dlink/sundance.c
 +
  SUPERH
  M:    Paul Mundt <lethal@linux-sh.org>
  L:    linux-sh@vger.kernel.org
index 8d726f6e1c5233c812c44648f9df007b696e7fa1,0cc26110868d409f00d551fbf1cc3c9c00a8b9bf..2361bf236ce302f112bd333014212d60d344dc28
@@@ -53,6 -53,7 +53,7 @@@ static inline void bnx2x_move_fp(struc
        struct bnx2x_fp_stats *to_fp_stats = &bp->fp_stats[to];
        int old_max_eth_txqs, new_max_eth_txqs;
        int old_txdata_index = 0, new_txdata_index = 0;
+       struct bnx2x_agg_info *old_tpa_info = to_fp->tpa_info;
  
        /* Copy the NAPI object as it has been already initialized */
        from_fp->napi = to_fp->napi;
        memcpy(to_fp, from_fp, sizeof(*to_fp));
        to_fp->index = to;
  
+       /* Retain the tpa_info of the original `to' version as we don't want
+        * 2 FPs to contain the same tpa_info pointer.
+        */
+       to_fp->tpa_info = old_tpa_info;
        /* move sp_objs contents as well, as their indices match fp ones */
        memcpy(to_sp_objs, from_sp_objs, sizeof(*to_sp_objs));
  
@@@ -1942,7 -1948,7 +1948,7 @@@ static void bnx2x_set_rx_buf_size(struc
        }
  }
  
 -static int bnx2x_init_rss_pf(struct bnx2x *bp)
 +static int bnx2x_init_rss(struct bnx2x *bp)
  {
        int i;
        u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp);
        return bnx2x_config_rss_eth(bp, bp->port.pmf || !CHIP_IS_E1x(bp));
  }
  
 -int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
 -                      bool config_hash)
 +int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
 +            bool config_hash, bool enable)
  {
        struct bnx2x_config_rss_params params = {NULL};
  
  
        __set_bit(RAMROD_COMP_WAIT, &params.ramrod_flags);
  
 -      __set_bit(BNX2X_RSS_MODE_REGULAR, &params.rss_flags);
 -
 -      /* RSS configuration */
 -      __set_bit(BNX2X_RSS_IPV4, &params.rss_flags);
 -      __set_bit(BNX2X_RSS_IPV4_TCP, &params.rss_flags);
 -      __set_bit(BNX2X_RSS_IPV6, &params.rss_flags);
 -      __set_bit(BNX2X_RSS_IPV6_TCP, &params.rss_flags);
 -      if (rss_obj->udp_rss_v4)
 -              __set_bit(BNX2X_RSS_IPV4_UDP, &params.rss_flags);
 -      if (rss_obj->udp_rss_v6)
 -              __set_bit(BNX2X_RSS_IPV6_UDP, &params.rss_flags);
 +      if (enable) {
 +              __set_bit(BNX2X_RSS_MODE_REGULAR, &params.rss_flags);
 +
 +              /* RSS configuration */
 +              __set_bit(BNX2X_RSS_IPV4, &params.rss_flags);
 +              __set_bit(BNX2X_RSS_IPV4_TCP, &params.rss_flags);
 +              __set_bit(BNX2X_RSS_IPV6, &params.rss_flags);
 +              __set_bit(BNX2X_RSS_IPV6_TCP, &params.rss_flags);
 +              if (rss_obj->udp_rss_v4)
 +                      __set_bit(BNX2X_RSS_IPV4_UDP, &params.rss_flags);
 +              if (rss_obj->udp_rss_v6)
 +                      __set_bit(BNX2X_RSS_IPV6_UDP, &params.rss_flags);
 +      } else {
 +              __set_bit(BNX2X_RSS_MODE_DISABLED, &params.rss_flags);
 +      }
  
        /* Hash bits */
        params.rss_result_mask = MULTI_MASK;
  
        if (config_hash) {
                /* RSS keys */
 -              prandom_bytes(params.rss_key, sizeof(params.rss_key));
 +              prandom_bytes(params.rss_key, T_ETH_RSS_KEY * 4);
                __set_bit(BNX2X_RSS_SET_SRCH, &params.rss_flags);
        }
  
 -      return bnx2x_config_rss(bp, &params);
 +      if (IS_PF(bp))
 +              return bnx2x_config_rss(bp, &params);
 +      else
 +              return bnx2x_vfpf_config_rss(bp, &params);
  }
  
  static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
@@@ -2067,11 -2066,7 +2073,11 @@@ void bnx2x_squeeze_objects(struct bnx2
        rparam.mcast_obj = &bp->mcast_obj;
        __set_bit(RAMROD_DRV_CLR_ONLY, &rparam.ramrod_flags);
  
 -      /* Add a DEL command... */
 +      /* Add a DEL command... - Since we're doing a driver cleanup only,
 +       * we take a lock surrounding both the initial send and the CONTs,
 +       * as we don't want a true completion to disrupt us in the middle.
 +       */
 +      netif_addr_lock_bh(bp->dev);
        rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);
        if (rc < 0)
                BNX2X_ERR("Failed to add a new DEL command to a multi-cast object: %d\n",
                if (rc < 0) {
                        BNX2X_ERR("Failed to clean multi-cast object: %d\n",
                                  rc);
 +                      netif_addr_unlock_bh(bp->dev);
                        return;
                }
  
                rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT);
        }
 +      netif_addr_unlock_bh(bp->dev);
  }
  
  #ifndef BNX2X_STOP_ON_ERROR
@@@ -2445,7 -2438,9 +2451,7 @@@ int bnx2x_load_cnic(struct bnx2x *bp
        }
  
        /* Initialize Rx filter. */
 -      netif_addr_lock_bh(bp->dev);
 -      bnx2x_set_rx_mode(bp->dev);
 -      netif_addr_unlock_bh(bp->dev);
 +      bnx2x_set_rx_mode_inner(bp);
  
        /* re-read iscsi info */
        bnx2x_get_iscsi_info(bp);
@@@ -2652,32 -2647,38 +2658,32 @@@ int bnx2x_nic_load(struct bnx2x *bp, in
  
                /* initialize FW coalescing state machines in RAM */
                bnx2x_update_coalesce(bp);
 +      }
  
 -              /* setup the leading queue */
 -              rc = bnx2x_setup_leading(bp);
 -              if (rc) {
 -                      BNX2X_ERR("Setup leading failed!\n");
 -                      LOAD_ERROR_EXIT(bp, load_error3);
 -              }
 -
 -              /* set up the rest of the queues */
 -              for_each_nondefault_eth_queue(bp, i) {
 -                      rc = bnx2x_setup_queue(bp, &bp->fp[i], 0);
 -                      if (rc) {
 -                              BNX2X_ERR("Queue setup failed\n");
 -                              LOAD_ERROR_EXIT(bp, load_error3);
 -                      }
 -              }
 +      /* setup the leading queue */
 +      rc = bnx2x_setup_leading(bp);
 +      if (rc) {
 +              BNX2X_ERR("Setup leading failed!\n");
 +              LOAD_ERROR_EXIT(bp, load_error3);
 +      }
  
 -              /* setup rss */
 -              rc = bnx2x_init_rss_pf(bp);
 +      /* set up the rest of the queues */
 +      for_each_nondefault_eth_queue(bp, i) {
 +              if (IS_PF(bp))
 +                      rc = bnx2x_setup_queue(bp, &bp->fp[i], false);
 +              else /* VF */
 +                      rc = bnx2x_vfpf_setup_q(bp, &bp->fp[i], false);
                if (rc) {
 -                      BNX2X_ERR("PF RSS init failed\n");
 +                      BNX2X_ERR("Queue %d setup failed\n", i);
                        LOAD_ERROR_EXIT(bp, load_error3);
                }
 +      }
  
 -      } else { /* vf */
 -              for_each_eth_queue(bp, i) {
 -                      rc = bnx2x_vfpf_setup_q(bp, i);
 -                      if (rc) {
 -                              BNX2X_ERR("Queue setup failed\n");
 -                              LOAD_ERROR_EXIT(bp, load_error3);
 -                      }
 -              }
 +      /* setup rss */
 +      rc = bnx2x_init_rss(bp);
 +      if (rc) {
 +              BNX2X_ERR("PF RSS init failed\n");
 +              LOAD_ERROR_EXIT(bp, load_error3);
        }
  
        /* Now when Clients are configured we are ready to work */
        /* Start fast path */
  
        /* Initialize Rx filter. */
 -      netif_addr_lock_bh(bp->dev);
 -      bnx2x_set_rx_mode(bp->dev);
 -      netif_addr_unlock_bh(bp->dev);
 +      bnx2x_set_rx_mode_inner(bp);
  
        /* Start the Tx */
        switch (load_mode) {
@@@ -2959,8 -2962,9 +2965,9 @@@ int bnx2x_nic_unload(struct bnx2x *bp, 
        if (IS_PF(bp)) {
                if (CNIC_LOADED(bp))
                        bnx2x_free_mem_cnic(bp);
-               bnx2x_free_mem(bp);
        }
+       bnx2x_free_mem(bp);
        bp->state = BNX2X_STATE_CLOSED;
        bp->cnic_loaded = false;
  
@@@ -4785,11 -4789,6 +4792,11 @@@ int bnx2x_resume(struct pci_dev *pdev
  void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt,
                              u32 cid)
  {
 +      if (!cxt) {
 +              BNX2X_ERR("bad context pointer %p\n", cxt);
 +              return;
 +      }
 +
        /* ustorm cxt validation */
        cxt->ustorm_ag_context.cdu_usage =
                CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, cid),
index c69990d2170e5a868e550b6bb6719f892c59e167,1627a4e09c32fd3980f7db8bbfc686621391b393..285f2a59a3a5c64f433acb87b6739146411e6d29
@@@ -6893,7 -6893,7 +6893,7 @@@ static int bnx2x_init_hw_common(struct 
                bnx2x_init_block(bp, BLOCK_TM, PHASE_COMMON);
  
        bnx2x_init_block(bp, BLOCK_DORQ, PHASE_COMMON);
 -      REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT);
 +
        if (!CHIP_REV_IS_SLOW(bp))
                /* enable hw interrupt from doorbell Q */
                REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
@@@ -7855,12 -7855,15 +7855,15 @@@ void bnx2x_free_mem(struct bnx2x *bp
  {
        int i;
  
-       BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
-                      sizeof(struct host_sp_status_block));
        BNX2X_PCI_FREE(bp->fw_stats, bp->fw_stats_mapping,
                       bp->fw_stats_data_sz + bp->fw_stats_req_sz);
  
+       if (IS_VF(bp))
+               return;
+       BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
+                      sizeof(struct host_sp_status_block));
        BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
                       sizeof(struct bnx2x_slowpath));
  
@@@ -8060,10 -8063,7 +8063,10 @@@ int bnx2x_set_eth_mac(struct bnx2x *bp
  
  int bnx2x_setup_leading(struct bnx2x *bp)
  {
 -      return bnx2x_setup_queue(bp, &bp->fp[0], 1);
 +      if (IS_PF(bp))
 +              return bnx2x_setup_queue(bp, &bp->fp[0], true);
 +      else /* VF */
 +              return bnx2x_vfpf_setup_q(bp, &bp->fp[0], true);
  }
  
  /**
@@@ -8077,10 -8077,8 +8080,10 @@@ int bnx2x_set_int_mode(struct bnx2x *bp
  {
        int rc = 0;
  
 -      if (IS_VF(bp) && int_mode != BNX2X_INT_MODE_MSIX)
 +      if (IS_VF(bp) && int_mode != BNX2X_INT_MODE_MSIX) {
 +              BNX2X_ERR("VF not loaded since interrupt mode not msix\n");
                return -EINVAL;
 +      }
  
        switch (int_mode) {
        case BNX2X_INT_MODE_MSIX:
@@@ -9649,9 -9647,11 +9652,9 @@@ sp_rtnl_not_reset
                }
        }
  
 -      if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
 -                             &bp->sp_rtnl_state)) {
 -              DP(BNX2X_MSG_SP,
 -                 "sending set storm rx mode vf pf channel message from rtnl sp-task\n");
 -              bnx2x_vfpf_storm_rx_mode(bp);
 +      if (test_and_clear_bit(BNX2X_SP_RTNL_RX_MODE, &bp->sp_rtnl_state)) {
 +              DP(BNX2X_MSG_SP, "Handling Rx Mode setting\n");
 +              bnx2x_set_rx_mode_inner(bp);
        }
  
        if (test_and_clear_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN,
@@@ -11663,11 -11663,9 +11666,11 @@@ static int bnx2x_init_bp(struct bnx2x *
         * second status block for the L2 queue, and a third status block for
         * CNIC if supported.
         */
 -      if (CNIC_SUPPORT(bp))
 +      if (IS_VF(bp))
 +              bp->min_msix_vec_cnt = 1;
 +      else if (CNIC_SUPPORT(bp))
                bp->min_msix_vec_cnt = 3;
 -      else
 +      else /* PF w/o cnic */
                bp->min_msix_vec_cnt = 2;
        BNX2X_DEV_INFO("bp->min_msix_vec_cnt %d", bp->min_msix_vec_cnt);
  
@@@ -11884,48 -11882,34 +11887,48 @@@ static int bnx2x_set_mc_list(struct bnx
  void bnx2x_set_rx_mode(struct net_device *dev)
  {
        struct bnx2x *bp = netdev_priv(dev);
 -      u32 rx_mode = BNX2X_RX_MODE_NORMAL;
  
        if (bp->state != BNX2X_STATE_OPEN) {
                DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
                return;
 +      } else {
 +              /* Schedule an SP task to handle rest of change */
 +              DP(NETIF_MSG_IFUP, "Scheduling an Rx mode change\n");
 +              smp_mb__before_clear_bit();
 +              set_bit(BNX2X_SP_RTNL_RX_MODE, &bp->sp_rtnl_state);
 +              smp_mb__after_clear_bit();
 +              schedule_delayed_work(&bp->sp_rtnl_task, 0);
        }
 +}
 +
 +void bnx2x_set_rx_mode_inner(struct bnx2x *bp)
 +{
 +      u32 rx_mode = BNX2X_RX_MODE_NORMAL;
  
        DP(NETIF_MSG_IFUP, "dev->flags = %x\n", bp->dev->flags);
  
 -      if (dev->flags & IFF_PROMISC)
 +      netif_addr_lock_bh(bp->dev);
 +
 +      if (bp->dev->flags & IFF_PROMISC) {
                rx_mode = BNX2X_RX_MODE_PROMISC;
 -      else if ((dev->flags & IFF_ALLMULTI) ||
 -               ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) &&
 -                CHIP_IS_E1(bp)))
 +      } else if ((bp->dev->flags & IFF_ALLMULTI) ||
 +                 ((netdev_mc_count(bp->dev) > BNX2X_MAX_MULTICAST) &&
 +                  CHIP_IS_E1(bp))) {
                rx_mode = BNX2X_RX_MODE_ALLMULTI;
 -      else {
 +      else {
                if (IS_PF(bp)) {
                        /* some multicasts */
                        if (bnx2x_set_mc_list(bp) < 0)
                                rx_mode = BNX2X_RX_MODE_ALLMULTI;
  
 +                      /* release bh lock, as bnx2x_set_uc_list might sleep */
 +                      netif_addr_unlock_bh(bp->dev);
                        if (bnx2x_set_uc_list(bp) < 0)
                                rx_mode = BNX2X_RX_MODE_PROMISC;
 +                      netif_addr_lock_bh(bp->dev);
                } else {
                        /* configuring mcast to a vf involves sleeping (when we
 -                       * wait for the pf's response). Since this function is
 -                       * called from non sleepable context we must schedule
 -                       * a work item for this purpose
 +                       * wait for the pf's response).
                         */
                        smp_mb__before_clear_bit();
                        set_bit(BNX2X_SP_RTNL_VFPF_MCAST,
        /* Schedule the rx_mode command */
        if (test_bit(BNX2X_FILTER_RX_MODE_PENDING, &bp->sp_state)) {
                set_bit(BNX2X_FILTER_RX_MODE_SCHED, &bp->sp_state);
 +              netif_addr_unlock_bh(bp->dev);
                return;
        }
  
        if (IS_PF(bp)) {
                bnx2x_set_storm_rx_mode(bp);
 +              netif_addr_unlock_bh(bp->dev);
        } else {
 -              /* configuring rx mode to storms in a vf involves sleeping (when
 -               * we wait for the pf's response). Since this function is
 -               * called from non sleepable context we must schedule
 -               * a work item for this purpose
 +              /* VF will need to request the PF to make this change, and so
 +               * the VF needs to release the bottom-half lock prior to the
 +               * request (as it will likely require sleep on the VF side)
                 */
 -              smp_mb__before_clear_bit();
 -              set_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
 -                      &bp->sp_rtnl_state);
 -              smp_mb__after_clear_bit();
 -              schedule_delayed_work(&bp->sp_rtnl_task, 0);
 +              netif_addr_unlock_bh(bp->dev);
 +              bnx2x_vfpf_storm_rx_mode(bp);
        }
  }
  
@@@ -12578,16 -12564,19 +12581,16 @@@ static int bnx2x_set_qm_cid_count(struc
   * @dev:      pci device
   *
   */
 -static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev,
 -                                   int cnic_cnt, bool is_vf)
 +static int bnx2x_get_num_non_def_sbs(struct pci_dev *pdev, int cnic_cnt)
  {
 -      int pos, index;
 +      int index;
        u16 control = 0;
  
 -      pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
 -
        /*
         * If MSI-X is not supported - return number of SBs needed to support
         * one fast path queue: one FP queue + SB for CNIC
         */
 -      if (!pos) {
 +      if (!pdev->msix_cap) {
                dev_info(&pdev->dev, "no msix capability found\n");
                return 1 + cnic_cnt;
        }
         * without the default SB.
         * For VFs there is no default SB, then we return (index+1).
         */
 -      pci_read_config_word(pdev, pos  + PCI_MSI_FLAGS, &control);
 +      pci_read_config_word(pdev, pdev->msix_cap + PCI_MSI_FLAGS, &control);
  
        index = control & PCI_MSIX_FLAGS_QSIZE;
  
 -      return is_vf ? index + 1 : index;
 +      return index;
  }
  
  static int set_max_cos_est(int chip_id)
@@@ -12684,13 -12673,10 +12687,13 @@@ static int bnx2x_init_one(struct pci_de
        is_vf = set_is_vf(ent->driver_data);
        cnic_cnt = is_vf ? 0 : 1;
  
 -      max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev, cnic_cnt, is_vf);
 +      max_non_def_sbs = bnx2x_get_num_non_def_sbs(pdev, cnic_cnt);
 +
 +      /* add another SB for VF as it has no default SB */
 +      max_non_def_sbs += is_vf ? 1 : 0;
  
        /* Maximum number of RSS queues: one IGU SB goes to CNIC */
 -      rss_count = is_vf ? 1 : max_non_def_sbs - cnic_cnt;
 +      rss_count = max_non_def_sbs - cnic_cnt;
  
        if (rss_count < 1)
                return -EINVAL;
index 73731eb68f2ab1efe418e73de7d89da1e42100eb,e8706e19f96f4f95b53f35e1d9cec6c6fc19b571..b26eb83069b6b45c608f25a037386a151a73a2b9
@@@ -170,11 -170,6 +170,11 @@@ enum bnx2x_vfop_qteardown_state 
           BNX2X_VFOP_QTEARDOWN_DONE
  };
  
 +enum bnx2x_vfop_rss_state {
 +         BNX2X_VFOP_RSS_CONFIG,
 +         BNX2X_VFOP_RSS_DONE
 +};
 +
  #define bnx2x_vfop_reset_wq(vf)       atomic_set(&vf->op_in_progress, 0)
  
  void bnx2x_vfop_qctor_dump_tx(struct bnx2x *bp, struct bnx2x_virtf *vf,
@@@ -270,6 -265,11 +270,6 @@@ void bnx2x_vfop_qctor_prep(struct bnx2
        __set_bit(BNX2X_Q_FLG_TX_SEC, &setup_p->flags);
        __set_bit(BNX2X_Q_FLG_ANTI_SPOOF, &setup_p->flags);
  
 -      if (vfq_is_leading(q)) {
 -              __set_bit(BNX2X_Q_FLG_LEADING_RSS, &setup_p->flags);
 -              __set_bit(BNX2X_Q_FLG_MCAST, &setup_p->flags);
 -      }
 -
        /* Setup-op rx parameters */
        if (test_bit(BNX2X_Q_TYPE_HAS_RX, &q_type)) {
                struct bnx2x_rxq_setup_params *rxq_p = &setup_p->rxq_params;
@@@ -398,11 -398,7 +398,11 @@@ static void bnx2x_vfop_qdtor(struct bnx
                    BNX2X_Q_LOGICAL_STATE_STOPPED) {
                        DP(BNX2X_MSG_IOV,
                           "Entered qdtor but queue was already stopped. Aborting gracefully\n");
 -                      goto op_done;
 +
 +                      /* next state */
 +                      vfop->state = BNX2X_VFOP_QDTOR_DONE;
 +
 +                      bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
                }
  
                /* next state */
@@@ -436,10 -432,8 +436,10 @@@ op_err
  op_done:
        case BNX2X_VFOP_QDTOR_DONE:
                /* invalidate the context */
 -              qdtor->cxt->ustorm_ag_context.cdu_usage = 0;
 -              qdtor->cxt->xstorm_ag_context.cdu_reserved = 0;
 +              if (qdtor->cxt) {
 +                      qdtor->cxt->ustorm_ag_context.cdu_usage = 0;
 +                      qdtor->cxt->xstorm_ag_context.cdu_reserved = 0;
 +              }
                bnx2x_vfop_end(bp, vf, vfop);
                return;
        default:
@@@ -471,8 -465,7 +471,8 @@@ static int bnx2x_vfop_qdtor_cmd(struct 
                return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdtor,
                                             cmd->block);
        }
 -      DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop.\n", vf->abs_vfid);
 +      DP(BNX2X_MSG_IOV, "VF[%d] failed to add a vfop. rc %d\n",
 +         vf->abs_vfid, vfop->rc);
        return -ENOMEM;
  }
  
@@@ -481,18 -474,10 +481,18 @@@ bnx2x_vf_set_igu_info(struct bnx2x *bp
  {
        struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
        if (vf) {
 +              /* the first igu entry belonging to VFs of this PF */
 +              if (!BP_VFDB(bp)->first_vf_igu_entry)
 +                      BP_VFDB(bp)->first_vf_igu_entry = igu_sb_id;
 +
 +              /* the first igu entry belonging to this VF */
                if (!vf_sb_count(vf))
                        vf->igu_base_id = igu_sb_id;
 +
                ++vf_sb_count(vf);
 +              ++vf->sb_count;
        }
 +      BP_VFDB(bp)->vf_sbs_pool++;
  }
  
  /* VFOP MAC/VLAN helpers */
@@@ -506,20 -491,12 +506,20 @@@ static inline void bnx2x_vfop_credit(st
         * and a valid credit counter
         */
        if (!vfop->rc && args->credit) {
 -              int cnt = 0;
                struct list_head *pos;
 +              int read_lock;
 +              int cnt = 0;
 +
 +              read_lock = bnx2x_vlan_mac_h_read_lock(bp, obj);
 +              if (read_lock)
 +                      DP(BNX2X_MSG_SP, "Failed to take vlan mac read head; continuing anyway\n");
  
                list_for_each(pos, &obj->head)
                        cnt++;
  
 +              if (!read_lock)
 +                      bnx2x_vlan_mac_h_read_unlock(bp, obj);
 +
                atomic_set(args->credit, cnt);
        }
  }
@@@ -545,23 -522,6 +545,6 @@@ static int bnx2x_vfop_set_user_req(stru
        return 0;
  }
  
- static int
- bnx2x_vfop_config_vlan0(struct bnx2x *bp,
-                       struct bnx2x_vlan_mac_ramrod_params *vlan_mac,
-                       bool add)
- {
-       int rc;
-       vlan_mac->user_req.cmd = add ? BNX2X_VLAN_MAC_ADD :
-               BNX2X_VLAN_MAC_DEL;
-       vlan_mac->user_req.u.vlan.vlan = 0;
-       rc = bnx2x_config_vlan_mac(bp, vlan_mac);
-       if (rc == -EEXIST)
-               rc = 0;
-       return rc;
- }
  static int bnx2x_vfop_config_list(struct bnx2x *bp,
                                  struct bnx2x_vfop_filters *filters,
                                  struct bnx2x_vlan_mac_ramrod_params *vlan_mac)
@@@ -666,30 -626,14 +649,14 @@@ static void bnx2x_vfop_vlan_mac(struct 
  
        case BNX2X_VFOP_VLAN_CONFIG_LIST:
                /* next state */
-               vfop->state = BNX2X_VFOP_VLAN_CONFIG_LIST_0;
-               /* remove vlan0 - could be no-op */
-               vfop->rc = bnx2x_vfop_config_vlan0(bp, vlan_mac, false);
-               if (vfop->rc)
-                       goto op_err;
+               vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE;
  
-               /* Do vlan list config. if this operation fails we try to
-                * restore vlan0 to keep the queue is working order
-                */
+               /* do list config */
                vfop->rc = bnx2x_vfop_config_list(bp, filters, vlan_mac);
                if (!vfop->rc) {
                        set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags);
                        vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac);
                }
-               bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); /* fall-through */
-       case BNX2X_VFOP_VLAN_CONFIG_LIST_0:
-               /* next state */
-               vfop->state = BNX2X_VFOP_VLAN_MAC_CHK_DONE;
-               if (list_empty(&obj->head))
-                       /* add vlan0 */
-                       vfop->rc = bnx2x_vfop_config_vlan0(bp, vlan_mac, true);
                bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE);
  
        default:
@@@ -748,7 -692,6 +715,7 @@@ static int bnx2x_vfop_mac_delall_cmd(st
                                     int qid, bool drv_only)
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +      int rc;
  
        if (vfop) {
                struct bnx2x_vfop_args_filters filters = {
                bnx2x_vfop_mac_prep_ramrod(ramrod, &flags);
  
                /* set object */
 +              rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj));
 +              if (rc)
 +                      return rc;
                ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj);
  
                /* set extra args */
@@@ -791,7 -731,6 +758,7 @@@ int bnx2x_vfop_mac_list_cmd(struct bnx2
                            int qid, bool drv_only)
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +      int rc;
  
        if (vfop) {
                struct bnx2x_vfop_args_filters filters = {
                bnx2x_vfop_mac_prep_ramrod(ramrod, &flags);
  
                /* set object */
 +              rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj));
 +              if (rc)
 +                      return rc;
                ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj);
  
                /* set extra args */
@@@ -837,7 -773,6 +804,7 @@@ int bnx2x_vfop_vlan_set_cmd(struct bnx2
                            int qid, u16 vid, bool add)
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +      int rc;
  
        if (vfop) {
                struct bnx2x_vfop_args_filters filters = {
                ramrod->user_req.u.vlan.vlan = vid;
  
                /* set object */
 +              rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
 +              if (rc)
 +                      return rc;
                ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
  
                /* set extra args */
@@@ -880,7 -812,6 +847,7 @@@ static int bnx2x_vfop_vlan_delall_cmd(s
                               int qid, bool drv_only)
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +      int rc;
  
        if (vfop) {
                struct bnx2x_vfop_args_filters filters = {
                bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags);
  
                /* set object */
 +              rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
 +              if (rc)
 +                      return rc;
                ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
  
                /* set extra args */
@@@ -923,7 -851,6 +890,7 @@@ int bnx2x_vfop_vlan_list_cmd(struct bnx
                             int qid, bool drv_only)
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +      int rc;
  
        if (vfop) {
                struct bnx2x_vfop_args_filters filters = {
                bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags);
  
                /* set object */
 +              rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
 +              if (rc)
 +                      return rc;
                ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
  
                /* set extra args */
@@@ -1056,25 -980,21 +1023,25 @@@ static void bnx2x_vfop_qflr(struct bnx2
        case BNX2X_VFOP_QFLR_CLR_VLAN:
                /* vlan-clear-all: driver-only, don't consume credit */
                vfop->state = BNX2X_VFOP_QFLR_CLR_MAC;
 -              vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid, true);
 +              if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj)))
 +                      vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid,
 +                                                            true);
                if (vfop->rc)
                        goto op_err;
 -              return;
 +              bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
  
        case BNX2X_VFOP_QFLR_CLR_MAC:
                /* mac-clear-all: driver only consume credit */
                vfop->state = BNX2X_VFOP_QFLR_TERMINATE;
 -              vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid, true);
 +              if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj)))
 +                      vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid,
 +                                                           true);
                DP(BNX2X_MSG_IOV,
                   "VF[%d] vfop->rc after bnx2x_vfop_mac_delall_cmd was %d",
                   vf->abs_vfid, vfop->rc);
                if (vfop->rc)
                        goto op_err;
 -              return;
 +              bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
  
        case BNX2X_VFOP_QFLR_TERMINATE:
                qstate = &vfop->op_p->qctor.qstate;
@@@ -1371,13 -1291,10 +1338,13 @@@ int bnx2x_vfop_qdown_cmd(struct bnx2x *
  {
        struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
  
 +      /* for non leading queues skip directly to qdown sate */
        if (vfop) {
                vfop->args.qx.qid = qid;
 -              bnx2x_vfop_opset(BNX2X_VFOP_QTEARDOWN_RXMODE,
 -                               bnx2x_vfop_qdown, cmd->done);
 +              bnx2x_vfop_opset(qid == LEADING_IDX ?
 +                               BNX2X_VFOP_QTEARDOWN_RXMODE :
 +                               BNX2X_VFOP_QTEARDOWN_QDTOR, bnx2x_vfop_qdown,
 +                               cmd->done);
                return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qdown,
                                             cmd->block);
        }
@@@ -1530,16 -1447,15 +1497,16 @@@ int bnx2x_vf_flr_clnup_epilog(struct bn
   * both known
   */
  static void
 -bnx2x_iov_static_resc(struct bnx2x *bp, struct vf_pf_resc_request *resc)
 +bnx2x_iov_static_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
  {
 +      struct vf_pf_resc_request *resc = &vf->alloc_resc;
        u16 vlan_count = 0;
  
        /* will be set only during VF-ACQUIRE */
        resc->num_rxqs = 0;
        resc->num_txqs = 0;
  
 -      /* no credit calculcis for macs (just yet) */
 +      /* no credit calculations for macs (just yet) */
        resc->num_mac_filters = 1;
  
        /* divvy up vlan rules */
        resc->num_mc_filters = 0;
  
        /* num_sbs already set */
 +      resc->num_sbs = vf->sb_count;
  }
  
  /* FLR routines: */
  static void bnx2x_vf_free_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
  {
        /* reset the state variables */
 -      bnx2x_iov_static_resc(bp, &vf->alloc_resc);
 +      bnx2x_iov_static_resc(bp, vf);
        vf->state = VF_FREE;
  }
  
@@@ -1778,7 -1693,8 +1745,7 @@@ void bnx2x_iov_init_dq(struct bnx2x *bp
        /* The VF doorbell size  0 - *B, 4 - 128B. We set it here to match
         * the Pf doorbell size although the 2 are independent.
         */
 -      REG_WR(bp, DORQ_REG_VF_NORM_CID_OFST,
 -             BNX2X_DB_SHIFT - BNX2X_DB_MIN_SHIFT);
 +      REG_WR(bp, DORQ_REG_VF_NORM_CID_OFST, 3);
  
        /* No security checks for now -
         * configure single rule (out of 16) mask = 0x1, value = 0x0,
@@@ -1845,7 -1761,7 +1812,7 @@@ bnx2x_get_vf_igu_cam_info(struct bnx2x 
  {
        int sb_id;
        u32 val;
 -      u8 fid;
 +      u8 fid, current_pf = 0;
  
        /* IGU in normal mode - read CAM */
        for (sb_id = 0; sb_id < IGU_REG_MAPPING_MEMORY_SIZE; sb_id++) {
                if (!(val & IGU_REG_MAPPING_MEMORY_VALID))
                        continue;
                fid = GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID);
 -              if (!(fid & IGU_FID_ENCODE_IS_PF))
 +              if (fid & IGU_FID_ENCODE_IS_PF)
 +                      current_pf = fid & IGU_FID_PF_NUM_MASK;
 +              else if (current_pf == BP_ABS_FUNC(bp))
                        bnx2x_vf_set_igu_info(bp, sb_id,
                                              (fid & IGU_FID_VF_NUM_MASK));
 -
                DP(BNX2X_MSG_IOV, "%s[%d], igu_sb_id=%d, msix=%d\n",
                   ((fid & IGU_FID_ENCODE_IS_PF) ? "PF" : "VF"),
                   ((fid & IGU_FID_ENCODE_IS_PF) ? (fid & IGU_FID_PF_NUM_MASK) :
                   (fid & IGU_FID_VF_NUM_MASK)), sb_id,
                   GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR));
        }
 +      DP(BNX2X_MSG_IOV, "vf_sbs_pool is %d\n", BP_VFDB(bp)->vf_sbs_pool);
  }
  
  static void __bnx2x_iov_free_vfdb(struct bnx2x *bp)
@@@ -1930,11 -1844,23 +1897,11 @@@ static int bnx2x_sriov_info(struct bnx2
        return 0;
  }
  
 -static u8 bnx2x_iov_get_max_queue_count(struct bnx2x *bp)
 -{
 -      int i;
 -      u8 queue_count = 0;
 -
 -      if (IS_SRIOV(bp))
 -              for_each_vf(bp, i)
 -                      queue_count += bnx2x_vf(bp, i, alloc_resc.num_sbs);
 -
 -      return queue_count;
 -}
 -
  /* must be called after PF bars are mapped */
  int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param,
 -                      int num_vfs_param)
 +                     int num_vfs_param)
  {
 -      int err, i, qcount;
 +      int err, i;
        struct bnx2x_sriov *iov;
        struct pci_dev *dev = bp->pdev;
  
        /* re-read the IGU CAM for VFs - index and abs_vfid must be set */
        bnx2x_get_vf_igu_cam_info(bp);
  
 -      /* get the total queue count and allocate the global queue arrays */
 -      qcount = bnx2x_iov_get_max_queue_count(bp);
 -
        /* allocate the queue arrays for all VFs */
 -      bp->vfdb->vfqs = kzalloc(qcount * sizeof(struct bnx2x_vf_queue),
 -                               GFP_KERNEL);
 +      bp->vfdb->vfqs = kzalloc(
 +              BNX2X_MAX_NUM_VF_QUEUES * sizeof(struct bnx2x_vf_queue),
 +              GFP_KERNEL);
 +
 +      DP(BNX2X_MSG_IOV, "bp->vfdb->vfqs was %p\n", bp->vfdb->vfqs);
 +
        if (!bp->vfdb->vfqs) {
                BNX2X_ERR("failed to allocate vf queue array\n");
                err = -ENOMEM;
@@@ -2159,14 -2084,49 +2126,14 @@@ static void bnx2x_vfq_init(struct bnx2
                             q_type);
  
        DP(BNX2X_MSG_IOV,
 -         "initialized vf %d's queue object. func id set to %d\n",
 -         vf->abs_vfid, q->sp_obj.func_id);
 -
 -      /* mac/vlan objects are per queue, but only those
 -       * that belong to the leading queue are initialized
 -       */
 -      if (vfq_is_leading(q)) {
 -              /* mac */
 -              bnx2x_init_mac_obj(bp, &q->mac_obj,
 -                                 cl_id, q->cid, func_id,
 -                                 bnx2x_vf_sp(bp, vf, mac_rdata),
 -                                 bnx2x_vf_sp_map(bp, vf, mac_rdata),
 -                                 BNX2X_FILTER_MAC_PENDING,
 -                                 &vf->filter_state,
 -                                 BNX2X_OBJ_TYPE_RX_TX,
 -                                 &bp->macs_pool);
 -              /* vlan */
 -              bnx2x_init_vlan_obj(bp, &q->vlan_obj,
 -                                  cl_id, q->cid, func_id,
 -                                  bnx2x_vf_sp(bp, vf, vlan_rdata),
 -                                  bnx2x_vf_sp_map(bp, vf, vlan_rdata),
 -                                  BNX2X_FILTER_VLAN_PENDING,
 -                                  &vf->filter_state,
 -                                  BNX2X_OBJ_TYPE_RX_TX,
 -                                  &bp->vlans_pool);
 -
 -              /* mcast */
 -              bnx2x_init_mcast_obj(bp, &vf->mcast_obj, cl_id,
 -                                   q->cid, func_id, func_id,
 -                                   bnx2x_vf_sp(bp, vf, mcast_rdata),
 -                                   bnx2x_vf_sp_map(bp, vf, mcast_rdata),
 -                                   BNX2X_FILTER_MCAST_PENDING,
 -                                   &vf->filter_state,
 -                                   BNX2X_OBJ_TYPE_RX_TX);
 -
 -              vf->leading_rss = cl_id;
 -      }
 +         "initialized vf %d's queue object. func id set to %d. cid set to 0x%x\n",
 +         vf->abs_vfid, q->sp_obj.func_id, q->cid);
  }
  
  /* called by bnx2x_nic_load */
  int bnx2x_iov_nic_init(struct bnx2x *bp)
  {
 -      int vfid, qcount, i;
 +      int vfid;
  
        if (!IS_SRIOV(bp)) {
                DP(BNX2X_MSG_IOV, "vfdb was not allocated\n");
                   BNX2X_FIRST_VF_CID + base_vf_cid, base_cxt);
  
                /* init statically provisioned resources */
 -              bnx2x_iov_static_resc(bp, &vf->alloc_resc);
 +              bnx2x_iov_static_resc(bp, vf);
  
                /* queues are initialized during VF-ACQUIRE */
  
        }
  
        /* Final VF init */
 -      qcount = 0;
 -      for_each_vf(bp, i) {
 -              struct bnx2x_virtf *vf = BP_VF(bp, i);
 +      for_each_vf(bp, vfid) {
 +              struct bnx2x_virtf *vf = BP_VF(bp, vfid);
  
                /* fill in the BDF and bars */
 -              vf->bus = bnx2x_vf_bus(bp, i);
 -              vf->devfn = bnx2x_vf_devfn(bp, i);
 +              vf->bus = bnx2x_vf_bus(bp, vfid);
 +              vf->devfn = bnx2x_vf_devfn(bp, vfid);
                bnx2x_vf_set_bars(bp, vf);
  
                DP(BNX2X_MSG_IOV,
                   (unsigned)vf->bars[0].bar, vf->bars[0].size,
                   (unsigned)vf->bars[1].bar, vf->bars[1].size,
                   (unsigned)vf->bars[2].bar, vf->bars[2].size);
 -
 -              /* set local queue arrays */
 -              vf->vfqs = &bp->vfdb->vfqs[qcount];
 -              qcount += bnx2x_vf(bp, i, alloc_resc.num_sbs);
        }
  
        return 0;
@@@ -2550,9 -2515,6 +2517,9 @@@ void bnx2x_iov_adjust_stats_req(struct 
                for_each_vfq(vf, j) {
                        struct bnx2x_vf_queue *rxq = vfq_get(vf, j);
  
 +                      dma_addr_t q_stats_addr =
 +                              vf->fw_stat_map + j * vf->stats_stride;
 +
                        /* collect stats fro active queues only */
                        if (bnx2x_get_q_logical_state(bp, &rxq->sp_obj) ==
                            BNX2X_Q_LOGICAL_STATE_STOPPED)
  
                        /* create stats query entry for this queue */
                        cur_query_entry->kind = STATS_TYPE_QUEUE;
 -                      cur_query_entry->index = vfq_cl_id(vf, rxq);
 +                      cur_query_entry->index = vfq_stat_id(vf, rxq);
                        cur_query_entry->funcID =
                                cpu_to_le16(FW_VF_HANDLE(vf->abs_vfid));
                        cur_query_entry->address.hi =
 -                              cpu_to_le32(U64_HI(vf->fw_stat_map));
 +                              cpu_to_le32(U64_HI(q_stats_addr));
                        cur_query_entry->address.lo =
 -                              cpu_to_le32(U64_LO(vf->fw_stat_map));
 +                              cpu_to_le32(U64_LO(q_stats_addr));
                        DP(BNX2X_MSG_IOV,
                           "added address %x %x for vf %d queue %d client %d\n",
                           cur_query_entry->address.hi,
                        cur_query_entry++;
                        cur_data_offset += sizeof(struct per_queue_stats);
                        stats_count++;
 +
 +                      /* all stats are coalesced to the leading queue */
 +                      if (vf->cfg_flags & VF_CFG_STATS_COALESCE)
 +                              break;
                }
        }
        bp->fw_stats_req->hdr.cmd_num = bp->fw_stats_num + stats_count;
@@@ -2597,11 -2555,6 +2564,11 @@@ void bnx2x_iov_sp_task(struct bnx2x *bp
        for_each_vf(bp, i) {
                struct bnx2x_virtf *vf = BP_VF(bp, i);
  
 +              if (!vf) {
 +                      BNX2X_ERR("VF was null! skipping...\n");
 +                      continue;
 +              }
 +
                if (!list_empty(&vf->op_list_head) &&
                    atomic_read(&vf->op_in_progress)) {
                        DP(BNX2X_MSG_IOV, "running pending op for vf %d\n", i);
@@@ -2749,7 -2702,7 +2716,7 @@@ int bnx2x_vf_acquire(struct bnx2x *bp, 
                struct bnx2x_vf_queue *q = vfq_get(vf, i);
  
                if (!q) {
 -                      DP(BNX2X_MSG_IOV, "q number %d was not allocated\n", i);
 +                      BNX2X_ERR("q number %d was not allocated\n", i);
                        return -EINVAL;
                }
  
@@@ -2833,6 -2786,18 +2800,18 @@@ int bnx2x_vf_init(struct bnx2x *bp, str
        return 0;
  }
  
+ struct set_vf_state_cookie {
+       struct bnx2x_virtf *vf;
+       u8 state;
+ };
+ void bnx2x_set_vf_state(void *cookie)
+ {
+       struct set_vf_state_cookie *p = (struct set_vf_state_cookie *)cookie;
+       p->vf->state = p->state;
+ }
  /* VFOP close (teardown the queues, delete mcasts and close HW) */
  static void bnx2x_vfop_close(struct bnx2x *bp, struct bnx2x_virtf *vf)
  {
  op_err:
        BNX2X_ERR("VF[%d] CLOSE error: rc %d\n", vf->abs_vfid, vfop->rc);
  op_done:
-       vf->state = VF_ACQUIRED;
+       /* need to make sure there are no outstanding stats ramrods which may
+        * cause the device to access the VF's stats buffer which it will free
+        * as soon as we return from the close flow.
+        */
+       {
+               struct set_vf_state_cookie cookie;
+               cookie.vf = vf;
+               cookie.state = VF_ACQUIRED;
+               bnx2x_stats_safe_exec(bp, bnx2x_set_vf_state, &cookie);
+       }
        DP(BNX2X_MSG_IOV, "set state to acquired\n");
        bnx2x_vfop_end(bp, vf, vfop);
  }
@@@ -2953,43 -2930,6 +2944,43 @@@ op_done
        bnx2x_vfop_end(bp, vf, vfop);
  }
  
 +static void bnx2x_vfop_rss(struct bnx2x *bp, struct bnx2x_virtf *vf)
 +{
 +      struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
 +      enum bnx2x_vfop_rss_state state;
 +
 +      if (!vfop) {
 +              BNX2X_ERR("vfop was null\n");
 +              return;
 +      }
 +
 +      state = vfop->state;
 +      bnx2x_vfop_reset_wq(vf);
 +
 +      if (vfop->rc < 0)
 +              goto op_err;
 +
 +      DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state);
 +
 +      switch (state) {
 +      case BNX2X_VFOP_RSS_CONFIG:
 +              /* next state */
 +              vfop->state = BNX2X_VFOP_RSS_DONE;
 +              bnx2x_config_rss(bp, &vfop->op_p->rss);
 +              bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE);
 +op_err:
 +              BNX2X_ERR("RSS error: rc %d\n", vfop->rc);
 +op_done:
 +      case BNX2X_VFOP_RSS_DONE:
 +              bnx2x_vfop_end(bp, vf, vfop);
 +              return;
 +      default:
 +              bnx2x_vfop_default(state);
 +      }
 +op_pending:
 +      return;
 +}
 +
  int bnx2x_vfop_release_cmd(struct bnx2x *bp,
                           struct bnx2x_virtf *vf,
                           struct bnx2x_vfop_cmd *cmd)
        return -ENOMEM;
  }
  
 +int bnx2x_vfop_rss_cmd(struct bnx2x *bp,
 +                     struct bnx2x_virtf *vf,
 +                     struct bnx2x_vfop_cmd *cmd)
 +{
 +      struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
 +
 +      if (vfop) {
 +              bnx2x_vfop_opset(BNX2X_VFOP_RSS_CONFIG, bnx2x_vfop_rss,
 +                               cmd->done);
 +              return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_rss,
 +                                           cmd->block);
 +      }
 +      return -ENOMEM;
 +}
 +
  /* VF release ~ VF close + VF release-resources
   * Release is the ultimate SW shutdown and is called whenever an
   * irrecoverable error is encountered.
@@@ -3030,8 -2955,6 +3021,8 @@@ void bnx2x_vf_release(struct bnx2x *bp
                .block = block,
        };
        int rc;
 +
 +      DP(BNX2X_MSG_IOV, "PF releasing vf %d\n", vf->abs_vfid);
        bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_RELEASE_VF);
  
        rc = bnx2x_vfop_release_cmd(bp, vf, &cmd);
@@@ -3060,12 -2983,6 +3051,12 @@@ static inline void bnx2x_vf_get_bars(st
  void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
                              enum channel_tlvs tlv)
  {
 +      /* we don't lock the channel for unsupported tlvs */
 +      if (!bnx2x_tlv_supported(tlv)) {
 +              BNX2X_ERR("attempting to lock with unsupported tlv. Aborting\n");
 +              return;
 +      }
 +
        /* lock the channel */
        mutex_lock(&vf->op_mutex);
  
  void bnx2x_unlock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
                                enum channel_tlvs expected_tlv)
  {
 +      enum channel_tlvs current_tlv;
 +
 +      if (!vf) {
 +              BNX2X_ERR("VF was %p\n", vf);
 +              return;
 +      }
 +
 +      current_tlv = vf->op_current;
 +
 +      /* we don't unlock the channel for unsupported tlvs */
 +      if (!bnx2x_tlv_supported(expected_tlv))
 +              return;
 +
        WARN(expected_tlv != vf->op_current,
             "lock mismatch: expected %d found %d", expected_tlv,
             vf->op_current);
  
 +      /* record the locking op */
 +      vf->op_current = CHANNEL_TLV_NONE;
 +
        /* lock the channel */
        mutex_unlock(&vf->op_mutex);
  
        /* log the unlock */
        DP(BNX2X_MSG_IOV, "VF[%d]: vf pf channel unlocked by %d\n",
           vf->abs_vfid, vf->op_current);
 -
 -      /* record the locking op */
 -      vf->op_current = CHANNEL_TLV_NONE;
  }
  
  int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param)
                return bnx2x_enable_sriov(bp);
        }
  }
 +#define IGU_ENTRY_SIZE 4
  
  int bnx2x_enable_sriov(struct bnx2x *bp)
  {
        int rc = 0, req_vfs = bp->requested_nr_virtfn;
 +      int vf_idx, sb_idx, vfq_idx, qcount, first_vf;
 +      u32 igu_entry, address;
 +      u16 num_vf_queues;
 +
 +      if (req_vfs == 0)
 +              return 0;
 +
 +      first_vf = bp->vfdb->sriov.first_vf_in_pf;
 +
 +      /* statically distribute vf sb pool between VFs */
 +      num_vf_queues = min_t(u16, BNX2X_VF_MAX_QUEUES,
 +                            BP_VFDB(bp)->vf_sbs_pool / req_vfs);
 +
 +      /* zero previous values learned from igu cam */
 +      for (vf_idx = 0; vf_idx < req_vfs; vf_idx++) {
 +              struct bnx2x_virtf *vf = BP_VF(bp, vf_idx);
 +
 +              vf->sb_count = 0;
 +              vf_sb_count(BP_VF(bp, vf_idx)) = 0;
 +      }
 +      bp->vfdb->vf_sbs_pool = 0;
 +
 +      /* prepare IGU cam */
 +      sb_idx = BP_VFDB(bp)->first_vf_igu_entry;
 +      address = IGU_REG_MAPPING_MEMORY + sb_idx * IGU_ENTRY_SIZE;
 +      for (vf_idx = first_vf; vf_idx < first_vf + req_vfs; vf_idx++) {
 +              for (vfq_idx = 0; vfq_idx < num_vf_queues; vfq_idx++) {
 +                      igu_entry = vf_idx << IGU_REG_MAPPING_MEMORY_FID_SHIFT |
 +                              vfq_idx << IGU_REG_MAPPING_MEMORY_VECTOR_SHIFT |
 +                              IGU_REG_MAPPING_MEMORY_VALID;
 +                      DP(BNX2X_MSG_IOV, "assigning sb %d to vf %d\n",
 +                         sb_idx, vf_idx);
 +                      REG_WR(bp, address, igu_entry);
 +                      sb_idx++;
 +                      address += IGU_ENTRY_SIZE;
 +              }
 +      }
 +
 +      /* Reinitialize vf database according to igu cam */
 +      bnx2x_get_vf_igu_cam_info(bp);
 +
 +      DP(BNX2X_MSG_IOV, "vf_sbs_pool %d, num_vf_queues %d\n",
 +         BP_VFDB(bp)->vf_sbs_pool, num_vf_queues);
  
 +      qcount = 0;
 +      for_each_vf(bp, vf_idx) {
 +              struct bnx2x_virtf *vf = BP_VF(bp, vf_idx);
 +
 +              /* set local queue arrays */
 +              vf->vfqs = &bp->vfdb->vfqs[qcount];
 +              qcount += vf_sb_count(vf);
 +      }
 +
 +      /* prepare msix vectors in VF configuration space */
 +      for (vf_idx = first_vf; vf_idx < first_vf + req_vfs; vf_idx++) {
 +              bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf_idx));
 +              REG_WR(bp, PCICFG_OFFSET + GRC_CONFIG_REG_VF_MSIX_CONTROL,
 +                     num_vf_queues);
 +      }
 +      bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
 +
 +      /* enable sriov. This will probe all the VFs, and consequentially cause
 +       * the "acquire" messages to appear on the VF PF channel.
 +       */
 +      DP(BNX2X_MSG_IOV, "about to call enable sriov\n");
 +      pci_disable_sriov(bp->pdev);
        rc = pci_enable_sriov(bp->pdev, req_vfs);
        if (rc) {
                BNX2X_ERR("pci_enable_sriov failed with %d\n", rc);
@@@ -3234,8 -3072,9 +3225,8 @@@ void bnx2x_disable_sriov(struct bnx2x *
        pci_disable_sriov(bp->pdev);
  }
  
 -static int bnx2x_vf_ndo_prep(struct bnx2x *bp, int vfidx,
 -                           struct bnx2x_virtf **vf,
 -                           struct pf_vf_bulletin_content **bulletin)
 +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");
        *bulletin = BP_VF_BULLETIN(bp, vfidx);
  
        if (!*vf) {
 -              BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n",
 +              BNX2X_ERR("vf ndo called but vf struct is null. vfidx was %d\n",
 +                        vfidx);
 +              return -EINVAL;
 +      }
 +
 +      if (!(*vf)->vfqs) {
 +              BNX2X_ERR("vf ndo called but vfqs struct is null. Was ndo invoked before dynamically enabling SR-IOV? vfidx was %d\n",
                          vfidx);
                return -EINVAL;
        }
@@@ -3292,8 -3125,8 +3283,8 @@@ int bnx2x_get_vf_config(struct net_devi
        rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
        if (rc)
                return rc;
 -      mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
 -      vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj);
 +      mac_obj = &bnx2x_leading_vfq(vf, mac_obj);
 +      vlan_obj = &bnx2x_leading_vfq(vf, vlan_obj);
        if (!mac_obj || !vlan_obj) {
                BNX2X_ERR("VF partially initialized\n");
                return -EINVAL;
        ivi->spoofchk = 1; /*always enabled */
        if (vf->state == VF_ENABLED) {
                /* mac and vlan are in vlan_mac objects */
 -              mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac,
 -                                      0, ETH_ALEN);
 -              vlan_obj->get_n_elements(bp, vlan_obj, 1, (u8 *)&ivi->vlan,
 -                                       0, VLAN_HLEN);
 +              if (validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj)))
 +                      mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac,
 +                                              0, ETH_ALEN);
 +              if (validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, vlan_obj)))
 +                      vlan_obj->get_n_elements(bp, vlan_obj, 1,
 +                                               (u8 *)&ivi->vlan, 0,
 +                                               VLAN_HLEN);
        } else {
                /* mac */
                if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
@@@ -3379,18 -3209,14 +3370,18 @@@ int bnx2x_set_vf_mac(struct net_device 
                return rc;
        }
  
 -      /* is vf initialized and queue set up? */
        q_logical_state =
 -              bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj));
 +              bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj));
        if (vf->state == VF_ENABLED &&
            q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
                /* configure the mac in device on this vf's queue */
                unsigned long ramrod_flags = 0;
 -              struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
 +              struct bnx2x_vlan_mac_obj *mac_obj =
 +                      &bnx2x_leading_vfq(vf, mac_obj);
 +
 +              rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj));
 +              if (rc)
 +                      return rc;
  
                /* must lock vfpf channel to protect against vf flows */
                bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
@@@ -3450,21 -3276,18 +3441,21 @@@ int bnx2x_set_vf_vlan(struct net_devic
  
        /* is vf initialized and queue set up? */
        q_logical_state =
 -              bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj));
 +              bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj));
        if (vf->state == VF_ENABLED &&
            q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
                /* configure the vlan in device on this vf's queue */
                unsigned long ramrod_flags = 0;
                unsigned long vlan_mac_flags = 0;
                struct bnx2x_vlan_mac_obj *vlan_obj =
 -                      &bnx2x_vfq(vf, 0, vlan_obj);
 +                      &bnx2x_leading_vfq(vf, vlan_obj);
                struct bnx2x_vlan_mac_ramrod_params ramrod_param;
                struct bnx2x_queue_state_params q_params = {NULL};
                struct bnx2x_queue_update_params *update_params;
  
 +              rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj));
 +              if (rc)
 +                      return rc;
                memset(&ramrod_param, 0, sizeof(ramrod_param));
  
                /* must lock vfpf channel to protect against vf flows */
                 */
                __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
                q_params.cmd = BNX2X_Q_CMD_UPDATE;
 -              q_params.q_obj = &bnx2x_vfq(vf, 0, sp_obj);
 +              q_params.q_obj = &bnx2x_leading_vfq(vf, sp_obj);
                update_params = &q_params.params.update;
                __set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG,
                          &update_params->update_flags);
index 2e55ee29cf13cc3e71c863d64f6a6f1571ad00df,9d289d33f66dc0c92bacb0cb0dec55be020ac623..5701f3d1a169a207440c3ec92da789d6ea948536
@@@ -94,10 -94,10 +94,10 @@@ static inline void _tg3_flag_clear(enu
  
  #define DRV_MODULE_NAME               "tg3"
  #define TG3_MAJ_NUM                   3
 -#define TG3_MIN_NUM                   132
 +#define TG3_MIN_NUM                   133
  #define DRV_MODULE_VERSION    \
        __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
 -#define DRV_MODULE_RELDATE    "May 21, 2013"
 +#define DRV_MODULE_RELDATE    "Jul 29, 2013"
  
  #define RESET_KIND_SHUTDOWN   0
  #define RESET_KIND_INIT               1
@@@ -3030,6 -3030,19 +3030,19 @@@ static bool tg3_phy_power_bug(struct tg
        return false;
  }
  
+ static bool tg3_phy_led_bug(struct tg3 *tp)
+ {
+       switch (tg3_asic_rev(tp)) {
+       case ASIC_REV_5719:
+               if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
+                   !tp->pci_fn)
+                       return true;
+               return false;
+       }
+       return false;
+ }
  static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
  {
        u32 val;
                }
                return;
        } else if (do_low_power) {
-               tg3_writephy(tp, MII_TG3_EXT_CTRL,
-                            MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+               if (!tg3_phy_led_bug(tp))
+                       tg3_writephy(tp, MII_TG3_EXT_CTRL,
+                                    MII_TG3_EXT_CTRL_FORCE_LED_OFF);
  
                val = MII_TG3_AUXCTL_PCTL_100TX_LPWR |
                      MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
@@@ -4226,6 -4240,8 +4240,6 @@@ static int tg3_power_down_prepare(struc
  
  static void tg3_power_down(struct tg3 *tp)
  {
 -      tg3_power_down_prepare(tp);
 -
        pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
        pci_set_power_state(tp->pdev, PCI_D3hot);
  }
@@@ -6093,12 -6109,10 +6107,12 @@@ static u64 tg3_refclk_read(struct tg3 *
  /* tp->lock must be held */
  static void tg3_refclk_write(struct tg3 *tp, u64 newval)
  {
 -      tw32(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_STOP);
 +      u32 clock_ctl = tr32(TG3_EAV_REF_CLCK_CTL);
 +
 +      tw32(TG3_EAV_REF_CLCK_CTL, clock_ctl | TG3_EAV_REF_CLCK_CTL_STOP);
        tw32(TG3_EAV_REF_CLCK_LSB, newval & 0xffffffff);
        tw32(TG3_EAV_REF_CLCK_MSB, newval >> 32);
 -      tw32_f(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_RESUME);
 +      tw32_f(TG3_EAV_REF_CLCK_CTL, clock_ctl | TG3_EAV_REF_CLCK_CTL_RESUME);
  }
  
  static inline void tg3_full_lock(struct tg3 *tp, int irq_sync);
@@@ -6214,59 -6228,6 +6228,59 @@@ static int tg3_ptp_settime(struct ptp_c
  static int tg3_ptp_enable(struct ptp_clock_info *ptp,
                          struct ptp_clock_request *rq, int on)
  {
 +      struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
 +      u32 clock_ctl;
 +      int rval = 0;
 +
 +      switch (rq->type) {
 +      case PTP_CLK_REQ_PEROUT:
 +              if (rq->perout.index != 0)
 +                      return -EINVAL;
 +
 +              tg3_full_lock(tp, 0);
 +              clock_ctl = tr32(TG3_EAV_REF_CLCK_CTL);
 +              clock_ctl &= ~TG3_EAV_CTL_TSYNC_GPIO_MASK;
 +
 +              if (on) {
 +                      u64 nsec;
 +
 +                      nsec = rq->perout.start.sec * 1000000000ULL +
 +                             rq->perout.start.nsec;
 +
 +                      if (rq->perout.period.sec || rq->perout.period.nsec) {
 +                              netdev_warn(tp->dev,
 +                                          "Device supports only a one-shot timesync output, period must be 0\n");
 +                              rval = -EINVAL;
 +                              goto err_out;
 +                      }
 +
 +                      if (nsec & (1ULL << 63)) {
 +                              netdev_warn(tp->dev,
 +                                          "Start value (nsec) is over limit. Maximum size of start is only 63 bits\n");
 +                              rval = -EINVAL;
 +                              goto err_out;
 +                      }
 +
 +                      tw32(TG3_EAV_WATCHDOG0_LSB, (nsec & 0xffffffff));
 +                      tw32(TG3_EAV_WATCHDOG0_MSB,
 +                           TG3_EAV_WATCHDOG0_EN |
 +                           ((nsec >> 32) & TG3_EAV_WATCHDOG_MSB_MASK));
 +
 +                      tw32(TG3_EAV_REF_CLCK_CTL,
 +                           clock_ctl | TG3_EAV_CTL_TSYNC_WDOG0);
 +              } else {
 +                      tw32(TG3_EAV_WATCHDOG0_MSB, 0);
 +                      tw32(TG3_EAV_REF_CLCK_CTL, clock_ctl);
 +              }
 +
 +err_out:
 +              tg3_full_unlock(tp);
 +              return rval;
 +
 +      default:
 +              break;
 +      }
 +
        return -EOPNOTSUPP;
  }
  
@@@ -6276,7 -6237,7 +6290,7 @@@ static const struct ptp_clock_info tg3_
        .max_adj        = 250000000,
        .n_alarm        = 0,
        .n_ext_ts       = 0,
 -      .n_per_out      = 0,
 +      .n_per_out      = 1,
        .pps            = 0,
        .adjfreq        = tg3_ptp_adjfreq,
        .adjtime        = tg3_ptp_adjtime,
@@@ -8591,10 -8552,10 +8605,10 @@@ static int tg3_mem_rx_acquire(struct tg
                if (!i && tg3_flag(tp, ENABLE_RSS))
                        continue;
  
 -              tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
 -                                                 TG3_RX_RCB_RING_BYTES(tp),
 -                                                 &tnapi->rx_rcb_mapping,
 -                                                 GFP_KERNEL | __GFP_ZERO);
 +              tnapi->rx_rcb = dma_zalloc_coherent(&tp->pdev->dev,
 +                                                  TG3_RX_RCB_RING_BYTES(tp),
 +                                                  &tnapi->rx_rcb_mapping,
 +                                                  GFP_KERNEL);
                if (!tnapi->rx_rcb)
                        goto err_out;
        }
@@@ -8643,9 -8604,10 +8657,9 @@@ static int tg3_alloc_consistent(struct 
  {
        int i;
  
 -      tp->hw_stats = dma_alloc_coherent(&tp->pdev->dev,
 -                                        sizeof(struct tg3_hw_stats),
 -                                        &tp->stats_mapping,
 -                                        GFP_KERNEL | __GFP_ZERO);
 +      tp->hw_stats = dma_zalloc_coherent(&tp->pdev->dev,
 +                                         sizeof(struct tg3_hw_stats),
 +                                         &tp->stats_mapping, GFP_KERNEL);
        if (!tp->hw_stats)
                goto err_out;
  
                struct tg3_napi *tnapi = &tp->napi[i];
                struct tg3_hw_status *sblk;
  
 -              tnapi->hw_status = dma_alloc_coherent(&tp->pdev->dev,
 -                                                    TG3_HW_STATUS_SIZE,
 -                                                    &tnapi->status_mapping,
 -                                                    GFP_KERNEL | __GFP_ZERO);
 +              tnapi->hw_status = dma_zalloc_coherent(&tp->pdev->dev,
 +                                                     TG3_HW_STATUS_SIZE,
 +                                                     &tnapi->status_mapping,
 +                                                     GFP_KERNEL);
                if (!tnapi->hw_status)
                        goto err_out;
  
@@@ -10419,9 -10381,6 +10433,9 @@@ static int tg3_reset_hw(struct tg3 *tp
        if (tg3_flag(tp, 5755_PLUS))
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
  
 +      if (tg3_asic_rev(tp) == ASIC_REV_5762)
 +              tp->rx_mode |= RX_MODE_IPV4_FRAG_FIX;
 +
        if (tg3_flag(tp, ENABLE_RSS))
                tp->rx_mode |= RX_MODE_RSS_ENABLE |
                               RX_MODE_RSS_ITBL_HASH_BITS_7 |
@@@ -11557,7 -11516,7 +11571,7 @@@ static int tg3_close(struct net_device 
        memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev));
        memset(&tp->estats_prev, 0, sizeof(tp->estats_prev));
  
 -      tg3_power_down(tp);
 +      tg3_power_down_prepare(tp);
  
        tg3_carrier_off(tp);
  
@@@ -11779,6 -11738,9 +11793,6 @@@ static int tg3_get_eeprom(struct net_de
        if (tg3_flag(tp, NO_NVRAM))
                return -EINVAL;
  
 -      if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 -              return -EAGAIN;
 -
        offset = eeprom->offset;
        len = eeprom->len;
        eeprom->len = 0;
@@@ -11836,6 -11798,9 +11850,6 @@@ static int tg3_set_eeprom(struct net_de
        u8 *buf;
        __be32 start, end;
  
 -      if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 -              return -EAGAIN;
 -
        if (tg3_flag(tp, NO_NVRAM) ||
            eeprom->magic != TG3_EEPROM_MAGIC)
                return -EINVAL;
@@@ -13564,7 -13529,7 +13578,7 @@@ static void tg3_self_test(struct net_de
                        tg3_phy_start(tp);
        }
        if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 -              tg3_power_down(tp);
 +              tg3_power_down_prepare(tp);
  
  }
  
@@@ -15966,7 -15931,7 +15980,7 @@@ static int tg3_get_invariants(struct tg
         */
        if (tg3_flag(tp, 5780_CLASS)) {
                tg3_flag_set(tp, 40BIT_DMA_BUG);
 -              tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
 +              tp->msi_cap = tp->pdev->msi_cap;
        } else {
                struct pci_dev *bridge = NULL;
  
@@@ -17596,6 -17561,11 +17610,6 @@@ static int tg3_init_one(struct pci_dev 
            tg3_asic_rev(tp) == ASIC_REV_5762)
                tg3_flag_set(tp, PTP_CAPABLE);
  
 -      if (tg3_flag(tp, 5717_PLUS)) {
 -              /* Resume a low-power mode */
 -              tg3_frob_aux_power(tp, false);
 -      }
 -
        tg3_timer_init(tp);
  
        tg3_carrier_off(tp);
  
  static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
  
 +static void tg3_shutdown(struct pci_dev *pdev)
 +{
 +      struct net_device *dev = pci_get_drvdata(pdev);
 +      struct tg3 *tp = netdev_priv(dev);
 +
 +      rtnl_lock();
 +      netif_device_detach(dev);
 +
 +      if (netif_running(dev))
 +              dev_close(dev);
 +
 +      if (system_state == SYSTEM_POWER_OFF)
 +              tg3_power_down(tp);
 +
 +      rtnl_unlock();
 +}
 +
  /**
   * tg3_io_error_detected - called when PCI error is detected
   * @pdev: Pointer to PCI device
@@@ -17975,7 -17928,6 +17989,7 @@@ static struct pci_driver tg3_driver = 
        .remove         = tg3_remove_one,
        .err_handler    = &tg3_err_handler,
        .driver.pm      = &tg3_pm_ops,
 +      .shutdown       = tg3_shutdown,
  };
  
  module_pci_driver(tg3_driver);
index e104db7fcf273c11ee22e4c9466c2ede82259fc3,3d91a5ec61a4e7a6cd37249d5bad08ee451eeb09..3224d28cdad4384d4322bd5765d503ef9ace1ca1
@@@ -21,7 -21,6 +21,7 @@@
  #include "be_cmds.h"
  #include <asm/div64.h>
  #include <linux/aer.h>
 +#include <linux/if_bridge.h>
  
  MODULE_VERSION(DRV_VER);
  MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@@ -146,8 -145,8 +146,8 @@@ static int be_queue_alloc(struct be_ada
        q->len = len;
        q->entry_size = entry_size;
        mem->size = len * entry_size;
 -      mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
 -                                   GFP_KERNEL | __GFP_ZERO);
 +      mem->va = dma_zalloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
 +                                    GFP_KERNEL);
        if (!mem->va)
                return -ENOMEM;
        return 0;
@@@ -248,54 -247,54 +248,54 @@@ void be_cq_notify(struct be_adapter *ad
  static int be_mac_addr_set(struct net_device *netdev, void *p)
  {
        struct be_adapter *adapter = netdev_priv(netdev);
 +      struct device *dev = &adapter->pdev->dev;
        struct sockaddr *addr = p;
 -      int status = 0;
 -      u8 current_mac[ETH_ALEN];
 -      u32 pmac_id = adapter->pmac_id[0];
 -      bool active_mac = true;
 +      int status;
 +      u8 mac[ETH_ALEN];
 +      u32 old_pmac_id = adapter->pmac_id[0], curr_pmac_id = 0;
  
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
  
 -      /* For BE VF, MAC address is already activated by PF.
 -       * Hence only operation left is updating netdev->devaddr.
 -       * Update it if user is passing the same MAC which was used
 -       * during configuring VF MAC from PF(Hypervisor).
 +      /* The PMAC_ADD cmd may fail if the VF doesn't have FILTMGMT
 +       * privilege or if PF did not provision the new MAC address.
 +       * On BE3, this cmd will always fail if the VF doesn't have the
 +       * FILTMGMT privilege. This failure is OK, only if the PF programmed
 +       * the MAC for the VF.
         */
 -      if (!lancer_chip(adapter) && !be_physfn(adapter)) {
 -              status = be_cmd_mac_addr_query(adapter, current_mac,
 -                                             false, adapter->if_handle, 0);
 -              if (!status && !memcmp(current_mac, addr->sa_data, ETH_ALEN))
 -                      goto done;
 -              else
 -                      goto err;
 -      }
 +      status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
 +                               adapter->if_handle, &adapter->pmac_id[0], 0);
 +      if (!status) {
 +              curr_pmac_id = adapter->pmac_id[0];
  
 -      if (!memcmp(addr->sa_data, netdev->dev_addr, ETH_ALEN))
 -              goto done;
 +              /* Delete the old programmed MAC. This call may fail if the
 +               * old MAC was already deleted by the PF driver.
 +               */
 +              if (adapter->pmac_id[0] != old_pmac_id)
 +                      be_cmd_pmac_del(adapter, adapter->if_handle,
 +                                      old_pmac_id, 0);
 +      }
  
 -      /* For Lancer check if any MAC is active.
 -       * If active, get its mac id.
 +      /* Decide if the new MAC is successfully activated only after
 +       * querying the FW
         */
 -      if (lancer_chip(adapter) && !be_physfn(adapter))
 -              be_cmd_get_mac_from_list(adapter, current_mac, &active_mac,
 -                                       &pmac_id, 0);
 -
 -      status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
 -                               adapter->if_handle,
 -                               &adapter->pmac_id[0], 0);
 -
 +      status = be_cmd_get_active_mac(adapter, curr_pmac_id, mac);
        if (status)
                goto err;
  
 -      if (active_mac)
 -              be_cmd_pmac_del(adapter, adapter->if_handle,
 -                              pmac_id, 0);
 -done:
 +      /* The MAC change did not happen, either due to lack of privilege
 +       * or PF didn't pre-provision.
 +       */
 +      if (memcmp(addr->sa_data, mac, ETH_ALEN)) {
 +              status = -EPERM;
 +              goto err;
 +      }
 +
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 +      dev_info(dev, "MAC address changed to %pM\n", mac);
        return 0;
  err:
 -      dev_err(&adapter->pdev->dev, "MAC %pM set Failed\n", addr->sa_data);
 +      dev_warn(dev, "MAC address change to %pM failed\n", addr->sa_data);
        return status;
  }
  
@@@ -473,7 -472,7 +473,7 @@@ static void accumulate_16bit_val(u32 *a
        ACCESS_ONCE(*acc) = newacc;
  }
  
 -void populate_erx_stats(struct be_adapter *adapter,
 +static void populate_erx_stats(struct be_adapter *adapter,
                        struct be_rx_obj *rxo,
                        u32 erx_stat)
  {
@@@ -1002,7 -1001,7 +1002,7 @@@ static int be_vid_config(struct be_adap
        if (adapter->promiscuous)
                return 0;
  
 -      if (adapter->vlans_added > adapter->max_vlans)
 +      if (adapter->vlans_added > be_max_vlans(adapter))
                goto set_vlan_promisc;
  
        /* Construct VLAN Table to give to HW */
@@@ -1043,7 -1042,7 +1043,7 @@@ static int be_vlan_add_vid(struct net_d
                goto ret;
  
        adapter->vlan_tag[vid] = 1;
 -      if (adapter->vlans_added <= (adapter->max_vlans + 1))
 +      if (adapter->vlans_added <= (be_max_vlans(adapter) + 1))
                status = be_vid_config(adapter);
  
        if (!status)
@@@ -1069,7 -1068,7 +1069,7 @@@ static int be_vlan_rem_vid(struct net_d
                goto ret;
  
        adapter->vlan_tag[vid] = 0;
 -      if (adapter->vlans_added <= adapter->max_vlans)
 +      if (adapter->vlans_added <= be_max_vlans(adapter))
                status = be_vid_config(adapter);
  
        if (!status)
@@@ -1102,7 -1101,7 +1102,7 @@@ static void be_set_rx_mode(struct net_d
  
        /* Enable multicast promisc if num configured exceeds what we support */
        if (netdev->flags & IFF_ALLMULTI ||
 -          netdev_mc_count(netdev) > adapter->max_mcast_mac) {
 +          netdev_mc_count(netdev) > be_max_mc(adapter)) {
                be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
                goto done;
        }
                                        adapter->pmac_id[i], 0);
                }
  
 -              if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
 +              if (netdev_uc_count(netdev) > be_max_uc(adapter)) {
                        be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
                        adapter->promiscuous = true;
                        goto done;
@@@ -1147,6 -1146,9 +1147,6 @@@ static int be_set_vf_mac(struct net_dev
        struct be_adapter *adapter = netdev_priv(netdev);
        struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
        int status;
 -      bool active_mac = false;
 -      u32 pmac_id;
 -      u8 old_mac[ETH_ALEN];
  
        if (!sriov_enabled(adapter))
                return -EPERM;
        if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs)
                return -EINVAL;
  
 -      if (lancer_chip(adapter)) {
 -              status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
 -                                                &pmac_id, vf + 1);
 -              if (!status && active_mac)
 -                      be_cmd_pmac_del(adapter, vf_cfg->if_handle,
 -                                      pmac_id, vf + 1);
 -
 -              status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
 -      } else {
 -              status = be_cmd_pmac_del(adapter, vf_cfg->if_handle,
 -                                       vf_cfg->pmac_id, vf + 1);
 +      if (BEx_chip(adapter)) {
 +              be_cmd_pmac_del(adapter, vf_cfg->if_handle, vf_cfg->pmac_id,
 +                              vf + 1);
  
                status = be_cmd_pmac_add(adapter, mac, vf_cfg->if_handle,
                                         &vf_cfg->pmac_id, vf + 1);
 +      } else {
 +              status = be_cmd_set_mac(adapter, mac, vf_cfg->if_handle,
 +                                      vf + 1);
        }
  
        if (status)
@@@ -1213,14 -1220,14 +1213,14 @@@ static int be_set_vf_vlan(struct net_de
                        adapter->vf_cfg[vf].vlan_tag = vlan;
  
                        status = be_cmd_set_hsw_config(adapter, vlan,
 -                              vf + 1, adapter->vf_cfg[vf].if_handle);
 +                              vf + 1, adapter->vf_cfg[vf].if_handle, 0);
                }
        } else {
                /* Reset Transparent Vlan Tagging. */
                adapter->vf_cfg[vf].vlan_tag = 0;
                vlan = adapter->vf_cfg[vf].def_vid;
                status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
 -                      adapter->vf_cfg[vf].if_handle);
 +                      adapter->vf_cfg[vf].if_handle, 0);
        }
  
  
@@@ -1483,9 -1490,8 +1483,9 @@@ static void be_rx_compl_process(struct 
  }
  
  /* Process the RX completion indicated by rxcp when GRO is enabled */
 -void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
 -                           struct be_rx_compl_info *rxcp)
 +static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
 +                                  struct napi_struct *napi,
 +                                  struct be_rx_compl_info *rxcp)
  {
        struct be_adapter *adapter = rxo->adapter;
        struct be_rx_page_info *page_info;
@@@ -1914,7 -1920,6 +1914,7 @@@ static void be_evt_queues_destroy(struc
                if (eqo->q.created) {
                        be_eq_clean(eqo);
                        be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
 +                      netif_napi_del(&eqo->napi);
                }
                be_queue_free(adapter, &eqo->q);
        }
@@@ -1926,12 -1931,9 +1926,12 @@@ static int be_evt_queues_create(struct 
        struct be_eq_obj *eqo;
        int i, rc;
  
 -      adapter->num_evt_qs = num_irqs(adapter);
 +      adapter->num_evt_qs = min_t(u16, num_irqs(adapter),
 +                                  adapter->cfg_num_qs);
  
        for_all_evt_queues(adapter, eqo, i) {
 +              netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
 +                             BE_NAPI_WEIGHT);
                eqo->adapter = adapter;
                eqo->tx_budget = BE_TX_BUDGET;
                eqo->idx = i;
                if (rc)
                        return rc;
  
 -              rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
 +              rc = be_cmd_eq_create(adapter, eqo);
                if (rc)
                        return rc;
        }
@@@ -2018,13 -2020,31 +2018,13 @@@ static void be_tx_queues_destroy(struc
        }
  }
  
 -static int be_num_txqs_want(struct be_adapter *adapter)
 -{
 -      if ((!lancer_chip(adapter) && sriov_want(adapter)) ||
 -          be_is_mc(adapter) ||
 -          (!lancer_chip(adapter) && !be_physfn(adapter)) ||
 -          BE2_chip(adapter))
 -              return 1;
 -      else
 -              return adapter->max_tx_queues;
 -}
 -
 -static int be_tx_cqs_create(struct be_adapter *adapter)
 +static int be_tx_qs_create(struct be_adapter *adapter)
  {
        struct be_queue_info *cq, *eq;
 -      int status;
        struct be_tx_obj *txo;
 -      u8 i;
 +      int status, i;
  
 -      adapter->num_tx_qs = be_num_txqs_want(adapter);
 -      if (adapter->num_tx_qs != MAX_TX_QS) {
 -              rtnl_lock();
 -              netif_set_real_num_tx_queues(adapter->netdev,
 -                      adapter->num_tx_qs);
 -              rtnl_unlock();
 -      }
 +      adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter));
  
        for_all_tx_queues(adapter, txo, i) {
                cq = &txo->cq;
                status = be_cmd_cq_create(adapter, cq, eq, false, 3);
                if (status)
                        return status;
 -      }
 -      return 0;
 -}
 -
 -static int be_tx_qs_create(struct be_adapter *adapter)
 -{
 -      struct be_tx_obj *txo;
 -      int i, status;
  
 -      for_all_tx_queues(adapter, txo, i) {
                status = be_queue_alloc(adapter, &txo->q, TX_Q_LEN,
                                        sizeof(struct be_eth_wrb));
                if (status)
@@@ -2076,14 -2105,17 +2076,14 @@@ static int be_rx_cqs_create(struct be_a
        struct be_rx_obj *rxo;
        int rc, i;
  
 -      /* We'll create as many RSS rings as there are irqs.
 -       * But when there's only one irq there's no use creating RSS rings
 +      /* We can create as many RSS rings as there are EQs. */
 +      adapter->num_rx_qs = adapter->num_evt_qs;
 +
 +      /* We'll use RSS only if atleast 2 RSS rings are supported.
 +       * When RSS is used, we'll need a default RXQ for non-IP traffic.
         */
 -      adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
 -                              num_irqs(adapter) + 1 : 1;
 -      if (adapter->num_rx_qs != MAX_RX_QS) {
 -              rtnl_lock();
 -              netif_set_real_num_rx_queues(adapter->netdev,
 -                                           adapter->num_rx_qs);
 -              rtnl_unlock();
 -      }
 +      if (adapter->num_rx_qs > 1)
 +              adapter->num_rx_qs++;
  
        adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
        for_all_rx_queues(adapter, rxo, i) {
@@@ -2347,24 -2379,38 +2347,24 @@@ static void be_msix_disable(struct be_a
        if (msix_enabled(adapter)) {
                pci_disable_msix(adapter->pdev);
                adapter->num_msix_vec = 0;
 +              adapter->num_msix_roce_vec = 0;
        }
  }
  
 -static uint be_num_rss_want(struct be_adapter *adapter)
 -{
 -      u32 num = 0;
 -
 -      if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
 -          (lancer_chip(adapter) ||
 -           (!sriov_want(adapter) && be_physfn(adapter)))) {
 -              num = adapter->max_rss_queues;
 -              num = min_t(u32, num, (u32)netif_get_num_default_rss_queues());
 -      }
 -      return num;
 -}
 -
  static int be_msix_enable(struct be_adapter *adapter)
  {
 -#define BE_MIN_MSIX_VECTORS           1
 -      int i, status, num_vec, num_roce_vec = 0;
 +      int i, status, num_vec;
        struct device *dev = &adapter->pdev->dev;
  
 -      /* If RSS queues are not used, need a vec for default RX Q */
 -      num_vec = min(be_num_rss_want(adapter), num_online_cpus());
 -      if (be_roce_supported(adapter)) {
 -              num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS,
 -                                      (num_online_cpus() + 1));
 -              num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS);
 -              num_vec += num_roce_vec;
 -              num_vec = min(num_vec, MAX_MSIX_VECTORS);
 -      }
 -      num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
 +      /* If RoCE is supported, program the max number of NIC vectors that
 +       * may be configured via set-channels, along with vectors needed for
 +       * RoCe. Else, just program the number we'll use initially.
 +       */
 +      if (be_roce_supported(adapter))
 +              num_vec = min_t(int, 2 * be_max_eqs(adapter),
 +                              2 * num_online_cpus());
 +      else
 +              num_vec = adapter->cfg_num_qs;
  
        for (i = 0; i < num_vec; i++)
                adapter->msix_entries[i].entry = i;
        status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
        if (status == 0) {
                goto done;
 -      } else if (status >= BE_MIN_MSIX_VECTORS) {
 +      } else if (status >= MIN_MSIX_VECTORS) {
                num_vec = status;
                status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
                                         num_vec);
        }
  
        dev_warn(dev, "MSIx enable failed\n");
 +
        /* INTx is not supported in VFs, so fail probe if enable_msix fails */
        if (!be_physfn(adapter))
                return status;
        return 0;
  done:
 -      if (be_roce_supported(adapter)) {
 -              if (num_vec > num_roce_vec) {
 -                      adapter->num_msix_vec = num_vec - num_roce_vec;
 -                      adapter->num_msix_roce_vec =
 -                              num_vec - adapter->num_msix_vec;
 -              } else {
 -                      adapter->num_msix_vec = num_vec;
 -                      adapter->num_msix_roce_vec = 0;
 -              }
 -      } else
 -              adapter->num_msix_vec = num_vec;
 -      dev_info(dev, "enabled %d MSI-x vector(s)\n", adapter->num_msix_vec);
 +      if (be_roce_supported(adapter) && num_vec > MIN_MSIX_VECTORS) {
 +              adapter->num_msix_roce_vec = num_vec / 2;
 +              dev_info(dev, "enabled %d MSI-x vector(s) for RoCE\n",
 +                       adapter->num_msix_roce_vec);
 +      }
 +
 +      adapter->num_msix_vec = num_vec - adapter->num_msix_roce_vec;
 +
 +      dev_info(dev, "enabled %d MSI-x vector(s) for NIC\n",
 +               adapter->num_msix_vec);
        return 0;
  }
  
  static inline int be_msix_vec_get(struct be_adapter *adapter,
                                struct be_eq_obj *eqo)
  {
 -      return adapter->msix_entries[eqo->idx].vector;
 +      return adapter->msix_entries[eqo->msix_idx].vector;
  }
  
  static int be_msix_register(struct be_adapter *adapter)
@@@ -2643,8 -2690,8 +2643,8 @@@ static int be_setup_wol(struct be_adapt
        memset(mac, 0, ETH_ALEN);
  
        cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
 -      cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
 -                                  GFP_KERNEL | __GFP_ZERO);
 +      cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
 +                                   GFP_KERNEL);
        if (cmd.va == NULL)
                return -1;
  
@@@ -2688,13 -2735,13 +2688,13 @@@ static int be_vf_eth_addr_config(struc
        be_vf_eth_addr_generate(adapter, mac);
  
        for_all_vfs(adapter, vf_cfg, vf) {
 -              if (lancer_chip(adapter)) {
 -                      status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
 -              } else {
 +              if (BEx_chip(adapter))
                        status = be_cmd_pmac_add(adapter, mac,
                                                 vf_cfg->if_handle,
                                                 &vf_cfg->pmac_id, vf + 1);
 -              }
 +              else
 +                      status = be_cmd_set_mac(adapter, mac, vf_cfg->if_handle,
 +                                              vf + 1);
  
                if (status)
                        dev_err(&adapter->pdev->dev,
@@@ -2712,7 -2759,7 +2712,7 @@@ static int be_vfs_mac_query(struct be_a
        int status, vf;
        u8 mac[ETH_ALEN];
        struct be_vf_cfg *vf_cfg;
 -      bool active;
 +      bool active = false;
  
        for_all_vfs(adapter, vf_cfg, vf) {
                be_cmd_get_mac_from_list(adapter, mac, &active,
@@@ -2741,12 -2788,11 +2741,12 @@@ static void be_vf_clear(struct be_adapt
        pci_disable_sriov(adapter->pdev);
  
        for_all_vfs(adapter, vf_cfg, vf) {
 -              if (lancer_chip(adapter))
 -                      be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
 -              else
 +              if (BEx_chip(adapter))
                        be_cmd_pmac_del(adapter, vf_cfg->if_handle,
                                        vf_cfg->pmac_id, vf + 1);
 +              else
 +                      be_cmd_set_mac(adapter, NULL, vf_cfg->if_handle,
 +                                     vf + 1);
  
                be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
        }
@@@ -2755,40 -2801,28 +2755,40 @@@ done
        adapter->num_vfs = 0;
  }
  
 -static int be_clear(struct be_adapter *adapter)
 +static void be_clear_queues(struct be_adapter *adapter)
  {
 -      int i = 1;
 +      be_mcc_queues_destroy(adapter);
 +      be_rx_cqs_destroy(adapter);
 +      be_tx_queues_destroy(adapter);
 +      be_evt_queues_destroy(adapter);
 +}
  
 +static void be_cancel_worker(struct be_adapter *adapter)
 +{
        if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
                cancel_delayed_work_sync(&adapter->work);
                adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
        }
 +}
 +
 +static int be_clear(struct be_adapter *adapter)
 +{
 +      int i;
 +
 +      be_cancel_worker(adapter);
  
        if (sriov_enabled(adapter))
                be_vf_clear(adapter);
  
 -      for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
 +      /* delete the primary mac along with the uc-mac list */
 +      for (i = 0; i < (adapter->uc_macs + 1); i++)
                be_cmd_pmac_del(adapter, adapter->if_handle,
 -                      adapter->pmac_id[i], 0);
 +                              adapter->pmac_id[i], 0);
 +      adapter->uc_macs = 0;
  
        be_cmd_if_destroy(adapter, adapter->if_handle,  0);
  
 -      be_mcc_queues_destroy(adapter);
 -      be_rx_cqs_destroy(adapter);
 -      be_tx_queues_destroy(adapter);
 -      be_evt_queues_destroy(adapter);
 +      be_clear_queues(adapter);
  
        kfree(adapter->pmac_id);
        adapter->pmac_id = NULL;
  
  static int be_vfs_if_create(struct be_adapter *adapter)
  {
 +      struct be_resources res = {0};
        struct be_vf_cfg *vf_cfg;
        u32 cap_flags, en_flags, vf;
        int status;
                    BE_IF_FLAGS_MULTICAST;
  
        for_all_vfs(adapter, vf_cfg, vf) {
 -              if (!BE3_chip(adapter))
 -                      be_cmd_get_profile_config(adapter, &cap_flags,
 -                                                NULL, vf + 1);
 +              if (!BE3_chip(adapter)) {
 +                      status = be_cmd_get_profile_config(adapter, &res,
 +                                                         vf + 1);
 +                      if (!status)
 +                              cap_flags = res.if_cap_flags;
 +              }
  
                /* If a FW profile exists, then cap_flags are updated */
                en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED |
@@@ -2850,7 -2880,6 +2850,7 @@@ static int be_vf_setup(struct be_adapte
        u16 def_vlan, lnk_speed;
        int status, old_vfs, vf;
        struct device *dev = &adapter->pdev->dev;
 +      u32 privileges;
  
        old_vfs = pci_num_vf(adapter->pdev);
        if (old_vfs) {
                        dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
                adapter->num_vfs = old_vfs;
        } else {
 -              if (num_vfs > adapter->dev_num_vfs)
 +              if (num_vfs > be_max_vfs(adapter))
                        dev_info(dev, "Device supports %d VFs and not %d\n",
 -                               adapter->dev_num_vfs, num_vfs);
 -              adapter->num_vfs = min_t(u16, num_vfs, adapter->dev_num_vfs);
 +                               be_max_vfs(adapter), num_vfs);
 +              adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
                if (!adapter->num_vfs)
                        return 0;
        }
        }
  
        for_all_vfs(adapter, vf_cfg, vf) {
 +              /* Allow VFs to programs MAC/VLAN filters */
 +              status = be_cmd_get_fn_privileges(adapter, &privileges, vf + 1);
 +              if (!status && !(privileges & BE_PRIV_FILTMGMT)) {
 +                      status = be_cmd_set_fn_privileges(adapter,
 +                                                        privileges |
 +                                                        BE_PRIV_FILTMGMT,
 +                                                        vf + 1);
 +                      if (!status)
 +                              dev_info(dev, "VF%d has FILTMGMT privilege\n",
 +                                       vf);
 +              }
 +
                /* BE3 FW, by default, caps VF TX-rate to 100mbps.
                 * Allow full available bandwidth
                 */
                        vf_cfg->tx_rate = lnk_speed;
  
                status = be_cmd_get_hsw_config(adapter, &def_vlan,
 -                                             vf + 1, vf_cfg->if_handle);
 +                                             vf + 1, vf_cfg->if_handle, NULL);
                if (status)
                        goto err;
                vf_cfg->def_vid = def_vlan;
        return status;
  }
  
 +/* On BE2/BE3 FW does not suggest the supported limits */
 +static void BEx_get_resources(struct be_adapter *adapter,
 +                            struct be_resources *res)
 +{
 +      struct pci_dev *pdev = adapter->pdev;
 +      bool use_sriov = false;
 +
 +      if (BE3_chip(adapter) && be_physfn(adapter)) {
 +              int max_vfs;
 +
 +              max_vfs = pci_sriov_get_totalvfs(pdev);
 +              res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
 +              use_sriov = res->max_vfs && num_vfs;
 +      }
 +
 +      if (be_physfn(adapter))
 +              res->max_uc_mac = BE_UC_PMAC_COUNT;
 +      else
 +              res->max_uc_mac = BE_VF_UC_PMAC_COUNT;
 +
 +      if (adapter->function_mode & FLEX10_MODE)
 +              res->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
 +      else
 +              res->max_vlans = BE_NUM_VLANS_SUPPORTED;
 +      res->max_mcast_mac = BE_MAX_MC;
 +
 +      if (BE2_chip(adapter) || use_sriov || be_is_mc(adapter) ||
 +          !be_physfn(adapter))
 +              res->max_tx_qs = 1;
 +      else
 +              res->max_tx_qs = BE3_MAX_TX_QS;
 +
 +      if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
 +          !use_sriov && be_physfn(adapter))
 +              res->max_rss_qs = (adapter->be3_native) ?
 +                                         BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
 +      res->max_rx_qs = res->max_rss_qs + 1;
 +
 +      res->max_evt_qs = be_physfn(adapter) ? BE3_MAX_EVT_QS : 1;
 +
 +      res->if_cap_flags = BE_IF_CAP_FLAGS_WANT;
 +      if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS))
 +              res->if_cap_flags &= ~BE_IF_FLAGS_RSS;
 +}
 +
  static void be_setup_init(struct be_adapter *adapter)
  {
        adapter->vlan_prio_bmap = 0xff;
                adapter->cmd_privileges = MIN_PRIVILEGES;
  }
  
 -static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
 -                         bool *active_mac, u32 *pmac_id)
 +static int be_get_resources(struct be_adapter *adapter)
  {
 -      int status = 0;
 -
 -      if (!is_zero_ether_addr(adapter->netdev->perm_addr)) {
 -              memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
 -              if (!lancer_chip(adapter) && !be_physfn(adapter))
 -                      *active_mac = true;
 -              else
 -                      *active_mac = false;
 +      struct device *dev = &adapter->pdev->dev;
 +      struct be_resources res = {0};
 +      int status;
  
 -              return status;
 +      if (BEx_chip(adapter)) {
 +              BEx_get_resources(adapter, &res);
 +              adapter->res = res;
        }
  
 -      if (lancer_chip(adapter)) {
 -              status = be_cmd_get_mac_from_list(adapter, mac,
 -                                                active_mac, pmac_id, 0);
 -              if (*active_mac) {
 -                      status = be_cmd_mac_addr_query(adapter, mac, false,
 -                                                     if_handle, *pmac_id);
 -              }
 -      } else if (be_physfn(adapter)) {
 -              /* For BE3, for PF get permanent MAC */
 -              status = be_cmd_mac_addr_query(adapter, mac, true, 0, 0);
 -              *active_mac = false;
 -      } else {
 -              /* For BE3, for VF get soft MAC assigned by PF*/
 -              status = be_cmd_mac_addr_query(adapter, mac, false,
 -                                             if_handle, 0);
 -              *active_mac = true;
 +      /* For BE3 only check if FW suggests a different max-txqs value */
 +      if (BE3_chip(adapter)) {
 +              status = be_cmd_get_profile_config(adapter, &res, 0);
 +              if (!status && res.max_tx_qs)
 +                      adapter->res.max_tx_qs =
 +                              min(adapter->res.max_tx_qs, res.max_tx_qs);
        }
 -      return status;
 -}
 -
 -static void be_get_resources(struct be_adapter *adapter)
 -{
 -      u16 dev_num_vfs;
 -      int pos, status;
 -      bool profile_present = false;
 -      u16 txq_count = 0;
  
 +      /* For Lancer, SH etc read per-function resource limits from FW.
 +       * GET_FUNC_CONFIG returns per function guaranteed limits.
 +       * GET_PROFILE_CONFIG returns PCI-E related limits PF-pool limits
 +       */
        if (!BEx_chip(adapter)) {
 -              status = be_cmd_get_func_config(adapter);
 -              if (!status)
 -                      profile_present = true;
 -      } else if (BE3_chip(adapter) && be_physfn(adapter)) {
 -              be_cmd_get_profile_config(adapter, NULL, &txq_count, 0);
 -      }
 -
 -      if (profile_present) {
 -              /* Sanity fixes for Lancer */
 -              adapter->max_pmac_cnt = min_t(u16, adapter->max_pmac_cnt,
 -                                            BE_UC_PMAC_COUNT);
 -              adapter->max_vlans = min_t(u16, adapter->max_vlans,
 -                                         BE_NUM_VLANS_SUPPORTED);
 -              adapter->max_mcast_mac = min_t(u16, adapter->max_mcast_mac,
 -                                             BE_MAX_MC);
 -              adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues,
 -                                             MAX_TX_QS);
 -              adapter->max_rss_queues = min_t(u16, adapter->max_rss_queues,
 -                                              BE3_MAX_RSS_QS);
 -              adapter->max_event_queues = min_t(u16,
 -                                                adapter->max_event_queues,
 -                                                BE3_MAX_RSS_QS);
 -
 -              if (adapter->max_rss_queues &&
 -                  adapter->max_rss_queues == adapter->max_rx_queues)
 -                      adapter->max_rss_queues -= 1;
 -
 -              if (adapter->max_event_queues < adapter->max_rss_queues)
 -                      adapter->max_rss_queues = adapter->max_event_queues;
 -
 -      } else {
 -              if (be_physfn(adapter))
 -                      adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
 -              else
 -                      adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
 -
 -              if (adapter->function_mode & FLEX10_MODE)
 -                      adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
 -              else
 -                      adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
 +              status = be_cmd_get_func_config(adapter, &res);
 +              if (status)
 +                      return status;
  
 -              adapter->max_mcast_mac = BE_MAX_MC;
 -              adapter->max_tx_queues = txq_count ? txq_count : MAX_TX_QS;
 -              adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues,
 -                                             MAX_TX_QS);
 -              adapter->max_rss_queues = (adapter->be3_native) ?
 -                                         BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
 -              adapter->max_event_queues = BE3_MAX_RSS_QS;
 +              /* If RoCE may be enabled stash away half the EQs for RoCE */
 +              if (be_roce_supported(adapter))
 +                      res.max_evt_qs /= 2;
 +              adapter->res = res;
  
 -              adapter->if_cap_flags = BE_IF_FLAGS_UNTAGGED |
 -                                      BE_IF_FLAGS_BROADCAST |
 -                                      BE_IF_FLAGS_MULTICAST |
 -                                      BE_IF_FLAGS_PASS_L3L4_ERRORS |
 -                                      BE_IF_FLAGS_MCAST_PROMISCUOUS |
 -                                      BE_IF_FLAGS_VLAN_PROMISCUOUS |
 -                                      BE_IF_FLAGS_PROMISCUOUS;
 +              if (be_physfn(adapter)) {
 +                      status = be_cmd_get_profile_config(adapter, &res, 0);
 +                      if (status)
 +                              return status;
 +                      adapter->res.max_vfs = res.max_vfs;
 +              }
  
 -              if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
 -                      adapter->if_cap_flags |= BE_IF_FLAGS_RSS;
 +              dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
 +                       be_max_txqs(adapter), be_max_rxqs(adapter),
 +                       be_max_rss(adapter), be_max_eqs(adapter),
 +                       be_max_vfs(adapter));
 +              dev_info(dev, "Max: uc-macs %d, mc-macs %d, vlans %d\n",
 +                       be_max_uc(adapter), be_max_mc(adapter),
 +                       be_max_vlans(adapter));
        }
  
 -      pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
 -      if (pos) {
 -              pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
 -                                   &dev_num_vfs);
 -              if (BE3_chip(adapter))
 -                      dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS);
 -              adapter->dev_num_vfs = dev_num_vfs;
 -      }
 +      return 0;
  }
  
  /* Routine to query per function resource limits */
@@@ -3061,171 -3095,100 +3061,171 @@@ static int be_get_config(struct be_adap
                                     &adapter->function_caps,
                                     &adapter->asic_rev);
        if (status)
 -              goto err;
 +              return status;
  
 -      be_get_resources(adapter);
 +      status = be_get_resources(adapter);
 +      if (status)
 +              return status;
  
        /* primary mac needs 1 pmac entry */
 -      adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
 -                                 sizeof(u32), GFP_KERNEL);
 -      if (!adapter->pmac_id) {
 -              status = -ENOMEM;
 -              goto err;
 -      }
 +      adapter->pmac_id = kcalloc(be_max_uc(adapter) + 1, sizeof(u32),
 +                                 GFP_KERNEL);
 +      if (!adapter->pmac_id)
 +              return -ENOMEM;
  
 -err:
 -      return status;
 +      /* Sanitize cfg_num_qs based on HW and platform limits */
 +      adapter->cfg_num_qs = min(adapter->cfg_num_qs, be_max_qs(adapter));
 +
 +      return 0;
  }
  
 -static int be_setup(struct be_adapter *adapter)
 +static int be_mac_setup(struct be_adapter *adapter)
  {
 -      struct device *dev = &adapter->pdev->dev;
 -      u32 en_flags;
 -      u32 tx_fc, rx_fc;
 -      int status;
        u8 mac[ETH_ALEN];
 -      bool active_mac;
 +      int status;
  
 -      be_setup_init(adapter);
 +      if (is_zero_ether_addr(adapter->netdev->dev_addr)) {
 +              status = be_cmd_get_perm_mac(adapter, mac);
 +              if (status)
 +                      return status;
  
 -      if (!lancer_chip(adapter))
 -              be_cmd_req_native_mode(adapter);
 +              memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 +              memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 +      } else {
 +              /* Maybe the HW was reset; dev_addr must be re-programmed */
 +              memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
 +      }
  
 -      status = be_get_config(adapter);
 +      /* On BE3 VFs this cmd may fail due to lack of privilege.
 +       * Ignore the failure as in this case pmac_id is fetched
 +       * in the IFACE_CREATE cmd.
 +       */
 +      be_cmd_pmac_add(adapter, mac, adapter->if_handle,
 +                      &adapter->pmac_id[0], 0);
 +      return 0;
 +}
 +
 +static void be_schedule_worker(struct be_adapter *adapter)
 +{
 +      schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
 +      adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
 +}
 +
 +static int be_setup_queues(struct be_adapter *adapter)
 +{
 +      struct net_device *netdev = adapter->netdev;
 +      int status;
 +
 +      status = be_evt_queues_create(adapter);
        if (status)
                goto err;
  
 -      status = be_msix_enable(adapter);
 +      status = be_tx_qs_create(adapter);
        if (status)
                goto err;
  
 -      status = be_evt_queues_create(adapter);
 +      status = be_rx_cqs_create(adapter);
        if (status)
                goto err;
  
 -      status = be_tx_cqs_create(adapter);
 +      status = be_mcc_queues_create(adapter);
        if (status)
                goto err;
  
 -      status = be_rx_cqs_create(adapter);
 +      status = netif_set_real_num_rx_queues(netdev, adapter->num_rx_qs);
        if (status)
                goto err;
  
 -      status = be_mcc_queues_create(adapter);
 +      status = netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs);
        if (status)
                goto err;
  
 -      be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0);
 -      /* In UMC mode FW does not return right privileges.
 -       * Override with correct privilege equivalent to PF.
 +      return 0;
 +err:
 +      dev_err(&adapter->pdev->dev, "queue_setup failed\n");
 +      return status;
 +}
 +
 +int be_update_queues(struct be_adapter *adapter)
 +{
 +      struct net_device *netdev = adapter->netdev;
 +      int status;
 +
 +      if (netif_running(netdev))
 +              be_close(netdev);
 +
 +      be_cancel_worker(adapter);
 +
 +      /* If any vectors have been shared with RoCE we cannot re-program
 +       * the MSIx table.
         */
 -      if (be_is_mc(adapter))
 -              adapter->cmd_privileges = MAX_PRIVILEGES;
 +      if (!adapter->num_msix_roce_vec)
 +              be_msix_disable(adapter);
  
 -      en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
 -                      BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
 +      be_clear_queues(adapter);
  
 -      if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
 -              en_flags |= BE_IF_FLAGS_RSS;
 +      if (!msix_enabled(adapter)) {
 +              status = be_msix_enable(adapter);
 +              if (status)
 +                      return status;
 +      }
  
 -      en_flags = en_flags & adapter->if_cap_flags;
 +      status = be_setup_queues(adapter);
 +      if (status)
 +              return status;
  
 -      status = be_cmd_if_create(adapter, adapter->if_cap_flags, en_flags,
 -                                &adapter->if_handle, 0);
 -      if (status != 0)
 +      be_schedule_worker(adapter);
 +
 +      if (netif_running(netdev))
 +              status = be_open(netdev);
 +
 +      return status;
 +}
 +
 +static int be_setup(struct be_adapter *adapter)
 +{
 +      struct device *dev = &adapter->pdev->dev;
 +      u32 tx_fc, rx_fc, en_flags;
 +      int status;
 +
 +      be_setup_init(adapter);
 +
 +      if (!lancer_chip(adapter))
 +              be_cmd_req_native_mode(adapter);
 +
 +      status = be_get_config(adapter);
 +      if (status)
                goto err;
  
 -      memset(mac, 0, ETH_ALEN);
 -      active_mac = false;
 -      status = be_get_mac_addr(adapter, mac, adapter->if_handle,
 -                               &active_mac, &adapter->pmac_id[0]);
 -      if (status != 0)
 +      status = be_msix_enable(adapter);
 +      if (status)
                goto err;
  
 -      if (!active_mac) {
 -              status = be_cmd_pmac_add(adapter, mac, adapter->if_handle,
 -                                       &adapter->pmac_id[0], 0);
 -              if (status != 0)
 -                      goto err;
 -      }
 +      en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
 +                 BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
 +      if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
 +              en_flags |= BE_IF_FLAGS_RSS;
 +      en_flags = en_flags & be_if_cap_flags(adapter);
 +      status = be_cmd_if_create(adapter, be_if_cap_flags(adapter), en_flags,
 +                                &adapter->if_handle, 0);
 +      if (status)
 +              goto err;
  
 -      if (is_zero_ether_addr(adapter->netdev->dev_addr)) {
 -              memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
 -              memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
 -      }
 +      /* Updating real_num_tx/rx_queues() requires rtnl_lock() */
 +      rtnl_lock();
 +      status = be_setup_queues(adapter);
 +      rtnl_unlock();
 +      if (status)
 +              goto err;
  
 -      status = be_tx_qs_create(adapter);
 +      be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0);
 +      /* In UMC mode FW does not return right privileges.
 +       * Override with correct privilege equivalent to PF.
 +       */
 +      if (be_is_mc(adapter))
 +              adapter->cmd_privileges = MAX_PRIVILEGES;
 +
 +      status = be_mac_setup(adapter);
        if (status)
                goto err;
  
                be_cmd_set_flow_control(adapter, adapter->tx_fc,
                                        adapter->rx_fc);
  
 -      if (be_physfn(adapter)) {
 -              if (adapter->dev_num_vfs)
 +      if (be_physfn(adapter) && num_vfs) {
 +              if (be_max_vfs(adapter))
                        be_vf_setup(adapter);
                else
                        dev_warn(dev, "device doesn't support SRIOV\n");
        if (!status && be_pause_supported(adapter))
                adapter->phy.fc_autoneg = 1;
  
 -      schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
 -      adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
 +      be_schedule_worker(adapter);
        return 0;
  err:
        be_clear(adapter);
@@@ -3277,7 -3241,7 +3277,7 @@@ static void be_netpoll(struct net_devic
  #endif
  
  #define FW_FILE_HDR_SIGN      "ServerEngines Corp. "
 -char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
 +static char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
  
  static bool be_flash_redboot(struct be_adapter *adapter,
                        const u8 *p, u32 img_start, int image_size,
@@@ -3334,7 -3298,7 +3334,7 @@@ static bool is_comp_in_ufi(struct be_ad
  
  }
  
 -struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
 +static struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
                                         int header_size,
                                         const struct firmware *fw)
  {
@@@ -3796,74 -3760,6 +3796,74 @@@ fw_exit
        return status;
  }
  
 +static int be_ndo_bridge_setlink(struct net_device *dev,
 +                                  struct nlmsghdr *nlh)
 +{
 +      struct be_adapter *adapter = netdev_priv(dev);
 +      struct nlattr *attr, *br_spec;
 +      int rem;
 +      int status = 0;
 +      u16 mode = 0;
 +
 +      if (!sriov_enabled(adapter))
 +              return -EOPNOTSUPP;
 +
 +      br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
 +
 +      nla_for_each_nested(attr, br_spec, rem) {
 +              if (nla_type(attr) != IFLA_BRIDGE_MODE)
 +                      continue;
 +
 +              mode = nla_get_u16(attr);
 +              if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
 +                      return -EINVAL;
 +
 +              status = be_cmd_set_hsw_config(adapter, 0, 0,
 +                                             adapter->if_handle,
 +                                             mode == BRIDGE_MODE_VEPA ?
 +                                             PORT_FWD_TYPE_VEPA :
 +                                             PORT_FWD_TYPE_VEB);
 +              if (status)
 +                      goto err;
 +
 +              dev_info(&adapter->pdev->dev, "enabled switch mode: %s\n",
 +                       mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
 +
 +              return status;
 +      }
 +err:
 +      dev_err(&adapter->pdev->dev, "Failed to set switch mode %s\n",
 +              mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
 +
 +      return status;
 +}
 +
 +static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 +                                  struct net_device *dev,
 +                                  u32 filter_mask)
 +{
 +      struct be_adapter *adapter = netdev_priv(dev);
 +      int status = 0;
 +      u8 hsw_mode;
 +
 +      if (!sriov_enabled(adapter))
 +              return 0;
 +
 +      /* BE and Lancer chips support VEB mode only */
 +      if (BEx_chip(adapter) || lancer_chip(adapter)) {
 +              hsw_mode = PORT_FWD_TYPE_VEB;
 +      } else {
 +              status = be_cmd_get_hsw_config(adapter, NULL, 0,
 +                                             adapter->if_handle, &hsw_mode);
 +              if (status)
 +                      return 0;
 +      }
 +
 +      return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
 +                                     hsw_mode == PORT_FWD_TYPE_VEPA ?
 +                                     BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
 +}
 +
  static const struct net_device_ops be_netdev_ops = {
        .ndo_open               = be_open,
        .ndo_stop               = be_close,
  #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = be_netpoll,
  #endif
 +      .ndo_bridge_setlink     = be_ndo_bridge_setlink,
 +      .ndo_bridge_getlink     = be_ndo_bridge_getlink,
  };
  
  static void be_netdev_init(struct net_device *netdev)
  {
        struct be_adapter *adapter = netdev_priv(netdev);
 -      struct be_eq_obj *eqo;
 -      int i;
  
        netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
        netdev->netdev_ops = &be_netdev_ops;
  
        SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
 -
 -      for_all_evt_queues(adapter, eqo, i)
 -              netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
  }
  
  static void be_unmap_pci_bars(struct be_adapter *adapter)
@@@ -4017,9 -3916,9 +4017,9 @@@ static int be_ctrl_init(struct be_adapt
        memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
  
        rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
 -      rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
 -                                         &rx_filter->dma,
 -                                         GFP_KERNEL | __GFP_ZERO);
 +      rx_filter->va = dma_zalloc_coherent(&adapter->pdev->dev,
 +                                          rx_filter->size, &rx_filter->dma,
 +                                          GFP_KERNEL);
        if (rx_filter->va == NULL) {
                status = -ENOMEM;
                goto free_mbox;
@@@ -4065,8 -3964,8 +4065,8 @@@ static int be_stats_init(struct be_adap
                /* BE3 and Skyhawk */
                cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
  
 -      cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
 -                                   GFP_KERNEL | __GFP_ZERO);
 +      cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
 +                                    GFP_KERNEL);
        if (cmd->va == NULL)
                return -1;
        return 0;
@@@ -4173,7 -4072,6 +4173,7 @@@ static int be_get_initial_config(struc
        level = be_get_fw_log_level(adapter);
        adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
  
 +      adapter->cfg_num_qs = netif_get_num_default_rss_queues();
        return 0;
  }
  
@@@ -4266,8 -4164,7 +4266,8 @@@ static void be_worker(struct work_struc
                        be_cmd_get_stats(adapter, &adapter->stats_cmd);
        }
  
 -      if (MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
 +      if (be_physfn(adapter) &&
 +          MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
                be_cmd_get_die_temperature(adapter);
  
        for_all_rx_queues(adapter, rxo, i) {
@@@ -4356,7 -4253,7 +4356,7 @@@ static int be_probe(struct pci_dev *pde
  
        status = pci_enable_pcie_error_reporting(pdev);
        if (status)
 -              dev_err(&pdev->dev, "Could not use PCIe error reporting\n");
 +              dev_info(&pdev->dev, "Could not use PCIe error reporting\n");
  
        status = be_ctrl_init(adapter);
        if (status)
@@@ -4476,6 -4373,10 +4476,10 @@@ static int be_resume(struct pci_dev *pd
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
  
+       status = be_fw_wait_ready(adapter);
+       if (status)
+               return status;
        /* tell fw we're ready to fire cmds */
        status = be_cmd_fw_init(adapter);
        if (status)
index 0cd5e4b8b545d9a0cc8f6af01a7a0af7841ff4fd,fd90bf561d83562848e020464939b2674be61b94..f9aacf5d85230c67fadaa9b892f9765da30171a7
@@@ -69,6 -69,7 +69,6 @@@ static void set_multicast_list(struct n
  #endif
  
  #define DRIVER_NAME   "fec"
 -#define FEC_NAPI_WEIGHT       64
  
  /* Pause frame feild and FIFO threshold */
  #define FEC_ENET_FCE  (1 << 5)
@@@ -238,22 -239,57 +238,57 @@@ MODULE_PARM_DESC(macaddr, "FEC Etherne
  
  static int mii_cnt;
  
- static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, int is_ex)
+ static inline
+ struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, struct fec_enet_private *fep)
  {
-       struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
-       if (is_ex)
-               return (struct bufdesc *)(ex + 1);
+       struct bufdesc *new_bd = bdp + 1;
+       struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp + 1;
+       struct bufdesc_ex *ex_base;
+       struct bufdesc *base;
+       int ring_size;
+       if (bdp >= fep->tx_bd_base) {
+               base = fep->tx_bd_base;
+               ring_size = fep->tx_ring_size;
+               ex_base = (struct bufdesc_ex *)fep->tx_bd_base;
+       } else {
+               base = fep->rx_bd_base;
+               ring_size = fep->rx_ring_size;
+               ex_base = (struct bufdesc_ex *)fep->rx_bd_base;
+       }
+       if (fep->bufdesc_ex)
+               return (struct bufdesc *)((ex_new_bd >= (ex_base + ring_size)) ?
+                       ex_base : ex_new_bd);
        else
-               return bdp + 1;
+               return (new_bd >= (base + ring_size)) ?
+                       base : new_bd;
  }
  
- static struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp, int is_ex)
+ static inline
+ struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp, struct fec_enet_private *fep)
  {
-       struct bufdesc_ex *ex = (struct bufdesc_ex *)bdp;
-       if (is_ex)
-               return (struct bufdesc *)(ex - 1);
+       struct bufdesc *new_bd = bdp - 1;
+       struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp - 1;
+       struct bufdesc_ex *ex_base;
+       struct bufdesc *base;
+       int ring_size;
+       if (bdp >= fep->tx_bd_base) {
+               base = fep->tx_bd_base;
+               ring_size = fep->tx_ring_size;
+               ex_base = (struct bufdesc_ex *)fep->tx_bd_base;
+       } else {
+               base = fep->rx_bd_base;
+               ring_size = fep->rx_ring_size;
+               ex_base = (struct bufdesc_ex *)fep->rx_bd_base;
+       }
+       if (fep->bufdesc_ex)
+               return (struct bufdesc *)((ex_new_bd < ex_base) ?
+                       (ex_new_bd + ring_size) : ex_new_bd);
        else
-               return bdp - 1;
+               return (new_bd < base) ? (new_bd + ring_size) : new_bd;
  }
  
  static void *swap_buffer(void *bufaddr, int len)
@@@ -379,7 -415,7 +414,7 @@@ fec_enet_start_xmit(struct sk_buff *skb
                }
        }
  
-       bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp_pre = fec_enet_get_prevdesc(bdp, fep);
        if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
            !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {
                fep->delay_work.trig_tx = true;
        }
  
        /* If this was the last BD in the ring, start at the beginning again. */
-       if (status & BD_ENET_TX_WRAP)
-               bdp = fep->tx_bd_base;
-       else
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_nextdesc(bdp, fep);
  
        fep->cur_tx = bdp;
  
@@@ -416,18 -449,18 +448,18 @@@ static void fec_enet_bd_init(struct net
  
        /* Initialize the receive buffer descriptors. */
        bdp = fep->rx_bd_base;
-       for (i = 0; i < RX_RING_SIZE; i++) {
+       for (i = 0; i < fep->rx_ring_size; i++) {
  
                /* Initialize the BD for every fragment in the page. */
                if (bdp->cbd_bufaddr)
                        bdp->cbd_sc = BD_ENET_RX_EMPTY;
                else
                        bdp->cbd_sc = 0;
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
        }
  
        /* Set the last buffer to wrap */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_prevdesc(bdp, fep);
        bdp->cbd_sc |= BD_SC_WRAP;
  
        fep->cur_rx = fep->rx_bd_base;
        /* ...and the same for transmit */
        bdp = fep->tx_bd_base;
        fep->cur_tx = bdp;
-       for (i = 0; i < TX_RING_SIZE; i++) {
+       for (i = 0; i < fep->tx_ring_size; i++) {
  
                /* Initialize the BD for every fragment in the page. */
                bdp->cbd_sc = 0;
                        fep->tx_skbuff[i] = NULL;
                }
                bdp->cbd_bufaddr = 0;
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
        }
  
        /* Set the last buffer to wrap */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_prevdesc(bdp, fep);
        bdp->cbd_sc |= BD_SC_WRAP;
        fep->dirty_tx = bdp;
  }
@@@ -509,10 -542,10 +541,10 @@@ fec_restart(struct net_device *ndev, in
        writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
        if (fep->bufdesc_ex)
                writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc_ex)
-                       * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
+                       * fep->rx_ring_size, fep->hwp + FEC_X_DES_START);
        else
                writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
-                       * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
+                       * fep->rx_ring_size,    fep->hwp + FEC_X_DES_START);
  
  
        for (i = 0; i <= TX_RING_MOD_MASK; i++) {
@@@ -726,10 -759,7 +758,7 @@@ fec_enet_tx(struct net_device *ndev
        bdp = fep->dirty_tx;
  
        /* get next bdp of dirty_tx */
-       if (bdp->cbd_sc & BD_ENET_TX_WRAP)
-               bdp = fep->tx_bd_base;
-       else
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_nextdesc(bdp, fep);
  
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
  
                fep->dirty_tx = bdp;
  
                /* Update pointer to next buffer descriptor to be transmitted */
-               if (status & BD_ENET_TX_WRAP)
-                       bdp = fep->tx_bd_base;
-               else
-                       bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
  
                /* Since we have freed up a buffer, the ring is no longer full
                 */
@@@ -970,8 -997,7 +996,7 @@@ fec_enet_rx(struct net_device *ndev, in
                                                       htons(ETH_P_8021Q),
                                                       vlan_tag);
  
-                       if (!skb_defer_rx_timestamp(skb))
-                               napi_gro_receive(&fep->napi, skb);
+                       napi_gro_receive(&fep->napi, skb);
                }
  
                bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, data,
@@@ -993,10 -1019,8 +1018,8 @@@ rx_processing_done
                }
  
                /* Update BD pointer to next entry */
-               if (status & BD_ENET_RX_WRAP)
-                       bdp = fep->rx_bd_base;
-               else
-                       bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
                /* Doing this here will keep the FEC running while we process
                 * incoming frames.  On a heavily loaded network, we should be
                 * able to keep up at the expense of system resources.
@@@ -1059,7 -1083,7 +1082,7 @@@ static int fec_enet_rx_napi(struct napi
  static void fec_get_mac(struct net_device *ndev)
  {
        struct fec_enet_private *fep = netdev_priv(ndev);
 -      struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
 +      struct fec_platform_data *pdata = dev_get_platdata(&fep->pdev->dev);
        unsigned char *iap, tmpaddr[ETH_ALEN];
  
        /*
         * 4) FEC mac registers set by bootloader
         */
        if (!is_valid_ether_addr(iap)) {
 -              *((unsigned long *) &tmpaddr[0]) =
 -                      be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
 -              *((unsigned short *) &tmpaddr[4]) =
 -                      be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
 +              *((__be32 *) &tmpaddr[0]) =
 +                      cpu_to_be32(readl(fep->hwp + FEC_ADDR_LOW));
 +              *((__be16 *) &tmpaddr[4]) =
 +                      cpu_to_be16(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
                iap = &tmpaddr[0];
        }
  
@@@ -1662,7 -1686,7 +1685,7 @@@ static void fec_enet_free_buffers(struc
        struct bufdesc  *bdp;
  
        bdp = fep->rx_bd_base;
-       for (i = 0; i < RX_RING_SIZE; i++) {
+       for (i = 0; i < fep->rx_ring_size; i++) {
                skb = fep->rx_skbuff[i];
  
                if (bdp->cbd_bufaddr)
                                        FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
                if (skb)
                        dev_kfree_skb(skb);
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
        }
  
        bdp = fep->tx_bd_base;
-       for (i = 0; i < TX_RING_SIZE; i++)
+       for (i = 0; i < fep->tx_ring_size; i++)
                kfree(fep->tx_bounce[i]);
  }
  
@@@ -1686,7 -1710,7 +1709,7 @@@ static int fec_enet_alloc_buffers(struc
        struct bufdesc  *bdp;
  
        bdp = fep->rx_bd_base;
-       for (i = 0; i < RX_RING_SIZE; i++) {
+       for (i = 0; i < fep->rx_ring_size; i++) {
                skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
                if (!skb) {
                        fec_enet_free_buffers(ndev);
                        ebdp->cbd_esc = BD_ENET_RX_INT;
                }
  
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
        }
  
        /* Set the last buffer to wrap. */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_prevdesc(bdp, fep);
        bdp->cbd_sc |= BD_SC_WRAP;
  
        bdp = fep->tx_bd_base;
-       for (i = 0; i < TX_RING_SIZE; i++) {
+       for (i = 0; i < fep->tx_ring_size; i++) {
                fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
  
                bdp->cbd_sc = 0;
                        ebdp->cbd_esc = BD_ENET_TX_INT;
                }
  
-               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+               bdp = fec_enet_get_nextdesc(bdp, fep);
        }
  
        /* Set the last buffer to wrap. */
-       bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
+       bdp = fec_enet_get_prevdesc(bdp, fep);
        bdp->cbd_sc |= BD_SC_WRAP;
  
        return 0;
@@@ -1966,13 -1990,17 +1989,17 @@@ static int fec_enet_init(struct net_dev
        /* Get the Ethernet address */
        fec_get_mac(ndev);
  
+       /* init the tx & rx ring size */
+       fep->tx_ring_size = TX_RING_SIZE;
+       fep->rx_ring_size = RX_RING_SIZE;
        /* Set receive and transmit descriptor base. */
        fep->rx_bd_base = cbd_base;
        if (fep->bufdesc_ex)
                fep->tx_bd_base = (struct bufdesc *)
-                       (((struct bufdesc_ex *)cbd_base) + RX_RING_SIZE);
+                       (((struct bufdesc_ex *)cbd_base) + fep->rx_ring_size);
        else
-               fep->tx_bd_base = cbd_base + RX_RING_SIZE;
+               fep->tx_bd_base = cbd_base + fep->rx_ring_size;
  
        /* The FEC Ethernet specific entries in the device structure */
        ndev->watchdog_timeo = TX_TIMEOUT;
        ndev->ethtool_ops = &fec_enet_ethtool_ops;
  
        writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK);
 -      netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT);
 +      netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, NAPI_POLL_WEIGHT);
  
        if (id_entry->driver_data & FEC_QUIRK_HAS_VLAN) {
                /* enable hw VLAN support */
@@@ -2055,6 -2083,10 +2082,6 @@@ fec_probe(struct platform_device *pdev
        if (of_id)
                pdev->id_entry = of_id->data;
  
 -      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!r)
 -              return -ENXIO;
 -
        /* Init network device */
        ndev = alloc_etherdev(sizeof(struct fec_enet_private));
        if (!ndev)
                fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
  #endif
  
 +      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        fep->hwp = devm_ioremap_resource(&pdev->dev, r);
        if (IS_ERR(fep->hwp)) {
                ret = PTR_ERR(fep->hwp);
  
        ret = of_get_phy_mode(pdev->dev.of_node);
        if (ret < 0) {
 -              pdata = pdev->dev.platform_data;
 +              pdata = dev_get_platdata(&pdev->dev);
                if (pdata)
                        fep->phy_interface = pdata->phy;
                else
                fep->bufdesc_ex = 0;
        }
  
 -      clk_prepare_enable(fep->clk_ahb);
 -      clk_prepare_enable(fep->clk_ipg);
 -      clk_prepare_enable(fep->clk_enet_out);
 -      clk_prepare_enable(fep->clk_ptp);
 +      ret = clk_prepare_enable(fep->clk_ahb);
 +      if (ret)
 +              goto failed_clk;
 +
 +      ret = clk_prepare_enable(fep->clk_ipg);
 +      if (ret)
 +              goto failed_clk_ipg;
 +
 +      if (fep->clk_enet_out) {
 +              ret = clk_prepare_enable(fep->clk_enet_out);
 +              if (ret)
 +                      goto failed_clk_enet_out;
 +      }
 +
 +      if (fep->clk_ptp) {
 +              ret = clk_prepare_enable(fep->clk_ptp);
 +              if (ret)
 +                      goto failed_clk_ptp;
 +      }
  
        fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
        if (!IS_ERR(fep->reg_phy)) {
                        ret = irq;
                        goto failed_irq;
                }
 -              ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
 -              if (ret) {
 -                      while (--i >= 0) {
 -                              irq = platform_get_irq(pdev, i);
 -                              free_irq(irq, ndev);
 -                      }
 +              ret = devm_request_irq(&pdev->dev, irq, fec_enet_interrupt,
 +                                     IRQF_DISABLED, pdev->name, ndev);
 +              if (ret)
                        goto failed_irq;
 -              }
        }
  
        ret = fec_enet_mii_init(pdev);
@@@ -2198,19 -2218,19 +2225,19 @@@ failed_register
        fec_enet_mii_remove(fep);
  failed_mii_init:
  failed_irq:
 -      for (i = 0; i < FEC_IRQ_NUM; i++) {
 -              irq = platform_get_irq(pdev, i);
 -              if (irq > 0)
 -                      free_irq(irq, ndev);
 -      }
  failed_init:
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
  failed_regulator:
 -      clk_disable_unprepare(fep->clk_ahb);
 +      if (fep->clk_ptp)
 +              clk_disable_unprepare(fep->clk_ptp);
 +failed_clk_ptp:
 +      if (fep->clk_enet_out)
 +              clk_disable_unprepare(fep->clk_enet_out);
 +failed_clk_enet_out:
        clk_disable_unprepare(fep->clk_ipg);
 -      clk_disable_unprepare(fep->clk_enet_out);
 -      clk_disable_unprepare(fep->clk_ptp);
 +failed_clk_ipg:
 +      clk_disable_unprepare(fep->clk_ahb);
  failed_clk:
  failed_ioremap:
        free_netdev(ndev);
@@@ -2223,21 -2243,25 +2250,21 @@@ fec_drv_remove(struct platform_device *
  {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct fec_enet_private *fep = netdev_priv(ndev);
 -      int i;
  
        cancel_delayed_work_sync(&(fep->delay_work.delay_work));
        unregister_netdev(ndev);
        fec_enet_mii_remove(fep);
        del_timer_sync(&fep->time_keep);
 -      for (i = 0; i < FEC_IRQ_NUM; i++) {
 -              int irq = platform_get_irq(pdev, i);
 -              if (irq > 0)
 -                      free_irq(irq, ndev);
 -      }
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
 -      clk_disable_unprepare(fep->clk_ptp);
 +      if (fep->clk_ptp)
 +              clk_disable_unprepare(fep->clk_ptp);
        if (fep->ptp_clock)
                ptp_clock_unregister(fep->ptp_clock);
 -      clk_disable_unprepare(fep->clk_enet_out);
 -      clk_disable_unprepare(fep->clk_ahb);
 +      if (fep->clk_enet_out)
 +              clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ipg);
 +      clk_disable_unprepare(fep->clk_ahb);
        free_netdev(ndev);
  
        return 0;
@@@ -2254,12 -2278,9 +2281,12 @@@ fec_suspend(struct device *dev
                fec_stop(ndev);
                netif_device_detach(ndev);
        }
 -      clk_disable_unprepare(fep->clk_enet_out);
 -      clk_disable_unprepare(fep->clk_ahb);
 +      if (fep->clk_ptp)
 +              clk_disable_unprepare(fep->clk_ptp);
 +      if (fep->clk_enet_out)
 +              clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ipg);
 +      clk_disable_unprepare(fep->clk_ahb);
  
        if (fep->reg_phy)
                regulator_disable(fep->reg_phy);
@@@ -2280,44 -2301,15 +2307,44 @@@ fec_resume(struct device *dev
                        return ret;
        }
  
 -      clk_prepare_enable(fep->clk_enet_out);
 -      clk_prepare_enable(fep->clk_ahb);
 -      clk_prepare_enable(fep->clk_ipg);
 +      ret = clk_prepare_enable(fep->clk_ahb);
 +      if (ret)
 +              goto failed_clk_ahb;
 +
 +      ret = clk_prepare_enable(fep->clk_ipg);
 +      if (ret)
 +              goto failed_clk_ipg;
 +
 +      if (fep->clk_enet_out) {
 +              ret = clk_prepare_enable(fep->clk_enet_out);
 +              if (ret)
 +                      goto failed_clk_enet_out;
 +      }
 +
 +      if (fep->clk_ptp) {
 +              ret = clk_prepare_enable(fep->clk_ptp);
 +              if (ret)
 +                      goto failed_clk_ptp;
 +      }
 +
        if (netif_running(ndev)) {
                fec_restart(ndev, fep->full_duplex);
                netif_device_attach(ndev);
        }
  
        return 0;
 +
 +failed_clk_ptp:
 +      if (fep->clk_enet_out)
 +              clk_disable_unprepare(fep->clk_enet_out);
 +failed_clk_enet_out:
 +      clk_disable_unprepare(fep->clk_ipg);
 +failed_clk_ipg:
 +      clk_disable_unprepare(fep->clk_ahb);
 +failed_clk_ahb:
 +      if (fep->reg_phy)
 +              regulator_disable(fep->reg_phy);
 +      return ret;
  }
  #endif /* CONFIG_PM_SLEEP */
  
index 2777c70c603b550676b77027fd96e7b9a79fbe6b,389a854b88fc7280403e17d249f128b9b4431382..e35bac7cfdf14dc85d2bb55b49a864c29f2ae2c6
  #define MVNETA_MAC_ADDR_HIGH                     0x2418
  #define MVNETA_SDMA_CONFIG                       0x241c
  #define      MVNETA_SDMA_BRST_SIZE_16            4
 -#define      MVNETA_NO_DESC_SWAP                 0x0
  #define      MVNETA_RX_BRST_SZ_MASK(burst)       ((burst) << 1)
  #define      MVNETA_RX_NO_DATA_SWAP              BIT(4)
  #define      MVNETA_TX_NO_DATA_SWAP              BIT(5)
 +#define      MVNETA_DESC_SWAP                    BIT(6)
  #define      MVNETA_TX_BRST_SZ_MASK(burst)       ((burst) << 22)
  #define MVNETA_PORT_STATUS                       0x2444
  #define      MVNETA_TX_IN_PRGRS                  BIT(1)
  #define      MVNETA_GMAC_FORCE_LINK_PASS         BIT(1)
  #define      MVNETA_GMAC_CONFIG_MII_SPEED        BIT(5)
  #define      MVNETA_GMAC_CONFIG_GMII_SPEED       BIT(6)
+ #define      MVNETA_GMAC_AN_SPEED_EN             BIT(7)
  #define      MVNETA_GMAC_CONFIG_FULL_DUPLEX      BIT(12)
+ #define      MVNETA_GMAC_AN_DUPLEX_EN            BIT(13)
  #define MVNETA_MIB_COUNTERS_BASE                 0x3080
  #define      MVNETA_MIB_LATE_COLLISION           0x7c
  #define MVNETA_DA_FILT_SPEC_MCAST                0x3400
@@@ -264,7 -266,8 +266,7 @@@ struct mvneta_port 
   * layout of the transmit and reception DMA descriptors, and their
   * layout is therefore defined by the hardware design
   */
 -struct mvneta_tx_desc {
 -      u32  command;           /* Options used by HW for packet transmitting.*/
 +
  #define MVNETA_TX_L3_OFF_SHIFT        0
  #define MVNETA_TX_IP_HLEN_SHIFT       8
  #define MVNETA_TX_L4_UDP      BIT(16)
  #define MVNETA_TX_L4_CSUM_FULL        BIT(30)
  #define MVNETA_TX_L4_CSUM_NOT BIT(31)
  
 -      u16  reserverd1;        /* csum_l4 (for future use)             */
 -      u16  data_size;         /* Data size of transmitted packet in bytes */
 -      u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
 -      u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
 -      u32  reserved3[4];      /* Reserved - (for future use)          */
 -};
 -
 -struct mvneta_rx_desc {
 -      u32  status;            /* Info about received packet           */
  #define MVNETA_RXD_ERR_CRC            0x0
  #define MVNETA_RXD_ERR_SUMMARY                BIT(16)
  #define MVNETA_RXD_ERR_OVERRUN                BIT(17)
  #define MVNETA_RXD_FIRST_LAST_DESC    (BIT(26) | BIT(27))
  #define MVNETA_RXD_L4_CSUM_OK         BIT(30)
  
 +#if defined(__LITTLE_ENDIAN)
 +struct mvneta_tx_desc {
 +      u32  command;           /* Options used by HW for packet transmitting.*/
 +      u16  reserverd1;        /* csum_l4 (for future use)             */
 +      u16  data_size;         /* Data size of transmitted packet in bytes */
 +      u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
 +      u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
 +      u32  reserved3[4];      /* Reserved - (for future use)          */
 +};
 +
 +struct mvneta_rx_desc {
 +      u32  status;            /* Info about received packet           */
        u16  reserved1;         /* pnc_info - (for future use, PnC)     */
        u16  data_size;         /* Size of received packet in bytes     */
 +
        u32  buf_phys_addr;     /* Physical address of the buffer       */
        u32  reserved2;         /* pnc_flow_id  (for future use, PnC)   */
 +
        u32  buf_cookie;        /* cookie for access to RX buffer in rx path */
        u16  reserved3;         /* prefetch_cmd, for future use         */
        u16  reserved4;         /* csum_l4 - (for future use, PnC)      */
 +
 +      u32  reserved5;         /* pnc_extra PnC (for future use, PnC)  */
 +      u32  reserved6;         /* hw_cmd (for future use, PnC and HWF) */
 +};
 +#else
 +struct mvneta_tx_desc {
 +      u16  data_size;         /* Data size of transmitted packet in bytes */
 +      u16  reserverd1;        /* csum_l4 (for future use)             */
 +      u32  command;           /* Options used by HW for packet transmitting.*/
 +      u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
 +      u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
 +      u32  reserved3[4];      /* Reserved - (for future use)          */
 +};
 +
 +struct mvneta_rx_desc {
 +      u16  data_size;         /* Size of received packet in bytes     */
 +      u16  reserved1;         /* pnc_info - (for future use, PnC)     */
 +      u32  status;            /* Info about received packet           */
 +
 +      u32  reserved2;         /* pnc_flow_id  (for future use, PnC)   */
 +      u32  buf_phys_addr;     /* Physical address of the buffer       */
 +
 +      u16  reserved4;         /* csum_l4 - (for future use, PnC)      */
 +      u16  reserved3;         /* prefetch_cmd, for future use         */
 +      u32  buf_cookie;        /* cookie for access to RX buffer in rx path */
 +
        u32  reserved5;         /* pnc_extra PnC (for future use, PnC)  */
        u32  reserved6;         /* hw_cmd (for future use, PnC and HWF) */
  };
 +#endif
  
  struct mvneta_tx_queue {
        /* Number of this TX queue, in the range 0-7 */
@@@ -939,15 -910,20 +941,22 @@@ static void mvneta_defaults_set(struct 
        /* Default burst size */
        val |= MVNETA_TX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
        val |= MVNETA_RX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
 +      val |= MVNETA_RX_NO_DATA_SWAP | MVNETA_TX_NO_DATA_SWAP;
  
 -      val |= (MVNETA_RX_NO_DATA_SWAP | MVNETA_TX_NO_DATA_SWAP |
 -              MVNETA_NO_DESC_SWAP);
 +#if defined(__BIG_ENDIAN)
 +      val |= MVNETA_DESC_SWAP;
 +#endif
  
        /* Assign port SDMA configuration */
        mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
  
+       /* Disable PHY polling in hardware, since we're using the
+        * kernel phylib to do this.
+        */
+       val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
+       val &= ~MVNETA_PHY_POLLING_ENABLE;
+       mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
        mvneta_set_ucast_table(pp, -1);
        mvneta_set_special_mcast_table(pp, -1);
        mvneta_set_other_mcast_table(pp, -1);
@@@ -2340,7 -2316,9 +2349,9 @@@ static void mvneta_adjust_link(struct n
                        val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
                        val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
                                 MVNETA_GMAC_CONFIG_GMII_SPEED |
-                                MVNETA_GMAC_CONFIG_FULL_DUPLEX);
+                                MVNETA_GMAC_CONFIG_FULL_DUPLEX |
+                                MVNETA_GMAC_AN_SPEED_EN |
+                                MVNETA_GMAC_AN_DUPLEX_EN);
  
                        if (phydev->duplex)
                                val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
@@@ -2473,6 -2451,21 +2484,21 @@@ static int mvneta_stop(struct net_devic
        return 0;
  }
  
+ static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+       struct mvneta_port *pp = netdev_priv(dev);
+       int ret;
+       if (!pp->phy_dev)
+               return -ENOTSUPP;
+       ret = phy_mii_ioctl(pp->phy_dev, ifr, cmd);
+       if (!ret)
+               mvneta_adjust_link(dev);
+       return ret;
+ }
  /* Ethtool methods */
  
  /* Get settings (phy address, speed) for ethtools */
@@@ -2591,6 -2584,7 +2617,7 @@@ static const struct net_device_ops mvne
        .ndo_change_mtu      = mvneta_change_mtu,
        .ndo_tx_timeout      = mvneta_tx_timeout,
        .ndo_get_stats64     = mvneta_get_stats64,
+       .ndo_do_ioctl        = mvneta_ioctl,
  };
  
  const struct ethtool_ops mvneta_eth_tool_ops = {
index 1046e9461509a57d314bb78052d88f7b26e2d6aa,ec4cf7fd4123e1a446dd125b41652bcf05f330bb..cbd75f97ffb3c6d32624e15b81adcb05d5d4b1d9
@@@ -197,7 -197,7 +197,7 @@@ netxen_napi_add(struct netxen_adapter *
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
                netif_napi_add(netdev, &sds_ring->napi,
-                               netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+                               netxen_nic_poll, NAPI_POLL_WEIGHT);
        }
  
        return 0;
@@@ -459,14 -459,16 +459,14 @@@ static void netxen_pcie_strap_init(stru
  static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
  {
        u32 control;
 -      int pos;
  
 -      pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
 -      if (pos) {
 -              pci_read_config_dword(pdev, pos, &control);
 +      if (pdev->msix_cap) {
 +              pci_read_config_dword(pdev, pdev->msix_cap, &control);
                if (enable)
                        control |= PCI_MSIX_FLAGS_ENABLE;
                else
                        control = 0;
 -              pci_write_config_dword(pdev, pos, control);
 +              pci_write_config_dword(pdev, pdev->msix_cap, control);
        }
  }
  
index 474c8a86a2af7ed4ae10bb875666127dabfaccfc,3426d32a1803c7fc7c19fe9249737e009aefbfda..5cd831ebfa83b0a95c472926a0105c521f7c352a
@@@ -189,7 -189,6 +189,7 @@@ static const u16 sh_eth_offset_fast_rca
        [RMCR]          = 0x0258,
        [TFUCR]         = 0x0264,
        [RFOCR]         = 0x0268,
 +      [RMIIMODE]      = 0x026c,
        [FCFTR]         = 0x0270,
        [TRIMD]         = 0x027c,
  };
@@@ -378,8 -377,6 +378,8 @@@ static struct sh_eth_cpu_data r8a777x_d
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_r8a777x,
  
 +      .register_type  = SH_ETH_REG_FAST_RCAR,
 +
        .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
        .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
        .eesipr_value   = 0x01ff009f,
        .hw_swap        = 1,
  };
  
 +/* R8A7790 */
 +static struct sh_eth_cpu_data r8a7790_data = {
 +      .set_duplex     = sh_eth_set_duplex,
 +      .set_rate       = sh_eth_set_rate_r8a777x,
 +
 +      .register_type  = SH_ETH_REG_FAST_RCAR,
 +
 +      .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
 +      .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
 +      .eesipr_value   = 0x01ff009f,
 +
 +      .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
 +      .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
 +                        EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
 +                        EESR_ECI,
 +
 +      .apr            = 1,
 +      .mpr            = 1,
 +      .tpauser        = 1,
 +      .hw_swap        = 1,
 +      .rmiimode       = 1,
 +      .shift_rd0      = 1,
 +};
 +
  static void sh_eth_set_rate_sh7724(struct net_device *ndev)
  {
        struct sh_eth_private *mdp = netdev_priv(ndev);
@@@ -440,8 -413,6 +440,8 @@@ static struct sh_eth_cpu_data sh7724_da
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_sh7724,
  
 +      .register_type  = SH_ETH_REG_FAST_SH4,
 +
        .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
        .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
        .eesipr_value   = 0x01ff009f,
@@@ -480,8 -451,6 +480,8 @@@ static struct sh_eth_cpu_data sh7757_da
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_sh7757,
  
 +      .register_type  = SH_ETH_REG_FAST_SH4,
 +
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
        .rmcr_value     = 0x00000001,
  
@@@ -550,8 -519,6 +550,8 @@@ static struct sh_eth_cpu_data sh7757_da
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_giga,
  
 +      .register_type  = SH_ETH_REG_GIGABIT,
 +
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
@@@ -610,8 -577,6 +610,8 @@@ static struct sh_eth_cpu_data sh7734_da
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_gether,
  
 +      .register_type  = SH_ETH_REG_GIGABIT,
 +
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
@@@ -639,8 -604,6 +639,8 @@@ static struct sh_eth_cpu_data sh7763_da
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_gether,
  
 +      .register_type  = SH_ETH_REG_GIGABIT,
 +
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
@@@ -678,8 -641,6 +678,8 @@@ static struct sh_eth_cpu_data r8a7740_d
        .set_duplex     = sh_eth_set_duplex,
        .set_rate       = sh_eth_set_rate_gether,
  
 +      .register_type  = SH_ETH_REG_GIGABIT,
 +
        .ecsr_value     = ECSR_ICD | ECSR_MPD,
        .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
  };
  
  static struct sh_eth_cpu_data sh7619_data = {
 +      .register_type  = SH_ETH_REG_FAST_SH3_SH2,
 +
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
  
        .apr            = 1,
  };
  
  static struct sh_eth_cpu_data sh771x_data = {
 +      .register_type  = SH_ETH_REG_FAST_SH3_SH2,
 +
        .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
        .tsu            = 1,
  };
@@@ -1167,9 -1124,6 +1167,9 @@@ static int sh_eth_dev_init(struct net_d
        if (ret)
                goto out;
  
 +      if (mdp->cd->rmiimode)
 +              sh_eth_write(ndev, 0x1, RMIIMODE);
 +
        /* Descriptor format */
        sh_eth_ring_format(ndev);
        if (mdp->cd->rpadir)
@@@ -1343,12 -1297,9 +1343,12 @@@ static int sh_eth_rx(struct net_device 
                        mdp->rx_skbuff[entry] = NULL;
                        if (mdp->cd->rpadir)
                                skb_reserve(skb, NET_IP_ALIGN);
 +                      dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr,
 +                                              mdp->rx_buf_sz,
 +                                              DMA_FROM_DEVICE);
                        skb_put(skb, pkt_len);
                        skb->protocol = eth_type_trans(skb, ndev);
-                       netif_rx(skb);
+                       netif_receive_skb(skb);
                        ndev->stats.rx_packets++;
                        ndev->stats.rx_bytes += pkt_len;
                }
@@@ -1906,11 -1857,13 +1906,13 @@@ static int sh_eth_open(struct net_devic
  
        pm_runtime_get_sync(&mdp->pdev->dev);
  
+       napi_enable(&mdp->napi);
        ret = request_irq(ndev->irq, sh_eth_interrupt,
                          mdp->cd->irq_flags, ndev->name, ndev);
        if (ret) {
                dev_err(&ndev->dev, "Can not assign IRQ number\n");
-               return ret;
+               goto out_napi_off;
        }
  
        /* Descriptor set */
        if (ret)
                goto out_free_irq;
  
-       napi_enable(&mdp->napi);
        return ret;
  
  out_free_irq:
        free_irq(ndev->irq, ndev);
+ out_napi_off:
+       napi_disable(&mdp->napi);
        pm_runtime_put_sync(&mdp->pdev->dev);
        return ret;
  }
@@@ -2025,8 -1978,6 +2027,6 @@@ static int sh_eth_close(struct net_devi
  {
        struct sh_eth_private *mdp = netdev_priv(ndev);
  
-       napi_disable(&mdp->napi);
        netif_stop_queue(ndev);
  
        /* Disable interrupts by clearing the interrupt mask. */
  
        free_irq(ndev->irq, ndev);
  
+       napi_disable(&mdp->napi);
        /* Free all the skbuffs in the Rx queue. */
        sh_eth_ring_free(ndev);
  
@@@ -2610,7 -2563,7 +2612,7 @@@ static int sh_eth_drv_probe(struct plat
        struct resource *res;
        struct net_device *ndev = NULL;
        struct sh_eth_private *mdp = NULL;
 -      struct sh_eth_plat_data *pd = pdev->dev.platform_data;
 +      struct sh_eth_plat_data *pd = dev_get_platdata(&pdev->dev);
        const struct platform_device_id *id = platform_get_device_id(pdev);
  
        /* get base addr */
  
        SET_NETDEV_DEV(ndev, &pdev->dev);
  
 -      /* Fill in the fields of the device structure with ethernet values. */
 -      ether_setup(ndev);
 -
        mdp = netdev_priv(ndev);
        mdp->num_tx_ring = TX_RING_SIZE;
        mdp->num_rx_ring = RX_RING_SIZE;
        mdp->edmac_endian = pd->edmac_endian;
        mdp->no_ether_link = pd->no_ether_link;
        mdp->ether_link_active_low = pd->ether_link_active_low;
 -      mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
  
        /* set cpu data */
        mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
 +      mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type);
        sh_eth_set_default_cpu_data(mdp->cd);
  
        /* set function */
@@@ -2795,7 -2751,6 +2797,7 @@@ static struct platform_device_id sh_eth
        { "sh7763-gether", (kernel_ulong_t)&sh7763_data },
        { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
        { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
 +      { "r8a7790-ether", (kernel_ulong_t)&r8a7790_data },
        { }
  };
  MODULE_DEVICE_TABLE(platform, sh_eth_id_table);
index 623ebc50fe6b2bb0122cbec89d0cefead9e4aa12,1c83a44c547b7f1612b748b6c640832fc5f51e66..7a0072003f34e3f5aba03f73718bcb412df3eb43
@@@ -71,19 -71,18 +71,22 @@@ static int stmmac_probe_config_dt(struc
                plat->force_sf_dma_mode = 1;
        }
  
-       dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL);
-       if (!dma_cfg)
-               return -ENOMEM;
-       plat->dma_cfg = dma_cfg;
-       of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
-       dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
-       dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
+       if (of_find_property(np, "snps,pbl", NULL)) {
+               dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
+                                      GFP_KERNEL);
+               if (!dma_cfg)
+                       return -ENOMEM;
+               plat->dma_cfg = dma_cfg;
+               of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
+               dma_cfg->fixed_burst =
+                       of_property_read_bool(np, "snps,fixed-burst");
+               dma_cfg->mixed_burst =
+                       of_property_read_bool(np, "snps,mixed-burst");
+       }
 +      plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
 +      if (plat->force_thresh_dma_mode) {
 +              plat->force_sf_dma_mode = 0;
 +              pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
-       }
  
        return 0;
  }
@@@ -114,11 -113,14 +117,11 @@@ static int stmmac_pltfr_probe(struct pl
        const char *mac = NULL;
  
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!res)
 -              return -ENODEV;
 -
        addr = devm_ioremap_resource(dev, res);
        if (IS_ERR(addr))
                return PTR_ERR(addr);
  
 -      plat_dat = pdev->dev.platform_data;
 +      plat_dat = dev_get_platdata(&pdev->dev);
        if (pdev->dev.of_node) {
                if (!plat_dat)
                        plat_dat = devm_kzalloc(&pdev->dev,
diff --combined include/net/xfrm.h
index 89d3d8ae204ec9f8e331862175b660d4377898e0,e823786e7c66a6763e1cfa29bfcc76a3b4f7f6ba..e253bf0cc7ef005721de3b7e8729cfabce52854f
@@@ -341,10 -341,13 +341,13 @@@ struct xfrm_state_afinfo 
                                                  struct sk_buff *skb);
        int                     (*transport_finish)(struct sk_buff *skb,
                                                    int async);
+       void                    (*local_error)(struct sk_buff *skb, u32 mtu);
  };
  
  extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
  extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
+ extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
+ extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
  
  extern void xfrm_state_delete_tunnel(struct xfrm_state *x);
  
@@@ -1477,6 -1480,7 +1480,7 @@@ extern int xfrm_input_resume(struct sk_
  extern int xfrm_output_resume(struct sk_buff *skb, int err);
  extern int xfrm_output(struct sk_buff *skb);
  extern int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+ extern void xfrm_local_error(struct sk_buff *skb, int mtu);
  extern int xfrm4_extract_header(struct sk_buff *skb);
  extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
  extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
@@@ -1497,6 -1501,7 +1501,7 @@@ extern int xfrm4_tunnel_register(struc
  extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
  extern int xfrm4_mode_tunnel_input_register(struct xfrm_tunnel *handler);
  extern int xfrm4_mode_tunnel_input_deregister(struct xfrm_tunnel *handler);
+ extern void xfrm4_local_error(struct sk_buff *skb, u32 mtu);
  extern int xfrm6_extract_header(struct sk_buff *skb);
  extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
  extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
@@@ -1514,6 -1519,7 +1519,7 @@@ extern int xfrm6_output(struct sk_buff 
  extern int xfrm6_output_finish(struct sk_buff *skb);
  extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
                                 u8 **prevhdr);
+ extern void xfrm6_local_error(struct sk_buff *skb, u32 mtu);
  
  #ifdef CONFIG_XFRM
  extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
@@@ -1548,7 -1554,7 +1554,7 @@@ struct xfrm_policy *xfrm_policy_byid(st
  int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info);
  u32 xfrm_get_acqseq(void);
  extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 -struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark,
 +struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
                                 u8 mode, u32 reqid, u8 proto,
                                 const xfrm_address_t *daddr,
                                 const xfrm_address_t *saddr, int create,
diff --combined net/bridge/br_device.c
index 0feaaa0d37d11979999a898fe297f0e31397c07b,89659d4ed1f91934b6d22f5c4f0ee323de414aa3..ca04163635da3bb4a090596edb3009afdc6ee033
@@@ -71,7 -71,7 +71,7 @@@ netdev_tx_t br_dev_xmit(struct sk_buff 
  
                mdst = br_mdb_get(br, skb, vid);
                if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
-                   br_multicast_querier_exists(br))
+                   br_multicast_querier_exists(br, eth_hdr(skb)))
                        br_multicast_deliver(mdst, skb);
                else
                        br_flood_deliver(br, skb, false);
@@@ -245,22 -245,22 +245,22 @@@ fail
  int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp)
  {
        struct netpoll *np;
 -      int err = 0;
 +      int err;
 +
 +      if (!p->br->dev->npinfo)
 +              return 0;
  
        np = kzalloc(sizeof(*p->np), gfp);
 -      err = -ENOMEM;
        if (!np)
 -              goto out;
 +              return -ENOMEM;
  
        err = __netpoll_setup(np, p->dev, gfp);
        if (err) {
                kfree(np);
 -              goto out;
 +              return err;
        }
  
        p->np = np;
 -
 -out:
        return err;
  }
  
diff --combined net/bridge/br_mdb.c
index de818d95c476190ab70966eeebfc68f0f0b05a4d,6319c4333c393b57c9e4210d9e37191a4446a922..85a09bb5ca51b864cd671c63746d65dfd531ed79
@@@ -9,7 -9,6 +9,7 @@@
  #include <net/netlink.h>
  #if IS_ENABLED(CONFIG_IPV6)
  #include <net/ipv6.h>
 +#include <net/addrconf.h>
  #endif
  
  #include "br_private.h"
@@@ -62,8 -61,7 +62,8 @@@ static int br_mdb_fill_info(struct sk_b
  
        for (i = 0; i < mdb->max; i++) {
                struct net_bridge_mdb_entry *mp;
 -              struct net_bridge_port_group *p, **pp;
 +              struct net_bridge_port_group *p;
 +              struct net_bridge_port_group __rcu **pp;
                struct net_bridge_port *port;
  
                hlist_for_each_entry_rcu(mp, &mdb->mhash[i], hlist[mdb->ver]) {
@@@ -255,7 -253,7 +255,7 @@@ static bool is_valid_mdb_entry(struct b
                        return false;
  #if IS_ENABLED(CONFIG_IPV6)
        } else if (entry->addr.proto == htons(ETH_P_IPV6)) {
 -              if (!ipv6_is_transient_multicast(&entry->addr.u.ip6))
 +              if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6))
                        return false;
  #endif
        } else
@@@ -416,16 -414,20 +416,20 @@@ static int __br_mdb_del(struct net_brid
        if (!netif_running(br->dev) || br->multicast_disabled)
                return -EINVAL;
  
-       if (timer_pending(&br->multicast_querier_timer))
-               return -EBUSY;
        ip.proto = entry->addr.proto;
-       if (ip.proto == htons(ETH_P_IP))
+       if (ip.proto == htons(ETH_P_IP)) {
+               if (timer_pending(&br->ip4_querier.timer))
+                       return -EBUSY;
                ip.u.ip4 = entry->addr.u.ip4;
  #if IS_ENABLED(CONFIG_IPV6)
-       else
+       } else {
+               if (timer_pending(&br->ip6_querier.timer))
+                       return -EBUSY;
                ip.u.ip6 = entry->addr.u.ip6;
  #endif
+       }
  
        spin_lock_bh(&br->multicast_lock);
        mdb = mlock_dereference(br->mdb, br);
index 23531471f16af7336514eca0933e6b5d211d9372,bbcb43582496de14497a8e4e1d71674cd40b8119..d1c5786306784a7353b845cad60e2d39abec0f72
  #include <net/ipv6.h>
  #include <net/mld.h>
  #include <net/ip6_checksum.h>
 +#include <net/addrconf.h>
  #endif
  
  #include "br_private.h"
  
- static void br_multicast_start_querier(struct net_bridge *br);
+ static void br_multicast_start_querier(struct net_bridge *br,
+                                      struct bridge_mcast_query *query);
  unsigned int br_mdb_rehash_seq;
  
  static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
@@@ -724,7 -724,7 +725,7 @@@ static int br_ip6_multicast_add_group(s
  {
        struct br_ip br_group;
  
 -      if (!ipv6_is_transient_multicast(group))
 +      if (ipv6_addr_is_ll_all_nodes(group))
                return 0;
  
        br_group.u.ip6 = *group;
@@@ -756,20 -756,35 +757,35 @@@ static void br_multicast_local_router_e
  {
  }
  
- static void br_multicast_querier_expired(unsigned long data)
+ static void br_multicast_querier_expired(struct net_bridge *br,
+                                        struct bridge_mcast_query *query)
  {
-       struct net_bridge *br = (void *)data;
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) || br->multicast_disabled)
                goto out;
  
-       br_multicast_start_querier(br);
+       br_multicast_start_querier(br, query);
  
  out:
        spin_unlock(&br->multicast_lock);
  }
  
+ static void br_ip4_multicast_querier_expired(unsigned long data)
+ {
+       struct net_bridge *br = (void *)data;
+       br_multicast_querier_expired(br, &br->ip4_query);
+ }
+ #if IS_ENABLED(CONFIG_IPV6)
+ static void br_ip6_multicast_querier_expired(unsigned long data)
+ {
+       struct net_bridge *br = (void *)data;
+       br_multicast_querier_expired(br, &br->ip6_query);
+ }
+ #endif
  static void __br_multicast_send_query(struct net_bridge *br,
                                      struct net_bridge_port *port,
                                      struct br_ip *ip)
  }
  
  static void br_multicast_send_query(struct net_bridge *br,
-                                   struct net_bridge_port *port, u32 sent)
+                                   struct net_bridge_port *port,
+                                   struct bridge_mcast_query *query)
  {
        unsigned long time;
        struct br_ip br_group;
+       struct bridge_mcast_querier *querier = NULL;
  
        if (!netif_running(br->dev) || br->multicast_disabled ||
-           !br->multicast_querier ||
-           timer_pending(&br->multicast_querier_timer))
+           !br->multicast_querier)
                return;
  
        memset(&br_group.u, 0, sizeof(br_group.u));
  
-       br_group.proto = htons(ETH_P_IP);
-       __br_multicast_send_query(br, port, &br_group);
+       if (port ? (query == &port->ip4_query) :
+                  (query == &br->ip4_query)) {
+               querier = &br->ip4_querier;
+               br_group.proto = htons(ETH_P_IP);
  #if IS_ENABLED(CONFIG_IPV6)
-       br_group.proto = htons(ETH_P_IPV6);
-       __br_multicast_send_query(br, port, &br_group);
+       } else {
+               querier = &br->ip6_querier;
+               br_group.proto = htons(ETH_P_IPV6);
  #endif
+       }
+       if (!querier || timer_pending(&querier->timer))
+               return;
+       __br_multicast_send_query(br, port, &br_group);
  
        time = jiffies;
-       time += sent < br->multicast_startup_query_count ?
+       time += query->startup_sent < br->multicast_startup_query_count ?
                br->multicast_startup_query_interval :
                br->multicast_query_interval;
-       mod_timer(port ? &port->multicast_query_timer :
-                        &br->multicast_query_timer, time);
+       mod_timer(&query->timer, time);
  }
  
- static void br_multicast_port_query_expired(unsigned long data)
+ static void br_multicast_port_query_expired(struct net_bridge_port *port,
+                                           struct bridge_mcast_query *query)
  {
-       struct net_bridge_port *port = (void *)data;
        struct net_bridge *br = port->br;
  
        spin_lock(&br->multicast_lock);
            port->state == BR_STATE_BLOCKING)
                goto out;
  
-       if (port->multicast_startup_queries_sent <
-           br->multicast_startup_query_count)
-               port->multicast_startup_queries_sent++;
+       if (query->startup_sent < br->multicast_startup_query_count)
+               query->startup_sent++;
  
-       br_multicast_send_query(port->br, port,
-                               port->multicast_startup_queries_sent);
+       br_multicast_send_query(port->br, port, query);
  
  out:
        spin_unlock(&br->multicast_lock);
  }
  
+ static void br_ip4_multicast_port_query_expired(unsigned long data)
+ {
+       struct net_bridge_port *port = (void *)data;
+       br_multicast_port_query_expired(port, &port->ip4_query);
+ }
+ #if IS_ENABLED(CONFIG_IPV6)
+ static void br_ip6_multicast_port_query_expired(unsigned long data)
+ {
+       struct net_bridge_port *port = (void *)data;
+       br_multicast_port_query_expired(port, &port->ip6_query);
+ }
+ #endif
  void br_multicast_add_port(struct net_bridge_port *port)
  {
        port->multicast_router = 1;
  
        setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
                    (unsigned long)port);
-       setup_timer(&port->multicast_query_timer,
-                   br_multicast_port_query_expired, (unsigned long)port);
+       setup_timer(&port->ip4_query.timer, br_ip4_multicast_port_query_expired,
+                   (unsigned long)port);
+ #if IS_ENABLED(CONFIG_IPV6)
+       setup_timer(&port->ip6_query.timer, br_ip6_multicast_port_query_expired,
+                   (unsigned long)port);
+ #endif
  }
  
  void br_multicast_del_port(struct net_bridge_port *port)
        del_timer_sync(&port->multicast_router_timer);
  }
  
- static void __br_multicast_enable_port(struct net_bridge_port *port)
+ static void br_multicast_enable(struct bridge_mcast_query *query)
  {
-       port->multicast_startup_queries_sent = 0;
+       query->startup_sent = 0;
  
-       if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
-           del_timer(&port->multicast_query_timer))
-               mod_timer(&port->multicast_query_timer, jiffies);
+       if (try_to_del_timer_sync(&query->timer) >= 0 ||
+           del_timer(&query->timer))
+               mod_timer(&query->timer, jiffies);
  }
  
  void br_multicast_enable_port(struct net_bridge_port *port)
        if (br->multicast_disabled || !netif_running(br->dev))
                goto out;
  
-       __br_multicast_enable_port(port);
+       br_multicast_enable(&port->ip4_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+       br_multicast_enable(&port->ip6_query);
+ #endif
  
  out:
        spin_unlock(&br->multicast_lock);
@@@ -890,7 -934,10 +935,10 @@@ void br_multicast_disable_port(struct n
        if (!hlist_unhashed(&port->rlist))
                hlist_del_init_rcu(&port->rlist);
        del_timer(&port->multicast_router_timer);
-       del_timer(&port->multicast_query_timer);
+       del_timer(&port->ip4_query.timer);
+ #if IS_ENABLED(CONFIG_IPV6)
+       del_timer(&port->ip6_query.timer);
+ #endif
        spin_unlock(&br->multicast_lock);
  }
  
@@@ -1015,14 -1062,15 +1063,15 @@@ static int br_ip6_multicast_mld2_report
  }
  #endif
  
- static void br_multicast_update_querier_timer(struct net_bridge *br,
-                                             unsigned long max_delay)
+ static void
+ br_multicast_update_querier_timer(struct net_bridge *br,
+                                 struct bridge_mcast_querier *querier,
+                                 unsigned long max_delay)
  {
-       if (!timer_pending(&br->multicast_querier_timer))
-               br->multicast_querier_delay_time = jiffies + max_delay;
+       if (!timer_pending(&querier->timer))
+               querier->delay_time = jiffies + max_delay;
  
-       mod_timer(&br->multicast_querier_timer,
-                 jiffies + br->multicast_querier_interval);
+       mod_timer(&querier->timer, jiffies + br->multicast_querier_interval);
  }
  
  /*
@@@ -1075,12 -1123,13 +1124,13 @@@ timer
  
  static void br_multicast_query_received(struct net_bridge *br,
                                        struct net_bridge_port *port,
+                                       struct bridge_mcast_querier *querier,
                                        int saddr,
                                        unsigned long max_delay)
  {
        if (saddr)
-               br_multicast_update_querier_timer(br, max_delay);
-       else if (timer_pending(&br->multicast_querier_timer))
+               br_multicast_update_querier_timer(br, querier, max_delay);
+       else if (timer_pending(&querier->timer))
                return;
  
        br_multicast_mark_router(br, port);
@@@ -1130,7 -1179,8 +1180,8 @@@ static int br_ip4_multicast_query(struc
                            IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
        }
  
-       br_multicast_query_received(br, port, !!iph->saddr, max_delay);
+       br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
+                                   max_delay);
  
        if (!group)
                goto out;
@@@ -1205,11 -1255,11 +1256,11 @@@ static int br_ip6_multicast_query(struc
                if (!mld2q->mld2q_nsrcs)
                        group = &mld2q->mld2q_mca;
  
 -              max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL);
 +              max_delay = max(msecs_to_jiffies(mldv2_mrc(mld2q)), 1UL);
        }
  
-       br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr),
-                                   max_delay);
+       br_multicast_query_received(br, port, &br->ip6_querier,
+                                   !ipv6_addr_any(&ip6h->saddr), max_delay);
  
        if (!group)
                goto out;
@@@ -1246,7 -1296,9 +1297,9 @@@ out
  
  static void br_multicast_leave_group(struct net_bridge *br,
                                     struct net_bridge_port *port,
-                                    struct br_ip *group)
+                                    struct br_ip *group,
+                                    struct bridge_mcast_querier *querier,
+                                    struct bridge_mcast_query *query)
  {
        struct net_bridge_mdb_htable *mdb;
        struct net_bridge_mdb_entry *mp;
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) ||
            (port && port->state == BR_STATE_DISABLED) ||
-           timer_pending(&br->multicast_querier_timer))
+           timer_pending(&querier->timer))
                goto out;
  
        mdb = mlock_dereference(br->mdb, br);
        if (!mp)
                goto out;
  
-       if (br->multicast_querier &&
-           !timer_pending(&br->multicast_querier_timer)) {
+       if (br->multicast_querier) {
                __br_multicast_send_query(br, port, &mp->addr);
  
                time = jiffies + br->multicast_last_member_count *
                                 br->multicast_last_member_interval;
-               mod_timer(port ? &port->multicast_query_timer :
-                                &br->multicast_query_timer, time);
+               mod_timer(&query->timer, time);
  
                for (p = mlock_dereference(mp->ports, br);
                     p != NULL;
                        mod_timer(&mp->timer, time);
                }
        }
  out:
        spin_unlock(&br->multicast_lock);
  }
@@@ -1336,6 -1386,8 +1387,8 @@@ static void br_ip4_multicast_leave_grou
                                         __u16 vid)
  {
        struct br_ip br_group;
+       struct bridge_mcast_query *query = port ? &port->ip4_query :
+                                                 &br->ip4_query;
  
        if (ipv4_is_local_multicast(group))
                return;
        br_group.proto = htons(ETH_P_IP);
        br_group.vid = vid;
  
-       br_multicast_leave_group(br, port, &br_group);
+       br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query);
  }
  
  #if IS_ENABLED(CONFIG_IPV6)
@@@ -1354,15 -1406,18 +1407,18 @@@ static void br_ip6_multicast_leave_grou
                                         __u16 vid)
  {
        struct br_ip br_group;
+       struct bridge_mcast_query *query = port ? &port->ip6_query :
+                                                 &br->ip6_query;
  
 -      if (!ipv6_is_transient_multicast(group))
 +      if (ipv6_addr_is_ll_all_nodes(group))
                return;
  
        br_group.u.ip6 = *group;
        br_group.proto = htons(ETH_P_IPV6);
        br_group.vid = vid;
  
-       br_multicast_leave_group(br, port, &br_group);
+       br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query);
  }
  #endif
  
@@@ -1492,14 -1547,8 +1548,14 @@@ static int br_multicast_ipv6_rcv(struc
         *  - MLD has always Router Alert hop-by-hop option
         *  - But we do not support jumbrograms.
         */
 -      if (ip6h->version != 6 ||
 -          ip6h->nexthdr != IPPROTO_HOPOPTS ||
 +      if (ip6h->version != 6)
 +              return 0;
 +
 +      /* Prevent flooding this packet if there is no listener present */
 +      if (!ipv6_addr_is_ll_all_nodes(&ip6h->daddr))
 +              BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 +
 +      if (ip6h->nexthdr != IPPROTO_HOPOPTS ||
            ip6h->payload_len == 0)
                return 0;
  
@@@ -1630,19 -1679,32 +1686,32 @@@ int br_multicast_rcv(struct net_bridge 
        return 0;
  }
  
- static void br_multicast_query_expired(unsigned long data)
+ static void br_multicast_query_expired(struct net_bridge *br,
+                                      struct bridge_mcast_query *query)
+ {
+       spin_lock(&br->multicast_lock);
+       if (query->startup_sent < br->multicast_startup_query_count)
+               query->startup_sent++;
+       br_multicast_send_query(br, NULL, query);
+       spin_unlock(&br->multicast_lock);
+ }
+ static void br_ip4_multicast_query_expired(unsigned long data)
  {
        struct net_bridge *br = (void *)data;
  
-       spin_lock(&br->multicast_lock);
-       if (br->multicast_startup_queries_sent <
-           br->multicast_startup_query_count)
-               br->multicast_startup_queries_sent++;
+       br_multicast_query_expired(br, &br->ip4_query);
+ }
  
-       br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent);
+ #if IS_ENABLED(CONFIG_IPV6)
+ static void br_ip6_multicast_query_expired(unsigned long data)
+ {
+       struct net_bridge *br = (void *)data;
  
-       spin_unlock(&br->multicast_lock);
+       br_multicast_query_expired(br, &br->ip6_query);
  }
+ #endif
  
  void br_multicast_init(struct net_bridge *br)
  {
        br->multicast_querier_interval = 255 * HZ;
        br->multicast_membership_interval = 260 * HZ;
  
-       br->multicast_querier_delay_time = 0;
+       br->ip4_querier.delay_time = 0;
+ #if IS_ENABLED(CONFIG_IPV6)
+       br->ip6_querier.delay_time = 0;
+ #endif
  
        spin_lock_init(&br->multicast_lock);
        setup_timer(&br->multicast_router_timer,
                    br_multicast_local_router_expired, 0);
-       setup_timer(&br->multicast_querier_timer,
-                   br_multicast_querier_expired, (unsigned long)br);
-       setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
+       setup_timer(&br->ip4_querier.timer, br_ip4_multicast_querier_expired,
+                   (unsigned long)br);
+       setup_timer(&br->ip4_query.timer, br_ip4_multicast_query_expired,
                    (unsigned long)br);
+ #if IS_ENABLED(CONFIG_IPV6)
+       setup_timer(&br->ip6_querier.timer, br_ip6_multicast_querier_expired,
+                   (unsigned long)br);
+       setup_timer(&br->ip6_query.timer, br_ip6_multicast_query_expired,
+                   (unsigned long)br);
+ #endif
  }
  
- void br_multicast_open(struct net_bridge *br)
+ static void __br_multicast_open(struct net_bridge *br,
+                               struct bridge_mcast_query *query)
  {
-       br->multicast_startup_queries_sent = 0;
+       query->startup_sent = 0;
  
        if (br->multicast_disabled)
                return;
  
-       mod_timer(&br->multicast_query_timer, jiffies);
+       mod_timer(&query->timer, jiffies);
+ }
+ void br_multicast_open(struct net_bridge *br)
+ {
+       __br_multicast_open(br, &br->ip4_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+       __br_multicast_open(br, &br->ip6_query);
+ #endif
  }
  
  void br_multicast_stop(struct net_bridge *br)
        int i;
  
        del_timer_sync(&br->multicast_router_timer);
-       del_timer_sync(&br->multicast_querier_timer);
-       del_timer_sync(&br->multicast_query_timer);
+       del_timer_sync(&br->ip4_querier.timer);
+       del_timer_sync(&br->ip4_query.timer);
+ #if IS_ENABLED(CONFIG_IPV6)
+       del_timer_sync(&br->ip6_querier.timer);
+       del_timer_sync(&br->ip6_query.timer);
+ #endif
  
        spin_lock_bh(&br->multicast_lock);
        mdb = mlock_dereference(br->mdb, br);
@@@ -1796,18 -1880,24 +1887,24 @@@ unlock
        return err;
  }
  
- static void br_multicast_start_querier(struct net_bridge *br)
+ static void br_multicast_start_querier(struct net_bridge *br,
+                                      struct bridge_mcast_query *query)
  {
        struct net_bridge_port *port;
  
-       br_multicast_open(br);
+       __br_multicast_open(br, query);
  
        list_for_each_entry(port, &br->port_list, list) {
                if (port->state == BR_STATE_DISABLED ||
                    port->state == BR_STATE_BLOCKING)
                        continue;
  
-               __br_multicast_enable_port(port);
+               if (query == &br->ip4_query)
+                       br_multicast_enable(&port->ip4_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+               else
+                       br_multicast_enable(&port->ip6_query);
+ #endif
        }
  }
  
@@@ -1842,7 -1932,10 +1939,10 @@@ rollback
                        goto rollback;
        }
  
-       br_multicast_start_querier(br);
+       br_multicast_start_querier(br, &br->ip4_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+       br_multicast_start_querier(br, &br->ip6_query);
+ #endif
  
  unlock:
        spin_unlock_bh(&br->multicast_lock);
@@@ -1865,10 -1958,18 +1965,18 @@@ int br_multicast_set_querier(struct net
                goto unlock;
  
        max_delay = br->multicast_query_response_interval;
-       if (!timer_pending(&br->multicast_querier_timer))
-               br->multicast_querier_delay_time = jiffies + max_delay;
  
-       br_multicast_start_querier(br);
+       if (!timer_pending(&br->ip4_querier.timer))
+               br->ip4_querier.delay_time = jiffies + max_delay;
+       br_multicast_start_querier(br, &br->ip4_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+       if (!timer_pending(&br->ip6_querier.timer))
+               br->ip6_querier.delay_time = jiffies + max_delay;
+       br_multicast_start_querier(br, &br->ip6_query);
+ #endif
  
  unlock:
        spin_unlock_bh(&br->multicast_lock);
diff --combined net/bridge/br_private.h
index 89b2949be02fa402d0b3bdc1fc38546e2a34e75e,263ba9034468e84db8cfd429124d2399e8707e36..598cb0b333c64b57c639dd7cda8df7aec229448d
@@@ -66,6 -66,20 +66,20 @@@ struct br_i
        __u16           vid;
  };
  
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+ /* our own querier */
+ struct bridge_mcast_query {
+       struct timer_list       timer;
+       u32                     startup_sent;
+ };
+ /* other querier */
+ struct bridge_mcast_querier {
+       struct timer_list               timer;
+       unsigned long                   delay_time;
+ };
+ #endif
  struct net_port_vlans {
        u16                             port_idx;
        u16                             pvid;
@@@ -162,10 -176,12 +176,12 @@@ struct net_bridge_por
  #define BR_FLOOD              0x00000040
  
  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
-       u32                             multicast_startup_queries_sent;
+       struct bridge_mcast_query       ip4_query;
+ #if IS_ENABLED(CONFIG_IPV6)
+       struct bridge_mcast_query       ip6_query;
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
        unsigned char                   multicast_router;
        struct timer_list               multicast_router_timer;
-       struct timer_list               multicast_query_timer;
        struct hlist_head               mglist;
        struct hlist_node               rlist;
  #endif
@@@ -258,7 -274,6 +274,6 @@@ struct net_bridg
        u32                             hash_max;
  
        u32                             multicast_last_member_count;
-       u32                             multicast_startup_queries_sent;
        u32                             multicast_startup_query_count;
  
        unsigned long                   multicast_last_member_interval;
        unsigned long                   multicast_query_interval;
        unsigned long                   multicast_query_response_interval;
        unsigned long                   multicast_startup_query_interval;
-       unsigned long                   multicast_querier_delay_time;
  
        spinlock_t                      multicast_lock;
        struct net_bridge_mdb_htable __rcu *mdb;
        struct hlist_head               router_list;
  
        struct timer_list               multicast_router_timer;
-       struct timer_list               multicast_querier_timer;
-       struct timer_list               multicast_query_timer;
+       struct bridge_mcast_querier     ip4_querier;
+       struct bridge_mcast_query       ip4_query;
+ #if IS_ENABLED(CONFIG_IPV6)
+       struct bridge_mcast_querier     ip6_querier;
+       struct bridge_mcast_query       ip6_query;
+ #endif /* IS_ENABLED(CONFIG_IPV6) */
  #endif
  
        struct timer_list               hello_timer;
@@@ -334,6 -352,11 +352,6 @@@ extern void br_dev_delete(struct net_de
  extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
                               struct net_device *dev);
  #ifdef CONFIG_NET_POLL_CONTROLLER
 -static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
 -{
 -      return br->dev->npinfo;
 -}
 -
  static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
                                       struct sk_buff *skb)
  {
  extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
  extern void br_netpoll_disable(struct net_bridge_port *p);
  #else
 -static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
 -{
 -      return NULL;
 -}
 -
  static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
                                       struct sk_buff *skb)
  {
@@@ -466,7 -494,7 +484,7 @@@ extern void br_multicast_free_pg(struc
  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 *next,
 +                              struct net_bridge_port_group __rcu *next,
                                unsigned char state);
  extern void br_mdb_init(void);
  extern void br_mdb_uninit(void);
@@@ -476,6 -504,16 +494,6 @@@ extern void br_mdb_notify(struct net_de
  #define mlock_dereference(X, br) \
        rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
  
 -#if IS_ENABLED(CONFIG_IPV6)
 -#include <net/addrconf.h>
 -static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
 -{
 -      if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr))
 -              return 1;
 -      return 0;
 -}
 -#endif
 -
  static inline bool br_multicast_is_router(struct net_bridge *br)
  {
        return br->multicast_router == 2 ||
                timer_pending(&br->multicast_router_timer));
  }
  
- static inline bool br_multicast_querier_exists(struct net_bridge *br)
+ static inline bool
+ __br_multicast_querier_exists(struct net_bridge *br,
+                             struct bridge_mcast_querier *querier)
  {
-       return time_is_before_jiffies(br->multicast_querier_delay_time) &&
-              (br->multicast_querier ||
-               timer_pending(&br->multicast_querier_timer));
+       return time_is_before_jiffies(querier->delay_time) &&
+              (br->multicast_querier || timer_pending(&querier->timer));
+ }
+ static inline bool br_multicast_querier_exists(struct net_bridge *br,
+                                              struct ethhdr *eth)
+ {
+       switch (eth->h_proto) {
+       case (htons(ETH_P_IP)):
+               return __br_multicast_querier_exists(br, &br->ip4_querier);
+ #if IS_ENABLED(CONFIG_IPV6)
+       case (htons(ETH_P_IPV6)):
+               return __br_multicast_querier_exists(br, &br->ip6_querier);
+ #endif
+       default:
+               return false;
+       }
  }
  #else
  static inline int br_multicast_rcv(struct net_bridge *br,
@@@ -545,7 -599,8 +579,8 @@@ static inline bool br_multicast_is_rout
  {
        return 0;
  }
- static inline bool br_multicast_querier_exists(struct net_bridge *br)
+ static inline bool br_multicast_querier_exists(struct net_bridge *br,
+                                              struct ethhdr *eth)
  {
        return false;
  }
index 159737cac76c3d180be308b64e5e37bf34cc51f0,d12e3a9a53562aca9cf58e68d35ae649493f2efd..0ff42f029ace683610115f5251554dc3e87b9210
@@@ -140,11 -140,7 +140,11 @@@ ipv6
                break;
        }
        case IPPROTO_IPIP:
 -              goto again;
 +              proto = htons(ETH_P_IP);
 +              goto ip;
 +      case IPPROTO_IPV6:
 +              proto = htons(ETH_P_IPV6);
 +              goto ipv6;
        default:
                break;
        }
@@@ -350,14 -346,9 +350,9 @@@ u16 __netdev_pick_tx(struct net_device 
                if (new_index < 0)
                        new_index = skb_tx_hash(dev, skb);
  
-               if (queue_index != new_index && sk) {
-                       struct dst_entry *dst =
-                                   rcu_dereference_check(sk->sk_dst_cache, 1);
-                       if (dst && skb_dst(skb) == dst)
-                               sk_tx_queue_set(sk, queue_index);
-               }
+               if (queue_index != new_index && sk &&
+                   rcu_access_pointer(sk->sk_dst_cache))
+                       sk_tx_queue_set(sk, queue_index);
  
                queue_index = new_index;
        }
diff --combined net/ipv4/ipip.c
index 87bd2952c7334e54ed49b1fa6bf5cb8237269ba6,b3ac3c3f62194bc6165be620f5ed50bb457b18ea..7f80fb4b82d3716ad79044a43ed43545f6183957
@@@ -190,15 -190,14 +190,14 @@@ static int ipip_rcv(struct sk_buff *skb
        struct ip_tunnel *tunnel;
        const struct iphdr *iph;
  
-       if (iptunnel_pull_header(skb, 0, tpi.proto))
-               goto drop;
        iph = ip_hdr(skb);
        tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
                        iph->saddr, iph->daddr, 0);
        if (tunnel) {
                if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                        goto drop;
+               if (iptunnel_pull_header(skb, 0, tpi.proto))
+                       goto drop;
                return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
        }
  
@@@ -286,6 -285,7 +285,6 @@@ static void ipip_tunnel_setup(struct ne
        dev->flags              = IFF_NOARP;
        dev->iflink             = 0;
        dev->addr_len           = 4;
 -      dev->features           |= NETIF_F_NETNS_LOCAL;
        dev->features           |= NETIF_F_LLTX;
        dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
  
@@@ -436,7 -436,7 +435,7 @@@ static int __net_init ipip_init_net(str
  static void __net_exit ipip_exit_net(struct net *net)
  {
        struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
 -      ip_tunnel_delete_net(itn);
 +      ip_tunnel_delete_net(itn, &ipip_link_ops);
  }
  
  static struct pernet_operations ipip_net_ops = {
diff --combined net/ipv4/raw.c
index 41d84505a9225af90386b135c4b053019070f7b4,61e60d67adca9d24729cd06d33b02f91552b3515..a86c7ae71881b1e65e998888c92749fe63fcf3c1
@@@ -571,7 -571,8 +571,8 @@@ static int raw_sendmsg(struct kiocb *io
        flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
                           RT_SCOPE_UNIVERSE,
                           inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
-                          inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP,
+                          inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP |
+                           (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
                           daddr, saddr, 0, 0);
  
        if (!inet->hdrincl) {
@@@ -987,7 -988,7 +988,7 @@@ static void raw_sock_seq_show(struct se
              srcp  = inet->inet_num;
  
        seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
 -              " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
 +              " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d\n",
                i, src, srcp, dest, destp, sp->sk_state,
                sk_wmem_alloc_get(sp),
                sk_rmem_alloc_get(sp),
diff --combined net/ipv4/tcp.c
index fdf74090a00134709dea6ad67760a5dcaa0141a7,95544e4028c05e628c24bb522f5f11f479dffaec..6e5617b9f9db6f3c2aeacc7923ea763660761d99
  
  int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
  
 +int sysctl_tcp_min_tso_segs __read_mostly = 2;
 +
  struct percpu_counter tcp_orphan_count;
  EXPORT_SYMBOL_GPL(tcp_orphan_count);
  
@@@ -412,6 -410,10 +412,6 @@@ void tcp_init_sock(struct sock *sk
  
        icsk->icsk_sync_mss = tcp_sync_mss;
  
 -      /* Presumed zeroed, in order of appearance:
 -       *      cookie_in_always, cookie_out_never,
 -       *      s_data_constant, s_data_in, s_data_out
 -       */
        sk->sk_sndbuf = sysctl_tcp_wmem[1];
        sk->sk_rcvbuf = sysctl_tcp_rmem[1];
  
@@@ -497,7 -499,7 +497,7 @@@ unsigned int tcp_poll(struct file *file
                        mask |= POLLIN | POLLRDNORM;
  
                if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
 -                      if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk)) {
 +                      if (sk_stream_is_writeable(sk)) {
                                mask |= POLLOUT | POLLWRNORM;
                        } else {  /* send SIGIO later */
                                set_bit(SOCK_ASYNC_NOSPACE,
                                 * wspace test but before the flags are set,
                                 * IO signal will be lost.
                                 */
 -                              if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
 +                              if (sk_stream_is_writeable(sk))
                                        mask |= POLLOUT | POLLWRNORM;
                        }
                } else
@@@ -787,28 -789,12 +787,28 @@@ static unsigned int tcp_xmit_size_goal(
        xmit_size_goal = mss_now;
  
        if (large_allowed && sk_can_gso(sk)) {
 -              xmit_size_goal = ((sk->sk_gso_max_size - 1) -
 -                                inet_csk(sk)->icsk_af_ops->net_header_len -
 -                                inet_csk(sk)->icsk_ext_hdr_len -
 -                                tp->tcp_header_len);
 +              u32 gso_size, hlen;
 +
 +              /* Maybe we should/could use sk->sk_prot->max_header here ? */
 +              hlen = inet_csk(sk)->icsk_af_ops->net_header_len +
 +                     inet_csk(sk)->icsk_ext_hdr_len +
 +                     tp->tcp_header_len;
 +
 +              /* Goal is to send at least one packet per ms,
 +               * not one big TSO packet every 100 ms.
 +               * This preserves ACK clocking and is consistent
 +               * with tcp_tso_should_defer() heuristic.
 +               */
 +              gso_size = sk->sk_pacing_rate / (2 * MSEC_PER_SEC);
 +              gso_size = max_t(u32, gso_size,
 +                               sysctl_tcp_min_tso_segs * mss_now);
  
 -              /* TSQ : try to have two TSO segments in flight */
 +              xmit_size_goal = min_t(u32, gso_size,
 +                                     sk->sk_gso_max_size - 1 - hlen);
 +
 +              /* TSQ : try to have at least two segments in flight
 +               * (one in NIC TX ring, another in Qdisc)
 +               */
                xmit_size_goal = min_t(u32, xmit_size_goal,
                                       sysctl_tcp_limit_output_bytes >> 1);
  
@@@ -2468,10 -2454,11 +2468,11 @@@ static int do_tcp_setsockopt(struct soc
        case TCP_THIN_DUPACK:
                if (val < 0 || val > 1)
                        err = -EINVAL;
-               else
+               else {
                        tp->thin_dupack = val;
                        if (tp->thin_dupack)
                                tcp_disable_early_retrans(tp);
+               }
                break;
  
        case TCP_REPAIR:
                else
                        tp->tsoffset = val - tcp_time_stamp;
                break;
 +      case TCP_NOTSENT_LOWAT:
 +              tp->notsent_lowat = val;
 +              sk->sk_write_space(sk);
 +              break;
        default:
                err = -ENOPROTOOPT;
                break;
@@@ -2872,9 -2855,6 +2873,9 @@@ static int do_tcp_getsockopt(struct soc
        case TCP_TIMESTAMP:
                val = tcp_time_stamp + tp->tsoffset;
                break;
 +      case TCP_NOTSENT_LOWAT:
 +              val = tp->notsent_lowat;
 +              break;
        default:
                return -ENOPROTOOPT;
        }
diff --combined net/ipv4/tcp_input.c
index 93d7e9de414374dab18eef44fa7bb6943e526308,3ca2139a130b1034bf24f212fa79b59ea8b8416f..1969e16d936d9b5cd37c01309df27ef31c9b2437
@@@ -688,34 -688,6 +688,34 @@@ static void tcp_rtt_estimator(struct so
        }
  }
  
 +/* Set the sk_pacing_rate to allow proper sizing of TSO packets.
 + * Note: TCP stack does not yet implement pacing.
 + * FQ packet scheduler can be used to implement cheap but effective
 + * TCP pacing, to smooth the burst on large writes when packets
 + * in flight is significantly lower than cwnd (or rwin)
 + */
 +static void tcp_update_pacing_rate(struct sock *sk)
 +{
 +      const struct tcp_sock *tp = tcp_sk(sk);
 +      u64 rate;
 +
 +      /* set sk_pacing_rate to 200 % of current rate (mss * cwnd / srtt) */
 +      rate = (u64)tp->mss_cache * 2 * (HZ << 3);
 +
 +      rate *= max(tp->snd_cwnd, tp->packets_out);
 +
 +      /* Correction for small srtt : minimum srtt being 8 (1 jiffy << 3),
 +       * be conservative and assume srtt = 1 (125 us instead of 1.25 ms)
 +       * We probably need usec resolution in the future.
 +       * Note: This also takes care of possible srtt=0 case,
 +       * when tcp_rtt_estimator() was not yet called.
 +       */
 +      if (tp->srtt > 8 + 2)
 +              do_div(rate, tp->srtt);
 +
 +      sk->sk_pacing_rate = min_t(u64, rate, ~0U);
 +}
 +
  /* Calculate rto without backoff.  This is the second half of Van Jacobson's
   * routine referred to above.
   */
@@@ -1076,7 -1048,6 +1076,7 @@@ struct tcp_sacktag_state 
        int reord;
        int fack_count;
        int flag;
 +      s32 rtt; /* RTT measured by SACKing never-retransmitted data */
  };
  
  /* Check if skb is fully within the SACK block. In presence of GSO skbs,
@@@ -1137,7 -1108,7 +1137,7 @@@ static int tcp_match_skb_to_sack(struc
  static u8 tcp_sacktag_one(struct sock *sk,
                          struct tcp_sacktag_state *state, u8 sacked,
                          u32 start_seq, u32 end_seq,
 -                        bool dup_sack, int pcount)
 +                        int dup_sack, int pcount, u32 xmit_time)
  {
        struct tcp_sock *tp = tcp_sk(sk);
        int fack_count = state->fack_count;
                                                           state->reord);
                                if (!after(end_seq, tp->high_seq))
                                        state->flag |= FLAG_ORIG_SACK_ACKED;
 +                              /* Pick the earliest sequence sacked for RTT */
 +                              if (state->rtt < 0)
 +                                      state->rtt = tcp_time_stamp - xmit_time;
                        }
  
                        if (sacked & TCPCB_LOST) {
@@@ -1237,8 -1205,7 +1237,8 @@@ static bool tcp_shifted_skb(struct soc
         * tcp_highest_sack_seq() when skb is highest_sack.
         */
        tcp_sacktag_one(sk, state, TCP_SKB_CB(skb)->sacked,
 -                      start_seq, end_seq, dup_sack, pcount);
 +                      start_seq, end_seq, dup_sack, pcount,
 +                      TCP_SKB_CB(skb)->when);
  
        if (skb == tp->lost_skb_hint)
                tp->lost_cnt_hint += pcount;
@@@ -1512,8 -1479,7 +1512,8 @@@ static struct sk_buff *tcp_sacktag_walk
                                                TCP_SKB_CB(skb)->seq,
                                                TCP_SKB_CB(skb)->end_seq,
                                                dup_sack,
 -                                              tcp_skb_pcount(skb));
 +                                              tcp_skb_pcount(skb),
 +                                              TCP_SKB_CB(skb)->when);
  
                        if (!before(TCP_SKB_CB(skb)->seq,
                                    tcp_highest_sack_seq(tp)))
@@@ -1570,7 -1536,7 +1570,7 @@@ static int tcp_sack_cache_ok(const stru
  
  static int
  tcp_sacktag_write_queue(struct sock *sk, const struct sk_buff *ack_skb,
 -                      u32 prior_snd_una)
 +                      u32 prior_snd_una, s32 *sack_rtt)
  {
        struct tcp_sock *tp = tcp_sk(sk);
        const unsigned char *ptr = (skb_transport_header(ack_skb) +
  
        state.flag = 0;
        state.reord = tp->packets_out;
 +      state.rtt = -1;
  
        if (!tp->sacked_out) {
                if (WARN_ON(tp->fackets_out))
@@@ -1772,7 -1737,6 +1772,7 @@@ out
        WARN_ON((int)tp->retrans_out < 0);
        WARN_ON((int)tcp_packets_in_flight(tp) < 0);
  #endif
 +      *sack_rtt = state.rtt;
        return state.flag;
  }
  
@@@ -1905,13 -1869,8 +1905,13 @@@ void tcp_enter_loss(struct sock *sk, in
        }
        tcp_verify_left_out(tp);
  
 -      tp->reordering = min_t(unsigned int, tp->reordering,
 -                             sysctl_tcp_reordering);
 +      /* Timeout in disordered state after receiving substantial DUPACKs
 +       * suggests that the degree of reordering is over-estimated.
 +       */
 +      if (icsk->icsk_ca_state <= TCP_CA_Disorder &&
 +          tp->sacked_out >= sysctl_tcp_reordering)
 +              tp->reordering = min_t(unsigned int, tp->reordering,
 +                                     sysctl_tcp_reordering);
        tcp_set_ca_state(sk, TCP_CA_Loss);
        tp->high_seq = tp->snd_nxt;
        TCP_ECN_queue_cwr(tp);
@@@ -2513,6 -2472,8 +2513,6 @@@ static void tcp_try_to_open(struct soc
  
        if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) {
                tcp_try_keep_open(sk);
 -              if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open)
 -                      tcp_moderate_cwnd(tp);
        } else {
                tcp_cwnd_reduction(sk, prior_unsacked, 0);
        }
@@@ -2831,51 -2792,65 +2831,51 @@@ static void tcp_fastretrans_alert(struc
        tcp_xmit_retransmit_queue(sk);
  }
  
 -void tcp_valid_rtt_meas(struct sock *sk, u32 seq_rtt)
 +static inline bool tcp_ack_update_rtt(struct sock *sk, const int flag,
 +                                    s32 seq_rtt, s32 sack_rtt)
  {
 -      tcp_rtt_estimator(sk, seq_rtt);
 -      tcp_set_rto(sk);
 -      inet_csk(sk)->icsk_backoff = 0;
 -}
 -EXPORT_SYMBOL(tcp_valid_rtt_meas);
 +      const struct tcp_sock *tp = tcp_sk(sk);
 +
 +      /* Prefer RTT measured from ACK's timing to TS-ECR. This is because
 +       * broken middle-boxes or peers may corrupt TS-ECR fields. But
 +       * Karn's algorithm forbids taking RTT if some retransmitted data
 +       * is acked (RFC6298).
 +       */
 +      if (flag & FLAG_RETRANS_DATA_ACKED)
 +              seq_rtt = -1;
 +
 +      if (seq_rtt < 0)
 +              seq_rtt = sack_rtt;
  
 -/* Read draft-ietf-tcplw-high-performance before mucking
 - * with this code. (Supersedes RFC1323)
 - */
 -static void tcp_ack_saw_tstamp(struct sock *sk, int flag)
 -{
        /* RTTM Rule: A TSecr value received in a segment is used to
         * update the averaged RTT measurement only if the segment
         * acknowledges some new data, i.e., only if it advances the
         * left edge of the send window.
 -       *
         * See draft-ietf-tcplw-high-performance-00, section 3.3.
 -       * 1998/04/10 Andrey V. Savochkin <saw@msu.ru>
 -       *
 -       * Changed: reset backoff as soon as we see the first valid sample.
 -       * If we do not, we get strongly overestimated rto. With timestamps
 -       * samples are accepted even from very old segments: f.e., when rtt=1
 -       * increases to 8, we retransmit 5 times and after 8 seconds delayed
 -       * answer arrives rto becomes 120 seconds! If at least one of segments
 -       * in window is lost... Voila.                          --ANK (010210)
         */
 -      struct tcp_sock *tp = tcp_sk(sk);
 -
 -      tcp_valid_rtt_meas(sk, tcp_time_stamp - tp->rx_opt.rcv_tsecr);
 -}
 +      if (seq_rtt < 0 && tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
 +              seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
  
 -static void tcp_ack_no_tstamp(struct sock *sk, u32 seq_rtt, int flag)
 -{
 -      /* We don't have a timestamp. Can only use
 -       * packets that are not retransmitted to determine
 -       * rtt estimates. Also, we must not reset the
 -       * backoff for rto until we get a non-retransmitted
 -       * packet. This allows us to deal with a situation
 -       * where the network delay has increased suddenly.
 -       * I.e. Karn's algorithm. (SIGCOMM '87, p5.)
 -       */
 +      if (seq_rtt < 0)
 +              return false;
  
 -      if (flag & FLAG_RETRANS_DATA_ACKED)
 -              return;
 +      tcp_rtt_estimator(sk, seq_rtt);
 +      tcp_set_rto(sk);
  
 -      tcp_valid_rtt_meas(sk, seq_rtt);
 +      /* RFC6298: only reset backoff on valid RTT measurement. */
 +      inet_csk(sk)->icsk_backoff = 0;
 +      return true;
  }
  
 -static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
 -                                    const s32 seq_rtt)
 +/* Compute time elapsed between (last) SYNACK and the ACK completing 3WHS. */
 +static void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req)
  {
 -      const struct tcp_sock *tp = tcp_sk(sk);
 -      /* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
 -      if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
 -              tcp_ack_saw_tstamp(sk, flag);
 -      else if (seq_rtt >= 0)
 -              tcp_ack_no_tstamp(sk, seq_rtt, flag);
 +      struct tcp_sock *tp = tcp_sk(sk);
 +      s32 seq_rtt = -1;
 +
 +      if (tp->lsndtime && !tp->total_retrans)
 +              seq_rtt = tcp_time_stamp - tp->lsndtime;
 +      tcp_ack_update_rtt(sk, FLAG_SYN_ACKED, seq_rtt, -1);
  }
  
  static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
@@@ -2964,7 -2939,7 +2964,7 @@@ static u32 tcp_tso_acked(struct sock *s
   * arrived at the other end.
   */
  static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
 -                             u32 prior_snd_una)
 +                             u32 prior_snd_una, s32 sack_rtt)
  {
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
                        if (sacked & TCPCB_SACKED_RETRANS)
                                tp->retrans_out -= acked_pcount;
                        flag |= FLAG_RETRANS_DATA_ACKED;
 -                      ca_seq_rtt = -1;
 -                      seq_rtt = -1;
                } else {
                        ca_seq_rtt = now - scb->when;
                        last_ackt = skb->tstamp;
        if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                flag |= FLAG_SACK_RENEGING;
  
 +      if (tcp_ack_update_rtt(sk, flag, seq_rtt, sack_rtt) ||
 +          (flag & FLAG_ACKED))
 +              tcp_rearm_rto(sk);
 +
        if (flag & FLAG_ACKED) {
                const struct tcp_congestion_ops *ca_ops
                        = inet_csk(sk)->icsk_ca_ops;
                        tcp_mtup_probe_success(sk);
                }
  
 -              tcp_ack_update_rtt(sk, flag, seq_rtt);
 -              tcp_rearm_rto(sk);
 -
                if (tcp_is_reno(tp)) {
                        tcp_remove_reno_sacks(sk, pkts_acked);
                } else {
@@@ -3154,24 -3130,11 +3154,24 @@@ static inline bool tcp_ack_is_dubious(c
                inet_csk(sk)->icsk_ca_state != TCP_CA_Open;
  }
  
 +/* Decide wheather to run the increase function of congestion control. */
  static inline bool tcp_may_raise_cwnd(const struct sock *sk, const int flag)
  {
 -      const struct tcp_sock *tp = tcp_sk(sk);
 -      return (!(flag & FLAG_ECE) || tp->snd_cwnd < tp->snd_ssthresh) &&
 -              !tcp_in_cwnd_reduction(sk);
 +      if (tcp_in_cwnd_reduction(sk))
 +              return false;
 +
 +      /* If reordering is high then always grow cwnd whenever data is
 +       * delivered regardless of its ordering. Otherwise stay conservative
 +       * and only grow cwnd on in-order delivery in Open state, and retain
 +       * cwnd in Disordered state (RFC5681). A stretched ACK with
 +       * new SACK or ECE mark may first advance cwnd here and later reduce
 +       * cwnd in tcp_fastretrans_alert() based on more states.
 +       */
 +      if (tcp_sk(sk)->reordering > sysctl_tcp_reordering)
 +              return flag & FLAG_FORWARD_PROGRESS;
 +
 +      return inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
 +             flag & FLAG_DATA_ACKED;
  }
  
  /* Check that window update is acceptable.
@@@ -3306,12 -3269,11 +3306,12 @@@ static int tcp_ack(struct sock *sk, con
        u32 ack_seq = TCP_SKB_CB(skb)->seq;
        u32 ack = TCP_SKB_CB(skb)->ack_seq;
        bool is_dupack = false;
 -      u32 prior_in_flight;
 +      u32 prior_in_flight, prior_cwnd = tp->snd_cwnd, prior_rtt = tp->srtt;
        u32 prior_fackets;
        int prior_packets = tp->packets_out;
        const int prior_unsacked = tp->packets_out - tp->sacked_out;
        int acked = 0; /* Number of packets newly acked */
 +      s32 sack_rtt = -1;
  
        /* If the ack is older than previous acks
         * then we can probably ignore it.
                flag |= tcp_ack_update_window(sk, skb, ack, ack_seq);
  
                if (TCP_SKB_CB(skb)->sacked)
 -                      flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
 +                      flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una,
 +                                                      &sack_rtt);
  
                if (TCP_ECN_rcv_ecn_echo(tp, tcp_hdr(skb)))
                        flag |= FLAG_ECE;
  
        /* See if we can take anything off of the retransmit queue. */
        acked = tp->packets_out;
 -      flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
 +      flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, sack_rtt);
        acked -= tp->packets_out;
  
 +      /* Advance cwnd if state allows */
 +      if (tcp_may_raise_cwnd(sk, flag))
 +              tcp_cong_avoid(sk, ack, prior_in_flight);
 +
        if (tcp_ack_is_dubious(sk, flag)) {
 -              /* Advance CWND, if state allows this. */
 -              if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(sk, flag))
 -                      tcp_cong_avoid(sk, ack, prior_in_flight);
                is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
                tcp_fastretrans_alert(sk, acked, prior_unsacked,
                                      is_dupack, flag);
 -      } else {
 -              if (flag & FLAG_DATA_ACKED)
 -                      tcp_cong_avoid(sk, ack, prior_in_flight);
        }
 -
        if (tp->tlp_high_seq)
                tcp_process_tlp_ack(sk, ack, flag);
  
  
        if (icsk->icsk_pending == ICSK_TIME_RETRANS)
                tcp_schedule_loss_probe(sk);
 +      if (tp->srtt != prior_rtt || tp->snd_cwnd != prior_cwnd)
 +              tcp_update_pacing_rate(sk);
        return 1;
  
  no_queue:
@@@ -3440,8 -3402,7 +3440,8 @@@ old_ack
         * If data was DSACKed, see if we can undo a cwnd reduction.
         */
        if (TCP_SKB_CB(skb)->sacked) {
 -              flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
 +              flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una,
 +                                              &sack_rtt);
                tcp_fastretrans_alert(sk, acked, prior_unsacked,
                                      is_dupack, flag);
        }
@@@ -3574,7 -3535,10 +3574,10 @@@ static bool tcp_parse_aligned_timestamp
                ++ptr;
                tp->rx_opt.rcv_tsval = ntohl(*ptr);
                ++ptr;
-               tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+               if (*ptr)
+                       tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+               else
+                       tp->rx_opt.rcv_tsecr = 0;
                return true;
        }
        return false;
@@@ -3599,7 -3563,7 +3602,7 @@@ static bool tcp_fast_parse_options(cons
        }
  
        tcp_parse_options(skb, &tp->rx_opt, 1, NULL);
-       if (tp->rx_opt.saw_tstamp)
+       if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
                tp->rx_opt.rcv_tsecr -= tp->tsoffset;
  
        return true;
@@@ -5049,8 -5013,8 +5052,8 @@@ discard
   *    the rest is checked inline. Fast processing is turned on in
   *    tcp_data_queue when everything is OK.
   */
 -int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 -                      const struct tcphdr *th, unsigned int len)
 +void tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 +                       const struct tcphdr *th, unsigned int len)
  {
        struct tcp_sock *tp = tcp_sk(sk);
  
                                tcp_ack(sk, skb, 0);
                                __kfree_skb(skb);
                                tcp_data_snd_check(sk);
 -                              return 0;
 +                              return;
                        } else { /* Header too small */
                                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
                                goto discard;
@@@ -5220,7 -5184,7 +5223,7 @@@ no_ack
                        if (eaten)
                                kfree_skb_partial(skb, fragstolen);
                        sk->sk_data_ready(sk, 0);
 -                      return 0;
 +                      return;
                }
        }
  
@@@ -5236,7 -5200,7 +5239,7 @@@ slow_path
         */
  
        if (!tcp_validate_incoming(sk, skb, th, 1))
 -              return 0;
 +              return;
  
  step5:
        if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
  
        tcp_data_snd_check(sk);
        tcp_ack_snd_check(sk);
 -      return 0;
 +      return;
  
  csum_error:
        TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
  
  discard:
        __kfree_skb(skb);
 -      return 0;
  }
  EXPORT_SYMBOL(tcp_rcv_established);
  
@@@ -5354,7 -5319,7 +5357,7 @@@ static int tcp_rcv_synsent_state_proces
        int saved_clamp = tp->rx_opt.mss_clamp;
  
        tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
-       if (tp->rx_opt.saw_tstamp)
+       if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
                tp->rx_opt.rcv_tsecr -= tp->tsoffset;
  
        if (th->ack) {
@@@ -5662,7 -5627,9 +5665,7 @@@ int tcp_rcv_state_process(struct sock *
                 * so release it.
                 */
                if (req) {
 -                      tcp_synack_rtt_meas(sk, req);
                        tp->total_retrans = req->num_retrans;
 -
                        reqsk_fastopen_remove(sk, req, false);
                } else {
                        /* Make sure socket is routed, for correct metrics. */
                tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
                tp->snd_wnd = ntohs(th->window) << tp->rx_opt.snd_wscale;
                tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
 +              tcp_synack_rtt_meas(sk, req);
  
                if (tp->rx_opt.tstamp_ok)
                        tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
diff --combined net/ipv4/tcp_output.c
index e63ae4c9691ddf886e6ef4a343665821a0b000f2,170737a9d56df7d1c3992a64244eea868774abf1..7c83cb8bf1378022ba3a68c56403ef40801cd3ae
@@@ -65,9 -65,6 +65,9 @@@ int sysctl_tcp_base_mss __read_mostly 
  /* By default, RFC2861 behavior.  */
  int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
  
 +unsigned int sysctl_tcp_notsent_lowat __read_mostly = UINT_MAX;
 +EXPORT_SYMBOL(sysctl_tcp_notsent_lowat);
 +
  static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
                           int push_one, gfp_t gfp);
  
@@@ -1631,7 -1628,7 +1631,7 @@@ static bool tcp_tso_should_defer(struc
  
        /* If a full-sized TSO skb can be sent, do it. */
        if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
 -                         sk->sk_gso_max_segs * tp->mss_cache))
 +                         tp->xmit_size_goal_segs * tp->mss_cache))
                goto send_now;
  
        /* Middle in queue won't get any more data, full sendable already? */
@@@ -2673,7 -2670,7 +2673,7 @@@ struct sk_buff *tcp_make_synack(struct 
        int tcp_header_size;
        int mss;
  
-       skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC));
+       skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
        if (unlikely(!skb)) {
                dst_release(dst);
                return NULL;
@@@ -2817,6 -2814,8 +2817,8 @@@ void tcp_connect_init(struct sock *sk
  
        if (likely(!tp->repair))
                tp->rcv_nxt = 0;
+       else
+               tp->rcv_tstamp = tcp_time_stamp;
        tp->rcv_wup = tp->rcv_nxt;
        tp->copied_seq = tp->rcv_nxt;
  
diff --combined net/ipv6/addrconf.c
index 2a66eaad047fca314ad6529c1a1c381a2d9dad8d,05c83dd54a4de18b833cd3ed8d7e1b2b9c433be7..d6ff12617f36f9eabbf7c9744b3b8121a567c1bf
@@@ -99,9 -99,9 +99,9 @@@
  #define ACONF_DEBUG 2
  
  #if ACONF_DEBUG >= 3
 -#define ADBG(x) printk x
 +#define ADBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
  #else
 -#define ADBG(x)
 +#define ADBG(fmt, ...) do { if (0) printk(fmt, ##__VA_ARGS__); } while (0)
  #endif
  
  #define       INFINITY_LIFE_TIME      0xFFFFFFFF
@@@ -177,8 -177,6 +177,8 @@@ static struct ipv6_devconf ipv6_devcon
        .accept_redirects       = 1,
        .autoconf               = 1,
        .force_mld_version      = 0,
 +      .mldv1_unsolicited_report_interval = 10 * HZ,
 +      .mldv2_unsolicited_report_interval = HZ,
        .dad_transmits          = 1,
        .rtr_solicits           = MAX_RTR_SOLICITATIONS,
        .rtr_solicit_interval   = RTR_SOLICITATION_INTERVAL,
        .accept_source_route    = 0,    /* we do not accept RH0 by default. */
        .disable_ipv6           = 0,
        .accept_dad             = 1,
 +      .suppress_frag_ndisc    = 1,
  };
  
  static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
        .accept_ra              = 1,
        .accept_redirects       = 1,
        .autoconf               = 1,
 +      .force_mld_version      = 0,
 +      .mldv1_unsolicited_report_interval = 10 * HZ,
 +      .mldv2_unsolicited_report_interval = HZ,
        .dad_transmits          = 1,
        .rtr_solicits           = MAX_RTR_SOLICITATIONS,
        .rtr_solicit_interval   = RTR_SOLICITATION_INTERVAL,
        .accept_source_route    = 0,    /* we do not accept RH0 by default. */
        .disable_ipv6           = 0,
        .accept_dad             = 1,
 +      .suppress_frag_ndisc    = 1,
  };
  
 -/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
 -const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 -const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 -const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
 -const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
 -const struct in6_addr in6addr_interfacelocal_allnodes = IN6ADDR_INTERFACELOCAL_ALLNODES_INIT;
 -const struct in6_addr in6addr_interfacelocal_allrouters = IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT;
 -const struct in6_addr in6addr_sitelocal_allrouters = IN6ADDR_SITELOCAL_ALLROUTERS_INIT;
 -
  /* Check if a valid qdisc is available */
  static inline bool addrconf_qdisc_ok(const struct net_device *dev)
  {
@@@ -304,6 -306,36 +304,6 @@@ err_ip
        return -ENOMEM;
  }
  
 -static void snmp6_free_dev(struct inet6_dev *idev)
 -{
 -      kfree(idev->stats.icmpv6msgdev);
 -      kfree(idev->stats.icmpv6dev);
 -      snmp_mib_free((void __percpu **)idev->stats.ipv6);
 -}
 -
 -/* Nobody refers to this device, we may destroy it. */
 -
 -void in6_dev_finish_destroy(struct inet6_dev *idev)
 -{
 -      struct net_device *dev = idev->dev;
 -
 -      WARN_ON(!list_empty(&idev->addr_list));
 -      WARN_ON(idev->mc_list != NULL);
 -      WARN_ON(timer_pending(&idev->rs_timer));
 -
 -#ifdef NET_REFCNT_DEBUG
 -      pr_debug("%s: %s\n", __func__, dev ? dev->name : "NIL");
 -#endif
 -      dev_put(dev);
 -      if (!idev->dead) {
 -              pr_warn("Freeing alive inet6 device %p\n", idev);
 -              return;
 -      }
 -      snmp6_free_dev(idev);
 -      kfree_rcu(idev, rcu);
 -}
 -EXPORT_SYMBOL(in6_dev_finish_destroy);
 -
  static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
  {
        struct inet6_dev *ndev;
        dev_hold(dev);
  
        if (snmp6_alloc_dev(ndev) < 0) {
 -              ADBG((KERN_WARNING
 +              ADBG(KERN_WARNING
                        "%s: cannot allocate memory for statistics; dev=%s.\n",
 -                      __func__, dev->name));
 +                      __func__, dev->name);
                neigh_parms_release(&nd_tbl, ndev->nd_parms);
                dev_put(dev);
                kfree(ndev);
        }
  
        if (snmp6_register_dev(ndev) < 0) {
 -              ADBG((KERN_WARNING
 +              ADBG(KERN_WARNING
                        "%s: cannot create /proc/net/dev_snmp6/%s\n",
 -                      __func__, dev->name));
 +                      __func__, dev->name);
                neigh_parms_release(&nd_tbl, ndev->nd_parms);
                ndev->dead = 1;
                in6_dev_finish_destroy(ndev);
@@@ -812,7 -844,7 +812,7 @@@ ipv6_add_addr(struct inet6_dev *idev, c
  
        /* Ignore adding duplicate addresses on an interface */
        if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) {
 -              ADBG(("ipv6_add_addr: already assigned\n"));
 +              ADBG("ipv6_add_addr: already assigned\n");
                err = -EEXIST;
                goto out;
        }
        ifa = kzalloc(sizeof(struct inet6_ifaddr), GFP_ATOMIC);
  
        if (ifa == NULL) {
 -              ADBG(("ipv6_add_addr: malloc failed\n"));
 +              ADBG("ipv6_add_addr: malloc failed\n");
                err = -ENOBUFS;
                goto out;
        }
@@@ -1022,7 -1054,6 +1022,6 @@@ static int ipv6_create_tempaddr(struct 
        unsigned long regen_advance;
        int tmp_plen;
        int ret = 0;
-       int max_addresses;
        u32 addr_flags;
        unsigned long now = jiffies;
  
@@@ -1068,7 -1099,6 +1067,6 @@@ retry
                                 idev->cnf.temp_prefered_lft + age -
                                 idev->cnf.max_desync_factor);
        tmp_plen = ifp->prefix_len;
-       max_addresses = idev->cnf.max_addresses;
        tmp_tstamp = ifp->tstamp;
        spin_unlock_bh(&ifp->lock);
  
@@@ -1775,16 -1805,6 +1773,16 @@@ static int addrconf_ifid_gre(u8 *eui, s
        return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
  }
  
 +static int addrconf_ifid_ip6tnl(u8 *eui, struct net_device *dev)
 +{
 +      memcpy(eui, dev->perm_addr, 3);
 +      memcpy(eui + 5, dev->perm_addr + 3, 3);
 +      eui[3] = 0xFF;
 +      eui[4] = 0xFE;
 +      eui[0] ^= 2;
 +      return 0;
 +}
 +
  static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
  {
        switch (dev->type) {
                return addrconf_ifid_eui64(eui, dev);
        case ARPHRD_IEEE1394:
                return addrconf_ifid_ieee1394(eui, dev);
 +      case ARPHRD_TUNNEL6:
 +              return addrconf_ifid_ip6tnl(eui, dev);
        }
        return -1;
  }
@@@ -2030,7 -2048,7 +2028,7 @@@ void addrconf_prefix_rcv(struct net_dev
        pinfo = (struct prefix_info *) opt;
  
        if (len < sizeof(struct prefix_info)) {
 -              ADBG(("addrconf: prefix option too short\n"));
 +              ADBG("addrconf: prefix option too short\n");
                return;
        }
  
@@@ -2682,8 -2700,7 +2680,8 @@@ static void addrconf_dev_config(struct 
            (dev->type != ARPHRD_ARCNET) &&
            (dev->type != ARPHRD_INFINIBAND) &&
            (dev->type != ARPHRD_IEEE802154) &&
 -          (dev->type != ARPHRD_IEEE1394)) {
 +          (dev->type != ARPHRD_IEEE1394) &&
 +          (dev->type != ARPHRD_TUNNEL6)) {
                /* Alas, we support only Ethernet autoconfiguration. */
                return;
        }
@@@ -2769,6 -2786,44 +2767,6 @@@ ipv6_inherit_linklocal(struct inet6_de
        return -1;
  }
  
 -static void ip6_tnl_add_linklocal(struct inet6_dev *idev)
 -{
 -      struct net_device *link_dev;
 -      struct net *net = dev_net(idev->dev);
 -
 -      /* first try to inherit the link-local address from the link device */
 -      if (idev->dev->iflink &&
 -          (link_dev = __dev_get_by_index(net, idev->dev->iflink))) {
 -              if (!ipv6_inherit_linklocal(idev, link_dev))
 -                      return;
 -      }
 -      /* then try to inherit it from any device */
 -      for_each_netdev(net, link_dev) {
 -              if (!ipv6_inherit_linklocal(idev, link_dev))
 -                      return;
 -      }
 -      pr_debug("init ip6-ip6: add_linklocal failed\n");
 -}
 -
 -/*
 - * Autoconfigure tunnel with a link-local address so routing protocols,
 - * DHCPv6, MLD etc. can be run over the virtual link
 - */
 -
 -static void addrconf_ip6_tnl_config(struct net_device *dev)
 -{
 -      struct inet6_dev *idev;
 -
 -      ASSERT_RTNL();
 -
 -      idev = addrconf_add_dev(dev);
 -      if (IS_ERR(idev)) {
 -              pr_debug("init ip6-ip6: add_dev failed\n");
 -              return;
 -      }
 -      ip6_tnl_add_linklocal(idev);
 -}
 -
  static int addrconf_notify(struct notifier_block *this, unsigned long event,
                           void *ptr)
  {
                        addrconf_gre_config(dev);
                        break;
  #endif
 -              case ARPHRD_TUNNEL6:
 -                      addrconf_ip6_tnl_config(dev);
 -                      break;
                case ARPHRD_LOOPBACK:
                        init_loopback(dev);
                        break;
@@@ -3060,7 -3118,6 +3058,7 @@@ static int addrconf_ifdown(struct net_d
  static void addrconf_rs_timer(unsigned long data)
  {
        struct inet6_dev *idev = (struct inet6_dev *)data;
 +      struct net_device *dev = idev->dev;
        struct in6_addr lladdr;
  
        write_lock(&idev->lock);
                goto out;
  
        if (idev->rs_probes++ < idev->cnf.rtr_solicits) {
 -              if (!__ipv6_get_lladdr(idev, &lladdr, IFA_F_TENTATIVE))
 -                      ndisc_send_rs(idev->dev, &lladdr,
 +              write_unlock(&idev->lock);
 +              if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
 +                      ndisc_send_rs(dev, &lladdr,
                                      &in6addr_linklocal_allrouters);
                else
 -                      goto out;
 +                      goto put;
  
 +              write_lock(&idev->lock);
                /* The wait after the last probe can be shorter */
                addrconf_mod_rs_timer(idev, (idev->rs_probes ==
                                             idev->cnf.rtr_solicits) ?
  
  out:
        write_unlock(&idev->lock);
 +put:
        in6_dev_put(idev);
  }
  
@@@ -3574,8 -3628,8 +3572,8 @@@ restart
        if (time_before(next_sched, jiffies + ADDRCONF_TIMER_FUZZ_MAX))
                next_sched = jiffies + ADDRCONF_TIMER_FUZZ_MAX;
  
 -      ADBG((KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n",
 -            now, next, next_sec, next_sched));
 +      ADBG(KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n",
 +            now, next, next_sec, next_sched);
  
        addr_chk_timer.expires = next_sched;
        add_timer(&addr_chk_timer);
@@@ -4121,10 -4175,6 +4119,10 @@@ static inline void ipv6_store_devconf(s
        array[DEVCONF_RTR_SOLICIT_DELAY] =
                jiffies_to_msecs(cnf->rtr_solicit_delay);
        array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
 +      array[DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL] =
 +              jiffies_to_msecs(cnf->mldv1_unsolicited_report_interval);
 +      array[DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL] =
 +              jiffies_to_msecs(cnf->mldv2_unsolicited_report_interval);
  #ifdef CONFIG_IPV6_PRIVACY
        array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
        array[DEVCONF_TEMP_VALID_LFT] = cnf->temp_valid_lft;
        array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad;
        array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
        array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify;
 +      array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc;
  }
  
  static inline size_t inet6_ifla6_size(void)
@@@ -4601,7 -4650,6 +4599,7 @@@ static void __ipv6_ifa_notify(int event
                break;
        }
        atomic_inc(&net->ipv6.dev_addr_genid);
 +      rt_genid_bump_ipv6(net);
  }
  
  static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@@ -4809,22 -4857,6 +4807,22 @@@ static struct addrconf_sysctl_tabl
                        .mode           = 0644,
                        .proc_handler   = proc_dointvec,
                },
 +              {
 +                      .procname       = "mldv1_unsolicited_report_interval",
 +                      .data           =
 +                              &ipv6_devconf.mldv1_unsolicited_report_interval,
 +                      .maxlen         = sizeof(int),
 +                      .mode           = 0644,
 +                      .proc_handler   = proc_dointvec_ms_jiffies,
 +              },
 +              {
 +                      .procname       = "mldv2_unsolicited_report_interval",
 +                      .data           =
 +                              &ipv6_devconf.mldv2_unsolicited_report_interval,
 +                      .maxlen         = sizeof(int),
 +                      .mode           = 0644,
 +                      .proc_handler   = proc_dointvec_ms_jiffies,
 +              },
  #ifdef CONFIG_IPV6_PRIVACY
                {
                        .procname       = "use_tempaddr",
                        .mode           = 0644,
                        .proc_handler   = proc_dointvec
                },
 +              {
 +                      .procname       = "suppress_frag_ndisc",
 +                      .data           = &ipv6_devconf.suppress_frag_ndisc,
 +                      .maxlen         = sizeof(int),
 +                      .mode           = 0644,
 +                      .proc_handler   = proc_dointvec
 +              },
                {
                        /* sentinel */
                }
diff --combined net/ipv6/icmp.c
index 73681c2274533bb8e50671728e35f7ad7e786005,67ae4e0d40bf239e969792b1edeac7c6b1fbf4c8..eef8d945b362cf698c9ee407acec38f40e69977d
@@@ -92,7 -92,7 +92,7 @@@ static void icmpv6_err(struct sk_buff *
        if (type == ICMPV6_PKT_TOOBIG)
                ip6_update_pmtu(skb, net, info, 0, 0);
        else if (type == NDISC_REDIRECT)
 -              ip6_redirect(skb, net, 0, 0);
 +              ip6_redirect(skb, net, skb->dev->ifindex, 0);
  
        if (!(type & ICMPV6_INFOMSG_MASK))
                if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
@@@ -940,6 -940,14 +940,14 @@@ static const struct icmp6_err 
                .err    = ECONNREFUSED,
                .fatal  = 1,
        },
+       {       /* POLICY_FAIL */
+               .err    = EACCES,
+               .fatal  = 1,
+       },
+       {       /* REJECT_ROUTE */
+               .err    = EACCES,
+               .fatal  = 1,
+       },
  };
  
  int icmpv6_err_convert(u8 type, u8 code, int *err)
        switch (type) {
        case ICMPV6_DEST_UNREACH:
                fatal = 1;
-               if (code <= ICMPV6_PORT_UNREACH) {
+               if (code < ARRAY_SIZE(tab_unreach)) {
                        *err  = tab_unreach[code].err;
                        fatal = tab_unreach[code].fatal;
                }
diff --combined net/ipv6/ip6_gre.c
index db992a373011241afcbc3094a683474b67742290,90747f1973fe048abd6d8283235b2d80d038d691..6b26e9feafb98eb8d269f553cbf8339a3341526b
@@@ -335,7 -335,6 +335,7 @@@ static struct ip6_tnl *ip6gre_tunnel_lo
        dev->rtnl_link_ops = &ip6gre_link_ops;
  
        nt->dev = dev;
 +      nt->net = dev_net(dev);
        ip6gre_tnl_link_config(nt, 1);
  
        if (register_netdevice(dev) < 0)
@@@ -509,6 -508,8 +509,6 @@@ static int ip6gre_rcv(struct sk_buff *s
                        goto drop;
                }
  
 -              secpath_reset(skb);
 -
                skb->protocol = gre_proto;
                /* WCCP version 1 and 2 protocol decoding.
                 * - Change protocol to IP
                skb->mac_header = skb->network_header;
                __pskb_pull(skb, offset);
                skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
 -              skb->pkt_type = PACKET_HOST;
  
                if (((flags&GRE_CSUM) && csum) ||
                    (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) {
                        skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
                }
  
 -              __skb_tunnel_rx(skb, tunnel->dev);
 +              __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
  
                skb_reset_network_header(skb);
  
@@@ -691,8 -693,6 +691,8 @@@ static netdev_tx_t ip6gre_xmit2(struct 
                        tunnel->err_count = 0;
        }
  
 +      skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
 +
        max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + dst->header_len;
  
        if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
                skb = new_skb;
        }
  
 -      skb_dst_drop(skb);
 -
        if (fl6->flowi6_mark) {
                skb_dst_set(skb, dst);
                ndst = NULL;
                ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
        }
  
+       if (likely(!skb->encapsulation)) {
+               skb_reset_inner_headers(skb);
+               skb->encapsulation = 1;
+       }
        skb_push(skb, gre_hlen);
        skb_reset_network_header(skb);
        skb_set_transport_header(skb, sizeof(*ipv6h));
@@@ -1253,7 -1260,6 +1258,7 @@@ static int ip6gre_tunnel_init(struct ne
        tunnel = netdev_priv(dev);
  
        tunnel->dev = dev;
 +      tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
  
        memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr));
@@@ -1274,7 -1280,6 +1279,7 @@@ static void ip6gre_fb_tunnel_init(struc
        struct ip6_tnl *tunnel = netdev_priv(dev);
  
        tunnel->dev = dev;
 +      tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
  
        tunnel->hlen            = sizeof(struct ipv6hdr) + 4;
@@@ -1450,7 -1455,6 +1455,7 @@@ static int ip6gre_tap_init(struct net_d
        tunnel = netdev_priv(dev);
  
        tunnel->dev = dev;
 +      tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
  
        ip6gre_tnl_link_config(tunnel, 1);
@@@ -1502,7 -1506,6 +1507,7 @@@ static int ip6gre_newlink(struct net *s
                eth_hw_addr_random(dev);
  
        nt->dev = dev;
 +      nt->net = dev_net(dev);
        ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
  
        /* Can use a lockless transmit, unless we generate output sequences */
diff --combined net/ipv6/ip6_output.c
index dd08cfd8999e0e319d610ce71e21733c01404735,e7ceb6c871d1518ddd4cdd61b993a395d01c7d34..3a692d5291636571266c6e26293bc7054228f4e3
  #include <net/checksum.h>
  #include <linux/mroute6.h>
  
 -int __ip6_local_out(struct sk_buff *skb)
 -{
 -      int len;
 -
 -      len = skb->len - sizeof(struct ipv6hdr);
 -      if (len > IPV6_MAXPLEN)
 -              len = 0;
 -      ipv6_hdr(skb)->payload_len = htons(len);
 -
 -      return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
 -                     skb_dst(skb)->dev, dst_output);
 -}
 -
 -int ip6_local_out(struct sk_buff *skb)
 -{
 -      int err;
 -
 -      err = __ip6_local_out(skb);
 -      if (likely(err == 1))
 -              err = dst_output(skb);
 -
 -      return err;
 -}
 -EXPORT_SYMBOL_GPL(ip6_local_out);
 -
  static int ip6_finish_output2(struct sk_buff *skb)
  {
        struct dst_entry *dst = skb_dst(skb);
@@@ -213,6 -238,7 +213,7 @@@ int ip6_xmit(struct sock *sk, struct sk
        hdr->saddr = fl6->saddr;
        hdr->daddr = *first_hop;
  
+       skb->protocol = htons(ETH_P_IPV6);
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
  
@@@ -1032,6 -1058,7 +1033,7 @@@ static inline int ip6_ufo_append_data(s
                /* initialize protocol header pointer */
                skb->transport_header = skb->network_header + fragheaderlen;
  
+               skb->protocol = htons(ETH_P_IPV6);
                skb->ip_summed = CHECKSUM_PARTIAL;
                skb->csum = 0;
        }
@@@ -1334,6 -1361,7 +1336,7 @@@ alloc_new_skb
                        /*
                         *      Fill in the control structures
                         */
+                       skb->protocol = htons(ETH_P_IPV6);
                        skb->ip_summed = CHECKSUM_NONE;
                        skb->csum = 0;
                        /* reserve for fragmentation and ipsec header */
diff --combined net/ipv6/ip6_tunnel.c
index 55999d923f265be4f6151437c0ee07523cfca503,46ba243605a3d4de90b693b20b0f9ed58288234c..61355f7f4da5b4bb7bcc3c12030e09abe9fa9691
@@@ -41,7 -41,6 +41,7 @@@
  #include <linux/netfilter_ipv6.h>
  #include <linux/slab.h>
  #include <linux/hash.h>
 +#include <linux/etherdevice.h>
  
  #include <asm/uaccess.h>
  #include <linux/atomic.h>
@@@ -316,7 -315,6 +316,7 @@@ static struct ip6_tnl *ip6_tnl_create(s
  
        t = netdev_priv(dev);
        t->parms = *p;
 +      t->net = dev_net(dev);
        err = ip6_tnl_create2(dev);
        if (err < 0)
                goto failed_free;
@@@ -376,7 -374,7 +376,7 @@@ static voi
  ip6_tnl_dev_uninit(struct net_device *dev)
  {
        struct ip6_tnl *t = netdev_priv(dev);
 -      struct net *net = dev_net(dev);
 +      struct net *net = t->net;
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
  
        if (dev == ip6n->fb_tnl_dev)
@@@ -743,7 -741,7 +743,7 @@@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t
  {
        struct __ip6_tnl_parm *p = &t->parms;
        int ret = 0;
 -      struct net *net = dev_net(t->dev);
 +      struct net *net = t->net;
  
        if ((p->flags & IP6_TNL_F_CAP_RCV) ||
            ((p->flags & IP6_TNL_F_CAP_PER_PACKET) &&
@@@ -802,12 -800,14 +802,12 @@@ static int ip6_tnl_rcv(struct sk_buff *
                        rcu_read_unlock();
                        goto discard;
                }
 -              secpath_reset(skb);
                skb->mac_header = skb->network_header;
                skb_reset_network_header(skb);
                skb->protocol = htons(protocol);
 -              skb->pkt_type = PACKET_HOST;
                memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
  
 -              __skb_tunnel_rx(skb, t->dev);
 +              __skb_tunnel_rx(skb, t->dev, t->net);
  
                err = dscp_ecn_decapsulate(t, ipv6h, skb);
                if (unlikely(err)) {
@@@ -895,7 -895,7 +895,7 @@@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t
  {
        struct __ip6_tnl_parm *p = &t->parms;
        int ret = 0;
 -      struct net *net = dev_net(t->dev);
 +      struct net *net = t->net;
  
        if (p->flags & IP6_TNL_F_CAP_XMIT) {
                struct net_device *ldev = NULL;
@@@ -945,8 -945,8 +945,8 @@@ static int ip6_tnl_xmit2(struct sk_buf
                         int encap_limit,
                         __u32 *pmtu)
  {
 -      struct net *net = dev_net(dev);
        struct ip6_tnl *t = netdev_priv(dev);
 +      struct net *net = t->net;
        struct net_device_stats *stats = &t->dev->stats;
        struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        struct ipv6_tel_txoption opt;
                goto tx_err_dst_release;
        }
  
 +      skb_scrub_packet(skb, !net_eq(t->net, dev_net(dev)));
 +
        /*
         * Okay, now see if we can stuff it in the buffer as-is.
         */
                consume_skb(skb);
                skb = new_skb;
        }
 -      skb_dst_drop(skb);
        if (fl6->flowi6_mark) {
                skb_dst_set(skb, dst);
                ndst = NULL;
                init_tel_txopt(&opt, encap_limit);
                ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
        }
+       if (likely(!skb->encapsulation)) {
+               skb_reset_inner_headers(skb);
+               skb->encapsulation = 1;
+       }
        skb_push(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
        ipv6h = ipv6_hdr(skb);
@@@ -1203,7 -1208,7 +1209,7 @@@ static void ip6_tnl_link_config(struct 
                int strict = (ipv6_addr_type(&p->raddr) &
                              (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
  
 -              struct rt6_info *rt = rt6_lookup(dev_net(dev),
 +              struct rt6_info *rt = rt6_lookup(t->net,
                                                 &p->raddr, &p->laddr,
                                                 p->link, strict);
  
@@@ -1252,7 -1257,7 +1258,7 @@@ ip6_tnl_change(struct ip6_tnl *t, cons
  
  static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
  {
 -      struct net *net = dev_net(t->dev);
 +      struct net *net = t->net;
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
        int err;
  
@@@ -1464,10 -1469,8 +1470,10 @@@ static void ip6_tnl_dev_setup(struct ne
                dev->mtu-=8;
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
 -      dev->features |= NETIF_F_NETNS_LOCAL;
        dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 +      /* This perm addr will be used as interface identifier by IPv6 */
 +      dev->addr_assign_type = NET_ADDR_RANDOM;
 +      eth_random_addr(dev->perm_addr);
  }
  
  
@@@ -1482,7 -1485,6 +1488,7 @@@ ip6_tnl_dev_init_gen(struct net_device 
        struct ip6_tnl *t = netdev_priv(dev);
  
        t->dev = dev;
 +      t->net = dev_net(dev);
        dev->tstats = alloc_percpu(struct pcpu_tstats);
        if (!dev->tstats)
                return -ENOMEM;
@@@ -1600,9 -1602,9 +1606,9 @@@ static int ip6_tnl_newlink(struct net *
  static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
                              struct nlattr *data[])
  {
 -      struct ip6_tnl *t;
 +      struct ip6_tnl *t = netdev_priv(dev);
        struct __ip6_tnl_parm p;
 -      struct net *net = dev_net(dev);
 +      struct net *net = t->net;
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
  
        if (dev == ip6n->fb_tnl_dev)
@@@ -1703,24 -1705,14 +1709,24 @@@ static struct xfrm6_tunnel ip6ip6_handl
  
  static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
  {
 +      struct net *net = dev_net(ip6n->fb_tnl_dev);
 +      struct net_device *dev, *aux;
        int h;
        struct ip6_tnl *t;
        LIST_HEAD(list);
  
 +      for_each_netdev_safe(net, dev, aux)
 +              if (dev->rtnl_link_ops == &ip6_link_ops)
 +                      unregister_netdevice_queue(dev, &list);
 +
        for (h = 0; h < HASH_SIZE; h++) {
                t = rtnl_dereference(ip6n->tnls_r_l[h]);
                while (t != NULL) {
 -                      unregister_netdevice_queue(t->dev, &list);
 +                      /* If dev is in the same netns, it has already
 +                       * been added to the list by the previous loop.
 +                       */
 +                      if (!net_eq(dev_net(t->dev), net))
 +                              unregister_netdevice_queue(t->dev, &list);
                        t = rtnl_dereference(t->next);
                }
        }
@@@ -1746,10 -1738,6 +1752,10 @@@ static int __net_init ip6_tnl_init_net(
        if (!ip6n->fb_tnl_dev)
                goto err_alloc_dev;
        dev_net_set(ip6n->fb_tnl_dev, net);
 +      /* FB netdevice is special: we have one, and only one per netns.
 +       * Allowing to move it to another netns is clearly unsafe.
 +       */
 +      ip6n->fb_tnl_dev->features |= NETIF_F_NETNS_LOCAL;
  
        err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
        if (err < 0)
diff --combined net/ipv6/ndisc.c
index c4bc7a35cd56f54eb543b68c2c081370cc50f3c0,78141fa46cf8b0b5e4a3425a2d37620617fb35b2..12179457b2cd8026dd867586078b6b900c0488b3
@@@ -372,14 -372,11 +372,11 @@@ static struct sk_buff *ndisc_alloc_skb(
        int tlen = dev->needed_tailroom;
        struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
        struct sk_buff *skb;
-       int err;
  
-       skb = sock_alloc_send_skb(sk,
-                                 hlen + sizeof(struct ipv6hdr) + len + tlen,
-                                 1, &err);
+       skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
        if (!skb) {
-               ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n",
-                         __func__, err);
+               ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
+                         __func__);
                return NULL;
        }
  
        skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
        skb_reset_transport_header(skb);
  
+       /* Manually assign socket ownership as we avoid calling
+        * sock_alloc_send_pskb() to bypass wmem buffer limits
+        */
+       skb_set_owner_w(skb, sk);
        return skb;
  }
  
@@@ -428,6 -430,7 +430,6 @@@ static void ndisc_send_skb(struct sk_bu
        type = icmp6h->icmp6_type;
  
        if (!dst) {
 -              struct sock *sk = net->ipv6.ndisc_sk;
                struct flowi6 fl6;
  
                icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
        rcu_read_unlock();
  }
  
 -static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 -                        const struct in6_addr *daddr,
 -                        const struct in6_addr *solicited_addr,
 -                        bool router, bool solicited, bool override, bool inc_opt)
 +void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 +                 const struct in6_addr *daddr,
 +                 const struct in6_addr *solicited_addr,
 +                 bool router, bool solicited, bool override, bool inc_opt)
  {
        struct sk_buff *skb;
        struct in6_addr tmpaddr;
@@@ -662,7 -665,9 +664,7 @@@ static void ndisc_solicit(struct neighb
                }
                ndisc_send_ns(dev, neigh, target, target, saddr);
        } else if ((probes -= neigh->parms->app_probes) < 0) {
 -#ifdef CONFIG_ARPD
                neigh_app_ns(neigh);
 -#endif
        } else {
                addrconf_addr_solict_mult(target, &mcaddr);
                ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
@@@ -1367,8 -1372,7 +1369,8 @@@ static void ndisc_redirect_rcv(struct s
                return;
  
        if (!ndopts.nd_opts_rh) {
 -              ip6_redirect_no_header(skb, dev_net(skb->dev), 0, 0);
 +              ip6_redirect_no_header(skb, dev_net(skb->dev),
 +                                      skb->dev->ifindex, 0);
                return;
        }
  
@@@ -1517,27 -1521,10 +1519,27 @@@ static void pndisc_redo(struct sk_buff 
        kfree_skb(skb);
  }
  
 +static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb)
 +{
 +      struct inet6_dev *idev = __in6_dev_get(skb->dev);
 +
 +      if (!idev)
 +              return true;
 +      if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED &&
 +          idev->cnf.suppress_frag_ndisc) {
 +              net_warn_ratelimited("Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n");
 +              return true;
 +      }
 +      return false;
 +}
 +
  int ndisc_rcv(struct sk_buff *skb)
  {
        struct nd_msg *msg;
  
 +      if (ndisc_suppress_frag_ndisc(skb))
 +              return 0;
 +
        if (skb_linearize(skb))
                return 0;
  
diff --combined net/ipv6/raw.c
index c1e53349820348b859f2f973454b40786635838f,cdaed47ba9321b537d5f99d90f5614ac485fbb68..58916bbb17284ed441611d0210c9514141ff9bf4
@@@ -63,8 -63,6 +63,8 @@@
  #include <linux/seq_file.h>
  #include <linux/export.h>
  
 +#define       ICMPV6_HDRLEN   4       /* ICMPv6 header, RFC 4443 Section 2.1 */
 +
  static struct raw_hashinfo raw_v6_hashinfo = {
        .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock),
  };
@@@ -110,14 -108,11 +110,14 @@@ found
   */
  static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
  {
 -      struct icmp6hdr *_hdr;
 +      struct icmp6hdr _hdr;
        const struct icmp6hdr *hdr;
  
 +      /* We require only the four bytes of the ICMPv6 header, not any
 +       * additional bytes of message body in "struct icmp6hdr".
 +       */
        hdr = skb_header_pointer(skb, skb_transport_offset(skb),
 -                               sizeof(_hdr), &_hdr);
 +                               ICMPV6_HDRLEN, &_hdr);
        if (hdr) {
                const __u32 *data = &raw6_sk(sk)->filter.data[0];
                unsigned int type = hdr->icmp6_type;
@@@ -633,6 -628,7 +633,7 @@@ static int rawv6_send_hdrinc(struct soc
                goto error;
        skb_reserve(skb, hlen);
  
+       skb->protocol = htons(ETH_P_IPV6);
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
        skb_dst_set(skb, &rt->dst);
diff --combined net/ipv6/sit.c
index 19abcc9d6a1a4f1ed07392927e27d05b0bba8301,21b25dd8466bc25b40d227ecf22d4d0674b7951f..7ee5cb96db348ab5c75946e77d3068c3c447ba17
@@@ -581,10 -581,12 +581,10 @@@ static int ipip6_rcv(struct sk_buff *sk
                    tunnel->parms.iph.protocol != 0)
                        goto out;
  
 -              secpath_reset(skb);
                skb->mac_header = skb->network_header;
                skb_reset_network_header(skb);
                IPCB(skb)->flags = 0;
                skb->protocol = htons(ETH_P_IPV6);
 -              skb->pkt_type = PACKET_HOST;
  
                if (tunnel->dev->priv_flags & IFF_ISATAP) {
                        if (!isatap_chksrc(skb, iph, tunnel)) {
                        }
                }
  
 -              __skb_tunnel_rx(skb, tunnel->dev);
 +              __skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
  
                err = IP_ECN_decapsulate(iph, skb);
                if (unlikely(err)) {
                tstats->rx_packets++;
                tstats->rx_bytes += skb->len;
  
 -              if (tunnel->net != dev_net(tunnel->dev))
 -                      skb_scrub_packet(skb);
                netif_rx(skb);
  
                return 0;
@@@ -641,11 -645,7 +641,7 @@@ static int ipip_rcv(struct sk_buff *skb
        const struct iphdr *iph;
        struct ip_tunnel *tunnel;
  
-       if (iptunnel_pull_header(skb, 0, tpi.proto))
-               goto drop;
        iph = ip_hdr(skb);
        tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
                                     iph->saddr, iph->daddr);
        if (tunnel != NULL) {
  
                if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                        goto drop;
+               if (iptunnel_pull_header(skb, 0, tpi.proto))
+                       goto drop;
                return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
        }
  
@@@ -856,6 -858,9 +854,6 @@@ static netdev_tx_t ipip6_tunnel_xmit(st
                        tunnel->err_count = 0;
        }
  
 -      if (tunnel->net != dev_net(dev))
 -              skb_scrub_packet(skb);
 -
        /*
         * Okay, now see if we can stuff it in the buffer as-is.
         */
                ttl = iph6->hop_limit;
        tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
  
 -      err = iptunnel_xmit(dev_net(dev), rt, skb, fl4.saddr, fl4.daddr,
 -                          IPPROTO_IPV6, tos, ttl, df);
+       if (likely(!skb->encapsulation)) {
+               skb_reset_inner_headers(skb);
+               skb->encapsulation = 1;
+       }
 +      err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
 +                          ttl, df, !net_eq(tunnel->net, dev_net(dev)));
        iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
        return NETDEV_TX_OK;
  
@@@ -1582,7 -1592,7 +1585,7 @@@ static void __net_exit sit_destroy_tunn
                                /* If dev is in the same netns, it has already
                                 * been added to the list by the previous loop.
                                 */
 -                              if (dev_net(t->dev) != net)
 +                              if (!net_eq(dev_net(t->dev), net))
                                        unregister_netdevice_queue(t->dev,
                                                                   head);
                                t = rtnl_dereference(t->next);
diff --combined net/ipv6/tcp_ipv6.c
index 9acdcedf9a141f1f39d415e603d3753f8f731c0e,eeb4cb0c57c1d36c318e6f5d2dd3717459400c83..5c71501fc917d6271f72cea50cb98b9ad783f1c4
@@@ -963,8 -963,7 +963,8 @@@ static int tcp_v6_conn_request(struct s
        if (!ipv6_unicast_destination(skb))
                goto drop;
  
 -      if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
 +      if ((sysctl_tcp_syncookies == 2 ||
 +           inet_csk_reqsk_queue_is_full(sk)) && !isn) {
                want_cookie = tcp_syn_flood_action(sk, skb, "TCPv6");
                if (!want_cookie)
                        goto drop;
@@@ -1238,6 -1237,8 +1238,6 @@@ static struct sock * tcp_v6_syn_recv_so
                newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
  
        tcp_initialize_rcv_mss(newsk);
 -      tcp_synack_rtt_meas(newsk, req);
 -      newtp->total_retrans = req->num_retrans;
  
        newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
        newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
@@@ -1360,7 -1361,8 +1360,7 @@@ static int tcp_v6_do_rcv(struct sock *s
                        }
                }
  
 -              if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
 -                      goto reset;
 +              tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len);
                if (opt_skb)
                        goto ipv6_pktoptions;
                return 0;
@@@ -1425,7 -1427,7 +1425,7 @@@ ipv6_pktoptions
                if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
                        np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
                if (np->rxopt.bits.rxtclass)
-                       np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
+                       np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(opt_skb));
                if (ipv6_opt_accepted(sk, opt_skb)) {
                        skb_set_owner_r(opt_skb, sk);
                        opt_skb = xchg(&np->pktoptions, opt_skb);
@@@ -1730,7 -1732,7 +1730,7 @@@ static void get_openreq6(struct seq_fil
  
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
 -                 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK\n",
 +                 "%02X %08X:%08X %02X:%08lX %08X %5u %8d %d %d %pK\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3],
@@@ -1781,7 -1783,7 +1781,7 @@@ static void get_tcp6_sock(struct seq_fi
  
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
 -                 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %lu %lu %u %u %d\n",
 +                 "%02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %lu %lu %u %u %d\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3], srcp,
@@@ -1924,7 -1926,6 +1924,7 @@@ struct proto tcpv6_prot = 
        .unhash                 = inet_unhash,
        .get_port               = inet_csk_get_port,
        .enter_memory_pressure  = tcp_enter_memory_pressure,
 +      .stream_memory_free     = tcp_stream_memory_free,
        .sockets_allocated      = &tcp_sockets_allocated,
        .memory_allocated       = &tcp_memory_allocated,
        .memory_pressure        = &tcp_memory_pressure,
diff --combined net/xfrm/xfrm_policy.c
index ad8cc7bcf0651eb1f9f00085f779a80060372c15,f77c371ea72b9e1a3d239998bdeb91de7585cd3b..ed38d5d81f9e1f4890cf36447713badd48691489
@@@ -308,7 -308,7 +308,7 @@@ void xfrm_policy_destroy(struct xfrm_po
  {
        BUG_ON(!policy->walk.dead);
  
 -      if (del_timer(&policy->timer))
 +      if (del_timer(&policy->timer) || del_timer(&policy->polq.hold_timer))
                BUG();
  
        security_xfrm_policy_free(policy->security);
@@@ -320,10 -320,8 +320,8 @@@ static void xfrm_queue_purge(struct sk_
  {
        struct sk_buff *skb;
  
-       while ((skb = skb_dequeue(list)) != NULL) {
-               dev_put(skb->dev);
+       while ((skb = skb_dequeue(list)) != NULL)
                kfree_skb(skb);
-       }
  }
  
  /* Rule must be locked. Release descentant resources, announce
@@@ -660,13 -658,7 +658,13 @@@ int xfrm_policy_insert(int dir, struct 
        xfrm_pol_hold(policy);
        net->xfrm.policy_count[dir]++;
        atomic_inc(&flow_cache_genid);
 -      rt_genid_bump(net);
 +
 +      /* After previous checking, family can either be AF_INET or AF_INET6 */
 +      if (policy->family == AF_INET)
 +              rt_genid_bump_ipv4(net);
 +      else
 +              rt_genid_bump_ipv6(net);
 +
        if (delpol) {
                xfrm_policy_requeue(delpol, policy);
                __xfrm_policy_unlink(delpol, dir);
@@@ -1764,7 -1756,6 +1762,6 @@@ static void xfrm_policy_queue_process(u
        struct sk_buff *skb;
        struct sock *sk;
        struct dst_entry *dst;
-       struct net_device *dev;
        struct xfrm_policy *pol = (struct xfrm_policy *)arg;
        struct xfrm_policy_queue *pq = &pol->polq;
        struct flowi fl;
                dst = xfrm_lookup(xp_net(pol), skb_dst(skb)->path,
                                  &fl, skb->sk, 0);
                if (IS_ERR(dst)) {
-                       dev_put(skb->dev);
                        kfree_skb(skb);
                        continue;
                }
                skb_dst_drop(skb);
                skb_dst_set(skb, dst);
  
-               dev = skb->dev;
                err = dst_output(skb);
-               dev_put(dev);
        }
  
        return;
@@@ -1845,7 -1833,6 +1839,6 @@@ static int xdst_queue_output(struct sk_
        }
  
        skb_dst_force(skb);
-       dev_hold(skb->dev);
  
        spin_lock_bh(&pq->hold_queue.lock);
  
@@@ -2132,6 -2119,8 +2125,6 @@@ restart
                 * have the xfrm_state's. We need to wait for KM to
                 * negotiate new SA's or bail out with error.*/
                if (net->xfrm.sysctl_larval_drop) {
 -                      /* EREMOTE tells the caller to generate
 -                       * a one-shot blackhole route. */
                        dst_release(dst);
                        xfrm_pols_put(pols, drop_pols);
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
diff --combined net/xfrm/xfrm_state.c
index 4f8ace8558649bacdc2f0c426d89c058bd5559d6,54c0acd2946861babd611bf8ecf8ecb6751a71ad..b9c3f9e943a9159d1617feec49c751055ea4dd55
@@@ -39,9 -39,6 +39,6 @@@ static DEFINE_SPINLOCK(xfrm_state_lock)
  
  static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
  
- static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
- static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
  static inline unsigned int xfrm_dst_hash(struct net *net,
                                         const xfrm_address_t *daddr,
                                         const xfrm_address_t *saddr,
@@@ -499,8 -496,7 +496,8 @@@ struct xfrm_state *xfrm_state_alloc(str
                INIT_HLIST_NODE(&x->bydst);
                INIT_HLIST_NODE(&x->bysrc);
                INIT_HLIST_NODE(&x->byspi);
 -              tasklet_hrtimer_init(&x->mtimer, xfrm_timer_handler, CLOCK_REALTIME, HRTIMER_MODE_ABS);
 +              tasklet_hrtimer_init(&x->mtimer, xfrm_timer_handler,
 +                                      CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
                setup_timer(&x->rtimer, xfrm_replay_timer_handler,
                                (unsigned long)x);
                x->curlft.add_time = get_seconds();
@@@ -991,13 -987,11 +988,13 @@@ void xfrm_state_insert(struct xfrm_stat
  EXPORT_SYMBOL(xfrm_state_insert);
  
  /* xfrm_state_lock is held */
 -static struct xfrm_state *__find_acq_core(struct net *net, struct xfrm_mark *m,
 +static struct xfrm_state *__find_acq_core(struct net *net,
 +                                        const struct xfrm_mark *m,
                                          unsigned short family, u8 mode,
                                          u32 reqid, u8 proto,
                                          const xfrm_address_t *daddr,
 -                                        const xfrm_address_t *saddr, int create)
 +                                        const xfrm_address_t *saddr,
 +                                        int create)
  {
        unsigned int h = xfrm_dst_hash(net, daddr, saddr, reqid, family);
        struct xfrm_state *x;
@@@ -1402,9 -1396,9 +1399,9 @@@ xfrm_state_lookup_byaddr(struct net *ne
  EXPORT_SYMBOL(xfrm_state_lookup_byaddr);
  
  struct xfrm_state *
 -xfrm_find_acq(struct net *net, struct xfrm_mark *mark, u8 mode, u32 reqid, u8 proto,
 -            const xfrm_address_t *daddr, const xfrm_address_t *saddr,
 -            int create, unsigned short family)
 +xfrm_find_acq(struct net *net, const struct xfrm_mark *mark, u8 mode, u32 reqid,
 +            u8 proto, const xfrm_address_t *daddr,
 +            const xfrm_address_t *saddr, int create, unsigned short family)
  {
        struct xfrm_state *x;
  
@@@ -1863,7 -1857,7 +1860,7 @@@ int xfrm_state_unregister_afinfo(struc
  }
  EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
  
- static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
+ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
  {
        struct xfrm_state_afinfo *afinfo;
        if (unlikely(family >= NPROTO))
        return afinfo;
  }
  
static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+ void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
  {
        rcu_read_unlock();
  }