Commit 992594ce authored by Weibo Zhao's avatar Weibo Zhao Committed by JiangShui
Browse files

hns3 udma: support of set eid

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


CVE: NA

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

This patch add support of setting EID(Entity ID). EID will be
set in gmv(GUID-MAC-VALN) table.

Signed-off-by: default avatarWeibo Zhao <zhaoweibo3@huawei.com>
parent 8f14e4c3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -430,6 +430,7 @@ struct udma_hw {
	int (*clear_hem)(struct udma_dev *udma_dev,
			 struct udma_hem_table *table, int obj,
			 int step_idx);
	int (*set_eid)(struct udma_dev *udma_dev, union ubcore_eid eid);
	int (*init_eq)(struct udma_dev *udma_dev);
	void (*cleanup_eq)(struct udma_dev *udma_dev);
};
+83 −0
Original line number Diff line number Diff line
@@ -1006,6 +1006,88 @@ static void udma_cmq_exit(struct udma_dev *udma_dev)
	udma_free_cmq_desc(udma_dev, &priv->cmq.csq);
}

static int config_gmv_table(struct udma_dev *udma_dev, union ubcore_eid eid)
{
	uint32_t sgid_type = SGID_TYPE_IPV4;
	struct udma_cfg_gmv_tb_a *tb_a;
	struct udma_cfg_gmv_tb_b *tb_b;
	struct udma_cmq_desc desc[2];
	uint16_t smac_l;

	tb_a = (struct udma_cfg_gmv_tb_a *)desc[0].data;
	tb_b = (struct udma_cfg_gmv_tb_b *)desc[1].data;

	udma_cmq_setup_basic_desc(&desc[0], UDMA_OPC_CFG_GMV_TBL, false);
	desc[0].flag |= cpu_to_le16(UDMA_CMD_FLAG_NEXT);
	udma_cmq_setup_basic_desc(&desc[1], UDMA_OPC_CFG_GMV_TBL, false);

	smac_l =
		*(uint16_t *)&udma_dev->uboe.netdevs[0]->dev_addr[SMAC_L_SHIFT];
	udma_set_field(tb_a->vf_type_vlan_smac, CFG_GMV_TB_VF_SMAC_L_M,
		       CFG_GMV_TB_VF_SMAC_L_S, smac_l);
	tb_a->vf_smac_h =
		*(uint32_t *)&udma_dev->uboe.netdevs[0]->dev_addr[SMAC_H_SHIFT];
	udma_set_field(tb_a->vf_type_vlan_smac, CFG_GMV_TB_VF_SGID_TYPE_M,
		       CFG_GMV_TB_VF_SGID_TYPE_S, sgid_type);
	memcpy(tb_a, &eid, sizeof(eid));
	udma_set_bit(tb_a->vf_type_vlan_smac, CFG_GMV_TB_VF_PATTERN_S, 0);
	tb_b->vf_id = 0;

	return udma_cmq_send(udma_dev, desc, CFG_GMV_TBL_CMD_NUM);
}

static void udma_fill_eid_addr(struct udma_eid_tbl_entry_cmd *eid_entry,
			       union ubcore_eid eid)
{
	int i;

	/* big endian */
	for (i = 0; i < UDMA_EID_SIZE_IDX; i++)
		eid_entry->eid_addr[i] = (*(((uint32_t *)eid.raw) + i));
}

static int set_eid_table(struct udma_dev *udma_dev, union ubcore_eid eid)
{
	struct udma_eid_tbl_entry_cmd *eid_entry;
	struct udma_cmq_desc desc = {};
	uint8_t resp_code;
	int ret;

	eid_entry = (struct udma_eid_tbl_entry_cmd *)desc.data;
	udma_cmq_setup_basic_desc(&desc, UDMA_OPC_DEID_TBL_ADD, false);
	udma_set_field(eid_entry->eid_ad, UDMA_EID_TB_VFID_M,
		       UDMA_EID_TB_VFID_S, 0);
	udma_fill_eid_addr(eid_entry, eid);
	ret = udma_cmq_send(udma_dev, &desc, 1);
	if (ret) {
		dev_err(udma_dev->dev, "Send set eid table cmd failed.\n");
		return ret;
	}

	resp_code = (le32_to_cpu(desc.data[0])) & 0xff;
	if (resp_code == UDMA_EID_TB_RES_SUCCESS ||
	    resp_code == UDMA_EID_TB_RES_MODIFY)
		return 0;
	else
		return -EIO;
}

