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:
commit
371d1ccf43
|
@ -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,29 +9943,50 @@ 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;
|
||||
|
||||
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;
|
||||
}
|
||||
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,
|
||||
|
@ -9945,6 +9995,9 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue