Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6075b19 authored by liuzhongzhu's avatar liuzhongzhu Committed by David S. Miller
Browse files

net: hns3: Record VF vlan tables



Record the vlan tables that the VF sends to the chip.
After the VF exception, the PF actively clears the VF to chip config.

Signed-off-by: default avatarliuzhongzhu <liuzhongzhu@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6dd86902
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -1329,6 +1329,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
		vport->back = hdev;
		vport->vport_id = i;
		vport->mps = HCLGE_MAC_DEFAULT_FRAME;
		INIT_LIST_HEAD(&vport->vlan_list);
		INIT_LIST_HEAD(&vport->uc_mac_list);
		INIT_LIST_HEAD(&vport->mc_mac_list);

@@ -6746,6 +6747,84 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
	return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}

void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id)
{
	struct hclge_vport_vlan_cfg *vlan;

	/* vlan 0 is reserved */
	if (!vlan_id)
		return;

	vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
	if (!vlan)
		return;

	vlan->hd_tbl_status = true;
	vlan->vlan_id = vlan_id;

	list_add_tail(&vlan->node, &vport->vlan_list);
}

void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
			       bool is_write_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) {
			if (is_write_tbl && vlan->hd_tbl_status)
				hclge_set_vlan_filter_hw(hdev,
							 htons(ETH_P_8021Q),
							 vport->vport_id,
							 vlan_id, 0,
							 true);

			list_del(&vlan->node);
			kfree(vlan);
			break;
		}
	}
}

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;

	list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) {
		if (vlan->hd_tbl_status)
			hclge_set_vlan_filter_hw(hdev,
						 htons(ETH_P_8021Q),
						 vport->vport_id,
						 vlan->vlan_id, 0,
						 true);

		vlan->hd_tbl_status = false;
		if (is_del_list) {
			list_del(&vlan->node);
			kfree(vlan);
		}
	}
}

void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev)
{
	struct hclge_vport_vlan_cfg *vlan, *tmp;
	struct hclge_vport *vport;
	int i;

	mutex_lock(&hdev->vport_cfg_mutex);
	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_cfg_mutex);
}

int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
@@ -7722,6 +7801,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
	hclge_pci_uninit(hdev);
	mutex_destroy(&hdev->vport_lock);
	hclge_uninit_vport_mac_table(hdev);
	hclge_uninit_vport_vlan_table(hdev);
	mutex_destroy(&hdev->vport_cfg_mutex);
	ae_dev->priv = NULL;
}
+12 −1
Original line number Diff line number Diff line
@@ -643,6 +643,12 @@ enum HCLGE_MAC_ADDR_TYPE {
	HCLGE_MAC_ADDR_MC
};

struct hclge_vport_vlan_cfg {
	struct list_head node;
	int hd_tbl_status;
	u16 vlan_id;
};

/* For each bit of TCAM entry, it uses a pair of 'x' and
 * 'y' to indicate which value to match, like below:
 * ----------------------------------
@@ -854,6 +860,7 @@ struct hclge_vport {

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

void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
@@ -916,5 +923,9 @@ void hclge_rm_vport_mac_table(struct hclge_vport *vport, const u8 *mac_addr,
void hclge_rm_vport_all_mac_table(struct hclge_vport *vport, bool is_del_list,
				  enum HCLGE_MAC_ADDR_TYPE mac_type);
void hclge_uninit_vport_mac_table(struct hclge_dev *hdev);

void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id);
void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id,
			       bool is_write_tbl);
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);
#endif
+4 −0
Original line number Diff line number Diff line
@@ -305,6 +305,9 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
		memcpy(&proto, &mbx_req->msg[5], sizeof(proto));
		status = hclge_set_vlan_filter(handle, cpu_to_be16(proto),
					       vlan, is_kill);
		if (!status)
			is_kill ? hclge_rm_vport_vlan_table(vport, vlan, false)
			: hclge_add_vport_vlan_table(vport, vlan);
	} else if (mbx_req->msg[1] == HCLGE_MBX_VLAN_RX_OFF_CFG) {
		struct hnae3_handle *handle = &vport->nic;
		bool en = mbx_req->msg[2] ? true : false;
@@ -609,6 +612,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
						     HCLGE_MAC_ADDR_UC);
			hclge_rm_vport_all_mac_table(vport, true,
						     HCLGE_MAC_ADDR_MC);
			hclge_rm_vport_all_vlan_table(vport, true);
			mutex_unlock(&hdev->vport_cfg_mutex);
			break;
		default: