Skip to content

Commit

Permalink
Merge branch 'net-hns3-add-some-fixes-for-net'
Browse files Browse the repository at this point in the history
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/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Mar 25, 2022
2 parents afec498 + 190cd8a commit 371d1cc
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 31 deletions.
123 changes: 92 additions & 31 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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)
Expand All @@ -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),
Expand All @@ -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;
}

Expand All @@ -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)
Expand All @@ -9877,13 +9899,17 @@ 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)
{
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,
Expand All @@ -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)
Expand All @@ -9907,44 +9934,70 @@ 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) {
list_del(&vlan->node);
kfree(vlan);
}
}

mutex_unlock(&hdev->vport_lock);
}

void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
void hclge_restore_vport_port_base_vlan_config(struct hclge_dev *hdev)
{
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
struct hclge_vlan_info *vlan_info;
struct hclge_vport *vport;
u16 vlan_proto;
u16 vlan_id;
u16 state;
int vf_id;
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;
/* 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;

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;
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;
}
}
}

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;
void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
{
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back;
int ret;

mutex_lock(&hdev->vport_lock);

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;
}
}

mutex_unlock(&hdev->vport_lock);
}

/* For global reset and imp reset, hardware will clear the mac table,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
};

Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 371d1cc

Please sign in to comment.