i40e: Fix RSS to not be limited by the number of CPUs
[deliverable/linux.git] / drivers / net / ethernet / intel / i40e / i40e_main.c
index 344912957cabb8391dc0a2d46baa16ccb6d3ffc7..a32be7c5e21eeead83da8ba3b4b00bf1599a388f 100644 (file)
 /* Local includes */
 #include "i40e.h"
 #include "i40e_diag.h"
-#if IS_ENABLED(CONFIG_VXLAN)
-#include <net/vxlan.h>
-#endif
-#if IS_ENABLED(CONFIG_GENEVE)
-#include <net/geneve.h>
-#endif
+#include <net/udp_tunnel.h>
 
 const char i40e_driver_name[] = "i40e";
 static const char i40e_driver_string[] =
@@ -45,8 +40,8 @@ static const char i40e_driver_string[] =
 #define DRV_KERN "-k"
 
 #define DRV_VERSION_MAJOR 1
-#define DRV_VERSION_MINOR 4
-#define DRV_VERSION_BUILD 25
+#define DRV_VERSION_MINOR 5
+#define DRV_VERSION_BUILD 16
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
             __stringify(DRV_VERSION_MINOR) "." \
             __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -90,6 +85,8 @@ static const struct pci_device_id i40e_pci_tbl[] = {
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_1G_BASE_T_X722), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T_X722), 0},
+       {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_I_X722), 0},
+       {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_I_X722), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2_A), 0},
        /* required last entry */
@@ -326,7 +323,7 @@ static void i40e_tx_timeout(struct net_device *netdev)
                unsigned long trans_start;
 
                q = netdev_get_tx_queue(netdev, i);
-               trans_start = q->trans_start ? : netdev->trans_start;
+               trans_start = q->trans_start;
                if (netif_xmit_stopped(q) &&
                    time_after(jiffies,
                               (trans_start + netdev->watchdog_timeo))) {
@@ -395,24 +392,6 @@ static void i40e_tx_timeout(struct net_device *netdev)
        pf->tx_timeout_recovery_level++;
 }
 
-/**
- * i40e_release_rx_desc - Store the new tail and head values
- * @rx_ring: ring to bump
- * @val: new head index
- **/
-static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)
-{
-       rx_ring->next_to_use = val;
-
-       /* Force memory writes to complete before letting h/w
-        * know there are new descriptors to fetch.  (Only
-        * applicable for weak-ordered memory model archs,
-        * such as IA-64).
-        */
-       wmb();
-       writel(val, rx_ring->tail);
-}
-
 /**
  * i40e_get_vsi_stats_struct - Get System Network Statistics
  * @vsi: the VSI we care about
@@ -1600,14 +1579,8 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
        vsi->tc_config.numtc = numtc;
        vsi->tc_config.enabled_tc = enabled_tc ? enabled_tc : 1;
        /* Number of queues per enabled TC */
-       /* In MFP case we can have a much lower count of MSIx
-        * vectors available and so we need to lower the used
-        * q count.
-        */
-       if (pf->flags & I40E_FLAG_MSIX_ENABLED)
-               qcount = min_t(int, vsi->alloc_queue_pairs, pf->num_lan_msix);
-       else
-               qcount = vsi->alloc_queue_pairs;
+       qcount = vsi->alloc_queue_pairs;
+
        num_tc_qps = qcount / numtc;
        num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf));
 
@@ -1861,6 +1834,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
 {
        struct list_head tmp_del_list, tmp_add_list;
        struct i40e_mac_filter *f, *ftmp, *fclone;
+       struct i40e_hw *hw = &vsi->back->hw;
        bool promisc_forced_on = false;
        bool add_happened = false;
        int filter_list_len = 0;
@@ -1941,7 +1915,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
        if (!list_empty(&tmp_del_list)) {
                int del_list_size;
 
-               filter_list_len = pf->hw.aq.asq_buf_size /
+               filter_list_len = hw->aq.asq_buf_size /
                            sizeof(struct i40e_aqc_remove_macvlan_element_data);
                del_list_size = filter_list_len *
                            sizeof(struct i40e_aqc_remove_macvlan_element_data);
@@ -1973,12 +1947,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
 
                        /* flush a full buffer */
                        if (num_del == filter_list_len) {
-                               aq_ret = i40e_aq_remove_macvlan(&pf->hw,
-                                                               vsi->seid,
-                                                               del_list,
-                                                               num_del,
-                                                               NULL);
-                               aq_err = pf->hw.aq.asq_last_status;
+                               aq_ret =
+                                       i40e_aq_remove_macvlan(hw, vsi->seid,
+                                                              del_list,
+                                                              num_del, NULL);
+                               aq_err = hw->aq.asq_last_status;
                                num_del = 0;
                                memset(del_list, 0, del_list_size);
 
@@ -1986,8 +1959,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                                        retval = -EIO;
                                        dev_err(&pf->pdev->dev,
                                                "ignoring delete macvlan error, err %s, aq_err %s while flushing a full buffer\n",
-                                               i40e_stat_str(&pf->hw, aq_ret),
-                                               i40e_aq_str(&pf->hw, aq_err));
+
+                                                i40e_stat_str(hw, aq_ret),
+                                                i40e_aq_str(hw, aq_err));
                                }
                        }
                        /* Release memory for MAC filter entries which were
@@ -1998,17 +1972,16 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                }
 
                if (num_del) {
-                       aq_ret = i40e_aq_remove_macvlan(&pf->hw, vsi->seid,
-                                                       del_list, num_del,
-                                                       NULL);
-                       aq_err = pf->hw.aq.asq_last_status;
+                       aq_ret = i40e_aq_remove_macvlan(hw, vsi->seid, del_list,
+                                                       num_del, NULL);
+                       aq_err = hw->aq.asq_last_status;
                        num_del = 0;
 
                        if (aq_ret && aq_err != I40E_AQ_RC_ENOENT)
                                dev_info(&pf->pdev->dev,
                                         "ignoring delete macvlan error, err %s aq_err %s\n",
-                                        i40e_stat_str(&pf->hw, aq_ret),
-                                        i40e_aq_str(&pf->hw, aq_err));
+                                        i40e_stat_str(hw, aq_ret),
+                                        i40e_aq_str(hw, aq_err));
                }
 
                kfree(del_list);
@@ -2019,7 +1992,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                int add_list_size;
 
                /* do all the adds now */
-               filter_list_len = pf->hw.aq.asq_buf_size /
+               filter_list_len = hw->aq.asq_buf_size /
                               sizeof(struct i40e_aqc_add_macvlan_element_data),
                add_list_size = filter_list_len *
                               sizeof(struct i40e_aqc_add_macvlan_element_data);
@@ -2054,10 +2027,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
 
                        /* flush a full buffer */
                        if (num_add == filter_list_len) {
-                               aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
+                               aq_ret = i40e_aq_add_macvlan(hw, vsi->seid,
                                                             add_list, num_add,
                                                             NULL);
-                               aq_err = pf->hw.aq.asq_last_status;
+                               aq_err = hw->aq.asq_last_status;
                                num_add = 0;
 
                                if (aq_ret)
@@ -2072,9 +2045,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                }
 
                if (num_add) {
-                       aq_ret = i40e_aq_add_macvlan(&pf->hw, vsi->seid,
+                       aq_ret = i40e_aq_add_macvlan(hw, vsi->seid,
                                                     add_list, num_add, NULL);
-                       aq_err = pf->hw.aq.asq_last_status;
+                       aq_err = hw->aq.asq_last_status;
                        num_add = 0;
                }
                kfree(add_list);
@@ -2084,9 +2057,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                        retval = i40e_aq_rc_to_posix(aq_ret, aq_err);
                        dev_info(&pf->pdev->dev,
                                 "add filter failed, err %s aq_err %s\n",
-                                i40e_stat_str(&pf->hw, aq_ret),
-                                i40e_aq_str(&pf->hw, aq_err));
-                       if ((pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOSPC) &&
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, aq_err));
+                       if ((hw->aq.asq_last_status == I40E_AQ_RC_ENOSPC) &&
                            !test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
                                      &vsi->state)) {
                                promisc_forced_on = true;
@@ -2097,6 +2070,12 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                }
        }
 
+       /* if the VF is not trusted do not do promisc */
+       if ((vsi->type == I40E_VSI_SRIOV) && !pf->vf[vsi->vf_id].trusted) {
+               clear_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
+               goto out;
+       }
+
        /* check for changes in promiscuous modes */
        if (changed_flags & IFF_ALLMULTI) {
                bool cur_multipromisc;
@@ -2108,12 +2087,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                                                               NULL);
                if (aq_ret) {
                        retval = i40e_aq_rc_to_posix(aq_ret,
-                                                    pf->hw.aq.asq_last_status);
+                                                    hw->aq.asq_last_status);
                        dev_info(&pf->pdev->dev,
                                 "set multi promisc failed, err %s aq_err %s\n",
-                                i40e_stat_str(&pf->hw, aq_ret),
-                                i40e_aq_str(&pf->hw,
-                                            pf->hw.aq.asq_last_status));
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
                }
        }
        if ((changed_flags & IFF_PROMISC) || promisc_forced_on) {
@@ -2136,28 +2114,33 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                        }
                } else {
                        aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
-                                                         &vsi->back->hw,
+                                                         hw,
                                                          vsi->seid,
-                                                         cur_promisc, NULL);
+                                                         cur_promisc, NULL,
+                                                         true);
                        if (aq_ret) {
                                retval =
                                i40e_aq_rc_to_posix(aq_ret,
-                                                   pf->hw.aq.asq_last_status);
+                                                   hw->aq.asq_last_status);
                                dev_info(&pf->pdev->dev,
-                                        "set unicast promisc failed, err %d, aq_err %d\n",
-                                        aq_ret, pf->hw.aq.asq_last_status);
+                                        "set unicast promisc failed, err %s, aq_err %s\n",
+                                        i40e_stat_str(hw, aq_ret),
+                                        i40e_aq_str(hw,
+                                                    hw->aq.asq_last_status));
                        }
                        aq_ret = i40e_aq_set_vsi_multicast_promiscuous(
-                                                         &vsi->back->hw,
+                                                         hw,
                                                          vsi->seid,
                                                          cur_promisc, NULL);
                        if (aq_ret) {
                                retval =
                                i40e_aq_rc_to_posix(aq_ret,
-                                                   pf->hw.aq.asq_last_status);
+                                                   hw->aq.asq_last_status);
                                dev_info(&pf->pdev->dev,
-                                        "set multicast promisc failed, err %d, aq_err %d\n",
-                                        aq_ret, pf->hw.aq.asq_last_status);
+                                        "set multicast promisc failed, err %s, aq_err %s\n",
+                                        i40e_stat_str(hw, aq_ret),
+                                        i40e_aq_str(hw,
+                                                    hw->aq.asq_last_status));
                        }
                }
                aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw,
@@ -2168,9 +2151,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                                                     pf->hw.aq.asq_last_status);
                        dev_info(&pf->pdev->dev,
                                 "set brdcast promisc failed, err %s, aq_err %s\n",
-                                i40e_stat_str(&pf->hw, aq_ret),
-                                i40e_aq_str(&pf->hw,
-                                            pf->hw.aq.asq_last_status));
+                                        i40e_stat_str(hw, aq_ret),
+                                        i40e_aq_str(hw,
+                                                    hw->aq.asq_last_status));
                }
        }
 out:
@@ -2865,34 +2848,21 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
        memset(&rx_ctx, 0, sizeof(rx_ctx));
 
        ring->rx_buf_len = vsi->rx_buf_len;
-       ring->rx_hdr_len = vsi->rx_hdr_len;
 
        rx_ctx.dbuff = ring->rx_buf_len >> I40E_RXQ_CTX_DBUFF_SHIFT;
-       rx_ctx.hbuff = ring->rx_hdr_len >> I40E_RXQ_CTX_HBUFF_SHIFT;
 
        rx_ctx.base = (ring->dma / 128);
        rx_ctx.qlen = ring->count;
 
-       if (vsi->back->flags & I40E_FLAG_16BYTE_RX_DESC_ENABLED) {
-               set_ring_16byte_desc_enabled(ring);
-               rx_ctx.dsize = 0;
-       } else {
-               rx_ctx.dsize = 1;
-       }
+       /* use 32 byte descriptors */
+       rx_ctx.dsize = 1;
 
-       rx_ctx.dtype = vsi->dtype;
-       if (vsi->dtype) {
-               set_ring_ps_enabled(ring);
-               rx_ctx.hsplit_0 = I40E_RX_SPLIT_L2      |
-                                 I40E_RX_SPLIT_IP      |
-                                 I40E_RX_SPLIT_TCP_UDP |
-                                 I40E_RX_SPLIT_SCTP;
-       } else {
-               rx_ctx.hsplit_0 = 0;
-       }
+       /* descriptor type is always zero
+        * rx_ctx.dtype = 0;
+        */
+       rx_ctx.hsplit_0 = 0;
 
-       rx_ctx.rxmax = min_t(u16, vsi->max_frame,
-                                 (chain_len * ring->rx_buf_len));
+       rx_ctx.rxmax = min_t(u16, vsi->max_frame, chain_len * ring->rx_buf_len);
        if (hw->revision_id == 0)
                rx_ctx.lrxqthresh = 0;
        else
@@ -2929,12 +2899,7 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
        ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q);
        writel(0, ring->tail);
 
-       if (ring_is_ps_enabled(ring)) {
-               i40e_alloc_rx_headers(ring);
-               i40e_alloc_rx_buffers_ps(ring, I40E_DESC_UNUSED(ring));
-       } else {
-               i40e_alloc_rx_buffers_1buf(ring, I40E_DESC_UNUSED(ring));
-       }
+       i40e_alloc_rx_buffers(ring, I40E_DESC_UNUSED(ring));
 
        return 0;
 }
@@ -2973,40 +2938,18 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
        else
                vsi->max_frame = I40E_RXBUFFER_2048;
 
-       /* figure out correct receive buffer length */
-       switch (vsi->back->flags & (I40E_FLAG_RX_1BUF_ENABLED |
-                                   I40E_FLAG_RX_PS_ENABLED)) {
-       case I40E_FLAG_RX_1BUF_ENABLED:
-               vsi->rx_hdr_len = 0;
-               vsi->rx_buf_len = vsi->max_frame;
-               vsi->dtype = I40E_RX_DTYPE_NO_SPLIT;
-               break;
-       case I40E_FLAG_RX_PS_ENABLED:
-               vsi->rx_hdr_len = I40E_RX_HDR_SIZE;
-               vsi->rx_buf_len = I40E_RXBUFFER_2048;
-               vsi->dtype = I40E_RX_DTYPE_HEADER_SPLIT;
-               break;
-       default:
-               vsi->rx_hdr_len = I40E_RX_HDR_SIZE;
-               vsi->rx_buf_len = I40E_RXBUFFER_2048;
-               vsi->dtype = I40E_RX_DTYPE_SPLIT_ALWAYS;
-               break;
-       }
+       vsi->rx_buf_len = I40E_RXBUFFER_2048;
 
 #ifdef I40E_FCOE
        /* setup rx buffer for FCoE */
        if ((vsi->type == I40E_VSI_FCOE) &&
            (vsi->back->flags & I40E_FLAG_FCOE_ENABLED)) {
-               vsi->rx_hdr_len = 0;
                vsi->rx_buf_len = I40E_RXBUFFER_3072;
                vsi->max_frame = I40E_RXBUFFER_3072;
-               vsi->dtype = I40E_RX_DTYPE_NO_SPLIT;
        }
 
 #endif /* I40E_FCOE */
        /* round up for the chip's needs */
-       vsi->rx_hdr_len = ALIGN(vsi->rx_hdr_len,
-                               BIT_ULL(I40E_RXQ_CTX_HBUFF_SHIFT));
        vsi->rx_buf_len = ALIGN(vsi->rx_buf_len,
                                BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT));
 
@@ -4001,6 +3944,7 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)
                        /* clear the affinity_mask in the IRQ descriptor */
                        irq_set_affinity_hint(pf->msix_entries[vector].vector,
                                              NULL);
+                       synchronize_irq(pf->msix_entries[vector].vector);
                        free_irq(pf->msix_entries[vector].vector,
                                 vsi->q_vectors[i]);
 
@@ -4164,7 +4108,7 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf)
        int i;
 
        i40e_stop_misc_vector(pf);
-       if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
+       if (pf->flags & I40E_FLAG_MSIX_ENABLED && pf->msix_entries) {
                synchronize_irq(pf->msix_entries[0].vector);
                free_irq(pf->msix_entries[0].vector, pf);
        }
