OSDN Git Service

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[uclinux-h8/linux.git] / drivers / net / ethernet / intel / i40e / i40e_main.c
index 8f3b53e..6700643 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
  *
  * Intel Ethernet Controller XL710 Family Linux Driver
- * Copyright(c) 2013 - 2015 Intel Corporation.
+ * Copyright(c) 2013 - 2016 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #include <linux/of_net.h>
 #include <linux/pci.h>
 
-#ifdef CONFIG_SPARC
-#include <asm/idprom.h>
-#include <asm/prom.h>
-#endif
-
 /* Local includes */
 #include "i40e.h"
 #include "i40e_diag.h"
@@ -51,7 +46,7 @@ static const char i40e_driver_string[] =
 
 #define DRV_VERSION_MAJOR 1
 #define DRV_VERSION_MINOR 4
-#define DRV_VERSION_BUILD 8
+#define DRV_VERSION_BUILD 25
 #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_10G_BASE_T), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T4), 0},
        {PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
+       {PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_X722), 0},
+       {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_X722), 0},
        {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},
@@ -110,6 +107,8 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Connection XL710 Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
+static struct workqueue_struct *i40e_wq;
+
 /**
  * i40e_allocate_dma_mem_d - OS specific memory alloc for shared code
  * @hw:   pointer to the HW structure
@@ -290,12 +289,12 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
  *
  * If not already scheduled, this puts the task into the work queue
  **/
-static void i40e_service_event_schedule(struct i40e_pf *pf)
+void i40e_service_event_schedule(struct i40e_pf *pf)
 {
        if (!test_bit(__I40E_DOWN, &pf->state) &&
            !test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) &&
            !test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
-               schedule_work(&pf->service_task);
+               queue_work(i40e_wq, &pf->service_task);
 }
 
 /**
@@ -769,7 +768,7 @@ static void i40e_update_fcoe_stats(struct i40e_vsi *vsi)
        if (vsi->type != I40E_VSI_FCOE)
                return;
 
-       idx = (pf->pf_seid - I40E_BASE_PF_SEID) + I40E_FCOE_PF_STAT_OFFSET;
+       idx = hw->pf_id + I40E_FCOE_PF_STAT_OFFSET;
        fs = &vsi->fcoe_stats;
        ofs = &vsi->fcoe_stats_offsets;
 
@@ -820,6 +819,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
        struct i40e_eth_stats *oes;
        struct i40e_eth_stats *es;     /* device's eth stats */
        u32 tx_restart, tx_busy;
+       u64 tx_lost_interrupt;
        struct i40e_ring *p;
        u32 rx_page, rx_buf;
        u64 bytes, packets;
@@ -845,6 +845,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
        rx_b = rx_p = 0;
        tx_b = tx_p = 0;
        tx_restart = tx_busy = tx_linearize = tx_force_wb = 0;
+       tx_lost_interrupt = 0;
        rx_page = 0;
        rx_buf = 0;
        rcu_read_lock();
@@ -863,6 +864,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
                tx_busy += p->tx_stats.tx_busy;
                tx_linearize += p->tx_stats.tx_linearize;
                tx_force_wb += p->tx_stats.tx_force_wb;
+               tx_lost_interrupt += p->tx_stats.tx_lost_interrupt;
 
                /* Rx queue is part of the same block as Tx queue */
                p = &p[1];
@@ -881,6 +883,7 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
        vsi->tx_busy = tx_busy;
        vsi->tx_linearize = tx_linearize;
        vsi->tx_force_wb = tx_force_wb;
+       vsi->tx_lost_interrupt = tx_lost_interrupt;
        vsi->rx_page_failed = rx_page;
        vsi->rx_buf_failed = rx_buf;
 
@@ -1368,7 +1371,7 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
                f->changed = true;
 
                INIT_LIST_HEAD(&f->list);
-               list_add(&f->list, &vsi->mac_filter_list);
+               list_add_tail(&f->list, &vsi->mac_filter_list);
        }
 
        /* increment counter and add a new flag if needed */
@@ -1538,7 +1541,11 @@ static int i40e_set_mac(struct net_device *netdev, void *p)
 
        ether_addr_copy(netdev->dev_addr, addr->sa_data);
 
-       return i40e_sync_vsi_filters(vsi);
+       /* schedule our worker thread which will take care of
+        * applying the new filter changes
+        */
+       i40e_service_event_schedule(vsi->back);
+       return 0;
 }
 
 /**
@@ -1762,6 +1769,11 @@ bottom_of_search_loop:
                vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
                vsi->back->flags |= I40E_FLAG_FILTER_SYNC;
        }
+
+       /* schedule our worker thread which will take care of
+        * applying the new filter changes
+        */
+       i40e_service_event_schedule(vsi->back);
 }
 
 /**
@@ -1933,7 +1945,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                            sizeof(struct i40e_aqc_remove_macvlan_element_data);
                del_list_size = filter_list_len *
                            sizeof(struct i40e_aqc_remove_macvlan_element_data);
-               del_list = kzalloc(del_list_size, GFP_KERNEL);
+               del_list = kzalloc(del_list_size, GFP_ATOMIC);
                if (!del_list) {
                        i40e_cleanup_add_list(&tmp_add_list);
 
@@ -2011,7 +2023,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                               sizeof(struct i40e_aqc_add_macvlan_element_data),
                add_list_size = filter_list_len *
                               sizeof(struct i40e_aqc_add_macvlan_element_data);
-               add_list = kzalloc(add_list_size, GFP_KERNEL);
+               add_list = kzalloc(add_list_size, GFP_ATOMIC);
                if (!add_list) {
                        /* Purge element from temporary lists */
                        i40e_cleanup_add_list(&tmp_add_list);
@@ -2110,7 +2122,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                cur_promisc = (!!(vsi->current_netdev_flags & IFF_PROMISC) ||
                               test_bit(__I40E_FILTER_OVERFLOW_PROMISC,
                                        &vsi->state));
