Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next...
authorDavid S. Miller <davem@davemloft.net>
Wed, 29 Jun 2016 12:23:08 +0000 (08:23 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Jun 2016 12:23:08 +0000 (08:23 -0400)
Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-06-27

This series contains updates to i40e and i40evf only.

Mitch provides several changes, first adds functions to enable and disable
VSI on a VEB, which allows for configuration of limited promiscuous mode
specifically for bridging purposes.  Sets the RSS Hash Enable registers by
default now that VF RSS is configured by the PF driver.  Fixed a issue
where we could overflow the buffer, by checking the address count and bail
out of the loop at the appropriate time.  Removed the need for a reset
when the device enters limited promiscuous mode, since this was causing
heartburn for people who were using VFs and bridging.

Catherine adds a call to set the client interface down when we put the VSI
down.  Fixed an issue where RSS queues was being limited to the number
of CPUs, so if a user wants to use more queues than CPUs, we want to
trust they know what they are doing and let them.

Greg cleans up the driver suspend routine to ensure we are calling
synchronize_irq() before freeing IRQ vectors and explicitly free the other
causes interrupt resources and shut down the MSIX interrupt.

Serey fixes i40e_set_settings() to not fail when a Direct Attach (DA)
cable is used.

Avinash fixes a supported link bug by removing code which was not allowing
100BaseT to show up in the supported link modes for 10GBaseT PHYs.

Shannon adds a bit of information to the error messages to help determine
the source of error by adding VSI info to macaddr messages.

Tushar Dave fixes error received when turning off TSO on some systems,
which was caused by enabling FD_SB without checking availability of
MSIx vectors, so add the check.

Neerav fixes a possible panic when LLDP/DCBX change happens and the
driver tried to notify the client(s) for each of the PF VSIs, which would
panic when it reached a VSI that did not have any netdev associated with
it.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/i40e/i40e.h
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_prototype.h
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index 9c44739da5e28f6352b4f8ae833d95517cbcd014..e83fc8afb30f04c0f3ee4ee4272587b2d4fc0039 100644 (file)
@@ -283,6 +283,7 @@ struct i40e_pf {
 #endif /* I40E_FCOE */
        u16 num_lan_qps;           /* num lan queues this PF has set up */
        u16 num_lan_msix;          /* num queue vectors for the base PF vsi */
+       u16 num_fdsb_msix;         /* num queue vectors for sideband Fdir */
        u16 num_iwarp_msix;        /* num of iwarp vectors for this PF */
        int iwarp_base_vector;
        int queues_left;           /* queues left unclaimed */
index 422b41d61c9a59f9c1f506487c0dd0f883b55f50..e447dc4354647751c84d561a8c441229056e038d 100644 (file)
@@ -1966,6 +1966,62 @@ aq_add_vsi_exit:
        return status;
 }
 
+/**
+ * i40e_aq_set_default_vsi
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw,
+                                   u16 seid,
+                                   struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+               (struct i40e_aqc_set_vsi_promiscuous_modes *)
+               &desc.params.raw;
+       i40e_status status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_set_vsi_promiscuous_modes);
+
+       cmd->promiscuous_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
+       cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
+       cmd->seid = cpu_to_le16(seid);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
+/**
+ * i40e_aq_clear_default_vsi
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw,
+                                     u16 seid,
+                                     struct i40e_asq_cmd_details *cmd_details)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+               (struct i40e_aqc_set_vsi_promiscuous_modes *)
+               &desc.params.raw;
+       i40e_status status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_set_vsi_promiscuous_modes);
+
+       cmd->promiscuous_flags = cpu_to_le16(0);
+       cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_DEFAULT);
+       cmd->seid = cpu_to_le16(seid);
+
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+       return status;
+}
+
 /**
  * i40e_aq_set_vsi_unicast_promiscuous
  * @hw: pointer to the hw struct
index 5e8d84ff7d5f576b275ec060414fa9aa2a9d2ed2..4962e855fbd372b12adb30fafb8541d6c3c1b6f8 100644 (file)
@@ -313,8 +313,7 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
                *advertising |= ADVERTISED_Autoneg |
                                ADVERTISED_40000baseCR4_Full;
        }
-       if ((phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) &&
-           !(phy_types & I40E_CAP_PHY_TYPE_1000BASE_T)) {
+       if (phy_types & I40E_CAP_PHY_TYPE_100BASE_TX) {
                *supported |= SUPPORTED_Autoneg |
                              SUPPORTED_100baseT_Full;
                *advertising |= ADVERTISED_Autoneg |
@@ -663,6 +662,7 @@ static int i40e_set_settings(struct net_device *netdev,
        if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
            hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
            hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
+           hw->phy.media_type != I40E_MEDIA_TYPE_DA &&
            hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
                return -EOPNOTSUPP;
 
index 734cba693d16cbc63712c084465a8a914a0ad262..2b1140563a64cb6e1682f89b48ca3002b49a1f47 100644 (file)
@@ -40,8 +40,8 @@ static const char i40e_driver_string[] =
 #define DRV_KERN "-k"
 
 #define DRV_VERSION_MAJOR 1
-#define DRV_VERSION_MINOR 5
-#define DRV_VERSION_BUILD 16
+#define DRV_VERSION_MINOR 6
+#define DRV_VERSION_BUILD 4
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
             __stringify(DRV_VERSION_MINOR) "." \
             __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -1579,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));
 
@@ -1840,8 +1834,10 @@ 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;
+       char vsi_name[16] = "PF";
        int filter_list_len = 0;
        u32 changed_flags = 0;
        i40e_status aq_ret = 0;
@@ -1869,6 +1865,11 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
        INIT_LIST_HEAD(&tmp_del_list);
        INIT_LIST_HEAD(&tmp_add_list);
 
+       if (vsi->type == I40E_VSI_SRIOV)
+               snprintf(vsi_name, sizeof(vsi_name) - 1, "VF %d", vsi->vf_id);
+       else if (vsi->type != I40E_VSI_MAIN)
+               snprintf(vsi_name, sizeof(vsi_name) - 1, "vsi %d", vsi->seid);
+
        if (vsi->flags & I40E_VSI_FLAG_FILTER_CHANGED) {
                vsi->flags &= ~I40E_VSI_FLAG_FILTER_CHANGED;
 
@@ -1920,7 +1921,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);
@@ -1952,21 +1953,21 @@ 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);
 
                                if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) {
                                        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));
+                                                "ignoring delete macvlan error on %s, err %s, aq_err %s while flushing a full buffer\n",
+                                                vsi_name,
+                                                i40e_stat_str(hw, aq_ret),
+                                                i40e_aq_str(hw, aq_err));
                                }
                        }
                        /* Release memory for MAC filter entries which were
@@ -1977,17 +1978,17 @@ 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));
+                                        "ignoring delete macvlan error on %s, err %s aq_err %s\n",
+                                        vsi_name,
+                                        i40e_stat_str(hw, aq_ret),
+                                        i40e_aq_str(hw, aq_err));
                }
 
                kfree(del_list);
@@ -1998,7 +1999,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);
@@ -2033,10 +2034,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)
@@ -2051,9 +2052,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);
@@ -2062,16 +2063,18 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                if (add_happened && aq_ret && aq_err != I40E_AQ_RC_EINVAL) {
                        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) &&
+                                "add filter failed on %s, err %s aq_err %s\n",
+                                vsi_name,
+                                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;
                                set_bit(__I40E_FILTER_OVERFLOW_PROMISC,
                                        &vsi->state);
-                               dev_info(&pf->pdev->dev, "promiscuous mode forced on\n");
+                               dev_info(&pf->pdev->dev, "promiscuous mode forced on %s\n",
+                                        vsi_name);
                        }
                }
        }
@@ -2093,12 +2096,12 @@ 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));
+                                "set multi promisc failed on %s, err %s aq_err %s\n",
+                                vsi_name,
+                                i40e_stat_str(hw, aq_ret),
+                                i40e_aq_str(hw, hw->aq.asq_last_status));
                }
        }
        if ((changed_flags & IFF_PROMISC) || promisc_forced_on) {
@@ -2117,33 +2120,58 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
                         */
                        if (pf->cur_promisc != cur_promisc) {
                                pf->cur_promisc = cur_promisc;
-                               set_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
+                               if (cur_promisc)
+                                       aq_ret =
+                                             i40e_aq_set_default_vsi(hw,
+                                                                     vsi->seid,
+                                                                     NULL);
+                               else
+                                       aq_ret =
+                                           i40e_aq_clear_default_vsi(hw,
+                                                                     vsi->seid,
+                                                                     NULL);
+                               if (aq_ret) {
+                                       retval = i40e_aq_rc_to_posix(aq_ret,
+                                                       hw->aq.asq_last_status);
+                                       dev_info(&pf->pdev->dev,
+                                                "Set default VSI failed on %s, err %s, aq_err %s\n",
+                                                vsi_name,
+                                                i40e_stat_str(hw, aq_ret),
+                                                i40e_aq_str(hw,
+                                                    hw->aq.asq_last_status));
+                               }
                        }
                } else {
                        aq_ret = i40e_aq_set_vsi_unicast_promiscuous(
-                                                         &vsi->back->hw,
+                                                         hw,
                                                          vsi->seid,
                                                          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 on %s, err %s, aq_err %s\n",
+                                        vsi_name,
+                                        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 on %s, err %s, aq_err %s\n",
+                                        vsi_name,
+                                        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,
@@ -2154,9 +2182,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:
@@ -3947,6 +3975,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]);
 
