@@ -4543,8 +4543,9 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
4543
4543
hclge_set_vlan_filter_ctrl (hdev , HCLGE_FILTER_TYPE_VF , enable );
4544
4544
}
4545
4545
4546
- int hclge_set_vf_vlan_common (struct hclge_dev * hdev , int vfid ,
4547
- bool is_kill , u16 vlan , u8 qos , __be16 proto )
4546
+ static int hclge_set_vf_vlan_common (struct hclge_dev * hdev , int vfid ,
4547
+ bool is_kill , u16 vlan , u8 qos ,
4548
+ __be16 proto )
4548
4549
{
4549
4550
#define HCLGE_MAX_VF_BYTES 16
4550
4551
struct hclge_vlan_filter_vf_cfg_cmd * req0 ;
@@ -4602,12 +4603,9 @@ int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
4602
4603
return - EIO ;
4603
4604
}
4604
4605
4605
- static int hclge_set_port_vlan_filter (struct hnae3_handle * handle ,
4606
- __be16 proto , u16 vlan_id ,
4607
- bool is_kill )
4606
+ static int hclge_set_port_vlan_filter (struct hclge_dev * hdev , __be16 proto ,
4607
+ u16 vlan_id , bool is_kill )
4608
4608
{
4609
- struct hclge_vport * vport = hclge_get_vport (handle );
4610
- struct hclge_dev * hdev = vport -> back ;
4611
4609
struct hclge_vlan_filter_pf_cfg_cmd * req ;
4612
4610
struct hclge_desc desc ;
4613
4611
u8 vlan_offset_byte_val ;
@@ -4627,22 +4625,66 @@ static int hclge_set_port_vlan_filter(struct hnae3_handle *handle,
4627
4625
req -> vlan_offset_bitmap [vlan_offset_byte ] = vlan_offset_byte_val ;
4628
4626
4629
4627
ret = hclge_cmd_send (& hdev -> hw , & desc , 1 );
4628
+ if (ret )
4629
+ dev_err (& hdev -> pdev -> dev ,
4630
+ "port vlan command, send fail, ret =%d.\n" , ret );
4631
+ return ret ;
4632
+ }
4633
+
4634
+ static int hclge_set_vlan_filter_hw (struct hclge_dev * hdev , __be16 proto ,
4635
+ u16 vport_id , u16 vlan_id , u8 qos ,
4636
+ bool is_kill )
4637
+ {
4638
+ u16 vport_idx , vport_num = 0 ;
4639
+ int ret ;
4640
+
4641
+ ret = hclge_set_vf_vlan_common (hdev , vport_id , is_kill , vlan_id ,
4642
+ 0 , proto );
4630
4643
if (ret ) {
4631
4644
dev_err (& hdev -> pdev -> dev ,
4632
- "port vlan command, send fail, ret =%d.\n" ,
4633
- ret );
4645
+ "Set %d vport vlan filter config fail, ret =%d.\n" ,
4646
+ vport_id , ret );
4634
4647
return ret ;
4635
4648
}
4636
4649
4637
- ret = hclge_set_vf_vlan_common (hdev , 0 , is_kill , vlan_id , 0 , proto );
4638
- if (ret ) {
4650
+ /* vlan 0 may be added twice when 8021q module is enabled */
4651
+ if (!is_kill && !vlan_id &&
4652
+ test_bit (vport_id , hdev -> vlan_table [vlan_id ]))
4653
+ return 0 ;
4654
+
4655
+ if (!is_kill && test_and_set_bit (vport_id , hdev -> vlan_table [vlan_id ])) {
4639
4656
dev_err (& hdev -> pdev -> dev ,
4640
- "Set pf vlan filter config fail, ret =%d. \n" ,
4641
- ret );
4642
- return - EIO ;
4657
+ "Add port vlan failed, vport %d is already in vlan %d \n" ,
4658
+ vport_id , vlan_id );
4659
+ return - EINVAL ;
4643
4660
}
4644
4661
4645
- return 0 ;
4662
+ if (is_kill &&
4663
+ !test_and_clear_bit (vport_id , hdev -> vlan_table [vlan_id ])) {
4664
+ dev_err (& hdev -> pdev -> dev ,
4665
+ "Delete port vlan failed, vport %d is not in vlan %d\n" ,
4666
+ vport_id , vlan_id );
4667
+ return - EINVAL ;
4668
+ }
4669
+
4670
+ for_each_set_bit (vport_idx , hdev -> vlan_table [vlan_id ], VLAN_N_VID )
4671
+ vport_num ++ ;
4672
+
4673
+ if ((is_kill && vport_num == 0 ) || (!is_kill && vport_num == 1 ))
4674
+ ret = hclge_set_port_vlan_filter (hdev , proto , vlan_id ,
4675
+ is_kill );
4676
+
4677
+ return ret ;
4678
+ }
4679
+
4680
+ int hclge_set_vlan_filter (struct hnae3_handle * handle , __be16 proto ,
4681
+ u16 vlan_id , bool is_kill )
4682
+ {
4683
+ struct hclge_vport * vport = hclge_get_vport (handle );
4684
+ struct hclge_dev * hdev = vport -> back ;
4685
+
4686
+ return hclge_set_vlan_filter_hw (hdev , proto , vport -> vport_id , vlan_id ,
4687
+ 0 , is_kill );
4646
4688
}
4647
4689
4648
4690
static int hclge_set_vf_vlan_filter (struct hnae3_handle * handle , int vfid ,
@@ -4656,7 +4698,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
4656
4698
if (proto != htons (ETH_P_8021Q ))
4657
4699
return - EPROTONOSUPPORT ;
4658
4700
4659
- return hclge_set_vf_vlan_common (hdev , vfid , false , vlan , qos , proto );
4701
+ return hclge_set_vlan_filter_hw (hdev , proto , vfid , vlan , qos , false );
4660
4702
}
4661
4703
4662
4704
static int hclge_set_vlan_tx_offload_cfg (struct hclge_vport * vport )
@@ -4821,7 +4863,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
4821
4863
}
4822
4864
4823
4865
handle = & hdev -> vport [0 ].nic ;
4824
- return hclge_set_port_vlan_filter (handle , htons (ETH_P_8021Q ), 0 , false);
4866
+ return hclge_set_vlan_filter (handle , htons (ETH_P_8021Q ), 0 , false);
4825
4867
}
4826
4868
4827
4869
static int hclge_en_hw_strip_rxvtag (struct hnae3_handle * handle , bool enable )
@@ -5604,6 +5646,7 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev)
5604
5646
set_bit (HCLGE_STATE_DOWN , & hdev -> state );
5605
5647
5606
5648
hclge_stats_clear (hdev );
5649
+ memset (hdev -> vlan_table , 0 , sizeof (hdev -> vlan_table ));
5607
5650
5608
5651
ret = hclge_cmd_init (hdev );
5609
5652
if (ret ) {
@@ -6221,7 +6264,7 @@ static const struct hnae3_ae_ops hclge_ops = {
6221
6264
.get_fw_version = hclge_get_fw_version ,
6222
6265
.get_mdix_mode = hclge_get_mdix_mode ,
6223
6266
.enable_vlan_filter = hclge_enable_vlan_filter ,
6224
- .set_vlan_filter = hclge_set_port_vlan_filter ,
6267
+ .set_vlan_filter = hclge_set_vlan_filter ,
6225
6268
.set_vf_vlan_filter = hclge_set_vf_vlan_filter ,
6226
6269
.enable_hw_strip_rxvtag = hclge_en_hw_strip_rxvtag ,
6227
6270
.reset_event = hclge_reset_event ,
0 commit comments