Commit 371d1ccf authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents afec4980 190cd8a7
Loading
Loading
Loading
Loading
+92 −31
Original line number Diff line number Diff line
@@ -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_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;
	/* 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]);
		hclge_set_vlan_filter_hw(hdev, htons(vlan_proto),
					 vport->vport_id, vlan_id,
					 false);
		return;
			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;
	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,
@@ -9947,6 +9997,9 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport)
		}
	}

	mutex_unlock(&hdev->vport_lock);
}

/* For global reset and imp reset, hardware will clear the mac table,
 * so we change the mac address state from ACTIVE to TO_ADD, then they
 * can be restored in the service task after reset complete. Furtherly,
@@ -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;
}

+4 −0
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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);