-               if (vsi->type == I40E_VSI_MAIN && pf->lan_veb != I40E_NO_VEB) {
+               if ((vsi->type == I40E_VSI_MAIN) &&
+                   (pf->lan_veb != I40E_NO_VEB) &&
+                   !(pf->flags & I40E_FLAG_MFP_ENABLED)) {
                        /* set defport ON for Main VSI instead of true promisc
                         * this way we will get all unicast/multicast and VLAN
                         * promisc behavior but will not get VF or VMDq traffic
@@ -2160,6 +2174,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                }
        }
 out:
+       /* if something went wrong then set the changed flag so we try again */
+       if (retval)
+               vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
+
        clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
        return retval;
 }
@@ -2212,7 +2230,7 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)
        netdev->mtu = new_mtu;
        if (netif_running(netdev))
                i40e_vsi_reinit_locked(vsi);
-
+       i40e_notify_client_of_l2_param_changes(vsi);
        return 0;
 }
 
@@ -3106,11 +3124,11 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
                struct i40e_q_vector *q_vector = vsi->q_vectors[i];
 
                q_vector->itr_countdown = ITR_COUNTDOWN_START;
-               q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
+               q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[i]->rx_itr_setting);
                q_vector->rx.latency_range = I40E_LOW_LATENCY;
                wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1),
                     q_vector->rx.itr);
-               q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
+               q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[i]->tx_itr_setting);
                q_vector->tx.latency_range = I40E_LOW_LATENCY;
                wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1),
                     q_vector->tx.itr);
@@ -3202,10 +3220,10 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
 
        /* set the ITR configuration */
        q_vector->itr_countdown = ITR_COUNTDOWN_START;
-       q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting);
+       q_vector->rx.itr = ITR_TO_REG(vsi->rx_rings[0]->rx_itr_setting);
        q_vector->rx.latency_range = I40E_LOW_LATENCY;
        wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.itr);
-       q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting);
+       q_vector->tx.itr = ITR_TO_REG(vsi->tx_rings[0]->tx_itr_setting);
        q_vector->tx.latency_range = I40E_LOW_LATENCY;
        wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.itr);
 
@@ -3245,14 +3263,15 @@ void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf)
 /**
  * i40e_irq_dynamic_enable_icr0 - Enable default interrupt generation for icr0
  * @pf: board private structure
+ * @clearpba: true when all pending interrupt events should be cleared
  **/
-void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf)
+void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba)
 {
        struct i40e_hw *hw = &pf->hw;
        u32 val;
 
        val = I40E_PFINT_DYN_CTL0_INTENA_MASK   |
-             I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
+             (clearpba ? I40E_PFINT_DYN_CTL0_CLEARPBA_MASK : 0) |
              (I40E_ITR_NONE << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT);
 
        wr32(hw, I40E_PFINT_DYN_CTL0, val);
@@ -3260,22 +3279,6 @@ void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf)
 }
 
 /**
- * i40e_irq_dynamic_disable - Disable default interrupt generation settings
- * @vsi: pointer to a vsi
- * @vector: disable a particular Hw Interrupt vector
- **/
-void i40e_irq_dynamic_disable(struct i40e_vsi *vsi, int vector)
-{
-       struct i40e_pf *pf = vsi->back;
-       struct i40e_hw *hw = &pf->hw;
-       u32 val;
-
-       val = I40E_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
-       wr32(hw, I40E_PFINT_DYN_CTLN(vector - 1), val);
-       i40e_flush(hw);
-}
-
-/**
  * i40e_msix_clean_rings - MSIX mode Interrupt Handler
  * @irq: interrupt number
  * @data: pointer to a q_vector
@@ -3400,7 +3403,7 @@ static int i40e_vsi_enable_irq(struct i40e_vsi *vsi)
                for (i = 0; i < vsi->num_q_vectors; i++)
                        i40e_irq_dynamic_enable(vsi, i);
        } else {
-               i40e_irq_dynamic_enable_icr0(pf);
+               i40e_irq_dynamic_enable_icr0(pf, true);
        }
 
        i40e_flush(&pf->hw);
@@ -3459,16 +3462,12 @@ static irqreturn_t i40e_intr(int irq, void *data)
                struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
                struct i40e_q_vector *q_vector = vsi->q_vectors[0];
 
-               /* temporarily disable queue cause for NAPI processing */
-               u32 qval = rd32(hw, I40E_QINT_RQCTL(0));
-
-               qval &= ~I40E_QINT_RQCTL_CAUSE_ENA_MASK;
-               wr32(hw, I40E_QINT_RQCTL(0), qval);
-
-               qval = rd32(hw, I40E_QINT_TQCTL(0));
-               qval &= ~I40E_QINT_TQCTL_CAUSE_ENA_MASK;
-               wr32(hw, I40E_QINT_TQCTL(0), qval);
-
+               /* We do not have a way to disarm Queue causes while leaving
+                * interrupt enabled for all other causes, ideally
+                * interrupt should be disabled while we are in NAPI but
+                * this is not a performance path and napi_schedule()
+                * can deal with rescheduling.
+                */
                if (!test_bit(__I40E_DOWN, &pf->state))
                        napi_schedule_irqoff(&q_vector->napi);
        }
@@ -3476,6 +3475,7 @@ static irqreturn_t i40e_intr(int irq, void *data)
        if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) {
                ena_mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK;
                set_bit(__I40E_ADMINQ_EVENT_PENDING, &pf->state);
+               i40e_debug(&pf->hw, I40E_DEBUG_NVM, "AdminQ event\n");
        }
 
        if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
@@ -3546,7 +3546,7 @@ enable_intr:
        wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask);
        if (!test_bit(__I40E_DOWN, &pf->state)) {
                i40e_service_event_schedule(pf);
-               i40e_irq_dynamic_enable_icr0(pf);
+               i40e_irq_dynamic_enable_icr0(pf, false);
        }
 
        return ret;
@@ -3750,7 +3750,7 @@ static int i40e_vsi_request_irq(struct i40e_vsi *vsi, char *basename)
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /**
- * i40e_netpoll - A Polling 'interrupt'handler
+ * i40e_netpoll - A Polling 'interrupt' handler
  * @netdev: network interface device structure
  *
  * This is used by netconsole to send skbs without having to re-enable
@@ -3929,6 +3929,9 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
                else
                        rx_reg &= ~I40E_QRX_ENA_QENA_REQ_MASK;
                wr32(hw, I40E_QRX_ENA(pf_q), rx_reg);
+               /* No waiting for the Tx queue to disable */
+               if (!enable && test_bit(__I40E_PORT_TX_SUSPENDED, &pf->state))
+                       continue;
 
                /* wait for the change to finish */
                ret = i40e_pf_rxq_wait(pf, pf_q, enable);
@@ -4166,6 +4169,9 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf)
                free_irq(pf->msix_entries[0].vector, pf);
        }
 
+       i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector,
+                     I40E_IWARP_IRQ_PILE_ID);
+
        i40e_put_lump(pf->irq_pile, 0, I40E_PILE_VALID_BIT-1);
        for (i = 0; i < pf->num_alloc_vsi; i++)
                if (pf->vsi[i])
@@ -4209,12 +4215,17 @@ static void i40e_napi_disable_all(struct i40e_vsi *vsi)
  **/
 static void i40e_vsi_close(struct i40e_vsi *vsi)
 {
+       bool reset = false;
+
        if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
                i40e_down(vsi);
        i40e_vsi_free_irq(vsi);
        i40e_vsi_free_tx_resources(vsi);
        i40e_vsi_free_rx_resources(vsi);
        vsi->current_netdev_flags = 0;
+       if (test_bit(__I40E_RESET_RECOVERY_PENDING, &vsi->back->state))
+               reset = true;
+       i40e_notify_client_of_netdev_close(vsi, reset);
 }
 
 /**
@@ -4287,12 +4298,12 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf)
 
 #ifdef CONFIG_I40E_DCB
 /**
- * i40e_vsi_wait_txq_disabled - Wait for VSI's queues to be disabled
+ * i40e_vsi_wait_queues_disabled - Wait for VSI's queues to be disabled
  * @vsi: the VSI being configured
  *
- * This function waits for the given VSI's Tx queues to be disabled.
+ * This function waits for the given VSI's queues to be disabled.
  **/
-static int i40e_vsi_wait_txq_disabled(struct i40e_vsi *vsi)
+static int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi)
 {
        struct i40e_pf *pf = vsi->back;
        int i, pf_q, ret;
@@ -4309,24 +4320,36 @@ static int i40e_vsi_wait_txq_disabled(struct i40e_vsi *vsi)
                }
        }
 
+       pf_q = vsi->base_queue;
+       for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
+               /* Check and wait for the disable status of the queue */
+               ret = i40e_pf_rxq_wait(pf, pf_q, false);
+               if (ret) {
+                       dev_info(&pf->pdev->dev,
+                                "VSI seid %d Rx ring %d disable timeout\n",
+                                vsi->seid, pf_q);
+                       return ret;
+               }
+       }
+
        return 0;
 }
 
 /**
- * i40e_pf_wait_txq_disabled - Wait for all queues of PF VSIs to be disabled
+ * i40e_pf_wait_queues_disabled - Wait for all queues of PF VSIs to be disabled
  * @pf: the PF
  *
- * This function waits for the Tx queues to be in disabled state for all the
+ * This function waits for the queues to be in disabled state for all the
  * VSIs that are managed by this PF.
  **/
-static int i40e_pf_wait_txq_disabled(struct i40e_pf *pf)
+static int i40e_pf_wait_queues_disabled(struct i40e_pf *pf)
 {
        int v, ret = 0;
 
        for (v = 0; v < pf->hw.func_caps.num_vsis; v++) {
                /* No need to wait for FCoE VSI queues */
                if (pf->vsi[v] && pf->vsi[v]->type != I40E_VSI_FCOE) {
-                       ret = i40e_vsi_wait_txq_disabled(pf->vsi[v]);
+                       ret = i40e_vsi_wait_queues_disabled(pf->vsi[v]);
                        if (ret)
                                break;
                }
@@ -4352,7 +4375,7 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)
 {
        struct i40e_ring *tx_ring = NULL;
        struct i40e_pf  *pf;
-       u32 head, val, tx_pending;
+       u32 head, val, tx_pending_hw;
        int i;
 
        pf = vsi->back;
@@ -4378,16 +4401,9 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)
        else
                val = rd32(&pf->hw, I40E_PFINT_DYN_CTL0);
 
-       /* Bail out if interrupts are disabled because napi_poll
-        * execution in-progress or will get scheduled soon.
-        * napi_poll cleans TX and RX queues and updates 'next_to_clean'.
-        */
-       if (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))
-               return;
-
        head = i40e_get_head(tx_ring);
 
-       tx_pending = i40e_get_tx_pending(tx_ring);
+       tx_pending_hw = i40e_get_tx_pending(tx_ring, false);
 
        /* HW is done executing descriptors, updated HEAD write back,
         * but SW hasn't processed those descriptors. If interrupt is
@@ -4395,12 +4411,12 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)
         * dev_watchdog detecting timeout on those netdev_queue,
         * hence proactively trigger SW interrupt.
         */
-       if (tx_pending) {
+       if (tx_pending_hw && (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {
                /* NAPI Poll didn't run and clear since it was set */
                if (test_and_clear_bit(I40E_Q_VECTOR_HUNG_DETECT,
                                       &tx_ring->q_vector->hung_detected)) {
-                       netdev_info(vsi->netdev, "VSI_seid %d, Hung TX queue %d, tx_pending: %d, NTC:0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x\n",
-                                   vsi->seid, q_idx, tx_pending,
+                       netdev_info(vsi->netdev, "VSI_seid %d, Hung TX queue %d, tx_pending_hw: %d, NTC:0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x\n",
+                                   vsi->seid, q_idx, tx_pending_hw,
                                    tx_ring->next_to_clean, head,
                                    tx_ring->next_to_use,
                                    readl(tx_ring->tail));
@@ -4413,6 +4429,17 @@ static void i40e_detect_recover_hung_queue(int q_idx, struct i40e_vsi *vsi)
                                &tx_ring->q_vector->hung_detected);
                }
        }
+
+       /* This is the case where we have interrupts missing,
+        * so the tx_pending in HW will most likely be 0, but we
+        * will have tx_pending in SW since the WB happened but the
+        * interrupt got lost.
+        */
+       if ((!tx_pending_hw) && i40e_get_tx_pending(tx_ring, true) &&
+           (!(val & I40E_PFINT_DYN_CTLN_INTENA_MASK))) {
+               if (napi_reschedule(&tx_ring->q_vector->napi))
+                       tx_ring->tx_stats.tx_lost_interrupt++;
+       }
 }
 
 /**
@@ -4831,6 +4858,12 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
        ctxt.info = vsi->info;
        i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, false);
 
+       if (vsi->back->flags & I40E_FLAG_IWARP_ENABLED) {
+               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;
+       }
+
        /* Update the VSI after updating the VSI queue-mapping information */
        ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
        if (ret) {
@@ -4974,6 +5007,7 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf)
                        if (pf->vsi[v]->netdev)
                                i40e_dcbnl_set_all(pf->vsi[v]);
                }
+               i40e_notify_client_of_l2_param_changes(pf->vsi[v]);
        }
 }
 
