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

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
......@@ -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 {
......
......@@ -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)
......
......@@ -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 */
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -938,6 +938,8 @@ struct hclge_dev {
u16 priv_umv_size;
/* unicast mac vlan space shared by PF and its VFs */
u16 share_umv_size;
/* multicast mac address number used by PF and its VFs */
u16 used_mc_mac_num;
DECLARE_KFIFO(mac_tnl_log, struct hclge_mac_tnl_stats,
HCLGE_MAC_TNL_LOG_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment