Merge branch 'net-hns3-add-some-fixes-for-net'

Guangbin Huang says:

====================
net: hns3: add some fixes for -net

This series adds some fixes for the HNS3 ethernet driver.
====================

Link: https://lore.kernel.org/r/20220324125450.56417-1-huangguangbin2@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2022-03-25 16:37:49 -07:00
commit 371d1ccf43
3 changed files with 102 additions and 32 deletions

View File

@ -1872,6 +1872,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
vport->vf_info.link_state = IFLA_VF_LINK_STATE_AUTO;
vport->mps = HCLGE_MAC_DEFAULT_FRAME;
vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
vport->port_base_vlan_cfg.tbl_sta = true;
vport->rxvlan_cfg.rx_vlan_offload_en = true;
vport->req_vlan_fltr_en = true;
INIT_LIST_HEAD(&vport->vlan_list);
@ -8438,12 +8439,11 @@ int hclge_rm_uc_addr_common(struct hclge_vport *vport,
hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0);
hclge_prepare_mac_addr(&req, addr, false);
ret = hclge_remove_mac_vlan_tbl(vport, &req);
if (!ret) {
if (!ret || ret == -ENOENT) {
mutex_lock(&hdev->vport_lock);
hclge_update_umv_space(vport, true);
mutex_unlock(&hdev->vport_lock);
} else if (ret == -ENOENT) {
ret = 0;
return 0;
}
return ret;
@ -8993,11 +8993,16 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
ether_addr_copy(vport->vf_info.mac, mac_addr);
/* there is a timewindow for PF to know VF unalive, it may
* cause send mailbox fail, but it doesn't matter, VF will
* query it when reinit.
*/
if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
dev_info(&hdev->pdev->dev,
"MAC of VF %d has been set to %s, and it will be reinitialized!\n",
vf, format_mac_addr);
return hclge_inform_reset_assert_to_vf(vport);
(void)hclge_inform_reset_assert_to_vf(vport);
return 0;
}
dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %s\n",
@ -9818,19 +9823,28 @@ static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
bool writen_to_tbl)
{
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node)
if (vlan->vlan_id == vlan_id)
mutex_lock(&hdev->vport_lock);
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
if (vlan->vlan_id == vlan_id) {
mutex_unlock(&hdev->vport_lock);
return;
}
}
vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
if (!vlan)
if (!vlan) {
mutex_unlock(&hdev->vport_lock);
return;
}
vlan->hd_tbl_status = writen_to_tbl;
vlan->vlan_id = vlan_id;
list_add_tail(&vlan->node, &vport->vlan_list);
mutex_unlock(&hdev->vport_lock);
}
static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
@ -9839,6 +9853,8 @@ static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
struct hclge_dev *hdev = vport->back;
int ret;
mutex_lock(&hdev->vport_lock);
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
if (!vlan->hd_tbl_status) {
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
@ -9848,12 +9864,16 @@ static int hclge_add_vport_all_vlan_table(struct hclge_vport *vport)
dev_err(&hdev->pdev->dev,
"restore vport vlan list failed, ret=%d\n",
ret);
mutex_unlock(&hdev->vport_lock);
return ret;
}
}
vlan->hd_tbl_status = true;
}
mutex_unlock(&hdev->vport_lock);
return 0;
}
@ -9863,6 +9883,8 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
mutex_lock(&hdev->vport_lock);
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
if (vlan->vlan_id == vlan_id) {
if (is_write_tbl && vlan->hd_tbl_status)
@ -9877,6 +9899,8 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
break;
}
}
mutex_unlock(&hdev->vport_lock);
}
void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
@ -9884,6 +9908,8 @@ void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
mutex_lock(&hdev->vport_lock);
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
if (vlan->hd_tbl_status)
hclge_set_vlan_filter_hw(hdev,
@ -9899,6 +9925,7 @@ void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list)
}
}
clear_bit(vport->vport_id, hdev->vf_vlan_full);
mutex_unlock(&hdev->vport_lock);
}
void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
@ -9907,6 +9934,8 @@ void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
struct hclge_vport *vport;
int i;
mutex_lock(&hdev->vport_lock);
for (i = 0; i < hdev->num_alloc_vport; i++) {
vport = &hdev->vport[i];
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
@ -9914,37 +9943,61 @@ void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
kfree(vlan);
}
}
mutex_unlock(&hdev->vport_lock);
}
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev)
{
struct hclge_vlan_info *vlan_info;
struct hclge_vport *vport;
u16 vlan_proto;
u16 vlan_id;
u16 state;
int vf_id;
int ret;
/* PF should restore all vfs port base vlan */
for (vf_id = 0; vf_id < hdev->num_alloc_vfs; vf_id++) {
vport = &hdev->vport[vf_id + HCLGE_VF_VPORT_START_NUM];
vlan_info = vport->port_base_vlan_cfg.tbl_sta ?
&vport->port_base_vlan_cfg.vlan_info :
&vport->port_base_vlan_cfg.old_vlan_info;
vlan_id = vlan_info->vlan_tag;
vlan_proto = vlan_info->vlan_proto;
state = vport->port_base_vlan_cfg.state;
if (state != HNAE3_PORT_BASE_VLAN_DISABLE) {
clear_bit(vport->vport_id, hdev->vlan_table[vlan_id]);
ret = hclge_set_vlan_filter_hw(hdev, htons(vlan_proto),
vport->vport_id,
vlan_id, false);
vport->port_base_vlan_cfg.tbl_sta = ret == 0;
}
}
}
void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
{
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
u16 vlan_proto;
u16 vlan_id;
u16 state;
int ret;
vlan_proto = vport->port_base_vlan_cfg.vlan_info.vlan_proto;
vlan_id = vport->port_base_vlan_cfg.vlan_info.vlan_tag;
state = vport->port_base_vlan_cfg.state;
mutex_lock(&hdev->vport_lock);
if (state != HNAE3_PORT_BASE_VLAN_DISABLE) {
clear_bit(vport->vport_id, hdev->vlan_table[vlan_id]);
hclge_set_vlan_filter_hw(hdev, htons(vlan_proto),
vport->vport_id, vlan_id,
false);
return;
if (vport->port_base_vlan_cfg.state == HNAE3_PORT_BASE_VLAN_DISABLE) {
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
vport->vport_id,
vlan->vlan_id, false);
if (ret)
break;
vlan->hd_tbl_status = true;
}
}
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q),
vport->vport_id,
vlan->vlan_id, false);
if (ret)
break;
vlan->hd_tbl_status = true;
}
mutex_unlock(&hdev->vport_lock);
}
/* For global reset and imp reset, hardware will clear the mac table,
@ -9984,6 +10037,7 @@ static void hclge_restore_hw_table(struct hclge_dev *hdev)
struct hnae3_handle *handle = &vport->nic;
hclge_restore_mac_table_common(vport);
hclge_restore_vport_port_base_vlan_config(hdev);
hclge_restore_vport_vlan_table(vport);
set_bit(HCLGE_STATE_FD_USER_DEF_CHANGED, &hdev->state);
hclge_restore_fd_entries(handle);
@ -10040,6 +10094,8 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
false);
}
vport->port_base_vlan_cfg.tbl_sta = false;
/* force add VLAN 0 */
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, false, 0);
if (ret)
@ -10129,7 +10185,9 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
else
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE;
vport->port_base_vlan_cfg.old_vlan_info = *old_vlan_info;
vport->port_base_vlan_cfg.vlan_info = *vlan_info;
vport->port_base_vlan_cfg.tbl_sta = true;
hclge_set_vport_vlan_fltr_change(vport);
return 0;
@ -10197,14 +10255,17 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
return ret;
}
/* for DEVICE_VERSION_V3, vf doesn't need to know about the port based
/* there is a timewindow for PF to know VF unalive, it may
* cause send mailbox fail, but it doesn't matter, VF will
* query it when reinit.
* for DEVICE_VERSION_V3, vf doesn't need to know about the port based
* VLAN state.
*/
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
vport->vport_id, state,
&vlan_info);
(void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
vport->vport_id,
state, &vlan_info);
return 0;
}
@ -11838,8 +11899,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
hclge_misc_irq_uninit(hdev);
hclge_devlink_uninit(hdev);
hclge_pci_uninit(hdev);
mutex_destroy(&hdev->vport_lock);
hclge_uninit_vport_vlan_table(hdev);
mutex_destroy(&hdev->vport_lock);
ae_dev->priv = NULL;
}