@@ -5016,8 +5050,7 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
        int err = 0;
 
        /* Do not enable DCB for SW1 and SW2 images even if the FW is capable */
-       if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-           (pf->hw.aq.fw_maj_ver < 4))
+       if (pf->flags & I40E_FLAG_NO_DCB_SUPPORT)
                goto out;
 
        /* Get the initial DCB configuration */
@@ -5173,6 +5206,11 @@ static int i40e_up_complete(struct i40e_vsi *vsi)
                }
                i40e_fdir_filter_restore(vsi);
        }
+
+       /* On the next run of the service_task, notify any clients of the new
+        * opened netdev
+        */
+       pf->flags |= I40E_FLAG_SERVICE_CLIENT_REQUESTED;
        i40e_service_event_schedule(pf);
 
        return 0;
@@ -5249,11 +5287,7 @@ void i40e_down(struct i40e_vsi *vsi)
  * @netdev: net device to configure
  * @tc: number of traffic classes to enable
  **/
-#ifdef I40E_FCOE
-int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#else
 static int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#endif
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
@@ -5306,6 +5340,19 @@ exit:
        return ret;
 }
 
+#ifdef I40E_FCOE
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                   struct tc_to_netdev *tc)
+#else
+static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                          struct tc_to_netdev *tc)
+#endif
+{
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+               return -EINVAL;
+       return i40e_setup_tc(netdev, tc->tc);
+}
+
 /**
  * i40e_open - Called when a network interface is made active
  * @netdev: network interface device structure
@@ -5348,9 +5395,12 @@ int i40e_open(struct net_device *netdev)
        vxlan_get_rx_port(netdev);
 #endif
 #ifdef CONFIG_I40E_GENEVE
-       geneve_get_rx_port(netdev);
+       if (pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE)
+               geneve_get_rx_port(netdev);
 #endif
 
+       i40e_notify_client_of_netdev_open(vsi);
+
        return 0;
 }
 
@@ -5713,8 +5763,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
        if (ret)
                goto exit;
 
-       /* Wait for the PF's Tx queues to be disabled */
-       ret = i40e_pf_wait_txq_disabled(pf);
+       /* Wait for the PF's queues to be disabled */
+       ret = i40e_pf_wait_queues_disabled(pf);
        if (ret) {
                /* Schedule PF reset to recover */
                set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
@@ -6015,6 +6065,7 @@ static void i40e_vsi_link_event(struct i40e_vsi *vsi, bool link_up)
        case I40E_VSI_SRIOV:
        case I40E_VSI_VMDQ2:
        case I40E_VSI_CTRL:
+       case I40E_VSI_IWARP:
        case I40E_VSI_MIRROR:
        default:
                /* there is no notification for other VSIs */
@@ -6244,6 +6295,7 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
                if (hw->debug_mask & I40E_DEBUG_AQ)
                        dev_info(&pf->pdev->dev, "ARQ Overflow Error detected\n");
                val &= ~I40E_PF_ARQLEN_ARQOVFL_MASK;
+               pf->arq_overflows++;
        }
        if (val & I40E_PF_ARQLEN_ARQCRIT_MASK) {
                if (hw->debug_mask & I40E_DEBUG_AQ)
@@ -6319,7 +6371,9 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
                case i40e_aqc_opc_nvm_erase:
                case i40e_aqc_opc_nvm_update:
                case i40e_aqc_opc_oem_post_update:
-                       i40e_debug(&pf->hw, I40E_DEBUG_NVM, "ARQ NVM operation completed\n");
+                       i40e_debug(&pf->hw, I40E_DEBUG_NVM,
+                                  "ARQ NVM operation 0x%04x completed\n",
+                                  opcode);
                        break;
                default:
                        dev_info(&pf->pdev->dev,
@@ -6803,12 +6857,12 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
        if (ret)
                goto end_core_reset;
 
-       /* driver is only interested in link up/down and module qualification
-        * reports from firmware
+       /* The driver only wants link up/down and module qualification
+        * reports from firmware.  Note the negative logic.
         */
        ret = i40e_aq_set_phy_int_mask(&pf->hw,
-                                      I40E_AQ_EVENT_LINK_UPDOWN |
-                                      I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
+                                      ~(I40E_AQ_EVENT_LINK_UPDOWN |
+                                        I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
        if (ret)
                dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
                         i40e_stat_str(&pf->hw, ret),
@@ -6889,8 +6943,7 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
                wr32(hw, I40E_REG_MSS, val);
        }
 
-       if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-           (pf->hw.aq.fw_maj_ver < 4)) {
+       if (pf->flags & I40E_FLAG_RESTART_AUTONEG) {
                msleep(75);
                ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
                if (ret)
@@ -7079,12 +7132,13 @@ static void i40e_sync_udp_filters_subtask(struct i40e_pf *pf)
                                ret = i40e_aq_del_udp_tunnel(hw, i, NULL);
 
                        if (ret) {
-                               dev_info(&pf->pdev->dev,
-                                        "%s vxlan port %d, index %d failed, err %s aq_err %s\n",
-                                        port ? "add" : "delete",
-                                        ntohs(port), i,
-                                        i40e_stat_str(&pf->hw, ret),
-                                        i40e_aq_str(&pf->hw,
+                               dev_dbg(&pf->pdev->dev,
+                                       "%s %s port %d, index %d failed, err %s aq_err %s\n",
+                                       pf->udp_ports[i].type ? "vxlan" : "geneve",
+                                       port ? "add" : "delete",
+                                       ntohs(port), i,
+                                       i40e_stat_str(&pf->hw, ret),
+                                       i40e_aq_str(&pf->hw,
                                                    pf->hw.aq.asq_last_status));
                                pf->udp_ports[i].index = 0;
                        }
@@ -7111,11 +7165,13 @@ static void i40e_service_task(struct work_struct *work)
        }
 
        i40e_detect_recover_hung(pf);
+       i40e_sync_filters_subtask(pf);
        i40e_reset_subtask(pf);
        i40e_handle_mdd_event(pf);
        i40e_vc_process_vflr_event(pf);
        i40e_watchdog_subtask(pf);
        i40e_fdir_reinit_subtask(pf);
+       i40e_client_subtask(pf);
        i40e_sync_filters_subtask(pf);
        i40e_sync_udp_filters_subtask(pf);
        i40e_clean_adminq_subtask(pf);
@@ -7290,8 +7346,6 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
        set_bit(__I40E_DOWN, &vsi->state);
        vsi->flags = 0;
        vsi->idx = vsi_idx;
-       vsi->rx_itr_setting = pf->rx_itr_default;
-       vsi->tx_itr_setting = pf->tx_itr_default;
        vsi->int_rate_limit = 0;
        vsi->rss_table_size = (vsi->type == I40E_VSI_MAIN) ?
                                pf->rss_table_size : 64;
@@ -7458,8 +7512,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
                tx_ring->dcb_tc = 0;
                if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)
                        tx_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
-               if (vsi->back->flags & I40E_FLAG_OUTER_UDP_CSUM_CAPABLE)
-                       tx_ring->flags |= I40E_TXR_FLAGS_OUTER_UDP_CSUM;
+               tx_ring->tx_itr_setting = pf->tx_itr_default;
                vsi->tx_rings[i] = tx_ring;
 
                rx_ring = &tx_ring[1];
@@ -7476,6 +7529,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
                        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;
        }
 
@@ -7520,6 +7574,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
        int vectors_left;
        int v_budget, i;
        int v_actual;
+       int iwarp_requested = 0;
 
        if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
                return -ENODEV;
@@ -7533,6 +7588,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
         *              is governed by number of cpus in the system.
         *      - assumes symmetric Tx/Rx pairing
         *   - The number of VMDq pairs
+        *   - The CPU count within the NUMA node if iWARP is enabled
 #ifdef I40E_FCOE
         *   - The number of FCOE qps.
 #endif
@@ -7579,6 +7635,16 @@ static int i40e_init_msix(struct i40e_pf *pf)
        }
 
 #endif
+       /* can we reserve enough for iWARP? */
+       if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
+               if (!vectors_left)
+                       pf->num_iwarp_msix = 0;
+               else if (vectors_left < pf->num_iwarp_msix)
+                       pf->num_iwarp_msix = 1;
+               v_budget += pf->num_iwarp_msix;
+               vectors_left -= pf->num_iwarp_msix;
+       }
+
        /* any vectors left over go for VMDq support */
        if (pf->flags & I40E_FLAG_VMDQ_ENABLED) {
                int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps;
@@ -7613,6 +7679,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
                 * of these features based on the policy and at the end disable
                 * the features that did not get any vectors.
                 */
+               iwarp_requested = pf->num_iwarp_msix;
+               pf->num_iwarp_msix = 0;
 #ifdef I40E_FCOE
                pf->num_fcoe_qps = 0;
                pf->num_fcoe_msix = 0;
@@ -7651,17 +7719,33 @@ static int i40e_init_msix(struct i40e_pf *pf)
                        pf->num_lan_msix = 1;
                        break;
                case 3:
+                       if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
+                               pf->num_lan_msix = 1;
+                               pf->num_iwarp_msix = 1;
+                       } else {
+                               pf->num_lan_msix = 2;
+                       }
 #ifdef I40E_FCOE
                        /* give one vector to FCoE */
                        if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
                                pf->num_lan_msix = 1;
                                pf->num_fcoe_msix = 1;
                        }
-#else
-                       pf->num_lan_msix = 2;
 #endif
                        break;
                default:
+                       if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
+                               pf->num_iwarp_msix = min_t(int, (vec / 3),
+                                                iwarp_requested);
+                               pf->num_vmdq_vsis = min_t(int, (vec / 3),
+                                                 I40E_DEFAULT_NUM_VMDQ_VSI);
+                       } else {
+                               pf->num_vmdq_vsis = min_t(int, (vec / 2),
+                                                 I40E_DEFAULT_NUM_VMDQ_VSI);
+                       }
+                       pf->num_lan_msix = min_t(int,
+                              (vec - (pf->num_iwarp_msix + pf->num_vmdq_vsis)),
+                                                             pf->num_lan_msix);
 #ifdef I40E_FCOE
                        /* give one vector to FCoE */
                        if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
@@ -7669,8 +7753,6 @@ static int i40e_init_msix(struct i40e_pf *pf)
                                vec--;
                        }
 #endif
-                       /* give the rest to the PF */
-                       pf->num_lan_msix = min_t(int, vec, pf->num_lan_qps);
                        break;
                }
        }
@@ -7680,6 +7762,12 @@ static int i40e_init_msix(struct i40e_pf *pf)
                dev_info(&pf->pdev->dev, "VMDq disabled, not enough MSI-X vectors\n");
                pf->flags &= ~I40E_FLAG_VMDQ_ENABLED;
        }
