summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2016-10-05 09:30:34 -0700
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-10-31 14:26:40 -0700
commit5feb3d7b0c0a66c8537ca8a79d8f80f54783e73f (patch)
tree038679eaafe8ca2cafd584ccbd0fe17b5e7597a5
parent35ec2ff37c5a4897e75d408828adac737b17d2bf (diff)
i40e: refactor i40e_put_mac_in_vlan to avoid changing f->vlan
When a PVID has been assigned to a VSI, the function i40e_put_mac_in_vlan arbitrarily modifies all filters to have the same VLAN. This is obviously incorrect because it could be modifying active filters without putting them into the NEW state. The correct method is to remove then re-add filters which is already done in the code where we assign the PVID. Fix this issue and a few other minor nits at the same time. First, when we have a PVID don't even bother looping and simply add the filter with the PVID immediately. In the case of the loop, we now can remove several checks. We also don't need to use i40e_find_filter first before calling i40e_add_filter, since i40e_add_filter implicitly does a lookup already. Finally, update the return semantics of this function so that on failure to add a filter it returns NULL, but on success, it returns the last filter added. Otherwise, we're just returning the last filter in the list. An alternative fix might be to return 0 or an error code, but this is pretty invasive to every call site. Change-ID: I2325dfd843aec76d89fb0d7cb0e7c4f290a34840 Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index f7fe020e5e2a..c09609339bd2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1312,27 +1312,28 @@ void i40e_del_filter(struct i40e_vsi *vsi, const u8 *macaddr, s16 vlan)
* @vsi: the VSI to be searched
* @macaddr: the mac address to be filtered
*
- * Goes through all the macvlan filters and adds a
- * macvlan filter for each unique vlan that already exists
+ * Goes through all the macvlan filters and adds a macvlan filter for each
+ * unique vlan that already exists. If a PVID has been assigned, instead only
+ * add the macaddr to that VLAN.
*
- * Returns first filter found on success, else NULL
+ * Returns last filter added on success, else NULL
**/
struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi,
const u8 *macaddr)
{
- struct i40e_mac_filter *f;
+ struct i40e_mac_filter *f, *add = NULL;
+
+ if (vsi->info.pvid)
+ return i40e_add_filter(vsi, macaddr,
+ le16_to_cpu(vsi->info.pvid));
list_for_each_entry(f, &vsi->mac_filter_list, list) {
- if (vsi->info.pvid)
- f->vlan = le16_to_cpu(vsi->info.pvid);
- if (!i40e_find_filter(vsi, macaddr, f->vlan)) {
- if (!i40e_add_filter(vsi, macaddr, f->vlan))
- return NULL;
- }
+ add = i40e_add_filter(vsi, macaddr, f->vlan);
+ if (!add)
+ return NULL;
}
- return list_first_entry_or_null(&vsi->mac_filter_list,
- struct i40e_mac_filter, list);
+ return add;
}
/**