Unverified Commit 84e0aed3 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!12547 [OLK-5.10] drivers: update yunsilicon drivers to version rel_2406_rc16.2

Merge Pull Request from: @OGman 
 
1. Support DCBX(Data Center Bridging Exchange Protocol) feature
2. Support netdim(Network Dynamic Interrupt Moderation) feature 
 
Link:https://gitee.com/openeuler/kernel/pulls/12547

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 74e85e88 7a77845c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ endif
obj-$(CONFIG_INFINIBAND_XSC) += xsc_ib.o

xsc_ib-y := main.o xsc_rdma_ctrl.o cq.o qp.o mem.o mr.o ah.o \
		counters.o devx.o global.o private_dev.o ib_umem_ex.o\
		counters.o devx.o private_dev.o ib_umem_ex.o\
		rtt.o xsc_ib_sysfs.o

xsc_ib-$(CONFIG_XSC_PEER_SUPPORT) += peer_mem.o
+2 −2
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>

#include "xsc_ib.h"
#include "user.h"

@@ -68,8 +67,10 @@ static struct ib_ah *create_ib_ah(struct xsc_ib_dev *dev,

	if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
		gid_type = ah_attr->grh.sgid_attr->gid_type;

		memcpy(ah->av.rmac, ah_attr->roce.dmac,
		       sizeof(ah_attr->roce.dmac));

		ah->av.udp_sport = xsc_ah_get_udp_sport(dev, ah_attr);
		ah->av.stat_rate_sl |= (rdma_ah_get_sl(ah_attr) & 0x7) << 1;
		if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
@@ -105,7 +106,6 @@ xsc_ib_create_ah_def()
			return RET_VALUE(-EINVAL);

		resp.response_length = min_resp_len;

		memcpy(resp.dmac, ah_attr->roce.dmac, ETH_ALEN);
		err = ib_copy_to_udata(udata, &resp, resp.response_length);
		if (err)
+319 −145
Original line number Diff line number Diff line
@@ -4,7 +4,8 @@
 * All rights reserved.
 */

#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include "common/xsc_core.h"
#include "common/xsc_hsi.h"
#include "common/driver.h"
@@ -16,77 +17,134 @@
#define COUNTERS_NAMES_FILE_NAME   "counters_names"
#define COUNTERS_VALUE_FILE_NAME   "counters_value"
#define COUNTERS_ATTER_GROUP_NAME  "counters"
#define GLOBAL_COUNTERS_GROUP_NAME "global_counters"
#define GLOBAL_COUNTERS_FILE_NAME  "counters"

static const struct counter_desc hw_stats_desc[] = {
static const struct counter_desc hw_rdma_stats_pf_desc[] = {
	/*by mac port*/
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  np_cnp_sent) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rp_cnp_handled) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  np_ecn_marked_roce_packets) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rp_cnp_ignored) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  tx_pause) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_pause) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_fcs_errors) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_discards) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_tx_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_tx_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_rx_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_rx_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  np_cnp_sent) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rp_cnp_handled) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  np_ecn_marked_roce_packets) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rp_cnp_ignored) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  read_rsp_out_of_seq) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  implied_nak_seq_err) },
	/*by function*/
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  out_of_sequence) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  packet_seq_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  out_of_buffer) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rnr_nak_retry_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  local_ack_timeout_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_read_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_write_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  duplicate_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_payload_bytes) },
	/*by global*/
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_loopback_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_loopback_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  out_of_sequence) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  packet_seq_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  out_of_buffer) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rnr_nak_retry_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  local_ack_timeout_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rx_read_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rx_write_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  duplicate_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_tx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_tx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_rx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_rx_payload_bytes) },
	/*global*/
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_loopback_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_pf,  rdma_loopback_bytes) },
};

static const struct counter_desc vf_hw_stats_desc[] = {
static const struct counter_desc hw_rdma_stats_vf_desc[] = {
	/*by function*/
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  out_of_sequence) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  packet_seq_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  out_of_buffer) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rnr_nak_retry_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  local_ack_timeout_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_read_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rx_write_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  duplicate_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_tx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats,  rdma_rx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rdma_tx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rdma_tx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rdma_rx_pkts_func) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rdma_rx_payload_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  out_of_sequence) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  packet_seq_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  out_of_buffer) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rnr_nak_retry_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  local_ack_timeout_err) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rx_read_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  rx_write_requests) },
	{ XSC_DECLARE_STAT(struct xsc_hw_stats_rdma_vf,  duplicate_requests) },
};

