Unverified Commit 2afbbaa3 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!7918 [OLK-6.6]drivers: support Yunsilicon's metaScale/metaVisor series NICs

Merge Pull Request from: @OGman 
 
1. Support for metaScale/metaVisor series network cards
2. ethtool feature completion
3. Code optimization 
 
Link:https://gitee.com/openeuler/kernel/pulls/7918

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 547bed38 5b8a867a
Loading
Loading
Loading
Loading
+34 −17
Original line number Diff line number Diff line
@@ -120,12 +120,12 @@ static void *get_cqe(struct xsc_ib_cq *cq, int n)

static void *get_sw_cqe(struct xsc_ib_cq *cq, int n)
{
	struct xsc_cqe64 *cqe64;
	struct xsc_cqe *cqe;

	cqe64 = (struct xsc_cqe64 *)get_cqe(cq, n & cq->ibcq.cqe);
	cqe = (struct xsc_cqe *)get_cqe(cq, n & (cq->ibcq.cqe - 1));

	return ((cqe64->owner & XSC_CQE_OWNER_MASK) ^
		!!(n & (cq->ibcq.cqe + 1))) ? NULL : cqe64;
	return ((cqe->owner & XSC_CQE_OWNER_MASK) ^
		!!(n & cq->ibcq.cqe)) ? NULL : cqe;
}

