Commit 8c3f8817 authored by Weibo Zhao's avatar Weibo Zhao Committed by JiangShui
Browse files

hns3 udma: add support of create / destroy JFS

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


CVE: NA

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

This patch add support of create / destroy JFS(jetty for
send). RM(Reliable Mode) mode of JFS can send packet to any
JFR. UM(Unreliable Mode) not support yet.

Signed-off-by: default avatarWeibo Zhao <zhaoweibo3@huawei.com>
parent 364d4bf5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -10,6 +10,6 @@ ccflags-y += -I$(srctree)/drivers/net/ethernet/hisilicon/hns3/ \
$(MODULE_NAME)-objs := hns3_udma_hw.o hns3_udma_main.o hns3_udma_cmd.o \
			hns3_udma_hem.o hns3_udma_qp.o hns3_udma_eq.o \
			hns3_udma_db.o hns3_udma_jfc.o hns3_udma_jfr.o \
			hns3_udma_segment.o  hns3_udma_tp.o
			hns3_udma_segment.o  hns3_udma_tp.o hns3_udma_jfs.o

obj-$(CONFIG_UB_UDMA_HNS3) := hns3_udma.o
+9 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#define MAP_INDEX_SHIFT			8
#define UDMA_DWQE_PAGE_SIZE		65536
#define UDMA_JETTY_X_PREFIX_BIT_NUM	2
#define UDMA_JFS_QPN_PREFIX		0x0
#define UDMA_JFR_QPN_PREFIX		0x1
#define UDMA_ADDR_4K_MASK		0xfffUL
#define URMA_SEG_ACCESS_GUARD		(1UL << 5)
@@ -105,6 +106,14 @@ struct udma_create_tp_resp {
	uint8_t			priority;
};

struct udma_create_jfs_ucmd {
	struct udma_create_tp_ucmd create_tp_ucmd;
};

struct udma_create_jfs_resp {
	struct udma_create_tp_resp create_tp_resp;
};

struct udma_create_ctx_resp {
	uint32_t num_comp_vectors;
	uint32_t num_qps_shift;
+166 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Huawei UDMA Linux driver
 * 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 "urma/ubcore_uapi.h"
#include "hns3_udma_abi.h"
#include "hns3_udma_hem.h"
#include "hns3_udma_tp.h"
#include "hns3_udma_jfs.h"

static int init_jfs_cfg(struct udma_dev *dev, struct udma_jfs *jfs,
			const struct ubcore_jfs_cfg *cfg)
{
	if (!cfg->max_sge ||
	    cfg->depth > dev->caps.max_wqes ||
	    cfg->max_sge > dev->caps.max_sq_sg) {
		dev_err(dev->dev, "invalid jfs cfg, depth = %u, sge = %u.\n",
			cfg->depth, cfg->max_sge);
		return -EINVAL;
	}
	memcpy(&jfs->ubcore_jfs.jfs_cfg, cfg, sizeof(struct ubcore_jfs_cfg));
	jfs->tp_mode = cfg->trans_mode;

	return 0;
}

int destroy_jfs_qp(struct udma_dev *dev, struct udma_jfs *jfs)
{
	int ret = 0;

	if (jfs->tp_mode == UBCORE_TP_UM)
		dev_err(dev->dev, "Not support UM mode.\n");

	return ret;
}

static int alloc_jfs_buf(struct udma_dev *udma_dev, struct udma_jfs *jfs,
			 const struct ubcore_jfs_cfg *cfg,
			 struct ubcore_udata *udata)
{
	struct udma_create_jfs_ucmd ucmd = {};
	int ret = 0;

	if (udata) {
		ret = copy_from_user(&ucmd, (void *)udata->udrv_data->in_addr,
				     min(udata->udrv_data->in_len,
					 (uint32_t)sizeof(ucmd)));
		if (ret) {
			dev_err(udma_dev->dev,
				"failed to copy jfs udata, ret = %d.\n", ret);
			return -EFAULT;
		}
	}

	if (cfg->trans_mode == UBCORE_TP_RM) {
		xa_init(&jfs->node_table);
	} else if (cfg->trans_mode == UBCORE_TP_UM) {
		dev_err(udma_dev->dev, "Not Support UM mode.\n");
		return -EINVAL;
	}