static const struct counter_desc hw_global_rdma_stats_desc[] = {
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  rdma_loopback_pkts) },
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  rdma_loopback_bytes) },
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  rx_icrc_encapsulated) },
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  req_cqe_error) },
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  resp_cqe_error) },
	{ XSC_DECLARE_STAT(struct xsc_hw_global_stats_rdma,  cqe_msg_code_error) },
};

static int get_hw_stats_rdma(struct xsc_core_device *dev, struct xsc_hw_stats_rdma *stats_rdma)
{
	int i = 0;
	int ret;
	int inlen;
	struct xsc_lag *lag;
	struct xsc_hw_stats_mbox_in *in;
	struct xsc_hw_stats_rdma_mbox_out out;
	struct xsc_core_device *xdev_tmp;

	memset(stats_rdma, 0, sizeof(*stats_rdma));

	if (!dev)
		return -1;

	inlen = sizeof(struct xsc_hw_stats_mbox_in) + XSC_MAX_PORTS;
	in = kzalloc(inlen, GFP_KERNEL);
	if (!in)
		return -ENOMEM;

	xsc_board_lag_lock(dev);
	if (xsc_lag_is_roce(dev)) {
		lag = xsc_get_lag(dev);
		in->lag_member_num = lag->xsc_member_cnt;
		list_for_each_entry(xdev_tmp, &lag->slave_list, slave_node)
			in->member_port[i++] = xdev_tmp->mac_port;
		in->is_lag = 1;
	} else {
		in->is_lag = 0;
		in->mac_port = dev->mac_port;
	}
	xsc_board_lag_unlock(dev);

	in->hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_HW_STATS_RDMA);
	memset(&out, 0, sizeof(out));
	ret = xsc_cmd_exec(dev, (void *)in, inlen, (void *)&out, sizeof(out));
	if (ret || out.hdr.status) {
		kfree(in);
		return -1;
	}

	memcpy(stats_rdma, &out.hw_stats, sizeof(*stats_rdma));
	kfree(in);
	return 0;
}

static ssize_t counters_names_show(struct kobject *kobjs,
				   struct attribute *attr, char *buf)
{
	int i;
	int desc_size;
	ssize_t count = 0;
	struct xsc_counters_attribute *xsc_counters_name_attr;
	const struct counter_desc *desc;
	struct xsc_counters_attribute *xsc_counters_name_attr;

	xsc_counters_name_attr = container_of(attr,
					      struct xsc_counters_attribute,
					      attr);

	if (!xsc_counters_name_attr->dev ||
	    !xsc_counters_name_attr->desc ||
	    xsc_counters_name_attr->desc_size == 0)
		return 0;

	for (i = 0; i < xsc_counters_name_attr->desc_size; ++i) {
		desc = xsc_counters_name_attr->desc + i;
		count += sprintf(&buf[count], "%s\n", desc->format);
	if (is_support_hw_pf_stats(xsc_counters_name_attr->dev)) {
		desc = &hw_rdma_stats_pf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_pf_desc);
	} else {
		desc = &hw_rdma_stats_vf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_vf_desc);
	}

	for (i = 0; i < desc_size; ++i)
		count += sprintf(&buf[count], "%s\n", desc[i].format);

	return count;
}

@@ -94,64 +152,40 @@ static ssize_t counters_show(struct kobject *kobjs,
			     struct attribute *attr, char *buf)
{
	int i;
	ssize_t count = 0;
	struct xsc_counters_attribute *xsc_counters_attr;
	struct xsc_hw_stats_mbox_in *in;
	struct xsc_hw_stats_mbox_out out;
	struct xsc_core_device *dev;
	int ret;
	u64 counter;
	u8 *stats;
	u64 value;
	int desc_size;
	ssize_t count = 0;
	const struct counter_desc *desc;
	int inlen;
	struct xsc_lag *ldev;
	struct xsc_hw_stats_rdma stats_rdma;
	struct xsc_counters_attribute *xsc_counters_attr;

	xsc_counters_attr = container_of(attr,
					 struct xsc_counters_attribute,
					 attr);