static inline void handle_good_req(struct ib_wc *wc,
@@ -198,6 +198,7 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq,
	void *recv;
	struct xsc_wqe_data_seg *data_seg;
	struct iphdr *ip4h = NULL;
	struct ipv6hdr *ip6h;
	struct udphdr *udph;
	struct ib_unpacked_eth *eth;
	struct ib_unpacked_vlan *vlan;
@@ -208,6 +209,8 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq,
	unsigned int pading_sz = 0;
	struct xsc_ib_wq *wq;
	int idx;
	u16 eth_type;
	void *l3_start;

	wq = &(*cur_qp)->rq;
	idx = wq->tail & (wq->wqe_cnt - 1);
@@ -221,23 +224,36 @@ static void xsc_handle_rdma_mad_resp_recv(struct xsc_ib_cq *cq,
	grh = (struct ib_grh *)recv;
	if (eth->type == htons(ETH_P_8021Q)) {
		vlan = (struct ib_unpacked_vlan *)(eth + 1);
		ip4h = (struct iphdr *)(vlan + 1);
		eth_type = ntohs(vlan->type);
		l3_start = vlan + 1;

		wc->vlan_id = ntohs(vlan->tag) & 0x0fff;
		wc->sl = (ntohs(vlan->tag) >> 13) & 0x7;
		wc->wc_flags |= IB_WC_WITH_VLAN;
	} else {
		ip4h = (struct iphdr *)(eth + 1);
		eth_type = ntohs(eth->type);
		l3_start = eth + 1;
	}

	if (eth_type == ETH_P_IP) {
		ip4h = (struct iphdr *)l3_start;
		udph = (struct udphdr *)(ip4h + 1);
	} else {
		ip6h = (struct ipv6hdr *)l3_start;
		udph = (struct udphdr *)(ip6h + 1);
	}
	bth = (struct rxe_bth *)(udph + 1);
	deth = (struct rxe_deth *)(bth + 1);
	mad = (struct ib_mad *)(deth + 1);

	memcpy(grh + 1, mad, sizeof(*mad));
	if (eth_type == ETH_P_IP) {
		pading_sz = sizeof(*grh) - sizeof(*ip4h);
		memmove((u8 *)(grh + 1) - sizeof(*ip4h), ip4h, sizeof(*ip4h));
		memset(grh, 0, pading_sz);
	} else {
		memmove(grh, ip6h, sizeof(*ip6h));
	}
	memmove(grh + 1, mad, sizeof(*mad));

	wc->wc_flags |= IB_WC_GRH;

@@ -543,7 +559,7 @@ xsc_ib_create_cq_def()
	int err;
	unsigned int eqn;

	entries = roundup_pow_of_two(entries + 1);
	entries = roundup_pow_of_two(entries);

	xsc_ib_dbg(dev, "entries:%d, vector:%d, max_cqes:%d\n", entries, vector,
		   dev->xdev->caps.max_cqes);
@@ -551,7 +567,7 @@ xsc_ib_create_cq_def()
	if (entries > dev->xdev->caps.max_cqes)
		entries = dev->xdev->caps.max_cqes;
	cq = to_xcq(ibcq);
	cq->ibcq.cqe = entries - 1;
	cq->ibcq.cqe = entries;
	mutex_init(&cq->resize_mutex);
	spin_lock_init(&cq->lock);
	cq->resize_buf = NULL;
@@ -628,7 +644,7 @@ xsc_ib_destroy_cq_def()
	return 0;
}

static int is_equal_rsn(struct xsc_cqe64 *cqe, u32 rsn)
static int is_equal_rsn(struct xsc_cqe *cqe, u32 rsn)
{
	u32 qpn = le32_to_cpu(cqe->qp_id);
	return rsn == qpn;
@@ -636,7 +652,7 @@ static int is_equal_rsn(struct xsc_cqe64 *cqe, u32 rsn)

void __xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 rsn)
{
	struct xsc_cqe64 *cqe, *dest;
	struct xsc_cqe *cqe, *dest;
	u32 prod_index;
	int nfreed = 0;
	u8 owner_bit;
@@ -658,11 +674,12 @@ void __xsc_ib_cq_clean(struct xsc_ib_cq *cq, u32 rsn)
	 * that match our QP by copying older entries on top of them.
	 */
	while ((int)(--prod_index) - (int)cq->xcq.cons_index >= 0) {
		cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
		cqe = (struct xsc_cqe *)get_cqe(cq, prod_index & (cq->ibcq.cqe - 1));
		if (is_equal_rsn(cqe, rsn)) {
			++nfreed;
		} else if (nfreed) {
			dest = get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe);
			dest = (struct xsc_cqe *)get_cqe(cq, (prod_index + nfreed) &
							 (cq->ibcq.cqe - 1));
			owner_bit = dest->owner & XSC_CQE_OWNER_MASK;
			memcpy(dest, cqe, cq->xcq.cqe_sz);
			dest->owner = owner_bit |
+0 −2
Original line number Diff line number Diff line
@@ -33,8 +33,6 @@ struct ib_peer_memory_client {
	struct mutex lock;
	struct list_head   core_ticket_list;
	u64	last_ticket;
	struct kobject *kobj;
	struct attribute_group peer_mem_attr_group;
	struct ib_peer_memory_statistics stats;
};

+6 −0
Original line number Diff line number Diff line
@@ -6,7 +6,9 @@

#include <linux/sched/mm.h>

#ifndef MLX_PEER_SUPPORT
#include "ib_peer_mem.h"
#endif

#include <rdma/ib_verbs.h>
#include "ib_umem_ex.h"
@@ -88,12 +90,16 @@ struct ib_umem_ex *ib_umem_ex(struct ib_umem *umem)
	if (!umem)
		return ERR_PTR(-EINVAL);

#ifndef MLX_PEER_SUPPORT
	ret_umem =  kzalloc(sizeof(*ret_umem), GFP_KERNEL);
	if (!ret_umem)
		return ERR_PTR(-ENOMEM);

	ret_umem->umem = *umem;
	kfree(umem);
#else
	ret_umem = (struct ib_umem_ex *)umem;
#endif
	return ret_umem;
}

+4 −0
Original line number Diff line number Diff line
@@ -15,14 +15,17 @@ struct invalidation_ctx;
// ib umem ex ib_umem add peer memory support
struct ib_umem_ex {
	struct ib_umem umem;
#ifndef MLX_PEER_SUPPORT
	struct ib_peer_memory_client *ib_peer_mem;
	struct invalidation_ctx *invalidation_ctx;
	void *peer_mem_client_context;
#endif
};

// expand ib_umem to ib_umem_ex by reallocate
struct ib_umem_ex *ib_umem_ex(struct ib_umem *umem);

#ifndef MLX_PEER_SUPPORT
typedef void (*umem_invalidate_func_t)(void *invalidation_cookie,
	struct ib_umem_ex *umem_ex, unsigned long addr, size_t size);

@@ -36,6 +39,7 @@ struct invalidation_ctx {
	int peer_invalidated;
	struct completion comp;
};
#endif

struct ib_umem_ex *ib_client_umem_get(struct ib_ucontext *context,
				      unsigned long addr, size_t size, int access,
+77 −17
Original line number Diff line number Diff line
@@ -12,10 +12,13 @@
#include <linux/slab.h>
#include <linux/io-mapping.h>
#include <linux/sched.h>
#include <linux/netdevice.h>
#include <net/bonding.h>
#include "common/xsc_core.h"
#include "common/xsc_hsi.h"
#include "common/xsc_cmd.h"
#include "common/driver.h"
#include "common/xsc_lag.h"

#include <rdma/ib_user_verbs.h>
#include <rdma/ib_smi.h>
@@ -98,6 +101,7 @@ static int xsc_ib_query_device(struct ib_device *ibdev,
		IB_DEVICE_SYS_IMAGE_GUID		|
		IB_DEVICE_RC_RNR_NAK_GEN;
	props->kernel_cap_flags =  IBK_BLOCK_MULTICAST_LOOPBACK;
	props->kernel_cap_flags |= IBK_LOCAL_DMA_LKEY;
	flags = dev->xdev->caps.flags;
	if (flags & XSC_DEV_CAP_FLAG_BAD_PKEY_CNTR)
		props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
@@ -105,7 +109,6 @@ static int xsc_ib_query_device(struct ib_device *ibdev,
		props->device_cap_flags |= IB_DEVICE_BAD_QKEY_CNTR;
	if (flags & XSC_DEV_CAP_FLAG_APM)
		props->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG;
	props->kernel_cap_flags |= IBK_LOCAL_DMA_LKEY;
	if (flags & XSC_DEV_CAP_FLAG_XRC)
		props->device_cap_flags |= IB_DEVICE_XRC;
	props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS;
@@ -113,7 +116,7 @@ static int xsc_ib_query_device(struct ib_device *ibdev,
	props->page_size_cap	   = dev->xdev->caps.min_page_sz;
	props->max_mr_size	   = (1 << dev->xdev->caps.log_max_mtt) * PAGE_SIZE;
	props->max_qp		   = 1 << dev->xdev->caps.log_max_qp;
	props->max_qp_wr	   = dev->xdev->caps.max_wqes;
	props->max_qp_wr	   = (32 * 1024); /* hack for GPFS */
	max_rq_sg = dev->xdev->caps.max_rq_desc_sz / sizeof(struct xsc_wqe_data_seg);
	max_sq_sg = (dev->xdev->caps.max_sq_desc_sz - sizeof(struct xsc_wqe_ctrl_seg_2)) /
		sizeof(struct xsc_wqe_data_seg_2);
@@ -207,6 +210,57 @@ static int xsc_ib_query_device(struct ib_device *ibdev,
	return 0;
}

void xsc_calc_link_info(struct xsc_core_device *xdev,
			struct ib_port_attr *props)
{
	switch (xsc_get_link_speed(xdev)) {
	case MODULE_SPEED_10G:
		props->active_speed = XSC_RDMA_LINK_SPEED_10GB;
		props->active_width = 1;
		break;
	case MODULE_SPEED_25G:
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		props->active_width = 1;
		break;
	case MODULE_SPEED_40G_R4:
		props->active_speed = XSC_RDMA_LINK_SPEED_10GB;
		props->active_width = 2;
		break;
	case MODULE_SPEED_50G_R:
		props->active_speed = XSC_RDMA_LINK_SPEED_50GB;
		props->active_width = 1;
		break;
	case MODULE_SPEED_50G_R2:
		props->active_speed = XSC_RDMA_LINK_SPEED_50GB;
		props->active_width = 1;
		break;
	case MODULE_SPEED_100G_R2:
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		props->active_width = 2;
		break;
	case MODULE_SPEED_100G_R4:
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		props->active_width = 2;
		break;
	case MODULE_SPEED_200G_R4:
		props->active_speed = XSC_RDMA_LINK_SPEED_50GB;
		props->active_width = 2;
		break;
	case MODULE_SPEED_200G_R8:
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		props->active_width = 4;
		break;
	case MODULE_SPEED_400G_R8:
		props->active_speed = XSC_RDMA_LINK_SPEED_50GB;
		props->active_width = 4;
		break;
	default:
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		props->active_width = 1;
		break;
	}
}

static enum rdma_link_layer xsc_ib_port_link_layer(struct ib_device *ibdev, u32 port)
{
	return IB_LINK_LAYER_ETHERNET;
@@ -246,11 +300,7 @@ int xsc_ib_query_port(struct ib_device *ibdev, u32 port,
		props->active_width = 1;
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
	} else {
		if (xsc_get_link_speed(xdev) == XSC_CMD_RESP_LINKSPEED_MODE_100G)
			props->active_width = 2;
		else
			props->active_width = 1;
		props->active_speed = XSC_RDMA_LINK_SPEED_25GB;
		xsc_calc_link_info(xdev, props);
	}

	props->phys_state = netif_carrier_ok(ndev) ? XSC_RDMA_PHY_STATE_LINK_UP :
@@ -455,6 +505,7 @@ xsc_ib_alloc_ucontext_def()

xsc_ib_dealloc_ucontext_def()
{
	return;
}

static int xsc_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
@@ -559,14 +610,27 @@ static void _xsc_get_netdev(struct xsc_ib_dev *dev)

static struct net_device *xsc_get_netdev(struct ib_device *ibdev, u32 port_num)
{
	struct xsc_ib_dev *dev = to_mdev(ibdev);
	struct net_device *netdev = dev->netdev;
	struct xsc_ib_dev *xsc_ib_dev = to_mdev(ibdev);
	struct net_device *dev = xsc_ib_dev->netdev;

	rcu_read_lock();
	if (netdev)
		dev_hold(netdev);
	if (dev) {
		if (xsc_ib_dev->xdev->priv.lag && __xsc_lag_is_active(xsc_ib_dev->xdev->priv.lag)) {
			struct net_device *upper = NULL;

			upper = netdev_master_upper_dev_get_rcu(dev);
			if (upper) {
				struct net_device *active;

				active = bond_option_active_slave_get_rcu(netdev_priv(upper));
				if (active)
					dev = active;
			}
		}
		dev_hold(dev);
	}
	rcu_read_unlock();
	return netdev;
	return dev;
}

void xsc_get_guid(const u8 *dev_addr, u8 *guid)
@@ -741,7 +805,6 @@ static int populate_specs_root(struct xsc_ib_dev *dev)
	const struct uverbs_object_tree_def **trees =
		(const struct uverbs_object_tree_def **)dev->driver_trees;
	size_t num_trees = 0;

	trees[num_trees++] = xsc_ib_get_devx_tree();

	WARN_ON(num_trees >= ARRAY_SIZE(dev->driver_trees));
@@ -809,7 +872,6 @@ static void xsc_ib_dev_setting(struct xsc_ib_dev *dev)
	dev->ib_dev.ops.dereg_mr		= xsc_ib_dereg_mr;
	dev->ib_dev.ops.alloc_mr		= xsc_ib_alloc_mr;
	dev->ib_dev.ops.map_mr_sg		= xsc_ib_map_mr_sg;

	dev->ib_dev.ops.get_port_immutable		= xsc_port_immutable;

	dev->ib_dev.ops INIT_RDMA_OBJ_SIZE(ib_ah, xsc_ib_ah, ibah);
@@ -826,7 +888,6 @@ static int init_one(struct xsc_core_device *xdev,
	int err;

	pr_info_once("%s", xsc_version);

	dev = (struct xsc_ib_dev *)ib_alloc_device(xsc_ib_dev, ib_dev);
	if (!dev)
		return -ENOMEM;
@@ -899,6 +960,7 @@ static int init_one(struct xsc_core_device *xdev,
	if (ib_register_device(&dev->ib_dev, dev->ib_dev.name, dev->xdev->device))
		goto err_rsrc;

	rdma_roce_rescan_device(&dev->ib_dev);
	dev->ib_active = true;
	*m_ibdev = dev;

@@ -949,7 +1011,6 @@ static void *xsc_add(struct xsc_core_device *xpdev)
		return NULL;
	}

	xpdev->rdma_ready = 1;
	return m_ibdev;
}

@@ -957,7 +1018,6 @@ static void xsc_remove(struct xsc_core_device *xpdev, void *context)
{
	pr_err("remove rdma driver\n");
	remove_one(xpdev, context);
	xpdev->rdma_ready = 0;
}

static struct xsc_interface xsc_interface = {
Loading