Commit f9c29387 authored by Haibin Lu's avatar Haibin Lu Committed by Fengyan
Browse files

UNIC: add support for querying and configuring the function guid

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


CVE: NA

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

In UB mode, there is no MAC address. Therefore, each function requires a
guid as the identity ID, and each function needs to be configured with a
guid during initialization. This patch supports the initialization and
configuration of the function guid. The guid is unique and comes from
imp or random.

Signed-off-by: default avatarFengyan Mu <mufengyan@hisilicon.com>
Signed-off-by: default avatarHaibin Lu <luhaibin10@hisilicon.com>
Signed-off-by: default avatarHaiqing Fang <fanghaiqing@huawei.com>
Signed-off-by: default avatarJunxin Chen <chenjunxin1@huawei.com>
parent 17bd48f8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o
hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o  hns3vf/hclgevf_devlink.o hns3vf/hclgevf_regs.o \
		hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o \
		hns3vf/hclgevf_udma.o
hclgevf-$(CONFIG_HNS3_UBL) += hns3_common/hclge_comm_unic_addr.o hns3vf/hclgevf_unic_guid.o

obj-$(CONFIG_HNS3_HCLGE) += hclge.o
hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hclge_sysfs.o hns3pf/hclge_regs.o \
@@ -31,4 +32,5 @@ hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hc
		hns3pf/hclge_udma.o
hclge-objs += hns3pf/hclge_ext.o

hclge-$(CONFIG_HNS3_UBL) += hns3_common/hclge_comm_unic_addr.o hns3pf/hclge_unic_guid.o
hclge-$(CONFIG_HNS3_DCB) += hns3pf/hclge_dcb.o
+3 −0
Original line number Diff line number Diff line
@@ -427,6 +427,7 @@ struct hnae3_dev_specs {
	u16 mc_mac_size;
	u32 mac_stats_num;
	u8 tnl_num;
	u16 guid_tbl_space;
};

struct hnae3_client_ops {
@@ -826,6 +827,8 @@ struct hnae3_ae_ops {
		       struct ethtool_wolinfo *wol);
	int (*priv_ops)(struct hnae3_handle *handle, int opcode,
			void *data, size_t length);
	int (*get_func_guid)(struct hnae3_handle *handle, u8 *guid);
	int (*set_func_guid)(struct hnae3_handle *handle, u8 *guid);
};

struct hnae3_dcb_ops {
+4 −0
Original line number Diff line number Diff line
@@ -310,6 +310,10 @@ enum hclge_opcode_type {

	/* Query link diagnosis info command */
	HCLGE_OPC_QUERY_LINK_DIAGNOSIS	= 0x702A,

	/* UB commands */
	HCLGE_OPC_COMM_GET_FUNC_GUID	= 0xA001,
	HCLGE_OPC_COMM_CFG_FUNC_GUID	= 0xA122,
};

enum hclge_comm_cmd_return_status {
+112 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) 2023-2023 Hisilicon Limited.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 */

#include "hclge_comm_unic_addr.h"

static void
hclge_comm_unic_func_guid_cmd_prepare(u8 *guid,
				      struct hclge_comm_func_guid_cmd *req)
{
	req->entry_vld = HCLGE_COMM_FUNC_GUID_ENTRY_VALID_EN;
	memcpy(req->guid, guid, UBL_ALEN);
}

int hclge_comm_unic_set_func_guid(struct hclge_comm_hw *hw, u8 *guid)
{
	struct hclge_comm_func_guid_cmd *req;
	struct hclge_desc desc;
	int ret;

	req = (struct hclge_comm_func_guid_cmd *)desc.data;

	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMM_CFG_FUNC_GUID,
					false);
	hclge_comm_unic_func_guid_cmd_prepare(guid, req);

	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret)
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to set guid for cmd_send, ret = %d\n", ret);

	return ret;
}

void hclge_comm_unic_rm_func_guid(struct hclge_comm_hw *hw)
{
	struct hclge_comm_func_guid_cmd *req;
	struct hclge_desc desc;
	int ret;

	req = (struct hclge_comm_func_guid_cmd *)desc.data;

	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMM_CFG_FUNC_GUID,
					false);
	req->entry_vld = 0;
	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret)
		dev_warn(&hw->cmq.csq.pdev->dev,
			 "failed to delete func guid for cmd_send, ret = %d.\n",
			 ret);
}

static bool hclge_comm_unic_is_valid_func_guid(u8 *guid)
{
	u8 invalid_guid_zero[UBL_ALEN] = {0};
	u8 invalid_guid_all_one[UBL_ALEN];

	memset(invalid_guid_all_one, 0xff, UBL_ALEN);
	if (!(memcmp(guid, invalid_guid_all_one, HCLGE_COMM_MGUID_PREFIX_LEN) &&
	      memcmp(guid, invalid_guid_zero, UBL_ALEN)))
		return false;

	return true;
}

static void hclge_comm_unic_guid_le_to_net_trans(u8 *src_guid, u8 *dest_guid)
{
	int i;

	for (i = 0; i < UBL_ALEN; i++)
		dest_guid[i] = src_guid[UBL_ALEN - i - 1];
}

int hclge_comm_unic_get_func_guid(struct hclge_comm_hw *hw, u8 *guid)
{
	struct hclge_desc desc;
	bool is_random = false;
	int ret;

	hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_COMM_GET_FUNC_GUID,
					true);
	ret = hclge_comm_cmd_send(hw, &desc, 1);
	if (ret) {
		dev_err(&hw->cmq.csq.pdev->dev,
			"failed to get function GUID, ret = %d\n", ret);
		return ret;
	}

	hclge_comm_unic_guid_le_to_net_trans((u8 *)desc.data, guid);
	while (unlikely(!hclge_comm_unic_is_valid_func_guid(guid))) {
		get_random_bytes(guid, UBL_ALEN);
		is_random = true;
	}

	if (unlikely(is_random))
		dev_warn(&hw->cmq.csq.pdev->dev,
			 "using random GUID %02x:%02x:...:%02x:%02x\n",
			 guid[0], guid[1],
			 guid[UBL_ALEN - 2], guid[UBL_ALEN - 1]);

	return 0;
}
+43 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2023-2023 Hisilicon Limited.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 */

#ifndef __HCLGE_COMM_UNIC_ADDR_H
#define __HCLGE_COMM_UNIC_ADDR_H

#include <linux/types.h>

#include "ubl.h"
#include "hclge_comm_cmd.h"

#define HCLGE_COMM_MGUID_PREFIX_LEN		14

#define HCLGE_COMM_FUNC_GUID_ENTRY_VALID_EN	0x01

struct hclge_comm_func_guid_cmd {
	u8 entry_vld	 : 1;
	u8 lookup_enable : 1;
	u8 rsv0		 : 6;
	u8 rsv1;
	__le16 rsv2;
	/* use big endian here */
	u8 guid[UBL_ALEN];
	__le16 hit_info;
	__le16 rsv3;
};

int hclge_comm_unic_set_func_guid(struct hclge_comm_hw *hw, u8 *guid);
int hclge_comm_unic_get_func_guid(struct hclge_comm_hw *hw, u8 *guid);
void hclge_comm_unic_rm_func_guid(struct hclge_comm_hw *hw);

#endif
Loading