@@ -5232,12 +5176,6 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi)
                usleep_range(1000, 2000);
        i40e_down(vsi);
 
-       /* Give a VF some time to respond to the reset.  The
-        * two second wait is based upon the watchdog cycle in
-        * the VF driver.
-        */
-       if (vsi->type == I40E_VSI_SRIOV)
-               msleep(2000);
        i40e_up(vsi);
        clear_bit(__I40E_CONFIG_BUSY, &pf->state);
 }
@@ -5280,6 +5218,9 @@ void i40e_down(struct i40e_vsi *vsi)
                i40e_clean_tx_ring(vsi->tx_rings[i]);
                i40e_clean_rx_ring(vsi->rx_rings[i]);
        }
+
+       i40e_notify_client_of_netdev_close(vsi, false);
+
 }
 
 /**
@@ -5391,14 +5332,7 @@ int i40e_open(struct net_device *netdev)
                                                       TCP_FLAG_CWR) >> 16);
        wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
 
-#ifdef CONFIG_I40E_VXLAN
-       vxlan_get_rx_port(netdev);
-#endif
-#ifdef CONFIG_I40E_GENEVE
-       if (pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE)
-               geneve_get_rx_port(netdev);
-#endif
-
+       udp_tunnel_get_rx_info(netdev);
        i40e_notify_client_of_netdev_open(vsi);
 
        return 0;
@@ -5509,11 +5443,7 @@ static void i40e_fdir_filter_exit(struct i40e_pf *pf)
  *
  * Returns 0, this is not allowed to fail
  **/
-#ifdef I40E_FCOE
 int i40e_close(struct net_device *netdev)
-#else
-static int i40e_close(struct net_device *netdev)
-#endif
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
@@ -5538,8 +5468,6 @@ void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags)
 
        WARN_ON(in_interrupt());
 
-       if (i40e_check_asq_alive(&pf->hw))
-               i40e_vc_notify_reset(pf);
 
        /* do the biggest reset indicated */
        if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) {
@@ -5995,7 +5923,6 @@ static void i40e_fdir_flush_and_replay(struct i40e_pf *pf)
                if (I40E_DEBUG_FD & pf->hw.debug_mask)
                        dev_info(&pf->pdev->dev, "FD Filter table flushed and FD-SB replayed.\n");
        }
-
 }
 
 /**
@@ -6377,7 +6304,7 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
                        break;
                default:
                        dev_info(&pf->pdev->dev,
-                                "ARQ Error: Unknown event 0x%04x received\n",
+                                "ARQ: Unknown event 0x%04x ignored\n",
                                 opcode);
                        break;
                }
@@ -6742,6 +6669,8 @@ static void i40e_prep_for_reset(struct i40e_pf *pf)
        clear_bit(__I40E_RESET_INTR_RECEIVED, &pf->state);
        if (test_and_set_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state))
                return;
+       if (i40e_check_asq_alive(&pf->hw))
+               i40e_vc_notify_reset(pf);
 
        dev_dbg(&pf->pdev->dev, "Tearing down internal switch for reset\n");
 
@@ -6862,6 +6791,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
         */
        ret = i40e_aq_set_phy_int_mask(&pf->hw,
                                       ~(I40E_AQ_EVENT_LINK_UPDOWN |
+                                        I40E_AQ_EVENT_MEDIA_NA |
                                         I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
        if (ret)
                dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
@@ -7109,7 +7039,6 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
  **/
 static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
 {
-#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
        struct i40e_hw *hw = &pf->hw;
        i40e_status ret;
        __be16 port;
@@ -7144,7 +7073,6 @@ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
                        }
                }
        }
-#endif
 }
 
 /**
@@ -7525,10 +7453,6 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
                rx_ring->count = vsi->num_desc;
                rx_ring->size = 0;
                rx_ring->dcb_tc = 0;
-               if (pf->flags & I40E_FLAG_16BYTE_RX_DESC_ENABLED)
-                       set_ring_16byte_desc_enabled(rx_ring);
-               else
-                       clear_ring_16byte_desc_enabled(rx_ring);
                rx_ring->rx_itr_setting = pf->rx_itr_default;
                vsi->rx_rings[i] = rx_ring;
        }
@@ -8084,24 +8008,45 @@ static int i40e_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
 {
        struct i40e_pf *pf = vsi->back;
        struct i40e_hw *hw = &pf->hw;
+       u16 vf_id = vsi->vf_id;
        u8 i;
 
        /* Fill out hash function seed */
        if (seed) {
                u32 *seed_dw = (u32 *)seed;
 
-               for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-                       i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
+               if (vsi->type == I40E_VSI_MAIN) {
+                       for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
+                               i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i),
+                                                 seed_dw[i]);
+               } else if (vsi->type == I40E_VSI_SRIOV) {
+                       for (i = 0; i <= I40E_VFQF_HKEY1_MAX_INDEX; i++)
+                               i40e_write_rx_ctl(hw,
+                                                 I40E_VFQF_HKEY1(i, vf_id),
+                                                 seed_dw[i]);
+               } else {
+                       dev_err(&pf->pdev->dev, "Cannot set RSS seed - invalid VSI type\n");
+               }
        }
 
        if (lut) {
                u32 *lut_dw = (u32 *)lut;
 
-               if (lut_size != I40E_HLUT_ARRAY_SIZE)
-                       return -EINVAL;
-
-               for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
-                       wr32(hw, I40E_PFQF_HLUT(i), lut_dw[i]);
+               if (vsi->type == I40E_VSI_MAIN) {
+                       if (lut_size != I40E_HLUT_ARRAY_SIZE)
+                               return -EINVAL;
+                       for (i = 0; i <= I40E_PFQF_HLUT_MAX_INDEX; i++)
+                               wr32(hw, I40E_PFQF_HLUT(i), lut_dw[i]);
+               } else if (vsi->type == I40E_VSI_SRIOV) {
+                       if (lut_size != I40E_VF_HLUT_ARRAY_SIZE)
+                               return -EINVAL;
+                       for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)
+                               i40e_write_rx_ctl(hw,
+                                                 I40E_VFQF_HLUT1(i, vf_id),
+                                                 lut_dw[i]);
+               } else {
+                       dev_err(&pf->pdev->dev, "Cannot set RSS LUT - invalid VSI type\n");
+               }
        }
        i40e_flush(hw);
 