@@ -4953,7 +4982,6 @@ 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]);
        }
 }
 
@@ -5178,12 +5206,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);
 }
@@ -5226,6 +5248,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);
+
 }
 
 /**
@@ -5704,6 +5729,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
                i40e_service_event_schedule(pf);
        } else {
                i40e_pf_unquiesce_all_vsi(pf);
+               /* Notify the client for the DCB changes */
+               i40e_notify_client_of_l2_param_changes(pf->vsi[pf->lan_vsi]);
        }
 
 exit:
@@ -5928,7 +5955,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");
        }
-
 }
 
 /**
@@ -7160,7 +7186,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
                vsi->alloc_queue_pairs = 1;
                vsi->num_desc = ALIGN(I40E_FDIR_RING_COUNT,
                                      I40E_REQ_DESCRIPTOR_MULTIPLE);
-               vsi->num_q_vectors = 1;
+               vsi->num_q_vectors = pf->num_fdsb_msix;
                break;
 
        case I40E_VSI_VMDQ2:
@@ -7544,9 +7570,11 @@ static int i40e_init_msix(struct i40e_pf *pf)
        /* reserve one vector for sideband flow director */
        if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
                if (vectors_left) {
+                       pf->num_fdsb_msix = 1;
                        v_budget++;
                        vectors_left--;
                } else {
+                       pf->num_fdsb_msix = 0;
                        pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
                }
        }
