Skip to content

Commit

Permalink
iavf: Fix VLAN_V2 addition/rejection
Browse files Browse the repository at this point in the history
Fix VLAN addition, so that PF driver does not reject whole VLAN batch.
Add VLAN reject handling, so rejected VLANs, won't litter VLAN filter
list. Fix handling of active_(c/s)vlans, so it will be possible to
re-add VLAN filters for user.
Without this patch, after changing trust to off, with VLAN filters
saturated, no VLAN is added, due to PF rejecting addition.

Fixes: 92fc508 ("iavf: Restrict maximum VLAN filters for VIRTCHNL_VF_OFFLOAD_VLAN_V2")
Signed-off-by: Przemyslaw Patynowski <przemyslawx.patynowski@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Przemyslaw Patynowski authored and Tony Nguyen committed Jul 18, 2022
1 parent 7b02f40 commit 968996c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 10 deletions.
9 changes: 7 additions & 2 deletions drivers/net/ethernet/intel/iavf/iavf.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,12 @@ struct iavf_vlan {
struct iavf_vlan_filter {
struct list_head list;
struct iavf_vlan vlan;
bool remove; /* filter needs to be removed */
bool add; /* filter needs to be added */
struct {
u8 is_new_vlan:1; /* filter is new, wait for PF answer */
u8 remove:1; /* filter needs to be removed */
u8 add:1; /* filter needs to be added */
u8 padding:5;
};
};

#define IAVF_MAX_TRAFFIC_CLASS 4
Expand Down Expand Up @@ -520,6 +524,7 @@ int iavf_get_vf_config(struct iavf_adapter *adapter);
int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter);
int iavf_send_vf_offload_vlan_v2_msg(struct iavf_adapter *adapter);
void iavf_set_queue_vlan_tag_loc(struct iavf_adapter *adapter);
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter);
void iavf_irq_enable(struct iavf_adapter *adapter, bool flush);
void iavf_configure_queues(struct iavf_adapter *adapter);
void iavf_deconfigure_queues(struct iavf_adapter *adapter);
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/intel/iavf/iavf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ static void iavf_restore_filters(struct iavf_adapter *adapter)
* iavf_get_num_vlans_added - get number of VLANs added
* @adapter: board private structure
*/
static u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
u16 iavf_get_num_vlans_added(struct iavf_adapter *adapter)
{
return bitmap_weight(adapter->vsi.active_cvlans, VLAN_N_VID) +
bitmap_weight(adapter->vsi.active_svlans, VLAN_N_VID);
Expand Down Expand Up @@ -906,11 +906,6 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
if (!iavf_add_vlan(adapter, IAVF_VLAN(vid, be16_to_cpu(proto))))
return -ENOMEM;

if (proto == cpu_to_be16(ETH_P_8021Q))
set_bit(vid, adapter->vsi.active_cvlans);
else
set_bit(vid, adapter->vsi.active_svlans);

return 0;
}

Expand Down Expand Up @@ -2956,6 +2951,9 @@ static void iavf_reset_task(struct work_struct *work)
adapter->aq_required |= IAVF_FLAG_AQ_ADD_CLOUD_FILTER;
iavf_misc_irq_enable(adapter);

bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);
bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID);

mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2);

/* We were running when the reset started, so we need to restore some
Expand Down
65 changes: 63 additions & 2 deletions drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,33 @@ static void iavf_mac_add_reject(struct iavf_adapter *adapter)
spin_unlock_bh(&adapter->mac_vlan_list_lock);
}

/**
* iavf_vlan_add_reject
* @adapter: adapter structure
*
* Remove VLAN filters from list based on PF response.
**/
static void iavf_vlan_add_reject(struct iavf_adapter *adapter)
{
struct iavf_vlan_filter *f, *ftmp;

spin_lock_bh(&adapter->mac_vlan_list_lock);
list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) {
if (f->is_new_vlan) {
if (f->vlan.tpid == ETH_P_8021Q)
clear_bit(f->vlan.vid,
adapter->vsi.active_cvlans);
else
clear_bit(f->vlan.vid,
adapter->vsi.active_svlans);

list_del(&f->list);
kfree(f);
}
}
spin_unlock_bh(&adapter->mac_vlan_list_lock);
}

/**
* iavf_add_vlans
* @adapter: adapter structure
Expand Down Expand Up @@ -683,6 +710,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
vvfl->vlan_id[i] = f->vlan.vid;
i++;
f->add = false;
f->is_new_vlan = true;
if (i == count)
break;
}
Expand All @@ -695,10 +723,18 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_VLAN, (u8 *)vvfl, len);
kfree(vvfl);
} else {
u16 max_vlans = adapter->vlan_v2_caps.filtering.max_filters;
u16 current_vlans = iavf_get_num_vlans_added(adapter);
struct virtchnl_vlan_filter_list_v2 *vvfl_v2;

adapter->current_op = VIRTCHNL_OP_ADD_VLAN_V2;

if ((count + current_vlans) > max_vlans &&
current_vlans < max_vlans) {
count = max_vlans - iavf_get_num_vlans_added(adapter);
more = true;
}

len = sizeof(*vvfl_v2) + ((count - 1) *
sizeof(struct virtchnl_vlan_filter));
if (len > IAVF_MAX_AQ_BUF_SIZE) {
Expand All @@ -725,6 +761,9 @@ void iavf_add_vlans(struct iavf_adapter *adapter)
&adapter->vlan_v2_caps.filtering.filtering_support;
struct virtchnl_vlan *vlan;

if (i == count)
break;

/* give priority over outer if it's enabled */
if (filtering_support->outer)
vlan = &vvfl_v2->filters[i].outer;
Expand All @@ -736,8 +775,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter)

i++;
f->add = false;
if (i == count)
break;
f->is_new_vlan = true;
}
}

Expand Down Expand Up @@ -2080,6 +2118,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
*/
iavf_netdev_features_vlan_strip_set(netdev, true);
break;
case VIRTCHNL_OP_ADD_VLAN_V2:
iavf_vlan_add_reject(adapter);
dev_warn(&adapter->pdev->dev, "Failed to add VLAN filter, error %s\n",
iavf_stat_str(&adapter->hw, v_retval));
break;
default:
dev_err(&adapter->pdev->dev, "PF returned error %d (%s) to our request %d\n",
v_retval, iavf_stat_str(&adapter->hw, v_retval),
Expand Down Expand Up @@ -2332,6 +2375,24 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
spin_unlock_bh(&adapter->adv_rss_lock);
}
break;
case VIRTCHNL_OP_ADD_VLAN_V2: {
struct iavf_vlan_filter *f;

spin_lock_bh(&adapter->mac_vlan_list_lock);
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
if (f->is_new_vlan) {
f->is_new_vlan = false;
if (f->vlan.tpid == ETH_P_8021Q)
set_bit(f->vlan.vid,
adapter->vsi.active_cvlans);
else
set_bit(f->vlan.vid,
adapter->vsi.active_svlans);
}
}
spin_unlock_bh(&adapter->mac_vlan_list_lock);
}
break;
case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
/* PF enabled vlan strip on this VF.
* Update netdev->features if needed to be in sync with ethtool.
Expand Down

0 comments on commit 968996c

Please sign in to comment.