@@ -4789,7 +4789,7 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
4789
4789
}
4790
4790
}
4791
4791
4792
- static void bnxt_free_ntp_fltrs (struct bnxt * bp , bool irq_reinit )
4792
+ static void bnxt_free_ntp_fltrs (struct bnxt * bp , bool all )
4793
4793
{
4794
4794
#ifdef CONFIG_RFS_ACCEL
4795
4795
int i ;
@@ -4804,14 +4804,19 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit)
4804
4804
4805
4805
head = & bp -> ntp_fltr_hash_tbl [i ];
4806
4806
hlist_for_each_entry_safe (fltr , tmp , head , base .hash ) {
4807
+ if (!all && (fltr -> base .flags & BNXT_ACT_FUNC_DST ))
4808
+ continue ;
4807
4809
hlist_del (& fltr -> base .hash );
4810
+ clear_bit (fltr -> base .sw_id , bp -> ntp_fltr_bmap );
4811
+ bp -> ntp_fltr_count -- ;
4808
4812
kfree (fltr );
4809
4813
}
4810
4814
}
4811
- if (irq_reinit ) {
4812
- bitmap_free (bp -> ntp_fltr_bmap );
4813
- bp -> ntp_fltr_bmap = NULL ;
4814
- }
4815
+ if (!all )
4816
+ return ;
4817
+
4818
+ bitmap_free (bp -> ntp_fltr_bmap );
4819
+ bp -> ntp_fltr_bmap = NULL ;
4815
4820
bp -> ntp_fltr_count = 0 ;
4816
4821
#endif
4817
4822
}
@@ -4821,7 +4826,7 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
4821
4826
#ifdef CONFIG_RFS_ACCEL
4822
4827
int i , rc = 0 ;
4823
4828
4824
- if (!(bp -> flags & BNXT_FLAG_RFS ))
4829
+ if (!(bp -> flags & BNXT_FLAG_RFS ) || bp -> ntp_fltr_bmap )
4825
4830
return 0 ;
4826
4831
4827
4832
for (i = 0 ; i < BNXT_NTP_FLTR_HASH_SIZE ; i ++ )
@@ -4839,14 +4844,47 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
4839
4844
#endif
4840
4845
}
4841
4846
4847
+ static void bnxt_free_l2_filters (struct bnxt * bp , bool all )
4848
+ {
4849
+ int i ;
4850
+
4851
+ for (i = 0 ; i < BNXT_L2_FLTR_HASH_SIZE ; i ++ ) {
4852
+ struct hlist_head * head ;
4853
+ struct hlist_node * tmp ;
4854
+ struct bnxt_l2_filter * fltr ;
4855
+
4856
+ head = & bp -> l2_fltr_hash_tbl [i ];
4857
+ hlist_for_each_entry_safe (fltr , tmp , head , base .hash ) {
4858
+ if (!all && (fltr -> base .flags & BNXT_ACT_FUNC_DST ))
4859
+ continue ;
4860
+ hlist_del (& fltr -> base .hash );
4861
+ if (fltr -> base .flags ) {
4862
+ clear_bit (fltr -> base .sw_id , bp -> ntp_fltr_bmap );
4863
+ bp -> ntp_fltr_count -- ;
4864
+ }
4865
+ kfree (fltr );
4866
+ }
4867
+ }
4868
+ }
4869
+
4870
+ static void bnxt_init_l2_fltr_tbl (struct bnxt * bp )
4871
+ {
4872
+ int i ;
4873
+
4874
+ for (i = 0 ; i < BNXT_L2_FLTR_HASH_SIZE ; i ++ )
4875
+ INIT_HLIST_HEAD (& bp -> l2_fltr_hash_tbl [i ]);
4876
+ get_random_bytes (& bp -> hash_seed , sizeof (bp -> hash_seed ));
4877
+ }
4878
+
4842
4879
static void bnxt_free_mem (struct bnxt * bp , bool irq_re_init )
4843
4880
{
4844
4881
bnxt_free_vnic_attributes (bp );
4845
4882
bnxt_free_tx_rings (bp );
4846
4883
bnxt_free_rx_rings (bp );
4847
4884
bnxt_free_cp_rings (bp );
4848
4885
bnxt_free_all_cp_arrays (bp );
4849
- bnxt_free_ntp_fltrs (bp , irq_re_init );
4886
+ bnxt_free_ntp_fltrs (bp , false);
4887
+ bnxt_free_l2_filters (bp , false);
4850
4888
if (irq_re_init ) {
4851
4889
bnxt_free_ring_stats (bp );
4852
4890
if (!(bp -> phy_flags & BNXT_PHY_FL_PORT_STATS_NO_RESET ) ||
@@ -5290,6 +5328,92 @@ static int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, u16 vnic_id)
5290
5328
return hwrm_req_send_silent (bp , req );
5291
5329
}
5292
5330
5331
+ void bnxt_del_l2_filter (struct bnxt * bp , struct bnxt_l2_filter * fltr )
5332
+ {
5333
+ if (!atomic_dec_and_test (& fltr -> refcnt ))
5334
+ return ;
5335
+ spin_lock_bh (& bp -> ntp_fltr_lock );
5336
+ hlist_del_rcu (& fltr -> base .hash );
5337
+ if (fltr -> base .flags ) {
5338
+ clear_bit (fltr -> base .sw_id , bp -> ntp_fltr_bmap );
5339
+ bp -> ntp_fltr_count -- ;
5340
+ }
5341
+ spin_unlock_bh (& bp -> ntp_fltr_lock );
5342
+ kfree_rcu (fltr , base .rcu );
5343
+ }
5344
+
5345
+ static struct bnxt_l2_filter * __bnxt_lookup_l2_filter (struct bnxt * bp ,
5346
+ struct bnxt_l2_key * key ,
5347
+ u32 idx )
5348
+ {
5349
+ struct hlist_head * head = & bp -> l2_fltr_hash_tbl [idx ];
5350
+ struct bnxt_l2_filter * fltr ;
5351
+
5352
+ hlist_for_each_entry_rcu (fltr , head , base .hash ) {
5353
+ struct bnxt_l2_key * l2_key = & fltr -> l2_key ;
5354
+
5355
+ if (ether_addr_equal (l2_key -> dst_mac_addr , key -> dst_mac_addr ) &&
5356
+ l2_key -> vlan == key -> vlan )
5357
+ return fltr ;
5358
+ }
5359
+ return NULL ;
5360
+ }
5361
+
5362
+ static struct bnxt_l2_filter * bnxt_lookup_l2_filter (struct bnxt * bp ,
5363
+ struct bnxt_l2_key * key ,
5364
+ u32 idx )
5365
+ {
5366
+ struct bnxt_l2_filter * fltr = NULL ;
5367
+
5368
+ rcu_read_lock ();
5369
+ fltr = __bnxt_lookup_l2_filter (bp , key , idx );
5370
+ if (fltr )
5371
+ atomic_inc (& fltr -> refcnt );
5372
+ rcu_read_unlock ();
5373
+ return fltr ;
5374
+ }
5375
+
5376
+ static int bnxt_init_l2_filter (struct bnxt * bp , struct bnxt_l2_filter * fltr ,
5377
+ struct bnxt_l2_key * key , u32 idx )
5378
+ {
5379
+ struct hlist_head * head ;
5380
+
5381
+ ether_addr_copy (fltr -> l2_key .dst_mac_addr , key -> dst_mac_addr );
5382
+ fltr -> l2_key .vlan = key -> vlan ;
5383
+ fltr -> base .type = BNXT_FLTR_TYPE_L2 ;
5384
+ head = & bp -> l2_fltr_hash_tbl [idx ];
5385
+ hlist_add_head_rcu (& fltr -> base .hash , head );
5386
+ atomic_set (& fltr -> refcnt , 1 );
5387
+ return 0 ;
5388
+ }
5389
+
5390
+ static struct bnxt_l2_filter * bnxt_alloc_l2_filter (struct bnxt * bp ,
5391
+ struct bnxt_l2_key * key ,
5392
+ gfp_t gfp )
5393
+ {
5394
+ struct bnxt_l2_filter * fltr ;
5395
+ u32 idx ;
5396
+ int rc ;
5397
+
5398
+ idx = jhash2 (& key -> filter_key , BNXT_L2_KEY_SIZE , bp -> hash_seed ) &
5399
+ BNXT_L2_FLTR_HASH_MASK ;
5400
+ fltr = bnxt_lookup_l2_filter (bp , key , idx );
5401
+ if (fltr )
5402
+ return fltr ;
5403
+
5404
+ fltr = kzalloc (sizeof (* fltr ), gfp );
5405
+ if (!fltr )
5406
+ return ERR_PTR (- ENOMEM );
5407
+ spin_lock_bh (& bp -> ntp_fltr_lock );
5408
+ rc = bnxt_init_l2_filter (bp , fltr , key , idx );
5409
+ spin_unlock_bh (& bp -> ntp_fltr_lock );
5410
+ if (rc ) {
5411
+ bnxt_del_l2_filter (bp , fltr );
5412
+ fltr = ERR_PTR (rc );
5413
+ }
5414
+ return fltr ;
5415
+ }
5416
+
5293
5417
#ifdef CONFIG_RFS_ACCEL
5294
5418
static int bnxt_hwrm_cfa_ntuple_filter_free (struct bnxt * bp ,
5295
5419
struct bnxt_ntuple_filter * fltr )
@@ -5330,6 +5454,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
5330
5454
struct hwrm_cfa_ntuple_filter_alloc_output * resp ;
5331
5455
struct hwrm_cfa_ntuple_filter_alloc_input * req ;
5332
5456
struct flow_keys * keys = & fltr -> fkeys ;
5457
+ struct bnxt_l2_filter * l2_fltr ;
5333
5458
struct bnxt_vnic_info * vnic ;
5334
5459
u32 flags = 0 ;
5335
5460
int rc ;
@@ -5338,7 +5463,9 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
5338
5463
if (rc )
5339
5464
return rc ;
5340
5465
5341
- req -> l2_filter_id = bp -> vnic_info [0 ].fw_l2_filter_id [fltr -> l2_fltr_idx ];
5466
+ l2_fltr = bp -> vnic_info [0 ].l2_filters [fltr -> l2_fltr_idx ];
5467
+ req -> l2_filter_id = l2_fltr -> base .filter_id ;
5468
+
5342
5469
5343
5470
if (bp -> fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2 ) {
5344
5471
flags = CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX ;
@@ -5400,8 +5527,16 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
5400
5527
{
5401
5528
struct hwrm_cfa_l2_filter_alloc_output * resp ;
5402
5529
struct hwrm_cfa_l2_filter_alloc_input * req ;
5530
+ struct bnxt_l2_filter * fltr ;
5531
+ struct bnxt_l2_key key ;
5403
5532
int rc ;
5404
5533
5534
+ ether_addr_copy (key .dst_mac_addr , mac_addr );
5535
+ key .vlan = 0 ;
5536
+ fltr = bnxt_alloc_l2_filter (bp , & key , GFP_KERNEL );
5537
+ if (IS_ERR (fltr ))
5538
+ return PTR_ERR (fltr );
5539
+
5405
5540
rc = hwrm_req_init (bp , req , HWRM_CFA_L2_FILTER_ALLOC );
5406
5541
if (rc )
5407
5542
return rc ;
@@ -5425,9 +5560,13 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
5425
5560
5426
5561
resp = hwrm_req_hold (bp , req );
5427
5562
rc = hwrm_req_send (bp , req );
5428
- if (!rc )
5429
- bp -> vnic_info [vnic_id ].fw_l2_filter_id [idx ] =
5430
- resp -> l2_filter_id ;
5563
+ if (rc ) {
5564
+ bnxt_del_l2_filter (bp , fltr );
5565
+ } else {
5566
+ fltr -> base .filter_id = resp -> l2_filter_id ;
5567
+ set_bit (BNXT_FLTR_VALID , & fltr -> base .state );
5568
+ bp -> vnic_info [vnic_id ].l2_filters [idx ] = fltr ;
5569
+ }
5431
5570
hwrm_req_drop (bp , req );
5432
5571
return rc ;
5433
5572
}
@@ -5447,9 +5586,13 @@ static int bnxt_hwrm_clear_vnic_filter(struct bnxt *bp)
5447
5586
struct bnxt_vnic_info * vnic = & bp -> vnic_info [i ];
5448
5587
5449
5588
for (j = 0 ; j < vnic -> uc_filter_count ; j ++ ) {
5450
- req -> l2_filter_id = vnic -> fw_l2_filter_id [j ];
5589
+ struct bnxt_l2_filter * fltr ;
5590
+
5591
+ fltr = vnic -> l2_filters [j ];
5592
+ req -> l2_filter_id = fltr -> base .filter_id ;
5451
5593
5452
5594
rc = hwrm_req_send (bp , req );
5595
+ bnxt_del_l2_filter (bp , fltr );
5453
5596
}
5454
5597
vnic -> uc_filter_count = 0 ;
5455
5598
}
@@ -11759,9 +11902,12 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
11759
11902
return rc ;
11760
11903
hwrm_req_hold (bp , req );
11761
11904
for (i = 1 ; i < vnic -> uc_filter_count ; i ++ ) {
11762
- req -> l2_filter_id = vnic -> fw_l2_filter_id [i ];
11905
+ struct bnxt_l2_filter * fltr = vnic -> l2_filters [i ];
11906
+
11907
+ req -> l2_filter_id = fltr -> base .filter_id ;
11763
11908
11764
11909
rc = hwrm_req_send (bp , req );
11910
+ bnxt_del_l2_filter (bp , fltr );
11765
11911
}
11766
11912
hwrm_req_drop (bp , req );
11767
11913
@@ -13901,6 +14047,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
13901
14047
13902
14048
bnxt_ptp_clear (bp );
13903
14049
unregister_netdev (dev );
14050
+ bnxt_free_l2_filters (bp , true);
14051
+ bnxt_free_ntp_fltrs (bp , true);
13904
14052
clear_bit (BNXT_STATE_IN_FW_RESET , & bp -> state );
13905
14053
/* Flush any pending tasks */
13906
14054
cancel_work_sync (& bp -> sp_task );
@@ -14450,6 +14598,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
14450
14598
if (rc )
14451
14599
goto init_err_pci_clean ;
14452
14600
14601
+ bnxt_init_l2_fltr_tbl (bp );
14453
14602
bnxt_set_rx_skb_mode (bp , false);
14454
14603
bnxt_set_tpa_flags (bp );
14455
14604
bnxt_set_ring_params (bp );
0 commit comments