@@ -6585,30 +6585,6 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
6585
6585
return ret ;
6586
6586
}
6587
6587
6588
- int hclge_set_vlan_filter (struct hnae3_handle * handle , __be16 proto ,
6589
- u16 vlan_id , bool is_kill )
6590
- {
6591
- struct hclge_vport * vport = hclge_get_vport (handle );
6592
- struct hclge_dev * hdev = vport -> back ;
6593
-
6594
- return hclge_set_vlan_filter_hw (hdev , proto , vport -> vport_id , vlan_id ,
6595
- 0 , is_kill );
6596
- }
6597
-
6598
- static int hclge_set_vf_vlan_filter (struct hnae3_handle * handle , int vfid ,
6599
- u16 vlan , u8 qos , __be16 proto )
6600
- {
6601
- struct hclge_vport * vport = hclge_get_vport (handle );
6602
- struct hclge_dev * hdev = vport -> back ;
6603
-
6604
- if ((vfid >= hdev -> num_alloc_vfs ) || (vlan > 4095 ) || (qos > 7 ))
6605
- return - EINVAL ;
6606
- if (proto != htons (ETH_P_8021Q ))
6607
- return - EPROTONOSUPPORT ;
6608
-
6609
- return hclge_set_vlan_filter_hw (hdev , proto , vfid , vlan , qos , false);
6610
- }
6611
-
6612
6588
static int hclge_set_vlan_tx_offload_cfg (struct hclge_vport * vport )
6613
6589
{
6614
6590
struct hclge_tx_vtag_cfg * vcfg = & vport -> txvlan_cfg ;
@@ -6833,7 +6809,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
6833
6809
return hclge_set_vlan_filter (handle , htons (ETH_P_8021Q ), 0 , false);
6834
6810
}
6835
6811
6836
- void hclge_add_vport_vlan_table (struct hclge_vport * vport , u16 vlan_id )
6812
+ static void hclge_add_vport_vlan_table (struct hclge_vport * vport , u16 vlan_id ,
6813
+ bool writen_to_tbl )
6837
6814
{
6838
6815
struct hclge_vport_vlan_cfg * vlan ;
6839
6816
@@ -6845,14 +6822,38 @@ void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id)
6845
6822
if (!vlan )
6846
6823
return ;
6847
6824
6848
- vlan -> hd_tbl_status = true ;
6825
+ vlan -> hd_tbl_status = writen_to_tbl ;
6849
6826
vlan -> vlan_id = vlan_id ;
6850
6827
6851
6828
list_add_tail (& vlan -> node , & vport -> vlan_list );
6852
6829
}
6853
6830
6854
- void hclge_rm_vport_vlan_table (struct hclge_vport * vport , u16 vlan_id ,
6855
- bool is_write_tbl )
6831
+ static int hclge_add_vport_all_vlan_table (struct hclge_vport * vport )
6832
+ {
6833
+ struct hclge_vport_vlan_cfg * vlan , * tmp ;
6834
+ struct hclge_dev * hdev = vport -> back ;
6835
+ int ret ;
6836
+
6837
+ list_for_each_entry_safe (vlan , tmp , & vport -> vlan_list , node ) {
6838
+ if (!vlan -> hd_tbl_status ) {
6839
+ ret = hclge_set_vlan_filter_hw (hdev , htons (ETH_P_8021Q ),
6840
+ vport -> vport_id ,
6841
+ vlan -> vlan_id , 0 , false);
6842
+ if (ret ) {
6843
+ dev_err (& hdev -> pdev -> dev ,
6844
+ "restore vport vlan list failed, ret=%d\n" ,
6845
+ ret );
6846
+ return ret ;
6847
+ }
6848
+ }
6849
+ vlan -> hd_tbl_status = true;
6850
+ }
6851
+
6852
+ return 0 ;
6853
+ }
6854
+
6855
+ static void hclge_rm_vport_vlan_table (struct hclge_vport * vport , u16 vlan_id ,
6856
+ bool is_write_tbl )
6856
6857
{
6857
6858
struct hclge_vport_vlan_cfg * vlan , * tmp ;
6858
6859
struct hclge_dev * hdev = vport -> back ;
@@ -6929,6 +6930,178 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
6929
6930
return hclge_set_vlan_rx_offload_cfg (vport );
6930
6931
}
6931
6932
6933
+ static int hclge_update_vlan_filter_entries (struct hclge_vport * vport ,
6934
+ u16 port_base_vlan_state ,
6935
+ struct hclge_vlan_info * new_info ,
6936
+ struct hclge_vlan_info * old_info )
6937
+ {
6938
+ struct hclge_dev * hdev = vport -> back ;
6939
+ int ret ;
6940
+
6941
+ if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_ENABLE ) {
6942
+ hclge_rm_vport_all_vlan_table (vport , false);
6943
+ return hclge_set_vlan_filter_hw (hdev ,
6944
+ htons (new_info -> vlan_proto ),
6945
+ vport -> vport_id ,
6946
+ new_info -> vlan_tag ,
6947
+ new_info -> qos , false);
6948
+ }
6949
+
6950
+ ret = hclge_set_vlan_filter_hw (hdev , htons (old_info -> vlan_proto ),
6951
+ vport -> vport_id , old_info -> vlan_tag ,
6952
+ old_info -> qos , true);
6953
+ if (ret )
6954
+ return ret ;
6955
+
6956
+ return hclge_add_vport_all_vlan_table (vport );
6957
+ }
6958
+
6959
+ int hclge_update_port_base_vlan_cfg (struct hclge_vport * vport , u16 state ,
6960
+ struct hclge_vlan_info * vlan_info )
6961
+ {
6962
+ struct hnae3_handle * nic = & vport -> nic ;
6963
+ struct hclge_vlan_info * old_vlan_info ;
6964
+ struct hclge_dev * hdev = vport -> back ;
6965
+ int ret ;
6966
+
6967
+ old_vlan_info = & vport -> port_base_vlan_cfg .vlan_info ;
6968
+
6969
+ ret = hclge_vlan_offload_cfg (vport , state , vlan_info -> vlan_tag );
6970
+ if (ret )
6971
+ return ret ;
6972
+
6973
+ if (state == HNAE3_PORT_BASE_VLAN_MODIFY ) {
6974
+ /* add new VLAN tag */
6975
+ ret = hclge_set_vlan_filter_hw (hdev , vlan_info -> vlan_proto ,
6976
+ vport -> vport_id ,
6977
+ vlan_info -> vlan_tag ,
6978
+ vlan_info -> qos , false);
6979
+ if (ret )
6980
+ return ret ;
6981
+
6982
+ /* remove old VLAN tag */
6983
+ ret = hclge_set_vlan_filter_hw (hdev , old_vlan_info -> vlan_proto ,
6984
+ vport -> vport_id ,
6985
+ old_vlan_info -> vlan_tag ,
6986
+ old_vlan_info -> qos , true);
6987
+ if (ret )
6988
+ return ret ;
6989
+
6990
+ goto update ;
6991
+ }
6992
+
6993
+ ret = hclge_update_vlan_filter_entries (vport , state , vlan_info ,
6994
+ old_vlan_info );
6995
+ if (ret )
6996
+ return ret ;
6997
+
6998
+ /* update state only when disable/enable port based VLAN */
6999
+ vport -> port_base_vlan_cfg .state = state ;
7000
+ if (state == HNAE3_PORT_BASE_VLAN_DISABLE )
7001
+ nic -> port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE ;
7002
+ else
7003
+ nic -> port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE ;
7004
+
7005
+ update :
7006
+ vport -> port_base_vlan_cfg .vlan_info .vlan_tag = vlan_info -> vlan_tag ;
7007
+ vport -> port_base_vlan_cfg .vlan_info .qos = vlan_info -> qos ;
7008
+ vport -> port_base_vlan_cfg .vlan_info .vlan_proto = vlan_info -> vlan_proto ;
7009
+
7010
+ return 0 ;
7011
+ }
7012
+
7013
+ static u16 hclge_get_port_base_vlan_state (struct hclge_vport * vport ,
7014
+ enum hnae3_port_base_vlan_state state ,
7015
+ u16 vlan )
7016
+ {
7017
+ if (state == HNAE3_PORT_BASE_VLAN_DISABLE ) {
7018
+ if (!vlan )
7019
+ return HNAE3_PORT_BASE_VLAN_NOCHANGE ;
7020
+ else
7021
+ return HNAE3_PORT_BASE_VLAN_ENABLE ;
7022
+ } else {
7023
+ if (!vlan )
7024
+ return HNAE3_PORT_BASE_VLAN_DISABLE ;
7025
+ else if (vport -> port_base_vlan_cfg .vlan_info .vlan_tag == vlan )
7026
+ return HNAE3_PORT_BASE_VLAN_NOCHANGE ;
7027
+ else
7028
+ return HNAE3_PORT_BASE_VLAN_MODIFY ;
7029
+ }
7030
+ }
7031
+
7032
+ static int hclge_set_vf_vlan_filter (struct hnae3_handle * handle , int vfid ,
7033
+ u16 vlan , u8 qos , __be16 proto )
7034
+ {
7035
+ struct hclge_vport * vport = hclge_get_vport (handle );
7036
+ struct hclge_dev * hdev = vport -> back ;
7037
+ struct hclge_vlan_info vlan_info ;
7038
+ u16 state ;
7039
+ int ret ;
7040
+
7041
+ if (hdev -> pdev -> revision == 0x20 )
7042
+ return - EOPNOTSUPP ;
7043
+
7044
+ /* qos is a 3 bits value, so can not be bigger than 7 */
7045
+ if (vfid >= hdev -> num_alloc_vfs || vlan > VLAN_N_VID - 1 || qos > 7 )
7046
+ return - EINVAL ;
7047
+ if (proto != htons (ETH_P_8021Q ))
7048
+ return - EPROTONOSUPPORT ;
7049
+
7050
+ vport = & hdev -> vport [vfid ];
7051
+ state = hclge_get_port_base_vlan_state (vport ,
7052
+ vport -> port_base_vlan_cfg .state ,
7053
+ vlan );
7054
+ if (state == HNAE3_PORT_BASE_VLAN_NOCHANGE )
7055
+ return 0 ;
7056
+
7057
+ vlan_info .vlan_tag = vlan ;
7058
+ vlan_info .qos = qos ;
7059
+ vlan_info .vlan_proto = ntohs (proto );
7060
+
7061
+ /* update port based VLAN for PF */
7062
+ if (!vfid ) {
7063
+ hclge_notify_client (hdev , HNAE3_DOWN_CLIENT );
7064
+ ret = hclge_update_port_base_vlan_cfg (vport , state , & vlan_info );
7065
+ hclge_notify_client (hdev , HNAE3_UP_CLIENT );
7066
+
7067
+ return ret ;
7068
+ }
7069
+
7070
+ return - EOPNOTSUPP ;
7071
+ }
7072
+
7073
+ int hclge_set_vlan_filter (struct hnae3_handle * handle , __be16 proto ,
7074
+ u16 vlan_id , bool is_kill )
7075
+ {
7076
+ struct hclge_vport * vport = hclge_get_vport (handle );
7077
+ struct hclge_dev * hdev = vport -> back ;
7078
+ bool writen_to_tbl = false;
7079
+ int ret = 0 ;
7080
+
7081
+ /* when port based VLAN enabled, we use port based VLAN as the VLAN
7082
+ * filter entry. In this case, we don't update VLAN filter table
7083
+ * when user add new VLAN or remove exist VLAN, just update the vport
7084
+ * VLAN list. The VLAN id in VLAN list won't be writen in VLAN filter
7085
+ * table until port based VLAN disabled
7086
+ */
7087
+ if (handle -> port_base_vlan_state == HNAE3_PORT_BASE_VLAN_DISABLE ) {
7088
+ ret = hclge_set_vlan_filter_hw (hdev , proto , vport -> vport_id ,
7089
+ vlan_id , 0 , is_kill );
7090
+ writen_to_tbl = true;
7091
+ }
7092
+
7093
+ if (ret )
7094
+ return ret ;
7095
+
7096
+ if (is_kill )
7097
+ hclge_rm_vport_vlan_table (vport , vlan_id , false);
7098
+ else
7099
+ hclge_add_vport_vlan_table (vport , vlan_id ,
7100
+ writen_to_tbl );
7101
+
7102
+ return 0 ;
7103
+ }
7104
+
6932
7105
static int hclge_set_mac_mtu (struct hclge_dev * hdev , int new_mps )
6933
7106
{
6934
7107
struct hclge_config_max_frm_size_cmd * req ;
0 commit comments