@@ -161,36 +161,68 @@ static inline int qlcnic_82xx_is_lb_pkt(u64 sts_data)
161
161
return (qlcnic_get_sts_status (sts_data ) == STATUS_CKSUM_LOOP ) ? 1 : 0 ;
162
162
}
163
163
164
+ static void qlcnic_delete_rx_list_mac (struct qlcnic_adapter * adapter ,
165
+ struct qlcnic_filter * fil ,
166
+ void * addr , u16 vlan_id )
167
+ {
168
+ int ret ;
169
+ u8 op ;
170
+
171
+ op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD ;
172
+ ret = qlcnic_sre_macaddr_change (adapter , addr , vlan_id , op );
173
+ if (ret )
174
+ return ;
175
+
176
+ op = vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL ;
177
+ ret = qlcnic_sre_macaddr_change (adapter , addr , vlan_id , op );
178
+ if (!ret ) {
179
+ hlist_del (& fil -> fnode );
180
+ adapter -> rx_fhash .fnum -- ;
181
+ }
182
+ }
183
+
184
+ static struct qlcnic_filter * qlcnic_find_mac_filter (struct hlist_head * head ,
185
+ void * addr , u16 vlan_id )
186
+ {
187
+ struct qlcnic_filter * tmp_fil = NULL ;
188
+ struct hlist_node * n ;
189
+
190
+ hlist_for_each_entry_safe (tmp_fil , n , head , fnode ) {
191
+ if (!memcmp (tmp_fil -> faddr , addr , ETH_ALEN ) &&
192
+ tmp_fil -> vlan_id == vlan_id )
193
+ return tmp_fil ;
194
+ }
195
+
196
+ return NULL ;
197
+ }
198
+
164
199
void qlcnic_add_lb_filter (struct qlcnic_adapter * adapter , struct sk_buff * skb ,
165
200
int loopback_pkt , u16 vlan_id )
166
201
{
167
202
struct ethhdr * phdr = (struct ethhdr * )(skb -> data );
168
203
struct qlcnic_filter * fil , * tmp_fil ;
169
- struct hlist_node * n ;
170
204
struct hlist_head * head ;
171
205
unsigned long time ;
172
206
u64 src_addr = 0 ;
173
- u8 hindex , found = 0 , op ;
207
+ u8 hindex , op ;
174
208
int ret ;
175
209
176
210
memcpy (& src_addr , phdr -> h_source , ETH_ALEN );
211
+ hindex = qlcnic_mac_hash (src_addr ) &
212
+ (adapter -> fhash .fbucket_size - 1 );
177
213
178
214
if (loopback_pkt ) {
179
215
if (adapter -> rx_fhash .fnum >= adapter -> rx_fhash .fmax )
180
216
return ;
181
217
182
- hindex = qlcnic_mac_hash (src_addr ) &
183
- (adapter -> fhash .fbucket_size - 1 );
184
218
head = & (adapter -> rx_fhash .fhead [hindex ]);
185
219
186
- hlist_for_each_entry_safe (tmp_fil , n , head , fnode ) {
187
- if (!memcmp (tmp_fil -> faddr , & src_addr , ETH_ALEN ) &&
188
- tmp_fil -> vlan_id == vlan_id ) {
189
- time = tmp_fil -> ftime ;
190
- if (jiffies > (QLCNIC_READD_AGE * HZ + time ))
191
- tmp_fil -> ftime = jiffies ;
192
- return ;
193
- }
220
+ tmp_fil = qlcnic_find_mac_filter (head , & src_addr , vlan_id );
221
+ if (tmp_fil ) {
222
+ time = tmp_fil -> ftime ;
223
+ if (time_after (jiffies , QLCNIC_READD_AGE * HZ + time ))
224
+ tmp_fil -> ftime = jiffies ;
225
+ return ;
194
226
}
195
227
196
228
fil = kzalloc (sizeof (struct qlcnic_filter ), GFP_ATOMIC );
@@ -205,36 +237,37 @@ void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, struct sk_buff *skb,
205
237
adapter -> rx_fhash .fnum ++ ;
206
238
spin_unlock (& adapter -> rx_mac_learn_lock );
207
239
} else {
208
- hindex = qlcnic_mac_hash (src_addr ) &
209
- (adapter -> fhash .fbucket_size - 1 );
210
- head = & (adapter -> rx_fhash .fhead [hindex ]);
211
- spin_lock (& adapter -> rx_mac_learn_lock );
212
- hlist_for_each_entry_safe (tmp_fil , n , head , fnode ) {
213
- if (!memcmp (tmp_fil -> faddr , & src_addr , ETH_ALEN ) &&
214
- tmp_fil -> vlan_id == vlan_id ) {
215
- found = 1 ;
216
- break ;
217
- }
218
- }
240
+ head = & adapter -> fhash .fhead [hindex ];
219
241
220
- if (!found ) {
221
- spin_unlock (& adapter -> rx_mac_learn_lock );
222
- return ;
223
- }
242
+ spin_lock (& adapter -> mac_learn_lock );
224
243
225
- op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD ;
226
- ret = qlcnic_sre_macaddr_change (adapter , (u8 * )& src_addr ,
227
- vlan_id , op );
228
- if (!ret ) {
244
+ tmp_fil = qlcnic_find_mac_filter (head , & src_addr , vlan_id );
245
+ if (tmp_fil ) {
229
246
op = vlan_id ? QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL ;
230
247
ret = qlcnic_sre_macaddr_change (adapter ,
231
248
(u8 * )& src_addr ,
232
249
vlan_id , op );
233
250
if (!ret ) {
234
- hlist_del (& ( tmp_fil -> fnode ) );
235
- adapter -> rx_fhash .fnum -- ;
251
+ hlist_del (& tmp_fil -> fnode );
252
+ adapter -> fhash .fnum -- ;
236
253
}
254
+
255
+ spin_unlock (& adapter -> mac_learn_lock );
256
+
257
+ return ;
237
258
}
259
+
260
+ spin_unlock (& adapter -> mac_learn_lock );
261
+
262
+ head = & adapter -> rx_fhash .fhead [hindex ];
263
+
264
+ spin_lock (& adapter -> rx_mac_learn_lock );
265
+
266
+ tmp_fil = qlcnic_find_mac_filter (head , & src_addr , vlan_id );
267
+ if (tmp_fil )
268
+ qlcnic_delete_rx_list_mac (adapter , tmp_fil , & src_addr ,
269
+ vlan_id );
270
+
238
271
spin_unlock (& adapter -> rx_mac_learn_lock );
239
272
}
240
273
}
0 commit comments