@@ -8440,7 +8385,6 @@ static int i40e_sw_init(struct i40e_pf *pf)
 
        pf->msg_enable = netif_msg_init(I40E_DEFAULT_MSG_ENABLE,
                                (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK));
-       pf->hw.debug_mask = pf->msg_enable | I40E_DEBUG_DIAG;
        if (debug != -1 && debug != I40E_DEFAULT_MSG_ENABLE) {
                if (I40E_DEBUG_USER & debug)
                        pf->hw.debug_mask = debug;
@@ -8451,14 +8395,8 @@ static int i40e_sw_init(struct i40e_pf *pf)
        /* Set default capability flags */
        pf->flags = I40E_FLAG_RX_CSUM_ENABLED |
                    I40E_FLAG_MSI_ENABLED     |
-                   I40E_FLAG_LINK_POLLING_ENABLED |
                    I40E_FLAG_MSIX_ENABLED;
 
-       if (iommu_present(&pci_bus_type))
-               pf->flags |= I40E_FLAG_RX_PS_ENABLED;
-       else
-               pf->flags |= I40E_FLAG_RX_1BUF_ENABLED;
-
        /* Set default ITR */
        pf->rx_itr_default = I40E_ITR_DYNAMIC | I40E_ITR_RX_DEF;
        pf->tx_itr_default = I40E_ITR_DYNAMIC | I40E_ITR_TX_DEF;
@@ -8670,7 +8608,6 @@ static int i40e_set_features(struct net_device *netdev,
        return 0;
 }
 
-#if IS_ENABLED(CONFIG_VXLAN) || IS_ENABLED(CONFIG_GENEVE)
 /**
  * i40e_get_udp_port_idx - Lookup a possibly offloaded for Rx UDP port
  * @pf: board private structure
@@ -8690,21 +8627,18 @@ static u8 i40e_get_udp_port_idx(struct i40e_pf *pf, __be16 port)
        return i;
 }
 
-#endif
-
-#if IS_ENABLED(CONFIG_VXLAN)
 /**
- * i40e_add_vxlan_port - Get notifications about VXLAN ports that come up
+ * i40e_udp_tunnel_add - Get notifications about UDP tunnel ports that come up
  * @netdev: This physical port's netdev
- * @sa_family: Socket Family that VXLAN is notifying us about
- * @port: New UDP port number that VXLAN started listening to
+ * @ti: Tunnel endpoint information
  **/
-static void i40e_add_vxlan_port(struct net_device *netdev,
-                               sa_family_t sa_family, __be16 port)
+static void i40e_udp_tunnel_add(struct net_device *netdev,
+                               struct udp_tunnel_info *ti)
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
        struct i40e_pf *pf = vsi->back;
+       __be16 port = ti->port;
        u8 next_idx;
        u8 idx;
 
@@ -8712,7 +8646,7 @@ static void i40e_add_vxlan_port(struct net_device *netdev,
 
        /* Check if port already exists */
        if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               netdev_info(netdev, "vxlan port %d already offloaded\n",
+               netdev_info(netdev, "port %d already offloaded\n",
                            ntohs(port));
                return;
        }
@@ -8721,131 +8655,75 @@ static void i40e_add_vxlan_port(struct net_device *netdev,
        next_idx = i40e_get_udp_port_idx(pf, 0);
 
        if (next_idx == I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               netdev_info(netdev, "maximum number of vxlan UDP ports reached, not adding port %d\n",
-                           ntohs(port));
-               return;
-       }
-
-       /* New port: add it and mark its index in the bitmap */
-       pf->udp_ports[next_idx].index = port;
-       pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_VXLAN;
-       pf->pending_udp_bitmap |= BIT_ULL(next_idx);
-       pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
-}
-
-/**
- * i40e_del_vxlan_port - Get notifications about VXLAN ports that go away
- * @netdev: This physical port's netdev
- * @sa_family: Socket Family that VXLAN is notifying us about
- * @port: UDP port number that VXLAN stopped listening to
- **/
-static void i40e_del_vxlan_port(struct net_device *netdev,
-                               sa_family_t sa_family, __be16 port)
-{
-       struct i40e_netdev_priv *np = netdev_priv(netdev);
-       struct i40e_vsi *vsi = np->vsi;
-       struct i40e_pf *pf = vsi->back;
-       u8 idx;
-
-       idx = i40e_get_udp_port_idx(pf, port);
-
-       /* Check if port already exists */
-       if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               /* if port exists, set it to 0 (mark for deletion)
-                * and make it pending
-                */
-               pf->udp_ports[idx].index = 0;
-               pf->pending_udp_bitmap |= BIT_ULL(idx);
-               pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
-       } else {
-               netdev_warn(netdev, "vxlan port %d was not found, not deleting\n",
-                           ntohs(port));
-       }
-}
-#endif
-
-#if IS_ENABLED(CONFIG_GENEVE)
-/**
- * i40e_add_geneve_port - Get notifications about GENEVE ports that come up
- * @netdev: This physical port's netdev
- * @sa_family: Socket Family that GENEVE is notifying us about
- * @port: New UDP port number that GENEVE started listening to
- **/
-static void i40e_add_geneve_port(struct net_device *netdev,
-                                sa_family_t sa_family, __be16 port)
-{
-       struct i40e_netdev_priv *np = netdev_priv(netdev);
-       struct i40e_vsi *vsi = np->vsi;
-       struct i40e_pf *pf = vsi->back;
-       u8 next_idx;
-       u8 idx;
-
-       if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
-               return;
-
-       idx = i40e_get_udp_port_idx(pf, port);
-
-       /* Check if port already exists */
-       if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               netdev_info(netdev, "udp port %d already offloaded\n",
+               netdev_info(netdev, "maximum number of offloaded UDP ports reached, not adding port %d\n",
                            ntohs(port));
                return;
        }
 
-       /* Now check if there is space to add the new port */
-       next_idx = i40e_get_udp_port_idx(pf, 0);
-
-       if (next_idx == I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               netdev_info(netdev, "maximum number of UDP ports reached, not adding port %d\n",
-                           ntohs(port));
+       switch (ti->type) {
+       case UDP_TUNNEL_TYPE_VXLAN:
+               pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_VXLAN;
+               break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
+                       return;
+               pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_NGE;
+               break;
+       default:
                return;
        }
 
        /* New port: add it and mark its index in the bitmap */
        pf->udp_ports[next_idx].index = port;
-       pf->udp_ports[next_idx].type = I40E_AQC_TUNNEL_TYPE_NGE;
        pf->pending_udp_bitmap |= BIT_ULL(next_idx);
        pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
-
-       dev_info(&pf->pdev->dev, "adding geneve port %d\n", ntohs(port));
 }
 
 /**
- * i40e_del_geneve_port - Get notifications about GENEVE ports that go away
+ * i40e_udp_tunnel_del - Get notifications about UDP tunnel ports that go away
  * @netdev: This physical port's netdev
- * @sa_family: Socket Family that GENEVE is notifying us about
- * @port: UDP port number that GENEVE stopped listening to
+ * @ti: Tunnel endpoint information
  **/
-static void i40e_del_geneve_port(struct net_device *netdev,
-                                sa_family_t sa_family, __be16 port)
+static void i40e_udp_tunnel_del(struct net_device *netdev,
+                               struct udp_tunnel_info *ti)
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
        struct i40e_pf *pf = vsi->back;
+       __be16 port = ti->port;
        u8 idx;
 
-       if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
-               return;
-
        idx = i40e_get_udp_port_idx(pf, port);
 
        /* Check if port already exists */
-       if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
-               /* if port exists, set it to 0 (mark for deletion)
-                * and make it pending
-                */
-               pf->udp_ports[idx].index = 0;
-               pf->pending_udp_bitmap |= BIT_ULL(idx);
-               pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
+       if (idx >= I40E_MAX_PF_UDP_OFFLOAD_PORTS)
+               goto not_found;
 
-               dev_info(&pf->pdev->dev, "deleting geneve port %d\n",
-                        ntohs(port));
-       } else {
-               netdev_warn(netdev, "geneve port %d was not found, not deleting\n",
-                           ntohs(port));
+       switch (ti->type) {
+       case UDP_TUNNEL_TYPE_VXLAN:
+               if (pf->udp_ports[idx].type != I40E_AQC_TUNNEL_TYPE_VXLAN)
+                       goto not_found;
+               break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               if (pf->udp_ports[idx].type != I40E_AQC_TUNNEL_TYPE_NGE)
+                       goto not_found;
+               break;
+       default:
+               goto not_found;
        }
+
+       /* if port exists, set it to 0 (mark for deletion)
+        * and make it pending
+        */
+       pf->udp_ports[idx].index = 0;
+       pf->pending_udp_bitmap |= BIT_ULL(idx);
+       pf->flags |= I40E_FLAG_UDP_FILTER_SYNC;
+
+       return;
+not_found:
+       netdev_warn(netdev, "UDP port %d was not found, not deleting\n",
+                   ntohs(port));
 }
-#endif
 
 static int i40e_get_phys_port_id(struct net_device *netdev,
                                 struct netdev_phys_item_id *ppid)
@@ -9074,14 +8952,9 @@ static const struct net_device_ops i40e_netdev_ops = {
        .ndo_get_vf_config      = i40e_ndo_get_vf_config,
        .ndo_set_vf_link_state  = i40e_ndo_set_vf_link_state,
        .ndo_set_vf_spoofchk    = i40e_ndo_set_vf_spoofchk,
-#if IS_ENABLED(CONFIG_VXLAN)
-       .ndo_add_vxlan_port     = i40e_add_vxlan_port,
-       .ndo_del_vxlan_port     = i40e_del_vxlan_port,
-#endif
-#if IS_ENABLED(CONFIG_GENEVE)
-       .ndo_add_geneve_port    = i40e_add_geneve_port,
-       .ndo_del_geneve_port    = i40e_del_geneve_port,
-#endif
+       .ndo_set_vf_trust       = i40e_ndo_set_vf_trust,
+       .ndo_udp_tunnel_add     = i40e_udp_tunnel_add,
+       .ndo_udp_tunnel_del     = i40e_udp_tunnel_del,
        .ndo_get_phys_port_id   = i40e_get_phys_port_id,
        .ndo_fdb_add            = i40e_ndo_fdb_add,
        .ndo_features_check     = i40e_features_check,
@@ -9114,40 +8987,44 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
        np = netdev_priv(netdev);
        np->vsi = vsi;
 
-       netdev->hw_enc_features |= NETIF_F_IP_CSUM             |
-                                  NETIF_F_IPV6_CSUM           |
-                                  NETIF_F_TSO                 |
-                                  NETIF_F_TSO6                |
-                                  NETIF_F_TSO_ECN             |
-                                  NETIF_F_GSO_GRE             |
-                                  NETIF_F_GSO_UDP_TUNNEL      |
-                                  NETIF_F_GSO_UDP_TUNNEL_CSUM |
+       netdev->hw_enc_features |= NETIF_F_SG                   |
+                                  NETIF_F_IP_CSUM              |
+                                  NETIF_F_IPV6_CSUM            |
+                                  NETIF_F_HIGHDMA              |
+                                  NETIF_F_SOFT_FEATURES        |
+                                  NETIF_F_TSO                  |
+                                  NETIF_F_TSO_ECN              |
+                                  NETIF_F_TSO6                 |
+                                  NETIF_F_GSO_GRE              |
+                                  NETIF_F_GSO_GRE_CSUM         |
+                                  NETIF_F_GSO_IPXIP4           |
+                                  NETIF_F_GSO_IPXIP6           |
+                                  NETIF_F_GSO_UDP_TUNNEL       |
+                                  NETIF_F_GSO_UDP_TUNNEL_CSUM  |
+                                  NETIF_F_GSO_PARTIAL          |
+                                  NETIF_F_SCTP_CRC             |
+                                  NETIF_F_RXHASH               |
+                                  NETIF_F_RXCSUM               |
                                   0;
 
-       netdev->features = NETIF_F_SG                  |
-                          NETIF_F_IP_CSUM             |
-                          NETIF_F_SCTP_CRC            |
-                          NETIF_F_HIGHDMA             |
-                          NETIF_F_GSO_UDP_TUNNEL      |
-                          NETIF_F_GSO_GRE             |
-                          NETIF_F_HW_VLAN_CTAG_TX     |
-                          NETIF_F_HW_VLAN_CTAG_RX     |
-                          NETIF_F_HW_VLAN_CTAG_FILTER |
-                          NETIF_F_IPV6_CSUM           |
-                          NETIF_F_TSO                 |
-                          NETIF_F_TSO_ECN             |
-                          NETIF_F_TSO6                |
-                          NETIF_F_RXCSUM              |
-                          NETIF_F_RXHASH              |
-                          0;
+       if (!(pf->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE))
+               netdev->gso_partial_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+
+       netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+
+       /* record features VLANs can make use of */
+       netdev->vlan_features |= netdev->hw_enc_features |
+                                NETIF_F_TSO_MANGLEID;
 
        if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
-               netdev->features |= NETIF_F_NTUPLE;
-       if (pf->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE)
-               netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
+               netdev->hw_features |= NETIF_F_NTUPLE;
+
+       netdev->hw_features |= netdev->hw_enc_features  |
+                              NETIF_F_HW_VLAN_CTAG_TX  |
+                              NETIF_F_HW_VLAN_CTAG_RX;
 
-       /* copy netdev features into list of user selectable features */
-       netdev->hw_features |= netdev->features;
+       netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER;
+       netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID;
 
        if (vsi->type == I40E_VSI_MAIN) {
                SET_NETDEV_DEV(netdev, &pf->pdev->dev);
@@ -9163,6 +9040,12 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
                                        I40E_VLAN_ANY, false, true);
                        spin_unlock_bh(&vsi->mac_filter_list_lock);
                }
+       } else if ((pf->hw.aq.api_maj_ver > 1) ||
+                  ((pf->hw.aq.api_maj_ver == 1) &&
+                   (pf->hw.aq.api_min_ver > 4))) {
+               /* Supported in FW API version higher than 1.4 */
+               pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
+               pf->auto_disable_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
        } else {
                /* relate the VSI_VMDQ name to the VSI_MAIN name */
                snprintf(netdev->name, IFNAMSIZ, "%sv%%d",
@@ -9180,12 +9063,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
        ether_addr_copy(netdev->dev_addr, mac_addr);
        ether_addr_copy(netdev->perm_addr, mac_addr);
-       /* vlan gets same features (except vlan offload)
-        * after any tweaks for specific VSI types
-        */
-       netdev->vlan_features = netdev->features & ~(NETIF_F_HW_VLAN_CTAG_TX |
-                                                    NETIF_F_HW_VLAN_CTAG_RX |
-                                                  NETIF_F_HW_VLAN_CTAG_FILTER);
+
        netdev->priv_flags |= IFF_UNICAST_FLT;
        netdev->priv_flags |= IFF_SUPP_NOFCS;
        /* Setup netdev TC information */
@@ -9398,7 +9276,8 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                        ctxt.info.valid_sections |=
                                cpu_to_le16(I40E_AQ_VSI_PROP_QUEUE_OPT_VALID);
                        ctxt.info.queueing_opt_flags |=
-                                               I40E_AQ_VSI_QUE_OPT_TCP_ENA;
+                               (I40E_AQ_VSI_QUE_OPT_TCP_ENA |
+                                I40E_AQ_VSI_QUE_OPT_RSS_LUT_VSI);
                }
 
                ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
@@ -10444,6 +10323,7 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig)
  **/
 static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
 {
+       u16 flags = 0;
        int ret;
 
        /* find out what's out there already */
@@ -10457,6 +10337,32 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
        }
        i40e_pf_reset_stats(pf);
 
