diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index fa4a04da47b7..06c80d4162af 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1842,6 +1842,31 @@ static void i40e_undo_filter_entries(struct i40e_vsi *vsi, } } +/** + * i40e_next_entry - Get the next non-broadcast filter from a list + * @f: pointer to filter in list + * + * Returns the next non-broadcast filter in the list. Required so that we + * ignore broadcast filters within the list, since these are not handled via + * the normal firmware update path. + */ +static struct i40e_mac_filter *i40e_next_filter(struct i40e_mac_filter *f) +{ + while (f) { + f = hlist_entry(f->hlist.next, + typeof(struct i40e_mac_filter), + hlist); + + /* keep going if we found a broadcast filter */ + if (f && is_broadcast_ether_addr(f->macaddr)) + continue; + + break; + } + + return f; +} + /** * i40e_update_filter_state - Update filter state based on return data * from firmware @@ -1874,9 +1899,9 @@ i40e_update_filter_state(int count, retval++; } - add_head = hlist_entry(add_head->hlist.next, - typeof(struct i40e_mac_filter), - hlist); + add_head = i40e_next_filter(add_head); + if (!add_head) + break; } return retval; @@ -2095,7 +2120,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) cmd_flags = 0; /* handle broadcast filters by updating the broadcast - * promiscuous flag instead of deleting a MAC filter. + * promiscuous flag and release filter list. */ if (is_broadcast_ether_addr(f->macaddr)) { i40e_aqc_broadcast_filter(vsi, vsi_name, f); @@ -2164,11 +2189,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) * promiscuous flag instead of adding a MAC filter. */ if (is_broadcast_ether_addr(f->macaddr)) { - u64 key = i40e_addr_to_hkey(f->macaddr); i40e_aqc_broadcast_filter(vsi, vsi_name, f); - - hlist_del(&f->hlist); - hash_add(vsi->mac_filter_hash, &f->hlist, key); continue; }