@@ -8565,7 +8593,9 @@ bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features)
                /* Enable filters and mark for reset */
                if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
                        need_reset = true;
-               pf->flags |= I40E_FLAG_FD_SB_ENABLED;
+               /* enable FD_SB only if there is MSI-X vector */
+               if (pf->num_fdsb_msix > 0)
+                       pf->flags |= I40E_FLAG_FD_SB_ENABLED;
        } else {
                /* turn off filters, mark for reset and clear SW filter list */
                if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
@@ -10053,14 +10083,14 @@ void i40e_veb_release(struct i40e_veb *veb)
 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 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,
+                             veb->enabled_tc, false,
                              &veb->seid, enable_stats, NULL);
+
+       /* get a VEB from the hardware */
        if (ret) {
                dev_info(&pf->pdev->dev,
                         "couldn't add VEB, err %s aq_err %s\n",
@@ -11441,6 +11471,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);
@@ -11452,10 +11483,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;
 }
 
 /**
index 80403c6ee7f073fccd2211ba3eec4e847014519e..4660c5abc855da92a16da5719869e112f5b07230 100644 (file)
@@ -98,6 +98,8 @@ i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,
                                struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_clear_default_vsi(struct i40e_hw *hw, u16 vsi_id,
+                                     struct i40e_asq_cmd_details *cmd_details);
 enum i40e_status_code i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
                        bool qualified_modules, bool report_init,
                        struct i40e_aq_get_phy_abilities_resp *abilities,
index 1fcafcfa8f14fe5a6fe0e693715bb06cdc7023aa..6fcbf764f32bc942866ba10740ccfbc0df92f6f9 100644 (file)
@@ -665,6 +665,8 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                goto error_alloc_vsi_res;
        }
        if (type == I40E_VSI_SRIOV) {
+               u64 hena = i40e_pf_get_default_rss_hena(pf);
+
                vf->lan_vsi_idx = vsi->idx;
                vf->lan_vsi_id = vsi->id;
                /* If the port VLAN has been configured and then the
@@ -687,6 +689,10 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
                                        vf->default_lan_addr.addr, vf->vf_id);
                }
                spin_unlock_bh(&vsi->mac_filter_list_lock);
+               i40e_write_rx_ctl(&pf->hw, I40E_VFQF_HENA1(0, vf->vf_id),
+                                 (u32)hena);
+               i40e_write_rx_ctl(&pf->hw, I40E_VFQF_HENA1(1, vf->vf_id),
+                                 (u32)(hena >> 32));
        }
 
        /* program mac filter */
