Commit 5c56ff48 authored by Guangbin Huang's avatar Guangbin Huang Committed by David S. Miller
Browse files

net: hns3: PF support get multicast MAC address space assigned by firmware



The new firmware supports to divides the whole multicast MAC address space
equally to functions of all PFs, and calculates the space size of each PF
according to its function number.

To support this feature, PF driver adds querying multicast MAC address
space size from firmware and limits used number according to space size.

Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e435a6b5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ enum HNAE3_DEV_CAP_BITS {
	HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
	HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,
	HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B,
	HNAE3_DEV_SUPPORT_MC_MAC_MNG_B,
};

#define hnae3_dev_fd_supported(hdev) \
@@ -151,6 +152,9 @@ enum HNAE3_DEV_CAP_BITS {
#define hnae3_ae_dev_rxd_adv_layout_supported(ae_dev) \
	test_bit(HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, (ae_dev)->caps)

#define hnae3_ae_dev_mc_mac_mng_supported(ae_dev) \
	test_bit(HNAE3_DEV_SUPPORT_MC_MAC_MNG_B, (ae_dev)->caps)

enum HNAE3_PF_CAP_BITS {
	HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0,
};
@@ -342,6 +346,7 @@ struct hnae3_dev_specs {
	u16 max_frm_size;
	u16 max_qset_num;
	u16 umv_size;
	u16 mc_mac_size;
};

struct hnae3_client_ops {
+2 −0
Original line number Diff line number Diff line
@@ -926,6 +926,8 @@ hns3_dbg_dev_specs(struct hnae3_handle *h, char *buf, int len, int *pos)
			  dev_specs->max_qset_num);
	*pos += scnprintf(buf + *pos, len - *pos, "umv size: %u\n",
			  dev_specs->umv_size);
	*pos += scnprintf(buf + *pos, len - *pos, "mc mac size: %u\n",
			  dev_specs->mc_mac_size);
}

static int hns3_dbg_dev_info(struct hnae3_handle *h, char *buf, int len)
+2 −1
Original line number Diff line number Diff line
@@ -1190,7 +1190,8 @@ struct hclge_dev_specs_1_cmd {
	__le16 max_int_gl;
	u8 rsv0[2];
	__le16 umv_size;
	u8 rsv1[14];
	__le16 mc_mac_size;
	u8 rsv1[12];
};

/* mac speed type defined in firmware command */
+3 −0
Original line number Diff line number Diff line
@@ -1968,6 +1968,9 @@ static int hclge_dbg_dump_umv_info(struct hclge_dev *hdev, char *buf, int len)
	}
	mutex_unlock(&hdev->vport_lock);

	pos += scnprintf(buf + pos, len - pos, "used_mc_mac_num  : %u\n",
			 hdev->used_mc_mac_num);

	return 0;
}

+29 −6
Original line number Diff line number Diff line
@@ -1440,6 +1440,7 @@ static void hclge_parse_dev_specs(struct hclge_dev *hdev,
	ae_dev->dev_specs.max_int_gl = le16_to_cpu(req1->max_int_gl);
	ae_dev->dev_specs.max_frm_size = le16_to_cpu(req1->max_frm_size);
	ae_dev->dev_specs.umv_size = le16_to_cpu(req1->umv_size);
	ae_dev->dev_specs.mc_mac_size = le16_to_cpu(req1->mc_mac_size);
}

static void hclge_check_dev_specs(struct hclge_dev *hdev)
@@ -8480,6 +8481,9 @@ static int hclge_init_umv_space(struct hclge_dev *hdev)
	hdev->share_umv_size = hdev->priv_umv_size +
			hdev->max_umv_size % (hdev->num_alloc_vport + 1);

	if (hdev->ae_dev->dev_specs.mc_mac_size)
		set_bit(HNAE3_DEV_SUPPORT_MC_MAC_MNG_B, hdev->ae_dev->caps);

	return 0;
}

@@ -8497,6 +8501,8 @@ static void hclge_reset_umv_space(struct hclge_dev *hdev)
	hdev->share_umv_size = hdev->priv_umv_size +
			hdev->max_umv_size % (hdev->num_alloc_vport + 1);
	mutex_unlock(&hdev->vport_lock);

	hdev->used_mc_mac_num = 0;
}

static bool hclge_is_umv_space_full(struct hclge_vport *vport, bool need_lock)
@@ -8758,6 +8764,7 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
	struct hclge_dev *hdev = vport->back;
	struct hclge_mac_vlan_tbl_entry_cmd req;
	struct hclge_desc desc[3];
	bool is_new_addr = false;
	int status;

	/* mac addr check */
@@ -8771,6 +8778,13 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
	hclge_prepare_mac_addr(&req, addr, true);
	status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true);
	if (status) {
		if (hnae3_ae_dev_mc_mac_mng_supported(hdev->ae_dev) &&
		    hdev->used_mc_mac_num >=
		    hdev->ae_dev->dev_specs.mc_mac_size)
			goto err_no_space;

		is_new_addr = true;

		/* This mac addr do not exist, add new entry for it */
		memset(desc[0].data, 0, sizeof(desc[0].data));
		memset(desc[1].data, 0, sizeof(desc[0].data));
@@ -8780,12 +8794,18 @@ int hclge_add_mc_addr_common(struct hclge_vport *vport,
	if (status)
		return status;
	status = hclge_add_mac_vlan_tbl(vport, &req, desc);
	/* if already overflow, not to print each time */
	if (status == -ENOSPC &&
	    !(vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE))
		dev_err(&hdev->pdev->dev, "mc mac vlan table is full\n");
	if (status == -ENOSPC)
		goto err_no_space;
	else if (!status && is_new_addr)
		hdev->used_mc_mac_num++;

	return status;

err_no_space:
	/* if already overflow, not to print each time */
	if (!(vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE))
		dev_err(&hdev->pdev->dev, "mc mac vlan table is full\n");
	return -ENOSPC;
}

static int hclge_rm_mc_addr(struct hnae3_handle *handle,
@@ -8822,12 +8842,15 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
		if (status)
			return status;

		if (hclge_is_all_function_id_zero(desc))
		if (hclge_is_all_function_id_zero(desc)) {
			/* All the vfid is zero, so need to delete this entry */
			status = hclge_remove_mac_vlan_tbl(vport, &req);
		else
			if (!status)
				hdev->used_mc_mac_num--;
		} else {
			/* Not all the vfid is zero, update the vfid */
			status = hclge_add_mac_vlan_tbl(vport, &req, desc);
		}
	} else if (status == -ENOENT) {
		status = 0;
	}
Loading