+
+       if ((pf->flags & I40E_FLAG_IWARP_ENABLED) &&
+           (pf->num_iwarp_msix == 0)) {
+               dev_info(&pf->pdev->dev, "IWARP disabled, not enough MSI-X vectors\n");
+               pf->flags &= ~I40E_FLAG_IWARP_ENABLED;
+       }
 #ifdef I40E_FCOE
 
        if ((pf->flags & I40E_FLAG_FCOE_ENABLED) && (pf->num_fcoe_msix == 0)) {
@@ -7771,6 +7859,7 @@ static int i40e_init_interrupt_scheme(struct i40e_pf *pf)
                vectors = i40e_init_msix(pf);
                if (vectors < 0) {
                        pf->flags &= ~(I40E_FLAG_MSIX_ENABLED   |
+                                      I40E_FLAG_IWARP_ENABLED  |
 #ifdef I40E_FCOE
                                       I40E_FLAG_FCOE_ENABLED   |
 #endif
@@ -7852,7 +7941,7 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
 
        i40e_flush(hw);
 
-       i40e_irq_dynamic_enable_icr0(pf);
+       i40e_irq_dynamic_enable_icr0(pf, true);
 
        return err;
 }
@@ -7936,6 +8025,52 @@ static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
 }
 
 /**
+ * i40e_get_rss_aq - Get RSS keys and lut by using AQ commands
+ * @vsi: Pointer to vsi structure
+ * @seed: Buffter to store the hash keys
+ * @lut: Buffer to store the lookup table entries
+ * @lut_size: Size of buffer to store the lookup table entries
+ *
+ * Return 0 on success, negative on failure
+ */
+static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+                          u8 *lut, u16 lut_size)
+{
+       struct i40e_pf *pf = vsi->back;
+       struct i40e_hw *hw = &pf->hw;
+       int ret = 0;
+
+       if (seed) {
+               ret = i40e_aq_get_rss_key(hw, vsi->id,
+                       (struct i40e_aqc_get_set_rss_key_data *)seed);
+               if (ret) {
+                       dev_info(&pf->pdev->dev,
+                                "Cannot get RSS key, err %s aq_err %s\n",
+                                i40e_stat_str(&pf->hw, ret),
+                                i40e_aq_str(&pf->hw,
+                                            pf->hw.aq.asq_last_status));
+                       return ret;
+               }
+       }
+
+       if (lut) {
+               bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
+
+               ret = i40e_aq_get_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
+               if (ret) {
+                       dev_info(&pf->pdev->dev,
+                                "Cannot get RSS lut, err %s aq_err %s\n",
+                                i40e_stat_str(&pf->hw, ret),
+                                i40e_aq_str(&pf->hw,
+                                            pf->hw.aq.asq_last_status));
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+/**
  * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
  * @vsi: Pointer to vsi structure
  * @seed: RSS hash seed
@@ -7956,7 +8091,7 @@ static int i40e_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
                u32 *seed_dw = (u32 *)seed;
 
                for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-                       wr32(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
+                       i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i), seed_dw[i]);
        }
 
        if (lut) {
@@ -7993,7 +8128,7 @@ static int i40e_get_rss_reg(struct i40e_vsi *vsi, u8 *seed,
                u32 *seed_dw = (u32 *)seed;
 
                for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
-                       seed_dw[i] = rd32(hw, I40E_PFQF_HKEY(i));
+                       seed_dw[i] = i40e_read_rx_ctl(hw, I40E_PFQF_HKEY(i));
        }
        if (lut) {
                u32 *lut_dw = (u32 *)lut;
@@ -8037,7 +8172,12 @@ int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
  */
 int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size)
 {
-       return i40e_get_rss_reg(vsi, seed, lut, lut_size);
+       struct i40e_pf *pf = vsi->back;
+
+       if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE)
+               return i40e_get_rss_aq(vsi, seed, lut, lut_size);
+       else
+               return i40e_get_rss_reg(vsi, seed, lut, lut_size);
 }
 
 /**
@@ -8071,19 +8211,19 @@ static int i40e_pf_config_rss(struct i40e_pf *pf)
        int ret;
 
        /* By default we enable TCP/UDP with IPv4/IPv6 ptypes */
-       hena = (u64)rd32(hw, I40E_PFQF_HENA(0)) |
-               ((u64)rd32(hw, I40E_PFQF_HENA(1)) << 32);
+       hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
+               ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
        hena |= i40e_pf_get_default_rss_hena(pf);
 
-       wr32(hw, I40E_PFQF_HENA(0), (u32)hena);
-       wr32(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
+       i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
+       i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
 
        /* Determine the RSS table size based on the hardware capabilities */
-       reg_val = rd32(hw, I40E_PFQF_CTL_0);
+       reg_val = i40e_read_rx_ctl(hw, I40E_PFQF_CTL_0);
        reg_val = (pf->rss_table_size == 512) ?
                        (reg_val | I40E_PFQF_CTL_0_HASHLUTSIZE_512) :
                        (reg_val & ~I40E_PFQF_CTL_0_HASHLUTSIZE_512);
-       wr32(hw, I40E_PFQF_CTL_0, reg_val);
+       i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, reg_val);
 
        /* Determine the RSS size of the VSI */
        if (!vsi->rss_size)
@@ -8367,12 +8507,38 @@ static int i40e_sw_init(struct i40e_pf *pf)
                                 pf->hw.func_caps.fd_filters_best_effort;
        }
 
+       if (i40e_is_mac_710(&pf->hw) &&
+           (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
+           (pf->hw.aq.fw_maj_ver < 4))) {
+               pf->flags |= I40E_FLAG_RESTART_AUTONEG;
+               /* No DCB support  for FW < v4.33 */
+               pf->flags |= I40E_FLAG_NO_DCB_SUPPORT;
+       }
+
+       /* Disable FW LLDP if FW < v4.3 */
+       if (i40e_is_mac_710(&pf->hw) &&
+           (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
+           (pf->hw.aq.fw_maj_ver < 4)))
+               pf->flags |= I40E_FLAG_STOP_FW_LLDP;
+
+       /* Use the FW Set LLDP MIB API if FW > v4.40 */
+       if (i40e_is_mac_710(&pf->hw) &&
+           (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver >= 40)) ||
+           (pf->hw.aq.fw_maj_ver >= 5)))
+               pf->flags |= I40E_FLAG_USE_SET_LLDP_MIB;
+
        if (pf->hw.func_caps.vmdq) {
                pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI;
                pf->flags |= I40E_FLAG_VMDQ_ENABLED;
                pf->num_vmdq_qps = i40e_default_queues_per_vmdq(pf);
        }
 
+       if (pf->hw.func_caps.iwarp) {
+               pf->flags |= I40E_FLAG_IWARP_ENABLED;
+               /* IWARP needs one extra vector for CQP just like MISC.*/
+               pf->num_iwarp_msix = (int)num_online_cpus() + 1;
+       }
+
 #ifdef I40E_FCOE
        i40e_init_pf_fcoe(pf);
 
@@ -8393,8 +8559,19 @@ static int i40e_sw_init(struct i40e_pf *pf)
                             I40E_FLAG_OUTER_UDP_CSUM_CAPABLE |
                             I40E_FLAG_WB_ON_ITR_CAPABLE |
                             I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE |
+                            I40E_FLAG_100M_SGMII_CAPABLE |
+                            I40E_FLAG_USE_SET_LLDP_MIB |
                             I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
+       } 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 {
+               pf->auto_disable_flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
        }
+
        pf->eeprom_version = 0xDEAD;
        pf->lan_veb = I40E_NO_VEB;
        pf->lan_vsi = I40E_NO_VSI;
