mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 23:25:54 +00:00
iavf: Fix VLAN_V2 addition/rejection
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: 92fc508598
("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>
This commit is contained in:
parent
7b02f40350
commit
968996c070
@ -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
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -2956,6 +2951,9 @@ continue_reset:
|
||||
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
|
||||
|
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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) {
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user