static int udma_hw_set_eid(struct udma_dev *udma_dev, union ubcore_eid eid)
{
	int ret;

	ret = config_gmv_table(udma_dev, eid);
	if (ret) {
		dev_err(udma_dev->dev, "Set EID to GMV table failed.\n");
		return ret;
	}

	ret = set_eid_table(udma_dev, eid);
	if (ret)
		dev_err(udma_dev->dev, "Set EID table failed.\n");

	return ret;
}

static void config_llm_table(struct udma_buf *data_buf, void *cfg_buf)
{
@@ -1456,6 +1538,7 @@ static const struct udma_hw udma_hw = {
	.poll_mbox_done = udma_poll_mbox_done,
	.set_hem = udma_set_hem,
	.clear_hem = udma_clear_hem,
	.set_eid = udma_hw_set_eid,
	.init_eq = udma_init_eq_table,
	.cleanup_eq = udma_cleanup_eq_table,
};
+56 −0
Original line number Diff line number Diff line
@@ -202,6 +202,8 @@ enum udma_opcode_type {
	UDMA_OPC_EXT_CFG				= 0x8512,
	UDMA_SWITCH_PARAMETER_CFG			= 0x1033,
	UDMA_QUERY_OOR_CAPS				= 0xA002,
	UDMA_OPC_DEID_TBL_ADD				= 0xA110,
	UDMA_OPC_CFG_GMV_TBL				= 0xA140,
};

#define UDMA_QUERY_PF_CAPS_CMD_NUM 5
@@ -400,4 +402,58 @@ enum {

#define UDMA_INT_NAME_LEN		32

struct udma_cfg_gmv_tb_a {
	uint32_t vf_sgid_l;
	uint32_t vf_sgid_ml;
	uint32_t vf_sgid_mh;
	uint32_t vf_sgid_h;
	uint32_t vf_type_vlan_smac;
	uint32_t vf_smac_h;
};

struct udma_cfg_gmv_tb_b {
	uint32_t	vf_upi;
	uint32_t	vf_eid_high;
	uint32_t	table_idx_rsv;
	uint32_t	vf_id;
	uint32_t	resv[2];
};

#define SGID_TYPE_IPV4 1

#define CFG_GMV_TB_VF_SGID_TYPE_S 0
#define CFG_GMV_TB_VF_SMAC_L_S 16
#define CFG_GMV_TB_VF_PATTERN_S 3
#define CFG_GMV_TB_VF_SGID_TYPE_M GENMASK(1, 0)
#define CFG_GMV_TB_VF_SMAC_L_M GENMASK(31, 16)

#define SGID_H_SHIFT 12
#define SMAC_L_SHIFT 0
#define SMAC_H_SHIFT 2

#define CFG_GMV_TBL_CMD_NUM 2

struct udma_eid_tbl_entry_cmd {
	uint8_t		resp_code;
	uint8_t		rsv1[3];
	uint32_t	eid_addr[4];
	uint16_t	eid_ad;
	uint8_t		rsv2[2];
};

#define UDMA_EID_TB_VFID_S 0
#define UDMA_EID_TB_VFID_M GENMASK(7, 0)
#define UDMA_EID_TB_RES_SUCCESS 0
#define UDMA_EID_TB_RES_MODIFY 2

union udma_eid {
	union ubcore_eid		ubcore_eid;
	struct {
		uint32_t	eid_l;
		uint32_t	eid_ml;
		uint32_t	eid_mh;
		uint32_t	eid_h;
	} bit32_data;
};

#endif /* _UDMA_HW_H */
+12 −0
Original line number Diff line number Diff line
@@ -21,6 +21,17 @@
#include "hns3_udma_hem.h"
#include "hns3_udma_jfc.h"
#include "hns3_udma_cmd.h"
static int udma_set_eid(struct ubcore_device *dev, union ubcore_eid eid)
{
	struct udma_dev *udma_dev = to_udma_dev(dev);
	uint8_t port = 0;

	if (port >= udma_dev->caps.num_ports)
		return -EINVAL;

	return udma_dev->hw->set_eid(udma_dev, eid);
}

static int udma_uar_alloc(struct udma_dev *udma_dev, struct udma_uar *uar)
{
	struct udma_ida *uar_ida = &udma_dev->uar_ida;
@@ -163,6 +174,7 @@ static int udma_mmap(struct ubcore_ucontext *uctx, struct vm_area_struct *vma)
static struct ubcore_ops g_udma_dev_ops = {
	.owner = THIS_MODULE,
	.abi_version = 1,
	.set_eid = udma_set_eid,
	.alloc_ucontext = udma_alloc_ucontext,
	.free_ucontext = udma_free_ucontext,
	.mmap = udma_mmap,