+       /* set the switch config bit for the whole device to
+        * support limited promisc or true promisc
+        * when user requests promisc. The default is limited
+        * promisc.
+       */
+
+       if ((pf->hw.pf_id == 0) &&
+           !(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
+               flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
+
+       if (pf->hw.pf_id == 0) {
+               u16 valid_flags;
+
+               valid_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
+               ret = i40e_aq_set_switch_config(&pf->hw, flags, valid_flags,
+                                               NULL);
+               if (ret && pf->hw.aq.asq_last_status != I40E_AQ_RC_ESRCH) {
+                       dev_info(&pf->pdev->dev,
+                                "couldn't set switch config bits, err %s aq_err %s\n",
+                                i40e_stat_str(&pf->hw, ret),
+                                i40e_aq_str(&pf->hw,
+                                            pf->hw.aq.asq_last_status));
+                       /* not a fatal problem, just keep going */
+               }
+       }
+
        /* first time setup */
        if (pf->lan_vsi == I40E_NO_VSI || reinit) {
                struct i40e_vsi *vsi = NULL;
@@ -10684,11 +10590,9 @@ static void i40e_print_features(struct i40e_pf *pf)
 #ifdef CONFIG_PCI_IOV
        i += snprintf(&buf[i], REMAIN(i), " VFs: %d", pf->num_req_vfs);
 #endif
-       i += snprintf(&buf[i], REMAIN(i), " VSIs: %d QP: %d RX: %s",
+       i += snprintf(&buf[i], REMAIN(i), " VSIs: %d QP: %d",
                      pf->hw.func_caps.num_vsis,
-                     pf->vsi[pf->lan_vsi]->num_queue_pairs,
-                     pf->flags & I40E_FLAG_RX_PS_ENABLED ? "PS" : "1BUF");
-
+                     pf->vsi[pf->lan_vsi]->num_queue_pairs);
        if (pf->flags & I40E_FLAG_RSS_ENABLED)
                i += snprintf(&buf[i], REMAIN(i), " RSS");
        if (pf->flags & I40E_FLAG_FD_ATR_ENABLED)
@@ -10699,12 +10603,8 @@ static void i40e_print_features(struct i40e_pf *pf)
        }
        if (pf->flags & I40E_FLAG_DCB_CAPABLE)
                i += snprintf(&buf[i], REMAIN(i), " DCB");
-#if IS_ENABLED(CONFIG_VXLAN)
        i += snprintf(&buf[i], REMAIN(i), " VxLAN");
-#endif
-#if IS_ENABLED(CONFIG_GENEVE)
        i += snprintf(&buf[i], REMAIN(i), " Geneve");
-#endif
        if (pf->flags & I40E_FLAG_PTP)
                i += snprintf(&buf[i], REMAIN(i), " PTP");
 #ifdef I40E_FCOE
@@ -10827,6 +10727,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        hw->bus.func = PCI_FUNC(pdev->devfn);
        pf->instance = pfs_found;
 
+       /* set up the locks for the AQ, do this only once in probe
+        * and destroy them only once in remove
+        */
+       mutex_init(&hw->aq.asq_mutex);
+       mutex_init(&hw->aq.arq_mutex);
+
        if (debug != -1) {
                pf->msg_enable = pf->hw.debug_mask;
                pf->msg_enable = debug;
@@ -10872,12 +10778,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* set up a default setting for link flow control */
        pf->hw.fc.requested_mode = I40E_FC_NONE;
 
-       /* set up the locks for the AQ, do this only once in probe
-        * and destroy them only once in remove
-        */
-       mutex_init(&hw->aq.asq_mutex);
-       mutex_init(&hw->aq.arq_mutex);
-
        err = i40e_init_adminq(hw);
        if (err) {
                if (err == I40E_ERR_FIRMWARE_API_VERSION)
@@ -11069,6 +10969,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        err = i40e_aq_set_phy_int_mask(&pf->hw,
                                       ~(I40E_AQ_EVENT_LINK_UPDOWN |
+                                        I40E_AQ_EVENT_MEDIA_NA |
                                         I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
        if (err)
                dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
@@ -11270,7 +11171,6 @@ err_init_lan_hmc:
        kfree(pf->qp_pile);
 err_sw_init:
 err_adminq_setup:
-       (void)i40e_shutdown_adminq(hw);
 err_pf_reset:
        iounmap(hw->hw_addr);
 err_ioremap:
@@ -11312,8 +11212,10 @@ static void i40e_remove(struct pci_dev *pdev)
        /* no more scheduling of any task */
        set_bit(__I40E_SUSPENDED, &pf->state);
        set_bit(__I40E_DOWN, &pf->state);
-       del_timer_sync(&pf->service_timer);
-       cancel_work_sync(&pf->service_task);
+       if (pf->service_timer.data)
+               del_timer_sync(&pf->service_timer);
+       if (pf->service_task.func)
+               cancel_work_sync(&pf->service_task);
 
        if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
                i40e_free_vfs(pf);
@@ -11533,6 +11435,7 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct i40e_pf *pf = pci_get_drvdata(pdev);
        struct i40e_hw *hw = &pf->hw;
+       int retval = 0;
 
        set_bit(__I40E_SUSPENDED, &pf->state);
        set_bit(__I40E_DOWN, &pf->state);
@@ -11544,10 +11447,16 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
        wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
        wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));
 
+       i40e_stop_misc_vector(pf);
+
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+
        pci_wake_from_d3(pdev, pf->wol_en);
        pci_set_power_state(pdev, PCI_D3hot);
 
-       return 0;
+       return retval;
 }
 
 /**
This page took 0.065497 seconds and 5 git commands to generate.