@@ -8530,9 +8707,6 @@ static void i40e_add_vxlan_port(struct net_device *netdev,
        u8 next_idx;
        u8 idx;
 
-       if (sa_family == AF_INET6)
-               return;
-
        idx = i40e_get_udp_port_idx(pf, port);
 
        /* Check if port already exists */
@@ -8572,9 +8746,6 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
        struct i40e_pf *pf = vsi->back;
        u8 idx;
 
-       if (sa_family == AF_INET6)
-               return;
-
        idx = i40e_get_udp_port_idx(pf, port);
 
        /* Check if port already exists */
@@ -8608,7 +8779,7 @@ static void i40e_add_geneve_port(struct net_device *netdev,
        u8 next_idx;
        u8 idx;
 
-       if (sa_family == AF_INET6)
+       if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
                return;
 
        idx = i40e_get_udp_port_idx(pf, port);
@@ -8652,7 +8823,7 @@ static void i40e_del_geneve_port(struct net_device *netdev,
        struct i40e_pf *pf = vsi->back;
        u8 idx;
 
-       if (sa_family == AF_INET6)
+       if (!(pf->flags & I40E_FLAG_GENEVE_OFFLOAD_CAPABLE))
                return;
 
        idx = i40e_get_udp_port_idx(pf, port);
@@ -8890,7 +9061,7 @@ static const struct net_device_ops i40e_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = i40e_netpoll,
 #endif
-       .ndo_setup_tc           = i40e_setup_tc,
+       .ndo_setup_tc           = __i40e_setup_tc,
 #ifdef I40E_FCOE
        .ndo_fcoe_enable        = i40e_fcoe_enable,
        .ndo_fcoe_disable       = i40e_fcoe_disable,
@@ -8942,11 +9113,15 @@ 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_RXCSUM         |
-                                 NETIF_F_GSO_UDP_TUNNEL |
-                                 NETIF_F_GSO_GRE        |
-                                 NETIF_F_TSO;
+       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 |
+                                  0;
 
        netdev->features = NETIF_F_SG                  |
                           NETIF_F_IP_CSUM             |
@@ -8967,6 +9142,8 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
 
        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;
 
        /* copy netdev features into list of user selectable features */
        netdev->hw_features |= netdev->features;
@@ -9216,6 +9393,13 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                                cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
                }
 
+               if (vsi->back->flags & I40E_FLAG_IWARP_ENABLED) {
+                       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;
+               }
+
                ctxt.info.valid_sections |= cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
                ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
                if (pf->vf[vsi->vf_id].spoofchk) {
@@ -9239,6 +9423,10 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
                break;
 
 #endif /* I40E_FCOE */
+       case I40E_VSI_IWARP:
+               /* send down message to iWARP */
+               break;
+
        default:
                return -ENODEV;
        }
@@ -9471,10 +9659,15 @@ vector_setup_out:
  **/
 static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
 {
-       struct i40e_pf *pf = vsi->back;
+       struct i40e_pf *pf;
        u8 enabled_tc;
        int ret;
 
+       if (!vsi)
+               return NULL;
+
+       pf = vsi->back;
+
        i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
        i40e_vsi_clear_rings(vsi);
 
@@ -9975,13 +10168,13 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi)
 {
        struct i40e_pf *pf = veb->pf;
        bool is_default = veb->pf->cur_promisc;
-       bool is_cloud = false;
+       bool enable_stats = !!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED);
        int ret;
 
        /* get a VEB from the hardware */
        ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid,
                              veb->enabled_tc, is_default,
-                             is_cloud, &veb->seid, NULL);
+                             &veb->seid, enable_stats, NULL);
        if (ret) {
                dev_info(&pf->pdev->dev,
                         "couldn't add VEB, err %s aq_err %s\n",
@@ -10350,6 +10543,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
 
                /* make sure all the fancies are disabled */
                pf->flags &= ~(I40E_FLAG_RSS_ENABLED    |
+                              I40E_FLAG_IWARP_ENABLED  |
 #ifdef I40E_FCOE
                               I40E_FLAG_FCOE_ENABLED   |
 #endif
@@ -10367,6 +10561,7 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf)
                queues_left -= pf->num_lan_qps;
 
                pf->flags &= ~(I40E_FLAG_RSS_ENABLED    |
+                              I40E_FLAG_IWARP_ENABLED  |
 #ifdef I40E_FCOE
                               I40E_FLAG_FCOE_ENABLED   |
 #endif
@@ -10538,21 +10733,9 @@ static void i40e_print_features(struct i40e_pf *pf)
  **/
 static void i40e_get_platform_mac_addr(struct pci_dev *pdev, struct i40e_pf *pf)
 {
-       struct device_node *dp = pci_device_to_OF_node(pdev);
-       const unsigned char *addr;
-       u8 *mac_addr = pf->hw.mac.addr;
-
        pf->flags &= ~I40E_FLAG_PF_MAC;
-       addr = of_get_mac_address(dp);
-       if (addr) {
-               ether_addr_copy(mac_addr, addr);
+       if (!eth_platform_get_mac_address(&pdev->dev, pf->hw.mac.addr))
                pf->flags |= I40E_FLAG_PF_MAC;
-#ifdef CONFIG_SPARC
-       } else {
-               ether_addr_copy(mac_addr, idprom->id_ethaddr);
-               pf->flags |= I40E_FLAG_PF_MAC;
-#endif /* CONFIG_SPARC */
-       }
 }
 
 /**
@@ -10575,7 +10758,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        u16 wol_nvm_bits;
        u16 link_status;
        int err;
-       u32 len;
        u32 val;
        u32 i;
        u8 set_fc_aq_fail;
@@ -10758,8 +10940,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * Ignore error return codes because if it was already disabled via
         * hardware settings this will fail
         */
-       if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
-           (pf->hw.aq.fw_maj_ver < 4)) {
+       if (pf->flags & I40E_FLAG_STOP_FW_LLDP) {
                dev_info(&pdev->dev, "Stopping firmware LLDP agent.\n");
                i40e_aq_stop_lldp(hw, true, NULL);
        }
@@ -10834,8 +11015,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                pf->num_alloc_vsi = pf->hw.func_caps.num_vsis;
 
        /* Set up the *vsi struct and our local tracking of the MAIN PF vsi. */
-       len = sizeof(struct i40e_vsi *) * pf->num_alloc_vsi;
-       pf->vsi = kzalloc(len, GFP_KERNEL);
+       pf->vsi = kcalloc(pf->num_alloc_vsi, sizeof(struct i40e_vsi *),
+                         GFP_KERNEL);
        if (!pf->vsi) {
                err = -ENOMEM;
                goto err_switch_setup;
@@ -10882,12 +11063,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
-       /* driver is only interested in link up/down and module qualification
-        * reports from firmware
+       /* The driver only wants link up/down and module qualification
+        * reports from firmware.  Note the negative logic.
         */
        err = i40e_aq_set_phy_int_mask(&pf->hw,
-                                      I40E_AQ_EVENT_LINK_UPDOWN |
-                                      I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
+                                      ~(I40E_AQ_EVENT_LINK_UPDOWN |
+                                        I40E_AQ_EVENT_MODULE_QUAL_FAIL), NULL);
        if (err)
                dev_info(&pf->pdev->dev, "set phy mask fail, err %s aq_err %s\n",
                         i40e_stat_str(&pf->hw, err),
@@ -10904,8 +11085,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                wr32(hw, I40E_REG_MSS, val);
        }
 
-       if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
-           (pf->hw.aq.fw_maj_ver < 4)) {
+       if (pf->flags & I40E_FLAG_RESTART_AUTONEG) {
                msleep(75);
                err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
                if (err)
@@ -10939,8 +11119,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if ((pf->flags & I40E_FLAG_SRIOV_ENABLED) &&
            (pf->flags & I40E_FLAG_MSIX_ENABLED) &&
            !test_bit(__I40E_BAD_EEPROM, &pf->state)) {
-               u32 val;
-
                /* disable link interrupts for VFs */
                val = rd32(hw, I40E_PFGEN_PORTMDIO_NUM);
                val &= ~I40E_PFGEN_PORTMDIO_NUM_VFLINK_STAT_ENA_MASK;
@@ -10959,7 +11137,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 #endif /* CONFIG_PCI_IOV */
 
-       pfs_found++;
+       if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
+               pf->iwarp_base_vector = i40e_get_lump(pf, pf->irq_pile,
+                                                     pf->num_iwarp_msix,
+                                                     I40E_IWARP_IRQ_PILE_ID);
+               if (pf->iwarp_base_vector < 0) {
+                       dev_info(&pdev->dev,
+                                "failed to get tracking for %d vectors for IWARP err=%d\n",
+                                pf->num_iwarp_msix, pf->iwarp_base_vector);
+                       pf->flags &= ~I40E_FLAG_IWARP_ENABLED;
+               }
+       }
 
        i40e_dbg_pf_init(pf);
 
@@ -10970,6 +11158,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        mod_timer(&pf->service_timer,
                  round_jiffies(jiffies + pf->service_timer_period));
 
+       /* add this PF to client device list and launch a client service task */
+       err = i40e_lan_add_device(pf);
+       if (err)
+               dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n",
+                        err);
+
 #ifdef I40E_FCOE
        /* create FCoE interface */
        i40e_fcoe_vsi_setup(pf);
@@ -11051,6 +11245,10 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
                                                       pf->main_vsi_seid);
 
+       if ((pf->hw.device_id == I40E_DEV_ID_10G_BASE_T) ||
+           (pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))
+               pf->flags |= I40E_FLAG_HAVE_10GBASET_PHY;
+
        /* print a string summarizing features */
        i40e_print_features(pf);
 
@@ -11107,10 +11305,11 @@ static void i40e_remove(struct pci_dev *pdev)
        i40e_ptp_stop(pf);
 
        /* Disable RSS in hw */
-       wr32(hw, I40E_PFQF_HENA(0), 0);
-       wr32(hw, I40E_PFQF_HENA(1), 0);
+       i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
+       i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 
        /* 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);
@@ -11140,9 +11339,16 @@ static void i40e_remove(struct pci_dev *pdev)
        if (pf->vsi[pf->lan_vsi])
                i40e_vsi_release(pf->vsi[pf->lan_vsi]);
 
+       /* remove attached clients */
+       ret_code = i40e_lan_del_device(pf);
+       if (ret_code) {
+               dev_warn(&pdev->dev, "Failed to delete client device: %d\n",
+                        ret_code);
+       }
+
        /* shutdown and destroy the HMC */
-       if (pf->hw.hmc.hmc_obj) {
-               ret_code = i40e_shutdown_lan_hmc(&pf->hw);
+       if (hw->hmc.hmc_obj) {
+               ret_code = i40e_shutdown_lan_hmc(hw);
                if (ret_code)
                        dev_warn(&pdev->dev,
                                 "Failed to destroy the HMC resources: %d\n",
@@ -11150,7 +11356,7 @@ static void i40e_remove(struct pci_dev *pdev)
        }
 
        /* shutdown the adminq */
-       ret_code = i40e_shutdown_adminq(&pf->hw);
+       ret_code = i40e_shutdown_adminq(hw);
        if (ret_code)
                dev_warn(&pdev->dev,
                         "Failed to destroy the Admin Queue resources: %d\n",
@@ -11178,7 +11384,7 @@ static void i40e_remove(struct pci_dev *pdev)
        kfree(pf->qp_pile);
        kfree(pf->vsi);
 
-       iounmap(pf->hw.hw_addr);
+       iounmap(hw->hw_addr);
        kfree(pf);
        pci_release_selected_regions(pdev,
                                     pci_select_bars(pdev, IORESOURCE_MEM));
@@ -11413,6 +11619,16 @@ static int __init i40e_init_module(void)
                i40e_driver_string, i40e_driver_version_str);
        pr_info("%s: %s\n", i40e_driver_name, i40e_copyright);
 
+       /* we will see if single thread per module is enough for now,
+        * it can't be any worse than using the system workqueue which
+        * was already single threaded
+        */
+       i40e_wq = create_singlethread_workqueue(i40e_driver_name);
+       if (!i40e_wq) {
+               pr_err("%s: Failed to create workqueue\n", i40e_driver_name);
+               return -ENOMEM;
+       }
+
        i40e_dbg_init();
        return pci_register_driver(&i40e_driver);
 }
@@ -11427,6 +11643,7 @@ module_init(i40e_init_module);
 static void __exit i40e_exit_module(void)
 {
        pci_unregister_driver(&i40e_driver);
+       destroy_workqueue(i40e_wq);
        i40e_dbg_exit();
 }
 module_exit(i40e_exit_module);