	return ret;
}

static int alloc_jfs_id(struct udma_dev *udma_dev, struct udma_jfs *jfs)
{
	struct udma_jfs_table *jfs_table = &udma_dev->jfs_table;
	struct udma_ida *jfs_ida = &jfs_table->jfs_ida;
	int ret;
	int id;

	id = ida_alloc_range(&jfs_ida->ida, jfs_ida->min, jfs_ida->max,
			     GFP_KERNEL);
	if (id < 0) {
		dev_err(udma_dev->dev, "failed to alloc jfs_id(%d).\n", id);
		return id;
	}
	jfs->jfs_id = (uint32_t)id;
	jfs->ubcore_jfs.id = jfs->jfs_id;

	ret = xa_err(xa_store(&jfs_table->xa, jfs->jfs_id, jfs, GFP_KERNEL));
	if (ret) {
		dev_err(udma_dev->dev, "failed to store JFS, ret = %d.\n", ret);
		ida_free(&jfs_ida->ida, id);
	}

	return ret;
}

static void free_jfs_id(struct udma_dev *udma_dev, struct udma_jfs *jfs)
{
	struct udma_jfs_table *jfs_table = &udma_dev->jfs_table;
	struct udma_ida *jfs_ida = &jfs_table->jfs_ida;

	xa_erase(&jfs_table->xa, jfs->jfs_id);
	ida_free(&jfs_ida->ida, (int)jfs->jfs_id);
}

struct ubcore_jfs *udma_create_jfs(struct ubcore_device *dev, const struct ubcore_jfs_cfg *cfg,
			      struct ubcore_udata *udata)
{
	struct udma_dev *udma_dev = to_udma_dev(dev);
	struct udma_jfs *jfs;
	int ret;

	jfs = kcalloc(1, sizeof(struct udma_jfs), GFP_KERNEL);
	if (!jfs)
		return NULL;

	ret = init_jfs_cfg(udma_dev, jfs, cfg);
	if (ret)
		goto err_init_cfg;

	ret = alloc_jfs_id(udma_dev, jfs);
	if (ret)
		goto err_alloc_jfs_id;

	init_jetty_x_qpn_bitmap(udma_dev, &jfs->qpn_map,
				udma_dev->caps.num_jfs_shift,
				UDMA_JFS_QPN_PREFIX, jfs->jfs_id);

	ret = alloc_jfs_buf(udma_dev, jfs, cfg, udata);
	if (ret) {
		dev_err(udma_dev->dev, "alloc jfs buf failed.\n");
		goto err_alloc_jfs_buf;
	}

	return &jfs->ubcore_jfs;

err_alloc_jfs_buf:
	clean_jetty_x_qpn_bitmap(&jfs->qpn_map);
	free_jfs_id(udma_dev, jfs);
err_alloc_jfs_id:
err_init_cfg:
	kfree(jfs);

	return NULL;
}

int udma_destroy_jfs(struct ubcore_jfs *jfs)
{
	struct udma_jfs *udma_jfs;
	struct udma_dev *udma_dev;
	int ret;

	udma_jfs = to_udma_jfs(jfs);
	udma_dev = to_udma_dev(jfs->ub_dev);

	ret = destroy_jfs_qp(udma_dev, udma_jfs);
	clean_jetty_x_qpn_bitmap(&udma_jfs->qpn_map);
	free_jfs_id(udma_dev, udma_jfs);
	kfree(udma_jfs);

	return ret;
}
+41 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Huawei UDMA Linux driver
 * 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 _UDMA_JFS_H
#define _UDMA_JFS_H

#include "hns3_udma_qp.h"
struct udma_jfs {
	struct ubcore_jfs		ubcore_jfs;
	uint32_t		jfs_id;
	enum ubcore_transport_mode	tp_mode;
	union {
		struct xarray	node_table;
		struct udma_qp	um_qp;
	};
	struct udma_qpn_bitmap qpn_map;
};

static inline struct udma_jfs *to_udma_jfs(struct ubcore_jfs *jfs)
{
	return container_of(jfs, struct udma_jfs, ubcore_jfs);
}

struct ubcore_jfs *udma_create_jfs(struct ubcore_device *dev,
			      const struct ubcore_jfs_cfg *cfg,
			      struct ubcore_udata *udata);
int udma_destroy_jfs(struct ubcore_jfs *ubcore_jfs);

#endif /* _UDMA_JFS_H */
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "hns3_udma_hem.h"
#include "hns3_udma_jfr.h"
#include "hns3_udma_jfc.h"
#include "hns3_udma_jfs.h"
#include "hns3_udma_segment.h"
#include "hns3_udma_cmd.h"
static int udma_set_eid(struct ubcore_device *dev, union ubcore_eid eid)
@@ -320,6 +321,8 @@ static struct ubcore_ops g_udma_dev_ops = {
	.create_jfc = udma_create_jfc,
	.modify_jfc = udma_modify_jfc,
	.destroy_jfc = udma_destroy_jfc,
	.create_jfs = udma_create_jfs,
	.destroy_jfs = udma_destroy_jfs,
	.create_jfr = udma_create_jfr,
	.modify_jfr = udma_modify_jfr,
	.destroy_jfr = udma_destroy_jfr,