View File

@ -985,7 +985,9 @@ struct hclge_vlan_info {
struct hclge_port_base_vlan_config {
u16 state;
bool tbl_sta;
struct hclge_vlan_info vlan_info;
struct hclge_vlan_info old_vlan_info;
};
struct hclge_vf_info {
@ -1031,6 +1033,7 @@ struct hclge_vport {
spinlock_t mac_list_lock; /* protect mac address need to add/detele */
struct list_head uc_mac_list; /* Store VF unicast table */
struct list_head mc_mac_list; /* Store VF multicast table */
struct list_head vlan_list; /* Store VF vlan table */
};
@ -1100,6 +1103,7 @@ void hclge_rm_vport_all_mac_table(struct hclge_vport *vport, bool is_del_list,
void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list);
void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev);
void hclge_restore_mac_table_common(struct hclge_vport *vport);
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev);
void hclge_restore_vport_vlan_table(struct hclge_vport *vport);
int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
struct hclge_vlan_info *vlan_info);

View File

@ -2862,6 +2862,11 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev)
return ret;
}
/* get current port based vlan state from PF */
ret = hclgevf_get_port_base_vlan_filter_state(hdev);
if (ret)
return ret;
set_bit(HCLGEVF_STATE_PROMISC_CHANGED, &hdev->state);
hclgevf_init_rxd_adv_layout(hdev);