Commit d97994b7 authored by Ke Chen's avatar Ke Chen Committed by Wang Wensheng
Browse files

net: hns3: intercept invalid MAC address setting in ROH

driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5WKYW



-----------------------------------------------------------------------

In ROH mode, MAC address is related to the EID. If an
invalid MAC address is set, the mapping between MAC and
EID cannot be ensured, and communication may be abnormal.
Therefore, firmware verification is required to intercept
invalid MAC address set by user.

Signed-off-by: default avatarYufeng Mo <moyufeng@huawei.com>
Signed-off-by: default avatarKe Chen <chenke54@huawei.com>
Reviewed-by: default avatarGang Zhang <gang.zhang@huawei.com>
Reviewed-by: default avatarYefeng Yan <yanyefeng@huawei.com>
Reviewed-by: default avatarJingchao Dai <daijingchao1@huawei.com>
Reviewed-by: default avatarJian Shen <shenjian15@huawei.com>
parent 9f736afb
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -410,6 +410,13 @@ struct hclge_mac_vlan_tbl_entry_cmd {
	u8      rsv2[6];
};

struct hclge_check_mac_addr_cmd {
	u8	response;
	u8	mac_addr[ETH_ALEN];
	u8	vf_id;
	u8	rsv[16];
};

#define HCLGE_UMV_SPC_ALC_B	0
struct hclge_umv_spc_alc_cmd {
	u8 allocate;
+35 −0
Original line number Diff line number Diff line
@@ -9059,6 +9059,35 @@ static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
	return return_status;
}

int hclge_check_mac_addr_valid(struct hclge_dev *hdev, u8 vf,
			       const u8 *mac_addr)
{
	char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN];
	struct hclge_check_mac_addr_cmd *req;
	struct hclge_desc desc;
	int ret;

	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_ADDR_CHECK, false);
	req = (struct hclge_check_mac_addr_cmd *)desc.data;
	ether_addr_copy(req->mac_addr, mac_addr);
	req->vf_id = vf;
	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
	if (ret) {
		dev_err(&hdev->pdev->dev, "failed to check function %u mac addr valid, ret = %d\n",
			vf, ret);
		return ret;
	}

	if (req->response) {
		hnae3_format_mac_addr(format_mac_addr, mac_addr);
		dev_err(&hdev->pdev->dev, "invalid function %u mac addr: %s\n",
			vf, format_mac_addr);
		return -EINVAL;
	}

	return 0;
}

static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
			    u8 *mac_addr)
{
@@ -9213,6 +9242,12 @@ static int hclge_set_mac_addr(struct hnae3_handle *handle, void *p,
		return -EINVAL;
	}

	if (hnae3_check_roh_mac_type(handle)) {
		ret = hclge_check_mac_addr_valid(hdev, 0, new_addr);
		if (ret)
			return ret;
	}

	ret = hclge_pause_addr_cfg(hdev, new_addr);
	if (ret) {
		dev_err(&hdev->pdev->dev,
+2 −0
Original line number Diff line number Diff line
@@ -1124,6 +1124,8 @@ void hclge_report_hw_error(struct hclge_dev *hdev,
			   enum hnae3_hw_error_type type);
void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len);
int hclge_check_mac_addr_valid(struct hclge_dev *hdev, u8 vf,
			       const u8 *mac_addr);
int hclge_push_vf_link_status(struct hclge_vport *vport);
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
int hclge_mac_update_stats(struct hclge_dev *hdev);