	if (!xsc_counters_attr->dev ||
	    !xsc_counters_attr->desc ||
		xsc_counters_attr->desc_size == 0)
		return 0;

	dev = xsc_counters_attr->dev;
	ldev = xsc_lag_dev_get(dev);
	if (ldev && __xsc_lag_is_roce(ldev))
		inlen = sizeof(struct xsc_hw_stats_mbox_in) + XSC_MAX_PORTS;
	else
		inlen = sizeof(struct xsc_hw_stats_mbox_in);

	in = kzalloc(inlen, GFP_KERNEL);
	if (!in)
	ret = get_hw_stats_rdma(xsc_counters_attr->dev, &stats_rdma);
	if (ret || is_support_hw_pf_stats(xsc_counters_attr->dev) != stats_rdma.is_pf)
		return 0;

	memset(&out, 0, sizeof(out));
	in->hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_HW_STATS);

	if (ldev && __xsc_lag_is_roce(ldev)) {
		in->is_lag = 1;
		in->lag_member_num = XSC_MAX_PORTS;
		for (i = 0; i < XSC_MAX_PORTS; i++)
			in->member_port[i] = ldev->pf[i].xdev->mac_port;
	if (is_support_hw_pf_stats(xsc_counters_attr->dev)) {
		desc = &hw_rdma_stats_pf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_pf_desc);
		stats = (u8 *)&stats_rdma.stats.pf_stats;
	} else {
		in->is_lag = 0;
		in->mac_port = dev->mac_port;
	}
	ret = xsc_cmd_exec(dev, (void *)in, inlen, (void *)&out, sizeof(out));
	if (ret || out.hdr.status) {
		kfree(in);
		return 0;
		desc = &hw_rdma_stats_vf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_vf_desc);
		stats = (u8 *)&stats_rdma.stats.vf_stats;
	}

	for (i = 0 ; i < xsc_counters_attr->desc_size; ++i) {
		desc = xsc_counters_attr->desc + i;
		counter = *(u64 *)((char *)&out.hw_stats + desc->offset);
		counter = be64_to_cpu(counter);
	for (i = 0 ; i < desc_size; i++) {
		value = *(u64 *)(stats + desc[i].offset);
		value = be64_to_cpu(value);
		count += sprintf(&buf[count], "%-26s    %-20llu\n",
				desc->format, counter);
				desc[i].format, value);
	}

	kfree(in);
	return count;
}

@@ -161,57 +195,64 @@ static ssize_t counters_value_read(struct file *file,
				   char *buf, loff_t loff, size_t size)
{
	int i;
	struct xsc_counters_bin_attribute *xsc_counters_bin_attr;
	u64 *tmp_value;
	struct xsc_hw_stats_mbox_in in;
	struct xsc_hw_stats_mbox_out out;
	struct xsc_core_device *dev;
	int ret;
	u8 *stats;
	int bin_size;
	int desc_size;
	u64 *tmp_value;
	struct xsc_core_device *xdev;
	const struct counter_desc *desc;
	struct xsc_hw_stats_rdma stats_rdma;
	struct xsc_counters_bin_attribute *xsc_counters_bin_attr;

	xsc_counters_bin_attr = container_of(&bin_attr->attr,
					     struct xsc_counters_bin_attribute,
					     attr);

	if (!xsc_counters_bin_attr->dev ||
	    !xsc_counters_bin_attr->desc ||
	    xsc_counters_bin_attr->desc_size == 0 ||
	    xsc_counters_bin_attr->size == 0)
	if (xsc_counters_bin_attr->size > size || xsc_counters_bin_attr->size == 0)
		return 0;

	dev = xsc_counters_bin_attr->dev;
	memset(&in, 0, sizeof(in));
	memset(&out, 0, sizeof(out));
	in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_HW_STATS);
	in.mac_port = dev->mac_port;
	ret = xsc_cmd_exec(dev, (void *)&in, sizeof(in), (void *)&out, sizeof(out));
	if (ret || out.hdr.status)
	xdev = (struct xsc_core_device *)xsc_counters_bin_attr->private;
	ret = get_hw_stats_rdma(xdev, &stats_rdma);
	if (ret || is_support_hw_pf_stats(xdev) != stats_rdma.is_pf)
		return 0;

	tmp_value = kmalloc(xsc_counters_bin_attr->size, GFP_KERNEL);
	if (is_support_hw_pf_stats(xdev)) {
		desc = &hw_rdma_stats_pf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_pf_desc);
		stats = (u8 *)&stats_rdma.stats.pf_stats;
	} else {
		desc = &hw_rdma_stats_vf_desc[0];
		desc_size = ARRAY_SIZE(hw_rdma_stats_vf_desc);
		stats = (u8 *)&stats_rdma.stats.vf_stats;
	}

	bin_size = desc_size * sizeof(u64);
	if (xsc_counters_bin_attr->size < bin_size)
		return 0;

	tmp_value = kzalloc(xsc_counters_bin_attr->size, GFP_KERNEL);
	if (!tmp_value)
		return 0;

	for (i = 0; i < xsc_counters_bin_attr->desc_size; ++i) {
		desc = xsc_counters_bin_attr->desc + i;
		tmp_value[i] = *(u64 *)((char *)&out.hw_stats + desc->offset);
	for (i = 0; i < desc_size; i++) {
		tmp_value[i] = *(u64 *)(stats + desc[i].offset);
		tmp_value[i] = be64_to_cpu(tmp_value[i]);
	}

	memcpy(buf, tmp_value, xsc_counters_bin_attr->size);
	kfree(tmp_value);

	kfree(tmp_value);
	return xsc_counters_bin_attr->size;
}

int xsc_counters_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
static int counters_sysfs_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
{
	struct xsc_counters_attribute *xsc_counters_name, *xsc_counters;
	struct xsc_counters_bin_attribute *xsc_counters_bin;
	struct attribute_group *counters_attr_g;
	struct bin_attribute **counters_bin_attrs;
	struct attribute **counters_attrs;
	int id, is_pf;
	int ret = -ENOMEM;

	xsc_counters_name = kzalloc(sizeof(*xsc_counters_name), GFP_KERNEL);
@@ -226,11 +267,6 @@ int xsc_counters_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
	if (!xsc_counters_bin)
		goto err_xsc_counters_bin;

	id = dev->mac_port;

	is_pf = xsc_core_is_pf(dev);
	xsc_core_dbg(dev, "get xscale id = %d, is_pf = %d.\n", id, is_pf);

	counters_bin_attrs = kzalloc(sizeof(*counters_bin_attrs) * 2, GFP_KERNEL);
	if (!counters_bin_attrs)
		goto err_counters_bin_attrs;
@@ -247,38 +283,20 @@ int xsc_counters_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
	xsc_counters_name->attr.name = COUNTERS_NAMES_FILE_NAME;
	xsc_counters_name->attr.mode = 0444;
	xsc_counters_name->show = counters_names_show;
	xsc_counters_name->dev = dev;

	sysfs_attr_init(&xsc_counters->attr);
	xsc_counters->attr.name = COUNTERS_FILE_NAME;
	xsc_counters->attr.mode = 0444;
	xsc_counters->show = counters_show;
	xsc_counters->id = id;
	xsc_counters->dev = dev;

	sysfs_attr_init(&xsc_counters_bin->attr);
	xsc_counters_bin->attr.name = COUNTERS_VALUE_FILE_NAME;
	xsc_counters_bin->attr.mode = 0444;
	xsc_counters_bin->read = counters_value_read;
	xsc_counters_bin->id = id;
	xsc_counters_bin->dev = dev;

	if (is_pf) {
		xsc_counters_name->desc = &hw_stats_desc[0];
		xsc_counters->desc = &hw_stats_desc[0];
		xsc_counters_bin->desc = &hw_stats_desc[0];
		xsc_counters_name->desc_size = ARRAY_SIZE(hw_stats_desc);
		xsc_counters->desc_size = ARRAY_SIZE(hw_stats_desc);
		xsc_counters_bin->desc_size = ARRAY_SIZE(hw_stats_desc);
		xsc_counters_bin->size = xsc_counters_bin->desc_size * sizeof(u64);
	} else {
		xsc_counters_name->desc = &vf_hw_stats_desc[0];
		xsc_counters->desc = &vf_hw_stats_desc[0];
		xsc_counters_bin->desc = &vf_hw_stats_desc[0];
		xsc_counters_name->desc_size = ARRAY_SIZE(vf_hw_stats_desc);
		xsc_counters->desc_size = ARRAY_SIZE(vf_hw_stats_desc);
		xsc_counters_bin->desc_size = ARRAY_SIZE(vf_hw_stats_desc);
		xsc_counters_bin->size = xsc_counters_bin->desc_size * sizeof(u64);
	}
	xsc_counters_bin->private = dev;
	xsc_counters_bin->size = sizeof(struct xsc_hw_stats_rdma);

	counters_bin_attrs[0] = (struct bin_attribute *)xsc_counters_bin;
	counters_attrs[0] = (struct attribute *)xsc_counters_name;
@@ -323,7 +341,7 @@ int xsc_counters_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
	return ret;
}

void xsc_counters_fini(struct ib_device *ib_dev, struct xsc_core_device *dev)
static void counters_sysfs_fini(struct ib_device *ib_dev, struct xsc_core_device *dev)
{
	struct xsc_counters_attribute *xsc_counters_name, *xsc_counters;
	struct xsc_counters_bin_attribute *xsc_counters_bin;
@@ -359,7 +377,163 @@ void xsc_counters_fini(struct ib_device *ib_dev, struct xsc_core_device *dev)

	kfree(xsc_counters);
	xsc_counters = NULL;
}

static ssize_t global_cnt_attr_show(struct kobject *kobj,
				    struct attribute *attr, char *buf)
{
	struct xsc_global_cnt_attributes *a =
		container_of(attr, struct xsc_global_cnt_attributes, attr);
	struct xsc_global_cnt_interface *g =
		container_of(kobj, struct xsc_global_cnt_interface, kobj);

	if (!a->show)
		return -EIO;

	return a->show(g, a, buf);
}

static ssize_t global_cnt_attr_store(struct kobject *kobj,
				     struct attribute *attr,
				     const char *buf, size_t size)
{
	struct xsc_global_cnt_attributes *a =
		container_of(attr, struct xsc_global_cnt_attributes, attr);
	struct xsc_global_cnt_interface *g =
		container_of(kobj, struct xsc_global_cnt_interface, kobj);

	if (!a->store)
		return -EIO;

	return a->store(g, a, buf, size);
}

static ssize_t global_counters_show(struct xsc_global_cnt_interface *g,
				    struct xsc_global_cnt_attributes *a, char *buf)
{
	int i;
	int ret;
	u8 *stats;
	u64 value;
	int desc_size;
	ssize_t count = 0;
	const struct counter_desc *desc;
	struct xsc_hw_global_stats_mbox_in in;
	struct xsc_hw_global_stats_mbox_out out;

	memset(&in, 0, sizeof(in));
	memset(&out, 0, sizeof(out));
	in.hdr.opcode = cpu_to_be16(XSC_CMD_OP_QUERY_HW_GLOBAL_STATS);
	ret = xsc_cmd_exec(g->xdev, (void *)&in, sizeof(in),
			   (void *)&out, sizeof(out));
	if (ret || out.hdr.status)
		return 0;

	desc = &hw_global_rdma_stats_desc[0];
	desc_size = ARRAY_SIZE(hw_global_rdma_stats_desc);
	stats = (u8 *)&out.hw_stats;

	for (i = 0 ; i < desc_size; i++) {
		value = *(u64 *)(stats + desc[i].offset);
		value = be64_to_cpu(value);
		count += sprintf(&buf[count], "%-26s    %-20llu\n",
				desc[i].format, value);
	}

	return count;
}

static ssize_t global_counters_store(struct xsc_global_cnt_interface *g,
				     struct xsc_global_cnt_attributes *a,
				     const char *buf, size_t count)
{
	return -EOPNOTSUPP;
}

#define GLOBAL_CNT_ATTR(_name) struct xsc_global_cnt_attributes xsc_global_cnt_attr_##_name = \
	__ATTR(_name, 0444, global_##_name##_show, global_##_name##_store)

GLOBAL_CNT_ATTR(counters);

	xsc_core_dbg(dev, "ok\n");
static const struct sysfs_ops global_cnt_sysfs_ops = {
	.show = global_cnt_attr_show,
	.store = global_cnt_attr_store,
};

static struct attribute *global_cnt_attrs[] = {
	&xsc_global_cnt_attr_counters.attr,
	NULL
};

ATTRIBUTE_GROUPS(global_cnt);

static struct kobj_type global_cnt_ktype = {
	.sysfs_ops     = &global_cnt_sysfs_ops,
	.default_groups = global_cnt_groups,
};

static struct xsc_global_cnt_interface *g_global_cnt_interface;

static int global_cnt_sysfs_init(struct ib_device *ib_dev, struct xsc_core_device *xdev)
{
	struct xsc_global_cnt_interface *tmp;
	int err;

	if (!xdev || !xsc_core_is_pf(xdev) || xdev->pf_id != 0)
		return 0;

	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	err = kobject_init_and_add(&tmp->kobj, &global_cnt_ktype,
				   &ib_dev->dev.kobj, GLOBAL_COUNTERS_GROUP_NAME);
	if (err)
		goto error_return;

	g_global_cnt_interface = tmp;
	tmp->xdev = xdev;
	return 0;

error_return:
	kobject_put(&tmp->kobj);
	kfree(tmp);
	return err;
}

static void global_cnt_sysfs_fini(struct xsc_core_device *xdev)
{
	if (!g_global_cnt_interface || !xdev || !xsc_core_is_pf(xdev) || xdev->pf_id != 0)
		return;

	kobject_put(&g_global_cnt_interface->kobj);
	kfree(g_global_cnt_interface);
	g_global_cnt_interface = NULL;
}

int xsc_counters_init(struct ib_device *ib_dev, struct xsc_core_device *dev)
{
	int ret;

	ret = counters_sysfs_init(ib_dev, dev);
	if (ret)
		goto error_return;

	ret = global_cnt_sysfs_init(ib_dev, dev);
	if (ret)
		goto error_global_cnt;

	return 0;

error_global_cnt:
	counters_sysfs_fini(ib_dev, dev);
error_return:
	return ret;
}

void xsc_counters_fini(struct ib_device *ib_dev, struct xsc_core_device *dev)
{
	counters_sysfs_fini(ib_dev, dev);
	global_cnt_sysfs_fini(dev);
}
+20 −31
Original line number Diff line number Diff line
@@ -22,42 +22,31 @@ struct xsc_counters_attribute {
	ssize_t (*store)(struct kobject *kobj,
			 struct attribute *attr, const char *buf,
			 size_t count);
	int     id;
	struct xsc_core_device *dev;
	const struct counter_desc *desc;
	int desc_size;
};

struct xsc_counters_bin_attribute {
	struct attribute	attr;
	ssize_t (*read)(struct file *file,
			struct kobject *kobj,
			struct bin_attribute *bin_attr,
			char *buf, loff_t off, size_t size);
	ssize_t (*write)(struct file *file,
			 struct kobject *kobj,
			 struct bin_attribute *bin_attr,
			 char *buf, loff_t off, size_t size);
	int (*mmap)(struct file *file,
		    struct kobject *kobj,
		    struct bin_attribute *attr,
		    struct vm_area_struct *vma);
	int    id;
	struct xsc_core_device *dev;
	const struct counter_desc *desc;
	int desc_size;
	size_t			size;
	void			*private;
	ssize_t (*read)(struct file *f, struct kobject *k, struct bin_attribute *bin_attr,
			char *buf, loff_t l, size_t s);
	ssize_t (*write)(struct file *f, struct kobject *k, struct bin_attribute *bin_attr,
			 char *buf, loff_t l, size_t s);
	int (*mmap)(struct file *f, struct kobject *k, struct bin_attribute *bin_attr,
		    struct vm_area_struct *vma);
};

ssize_t counters_vf_names_show(struct kobject *kobjs,
			       struct attribute *attr, char *buf);

ssize_t counters_vf_value_read(struct file *file,
			       struct kobject *kob,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t loff, size_t size);

ssize_t counters_vf_show(struct kobject *kobjs,
			 struct attribute *attr, char *buf);
struct xsc_global_cnt_interface {
	struct xsc_core_device  *xdev;
	struct kobject		kobj;
};

#endif
struct xsc_global_cnt_attributes {
	struct attribute attr;
	ssize_t (*show)(struct xsc_global_cnt_interface *g, struct xsc_global_cnt_attributes *a,
			char *buf);
	ssize_t (*store)(struct xsc_global_cnt_interface *g, struct xsc_global_cnt_attributes *a,
			 const char *buf, size_t count);
};
#endif /* __COUNTERS_H__ */
+9 −32

File changed.

Preview size limit exceeded, changes collapsed.

Loading