index 16c5529528600324a1f3116ac7023d7b57b3d6c9..eac057b880550a7fe945fe436e743aed12987876 100644 (file)
@@ -37,8 +37,8 @@ static const char i40evf_driver_string[] =
 #define DRV_KERN "-k"
 
 #define DRV_VERSION_MAJOR 1
-#define DRV_VERSION_MINOR 5
-#define DRV_VERSION_BUILD 10
+#define DRV_VERSION_MINOR 6
+#define DRV_VERSION_BUILD 4
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
             __stringify(DRV_VERSION_MINOR) "." \
             __stringify(DRV_VERSION_BUILD) \
@@ -825,7 +825,7 @@ i40evf_mac_filter *i40evf_add_filter(struct i40evf_adapter *adapter,
 
                ether_addr_copy(f->macaddr, macaddr);
 
-               list_add(&f->list, &adapter->mac_filter_list);
+               list_add_tail(&f->list, &adapter->mac_filter_list);
                f->add = true;
                adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
        }
index f13445691507c2b7ea668f402cbb04e6f65cf38c..d76c221d4c8a3ab7f2e5fe386962842b91d8ae2c 100644 (file)
@@ -434,6 +434,8 @@ void i40evf_add_ether_addrs(struct i40evf_adapter *adapter)
                        ether_addr_copy(veal->list[i].addr, f->macaddr);
                        i++;
                        f->add = false;
+                       if (i == count)
+                               break;
                }
        }
        if (!more)
@@ -497,6 +499,8 @@ void i40evf_del_ether_addrs(struct i40evf_adapter *adapter)
                        i++;
                        list_del(&f->list);
                        kfree(f);
+                       if (i == count)
+                               break;
                }
        }
        if (!more)
@@ -560,6 +564,8 @@ void i40evf_add_vlans(struct i40evf_adapter *adapter)
                        vvfl->vlan_id[i] = f->vlan;
                        i++;
                        f->add = false;
+                       if (i == count)
+                               break;
                }
        }
        if (!more)
@@ -623,6 +629,8 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
                        i++;
                        list_del(&f->list);
                        kfree(f);
+                       if (i == count)
+                               break;
                }
        }
        if (!more)