@@ -6585,30 +6585,6 @@ static int hclge_set_vlan_filter_hw(struct hclge_dev *hdev, __be16 proto,
65856585 return ret ;
65866586}
65876587
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-
66126588static int hclge_set_vlan_tx_offload_cfg (struct hclge_vport * vport )
66136589{
66146590 struct hclge_tx_vtag_cfg * vcfg = & vport -> txvlan_cfg ;
@@ -6833,7 +6809,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
68336809 return hclge_set_vlan_filter (handle , htons (ETH_P_8021Q ), 0 , false);
68346810}
68356811
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 )
68376814{
68386815 struct hclge_vport_vlan_cfg * vlan ;
68396816
@@ -6845,14 +6822,38 @@ void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id)
68456822 if (!vlan )
68466823 return ;
68476824
6848- vlan -> hd_tbl_status = true ;
6825+ vlan -> hd_tbl_status = writen_to_tbl ;
68496826 vlan -> vlan_id = vlan_id ;
68506827
68516828 list_add_tail (& vlan -> node , & vport -> vlan_list );
68526829}
68536830
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 )
68566857{
68576858 struct hclge_vport_vlan_cfg * vlan , * tmp ;
68586859 struct hclge_dev * hdev = vport -> back ;
@@ -6929,6 +6930,178 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
69296930 return hclge_set_vlan_rx_offload_cfg (vport );
69306931}
69316932
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+
69327105static int hclge_set_mac_mtu (struct hclge_dev * hdev , int new_mps )
69337106{
69347107 struct hclge_config_max_frm_size_cmd * req ;
0 commit comments