|
@@ -943,6 +943,14 @@ static void i40evf_set_rx_mode(struct net_device *netdev)
|
|
bottom_of_search_loop:
|
|
bottom_of_search_loop:
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (netdev->flags & IFF_PROMISC &&
|
|
|
|
+ !(adapter->flags & I40EVF_FLAG_PROMISC_ON))
|
|
|
|
+ adapter->aq_required |= I40EVF_FLAG_AQ_REQUEST_PROMISC;
|
|
|
|
+ else if (!(netdev->flags & IFF_PROMISC) &&
|
|
|
|
+ adapter->flags & I40EVF_FLAG_PROMISC_ON)
|
|
|
|
+ adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_PROMISC;
|
|
|
|
+
|
|
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
|
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1224,24 +1232,18 @@ out:
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * i40e_config_rss_aq - Prepare for RSS using AQ commands
|
|
|
|
- * @vsi: vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
|
|
+ * i40e_config_rss_aq - Configure RSS keys and lut by using AQ commands
|
|
|
|
+ * @adapter: board private structure
|
|
*
|
|
*
|
|
* Return 0 on success, negative on failure
|
|
* Return 0 on success, negative on failure
|
|
**/
|
|
**/
|
|
-static int i40evf_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
|
|
|
|
- u8 *lut, u16 lut_size)
|
|
|
|
|
|
+static int i40evf_config_rss_aq(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
|
|
+ struct i40e_aqc_get_set_rss_key_data *rss_key =
|
|
|
|
+ (struct i40e_aqc_get_set_rss_key_data *)adapter->rss_key;
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
|
|
|
|
- if (!vsi->id)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
|
|
if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
|
|
/* bail because we already have a command pending */
|
|
/* bail because we already have a command pending */
|
|
dev_err(&adapter->pdev->dev, "Cannot configure RSS, command %d pending\n",
|
|
dev_err(&adapter->pdev->dev, "Cannot configure RSS, command %d pending\n",
|
|
@@ -1249,198 +1251,82 @@ static int i40evf_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
- if (seed) {
|
|
|
|
- struct i40e_aqc_get_set_rss_key_data *rss_key =
|
|
|
|
- (struct i40e_aqc_get_set_rss_key_data *)seed;
|
|
|
|
- ret = i40evf_aq_set_rss_key(hw, vsi->id, rss_key);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_err(&adapter->pdev->dev, "Cannot set RSS key, err %s aq_err %s\n",
|
|
|
|
- i40evf_stat_str(hw, ret),
|
|
|
|
- i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
|
|
+ ret = i40evf_aq_set_rss_key(hw, adapter->vsi.id, rss_key);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(&adapter->pdev->dev, "Cannot set RSS key, err %s aq_err %s\n",
|
|
|
|
+ i40evf_stat_str(hw, ret),
|
|
|
|
+ i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
- if (lut) {
|
|
|
|
- ret = i40evf_aq_set_rss_lut(hw, vsi->id, false, lut, lut_size);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
|
- "Cannot set RSS lut, err %s aq_err %s\n",
|
|
|
|
- i40evf_stat_str(hw, ret),
|
|
|
|
- i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
|
|
+ ret = i40evf_aq_set_rss_lut(hw, adapter->vsi.id, false,
|
|
|
|
+ adapter->rss_lut, adapter->rss_lut_size);
|
|
|
|
+ if (ret) {
|
|
|
|
+ dev_err(&adapter->pdev->dev, "Cannot set RSS lut, err %s aq_err %s\n",
|
|
|
|
+ i40evf_stat_str(hw, ret),
|
|
|
|
+ i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
}
|
|
}
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* i40evf_config_rss_reg - Configure RSS keys and lut by writing registers
|
|
* i40evf_config_rss_reg - Configure RSS keys and lut by writing registers
|
|
- * @vsi: Pointer to vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
|
|
+ * @adapter: board private structure
|
|
*
|
|
*
|
|
* Returns 0 on success, negative on failure
|
|
* Returns 0 on success, negative on failure
|
|
**/
|
|
**/
|
|
-static int i40evf_config_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
|
|
|
|
- const u8 *lut, u16 lut_size)
|
|
|
|
|
|
+static int i40evf_config_rss_reg(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
|
|
+ u32 *dw;
|
|
u16 i;
|
|
u16 i;
|
|
|
|
|
|
- if (seed) {
|
|
|
|
- u32 *seed_dw = (u32 *)seed;
|
|
|
|
-
|
|
|
|
- for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
|
|
|
|
- wr32(hw, I40E_VFQF_HKEY(i), seed_dw[i]);
|
|
|
|
- }
|
|
|
|
|
|
+ dw = (u32 *)adapter->rss_key;
|
|
|
|
+ for (i = 0; i <= adapter->rss_key_size / 4; i++)
|
|
|
|
+ wr32(hw, I40E_VFQF_HKEY(i), dw[i]);
|
|
|
|
|
|
- if (lut) {
|
|
|
|
- u32 *lut_dw = (u32 *)lut;
|
|
|
|
|
|
+ dw = (u32 *)adapter->rss_lut;
|
|
|
|
+ for (i = 0; i <= adapter->rss_lut_size / 4; i++)
|
|
|
|
+ wr32(hw, I40E_VFQF_HLUT(i), dw[i]);
|
|
|
|
|
|
- if (lut_size != I40EVF_HLUT_ARRAY_SIZE)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)
|
|
|
|
- wr32(hw, I40E_VFQF_HLUT(i), lut_dw[i]);
|
|
|
|
- }
|
|
|
|
i40e_flush(hw);
|
|
i40e_flush(hw);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * * i40evf_get_rss_aq - Get RSS keys and lut by using AQ commands
|
|
|
|
- * @vsi: Pointer to vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
- *
|
|
|
|
- * Return 0 on success, negative on failure
|
|
|
|
- **/
|
|
|
|
-static int i40evf_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
|
|
|
|
- u8 *lut, u16 lut_size)
|
|
|
|
-{
|
|
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
- struct i40e_hw *hw = &adapter->hw;
|
|
|
|
- int ret = 0;
|
|
|
|
-
|
|
|
|
- if (seed) {
|
|
|
|
- ret = i40evf_aq_get_rss_key(hw, vsi->id,
|
|
|
|
- (struct i40e_aqc_get_set_rss_key_data *)seed);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
|
- "Cannot get RSS key, err %s aq_err %s\n",
|
|
|
|
- i40evf_stat_str(hw, ret),
|
|
|
|
- i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (lut) {
|
|
|
|
- ret = i40evf_aq_get_rss_lut(hw, vsi->id, false, lut, lut_size);
|
|
|
|
- if (ret) {
|
|
|
|
- dev_err(&adapter->pdev->dev,
|
|
|
|
- "Cannot get RSS lut, err %s aq_err %s\n",
|
|
|
|
- i40evf_stat_str(hw, ret),
|
|
|
|
- i40evf_aq_str(hw, hw->aq.asq_last_status));
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * * i40evf_get_rss_reg - Get RSS keys and lut by reading registers
|
|
|
|
- * @vsi: Pointer to vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
- *
|
|
|
|
- * Returns 0 on success, negative on failure
|
|
|
|
- **/
|
|
|
|
-static int i40evf_get_rss_reg(struct i40e_vsi *vsi, const u8 *seed,
|
|
|
|
- const u8 *lut, u16 lut_size)
|
|
|
|
-{
|
|
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
- struct i40e_hw *hw = &adapter->hw;
|
|
|
|
- u16 i;
|
|
|
|
-
|
|
|
|
- if (seed) {
|
|
|
|
- u32 *seed_dw = (u32 *)seed;
|
|
|
|
-
|
|
|
|
- for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
|
|
|
|
- seed_dw[i] = rd32(hw, I40E_VFQF_HKEY(i));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (lut) {
|
|
|
|
- u32 *lut_dw = (u32 *)lut;
|
|
|
|
-
|
|
|
|
- if (lut_size != I40EVF_HLUT_ARRAY_SIZE)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++)
|
|
|
|
- lut_dw[i] = rd32(hw, I40E_VFQF_HLUT(i));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* i40evf_config_rss - Configure RSS keys and lut
|
|
* i40evf_config_rss - Configure RSS keys and lut
|
|
- * @vsi: Pointer to vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
- *
|
|
|
|
- * Returns 0 on success, negative on failure
|
|
|
|
- **/
|
|
|
|
-int i40evf_config_rss(struct i40e_vsi *vsi, const u8 *seed,
|
|
|
|
- u8 *lut, u16 lut_size)
|
|
|
|
-{
|
|
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
-
|
|
|
|
- if (RSS_AQ(adapter))
|
|
|
|
- return i40evf_config_rss_aq(vsi, seed, lut, lut_size);
|
|
|
|
- else
|
|
|
|
- return i40evf_config_rss_reg(vsi, seed, lut, lut_size);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * i40evf_get_rss - Get RSS keys and lut
|
|
|
|
- * @vsi: Pointer to vsi structure
|
|
|
|
- * @seed: RSS hash seed
|
|
|
|
- * @lut: Lookup table
|
|
|
|
- * @lut_size: Lookup table size
|
|
|
|
|
|
+ * @adapter: board private structure
|
|
*
|
|
*
|
|
* Returns 0 on success, negative on failure
|
|
* Returns 0 on success, negative on failure
|
|
**/
|
|
**/
|
|
-int i40evf_get_rss(struct i40e_vsi *vsi, const u8 *seed, u8 *lut, u16 lut_size)
|
|
|
|
|
|
+int i40evf_config_rss(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
- struct i40evf_adapter *adapter = vsi->back;
|
|
|
|
|
|
|
|
- if (RSS_AQ(adapter))
|
|
|
|
- return i40evf_get_rss_aq(vsi, seed, lut, lut_size);
|
|
|
|
- else
|
|
|
|
- return i40evf_get_rss_reg(vsi, seed, lut, lut_size);
|
|
|
|
|
|
+ if (RSS_PF(adapter)) {
|
|
|
|
+ adapter->aq_required |= I40EVF_FLAG_AQ_SET_RSS_LUT |
|
|
|
|
+ I40EVF_FLAG_AQ_SET_RSS_KEY;
|
|
|
|
+ return 0;
|
|
|
|
+ } else if (RSS_AQ(adapter)) {
|
|
|
|
+ return i40evf_config_rss_aq(adapter);
|
|
|
|
+ } else {
|
|
|
|
+ return i40evf_config_rss_reg(adapter);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* i40evf_fill_rss_lut - Fill the lut with default values
|
|
* i40evf_fill_rss_lut - Fill the lut with default values
|
|
- * @lut: Lookup table to be filled with
|
|
|
|
- * @rss_table_size: Lookup table size
|
|
|
|
- * @rss_size: Range of queue number for hashing
|
|
|
|
|
|
+ * @adapter: board private structure
|
|
**/
|
|
**/
|
|
-static void i40evf_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)
|
|
|
|
|
|
+static void i40evf_fill_rss_lut(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
u16 i;
|
|
u16 i;
|
|
|
|
|
|
- for (i = 0; i < rss_table_size; i++)
|
|
|
|
- lut[i] = i % rss_size;
|
|
|
|
|
|
+ for (i = 0; i < adapter->rss_lut_size; i++)
|
|
|
|
+ adapter->rss_lut[i] = i % adapter->num_active_queues;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1451,42 +1337,25 @@ static void i40evf_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size)
|
|
**/
|
|
**/
|
|
static int i40evf_init_rss(struct i40evf_adapter *adapter)
|
|
static int i40evf_init_rss(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
- struct i40e_vsi *vsi = &adapter->vsi;
|
|
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
struct i40e_hw *hw = &adapter->hw;
|
|
- u8 seed[I40EVF_HKEY_ARRAY_SIZE];
|
|
|
|
- u64 hena;
|
|
|
|
- u8 *lut;
|
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- /* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */
|
|
|
|
- if (adapter->vf_res->vf_offload_flags &
|
|
|
|
- I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
|
|
|
|
- hena = I40E_DEFAULT_RSS_HENA_EXPANDED;
|
|
|
|
- else
|
|
|
|
- hena = I40E_DEFAULT_RSS_HENA;
|
|
|
|
- wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
|
|
|
|
- wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
|
|
|
|
|
|
+ if (!RSS_PF(adapter)) {
|
|
|
|
+ /* Enable PCTYPES for RSS, TCP/UDP with IPv4/IPv6 */
|
|
|
|
+ if (adapter->vf_res->vf_offload_flags &
|
|
|
|
+ I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2)
|
|
|
|
+ adapter->hena = I40E_DEFAULT_RSS_HENA_EXPANDED;
|
|
|
|
+ else
|
|
|
|
+ adapter->hena = I40E_DEFAULT_RSS_HENA;
|
|
|
|
|
|
- lut = kzalloc(I40EVF_HLUT_ARRAY_SIZE, GFP_KERNEL);
|
|
|
|
- if (!lut)
|
|
|
|
- return -ENOMEM;
|
|
|
|
|
|
+ wr32(hw, I40E_VFQF_HENA(0), (u32)adapter->hena);
|
|
|
|
+ wr32(hw, I40E_VFQF_HENA(1), (u32)(adapter->hena >> 32));
|
|
|
|
+ }
|
|
|
|
|
|
- /* Use user configured lut if there is one, otherwise use default */
|
|
|
|
- if (vsi->rss_lut_user)
|
|
|
|
- memcpy(lut, vsi->rss_lut_user, I40EVF_HLUT_ARRAY_SIZE);
|
|
|
|
- else
|
|
|
|
- i40evf_fill_rss_lut(lut, I40EVF_HLUT_ARRAY_SIZE,
|
|
|
|
- adapter->num_active_queues);
|
|
|
|
|
|
+ i40evf_fill_rss_lut(adapter);
|
|
|
|
|
|
- /* Use user configured hash key if there is one, otherwise
|
|
|
|
- * user default.
|
|
|
|
- */
|
|
|
|
- if (vsi->rss_hkey_user)
|
|
|
|
- memcpy(seed, vsi->rss_hkey_user, I40EVF_HKEY_ARRAY_SIZE);
|
|
|
|
- else
|
|
|
|
- netdev_rss_key_fill((void *)seed, I40EVF_HKEY_ARRAY_SIZE);
|
|
|
|
- ret = i40evf_config_rss(vsi, seed, lut, I40EVF_HLUT_ARRAY_SIZE);
|
|
|
|
- kfree(lut);
|
|
|
|
|
|
+ netdev_rss_key_fill((void *)adapter->rss_key, adapter->rss_key_size);
|
|
|
|
+ ret = i40evf_config_rss(adapter);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -1601,19 +1470,16 @@ err_set_interrupt:
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * i40evf_clear_rss_config_user - Clear user configurations of RSS
|
|
|
|
- * @vsi: Pointer to VSI structure
|
|
|
|
|
|
+ * i40evf_free_rss - Free memory used by RSS structs
|
|
|
|
+ * @adapter: board private structure
|
|
**/
|
|
**/
|
|
-static void i40evf_clear_rss_config_user(struct i40e_vsi *vsi)
|
|
|
|
|
|
+static void i40evf_free_rss(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
- if (!vsi)
|
|
|
|
- return;
|
|
|
|
|
|
+ kfree(adapter->rss_key);
|
|
|
|
+ adapter->rss_key = NULL;
|
|
|
|
|
|
- kfree(vsi->rss_hkey_user);
|
|
|
|
- vsi->rss_hkey_user = NULL;
|
|
|
|
-
|
|
|
|
- kfree(vsi->rss_lut_user);
|
|
|
|
- vsi->rss_lut_user = NULL;
|
|
|
|
|
|
+ kfree(adapter->rss_lut);
|
|
|
|
+ adapter->rss_lut = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1747,6 +1613,33 @@ static void i40evf_watchdog_task(struct work_struct *work)
|
|
adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_RSS;
|
|
adapter->aq_required &= ~I40EVF_FLAG_AQ_CONFIGURE_RSS;
|
|
goto watchdog_done;
|
|
goto watchdog_done;
|
|
}
|
|
}
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_GET_HENA) {
|
|
|
|
+ i40evf_get_hena(adapter);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_SET_HENA) {
|
|
|
|
+ i40evf_set_hena(adapter);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_SET_RSS_KEY) {
|
|
|
|
+ i40evf_set_rss_key(adapter);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_SET_RSS_LUT) {
|
|
|
|
+ i40evf_set_rss_lut(adapter);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_REQUEST_PROMISC) {
|
|
|
|
+ i40evf_set_promiscuous(adapter, I40E_FLAG_VF_UNICAST_PROMISC |
|
|
|
|
+ I40E_FLAG_VF_MULTICAST_PROMISC);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (adapter->aq_required & I40EVF_FLAG_AQ_RELEASE_PROMISC) {
|
|
|
|
+ i40evf_set_promiscuous(adapter, 0);
|
|
|
|
+ goto watchdog_done;
|
|
|
|
+ }
|
|
|
|
|
|
if (adapter->state == __I40EVF_RUNNING)
|
|
if (adapter->state == __I40EVF_RUNNING)
|
|
i40evf_request_stats(adapter);
|
|
i40evf_request_stats(adapter);
|
|
@@ -2325,6 +2218,7 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
|
|
{
|
|
{
|
|
struct i40e_virtchnl_vf_resource *vfres = adapter->vf_res;
|
|
struct i40e_virtchnl_vf_resource *vfres = adapter->vf_res;
|
|
struct net_device *netdev = adapter->netdev;
|
|
struct net_device *netdev = adapter->netdev;
|
|
|
|
+ struct i40e_vsi *vsi = &adapter->vsi;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
/* got VF config message back from PF, now we can parse it */
|
|
/* got VF config message back from PF, now we can parse it */
|
|
@@ -2337,40 +2231,40 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
|
|
- netdev->features |= NETIF_F_HIGHDMA |
|
|
|
|
- NETIF_F_SG |
|
|
|
|
- NETIF_F_IP_CSUM |
|
|
|
|
- NETIF_F_SCTP_CRC |
|
|
|
|
- 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_RXCSUM |
|
|
|
|
- NETIF_F_GRO;
|
|
|
|
-
|
|
|
|
- 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;
|
|
|
|
-
|
|
|
|
- if (adapter->flags & I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE)
|
|
|
|
- netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
-
|
|
|
|
- /* always clear VLAN features because they can change at every reset */
|
|
|
|
- netdev->features &= ~(I40EVF_VLAN_FEATURES);
|
|
|
|
- /* copy netdev features into list of user selectable features */
|
|
|
|
- netdev->hw_features |= netdev->features;
|
|
|
|
-
|
|
|
|
- if (vfres->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_VLAN) {
|
|
|
|
- netdev->vlan_features = netdev->features;
|
|
|
|
- netdev->features |= I40EVF_VLAN_FEATURES;
|
|
|
|
- }
|
|
|
|
|
|
+ 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_IPIP |
|
|
|
|
+ NETIF_F_GSO_SIT |
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL |
|
|
|
|
+ NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
|
|
|
+ NETIF_F_SCTP_CRC |
|
|
|
|
+ NETIF_F_RXHASH |
|
|
|
|
+ NETIF_F_RXCSUM |
|
|
|
|
+ 0;
|
|
|
|
+
|
|
|
|
+ if (!(adapter->flags & I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE))
|
|
|
|
+ netdev->hw_enc_features ^= NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
+
|
|
|
|
+ /* record features VLANs can make use of */
|
|
|
|
+ netdev->vlan_features |= netdev->hw_enc_features;
|
|
|
|
+
|
|
|
|
+ /* Write features and hw_features separately to avoid polluting
|
|
|
|
+ * with, or dropping, features that are set when we registgered.
|
|
|
|
+ */
|
|
|
|
+ netdev->hw_features |= netdev->hw_enc_features;
|
|
|
|
+
|
|
|
|
+ netdev->features |= netdev->hw_enc_features | I40EVF_VLAN_FEATURES;
|
|
|
|
+
|
|
|
|
+ /* disable VLAN features if not supported */
|
|
|
|
+ if (!(vfres->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_VLAN))
|
|
|
|
+ netdev->features ^= I40EVF_VLAN_FEATURES;
|
|
|
|
|
|
adapter->vsi.id = adapter->vsi_res->vsi_id;
|
|
adapter->vsi.id = adapter->vsi_res->vsi_id;
|
|
|
|
|
|
@@ -2381,8 +2275,16 @@ int i40evf_process_config(struct i40evf_adapter *adapter)
|
|
ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
|
|
ITR_REG_TO_USEC(I40E_ITR_RX_DEF));
|
|
adapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC |
|
|
adapter->vsi.tx_itr_setting = (I40E_ITR_DYNAMIC |
|
|
ITR_REG_TO_USEC(I40E_ITR_TX_DEF));
|
|
ITR_REG_TO_USEC(I40E_ITR_TX_DEF));
|
|
- adapter->vsi.netdev = adapter->netdev;
|
|
|
|
- adapter->vsi.qs_handle = adapter->vsi_res->qset_handle;
|
|
|
|
|
|
+ vsi->netdev = adapter->netdev;
|
|
|
|
+ vsi->qs_handle = adapter->vsi_res->qset_handle;
|
|
|
|
+ if (vfres->vf_offload_flags & I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF) {
|
|
|
|
+ adapter->rss_key_size = vfres->rss_key_size;
|
|
|
|
+ adapter->rss_lut_size = vfres->rss_lut_size;
|
|
|
|
+ } else {
|
|
|
|
+ adapter->rss_key_size = I40EVF_HKEY_ARRAY_SIZE;
|
|
|
|
+ adapter->rss_lut_size = I40EVF_HLUT_ARRAY_SIZE;
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2578,6 +2480,11 @@ static void i40evf_init_task(struct work_struct *work)
|
|
set_bit(__I40E_DOWN, &adapter->vsi.state);
|
|
set_bit(__I40E_DOWN, &adapter->vsi.state);
|
|
i40evf_misc_irq_enable(adapter);
|
|
i40evf_misc_irq_enable(adapter);
|
|
|
|
|
|
|
|
+ adapter->rss_key = kzalloc(adapter->rss_key_size, GFP_KERNEL);
|
|
|
|
+ adapter->rss_lut = kzalloc(adapter->rss_lut_size, GFP_KERNEL);
|
|
|
|
+ if (!adapter->rss_key || !adapter->rss_lut)
|
|
|
|
+ goto err_mem;
|
|
|
|
+
|
|
if (RSS_AQ(adapter)) {
|
|
if (RSS_AQ(adapter)) {
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_RSS;
|
|
adapter->aq_required |= I40EVF_FLAG_AQ_CONFIGURE_RSS;
|
|
mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
|
|
mod_timer_pending(&adapter->watchdog_timer, jiffies + 1);
|
|
@@ -2588,7 +2495,8 @@ static void i40evf_init_task(struct work_struct *work)
|
|
restart:
|
|
restart:
|
|
schedule_delayed_work(&adapter->init_task, msecs_to_jiffies(30));
|
|
schedule_delayed_work(&adapter->init_task, msecs_to_jiffies(30));
|
|
return;
|
|
return;
|
|
-
|
|
|
|
|
|
+err_mem:
|
|
|
|
+ i40evf_free_rss(adapter);
|
|
err_register:
|
|
err_register:
|
|
i40evf_free_misc_irq(adapter);
|
|
i40evf_free_misc_irq(adapter);
|
|
err_sw_init:
|
|
err_sw_init:
|
|
@@ -2870,8 +2778,7 @@ static void i40evf_remove(struct pci_dev *pdev)
|
|
|
|
|
|
flush_scheduled_work();
|
|
flush_scheduled_work();
|
|
|
|
|
|
- /* Clear user configurations for RSS */
|
|
|
|
- i40evf_clear_rss_config_user(&adapter->vsi);
|
|
|
|
|
|
+ i40evf_free_rss(adapter);
|
|
|
|
|
|
if (hw->aq.asq.count)
|
|
if (hw->aq.asq.count)
|
|
i40evf_shutdown_adminq(hw);
|
|
i40evf_shutdown_adminq(hw);
|