@@ -99,6 +99,24 @@ MODULE_LICENSE("GPL v2");
99
99
100
100
static struct workqueue_struct * i40e_wq ;
101
101
102
+ static void netdev_hw_addr_refcnt (struct i40e_mac_filter * f ,
103
+ struct net_device * netdev , int delta )
104
+ {
105
+ struct netdev_hw_addr * ha ;
106
+
107
+ if (!f || !netdev )
108
+ return ;
109
+
110
+ netdev_for_each_mc_addr (ha , netdev ) {
111
+ if (ether_addr_equal (ha -> addr , f -> macaddr )) {
112
+ ha -> refcount += delta ;
113
+ if (ha -> refcount <= 0 )
114
+ ha -> refcount = 1 ;
115
+ break ;
116
+ }
117
+ }
118
+ }
119
+
102
120
/**
103
121
* i40e_allocate_dma_mem_d - OS specific memory alloc for shared code
104
122
* @hw: pointer to the HW structure
@@ -2036,6 +2054,7 @@ static void i40e_undo_add_filter_entries(struct i40e_vsi *vsi,
2036
2054
hlist_for_each_entry_safe (new , h , from , hlist ) {
2037
2055
/* We can simply free the wrapper structure */
2038
2056
hlist_del (& new -> hlist );
2057
+ netdev_hw_addr_refcnt (new -> f , vsi -> netdev , -1 );
2039
2058
kfree (new );
2040
2059
}
2041
2060
}
@@ -2383,6 +2402,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2383
2402
& tmp_add_list ,
2384
2403
& tmp_del_list ,
2385
2404
vlan_filters );
2405
+
2406
+ hlist_for_each_entry (new , & tmp_add_list , hlist )
2407
+ netdev_hw_addr_refcnt (new -> f , vsi -> netdev , 1 );
2408
+
2386
2409
if (retval )
2387
2410
goto err_no_memory_locked ;
2388
2411
@@ -2515,6 +2538,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
2515
2538
if (new -> f -> state == I40E_FILTER_NEW )
2516
2539
new -> f -> state = new -> state ;
2517
2540
hlist_del (& new -> hlist );
2541
+ netdev_hw_addr_refcnt (new -> f , vsi -> netdev , -1 );
2518
2542
kfree (new );
2519
2543
}
2520
2544
spin_unlock_bh (& vsi -> mac_filter_hash_lock );
0 commit comments