Commit eb7ae3e3 authored by Yizhen Fan's avatar Yizhen Fan Committed by fanyizhen1995
Browse files

ub: support query stat of ubcore device



driver inclusion
category: feature
bugzilla: NA
CVE: NA

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

Add query device stat function in ubcore,
which support user in user mode to query device statistics
including tx/rx packets, running status of device.

Hw drivers should register their implementation of this api.

Signed-off-by: default avatarGuoxin Qian <qianguoxin@huawei.com>
Signed-off-by: default avatarYizhen Fan <fanyizhen@huawei.com>
parent 0de8eb86
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -40,7 +40,11 @@ struct ubcore_cmd_hdr {
/* only for ubcore device ioctl */
enum ubcore_cmd {
	UBCORE_CMD_SET_UASID = 1,
	UBCORE_CMD_PUT_UASID
	UBCORE_CMD_PUT_UASID,
	UBCORE_CMD_SET_UTP,
	UBCORE_CMD_SHOW_UTP,
	UBCORE_CMD_QUERY_STATS,
	UBCORE_CMD_QUERY_RES
};

struct ubcore_cmd_set_uasid {
@@ -59,6 +63,24 @@ struct ubcore_cmd_put_uasid {
	} in;
};

struct ubcore_cmd_query_stats {
	struct {
		char dev_name[UBCORE_MAX_DEV_NAME];
		uint8_t eid[UBCORE_CMD_EID_SIZE];
		uint32_t tp_type;
		uint32_t type;
		uint32_t key;
	} in;
	struct {
		uint64_t tx_pkt;
		uint64_t rx_pkt;
		uint64_t tx_bytes;
		uint64_t rx_bytes;
		uint64_t tx_pkt_err;
		uint64_t rx_pkt_err;
	} out;
};

/* copy from user_space addr to kernel args */
static inline int ubcore_copy_from_user(void *args, const void *args_addr, unsigned long args_size)
{
+20 −0
Original line number Diff line number Diff line
@@ -153,3 +153,23 @@ int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid)
	return 0;
}
EXPORT_SYMBOL(ubcore_set_eid);

int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key,
		       struct ubcore_stats_val *val)
{
	int ret;

	if (dev == NULL || key == NULL || val == NULL || dev->ops == NULL ||
	    dev->ops->query_stats == NULL) {
		ubcore_log_err("Invalid argument.\n");
		return -EINVAL;
	}

	ret = dev->ops->query_stats(dev, key, val);
	if (ret != 0) {
		ubcore_log_err("Failed to query stats, ret: %d.\n", ret);
		return -EPERM;
	}
	return 0;
}
EXPORT_SYMBOL(ubcore_query_stats);
+45 −0
Original line number Diff line number Diff line
@@ -151,6 +151,49 @@ static int ubcore_cmd_put_uasid(struct ubcore_cmd_hdr *hdr)
	ubcore_log_info("put uasid free success, uasid: %u.\n", arg.in.uasid);
	return 0;
}

static int ubcore_cmd_query_stats(struct ubcore_cmd_hdr *hdr)
{
	enum ubcore_transport_type trans_type;
	struct ubcore_cmd_query_stats arg = { 0 };
	struct ubcore_stats_com_val com_val;
	struct ubcore_stats_key key = { 0 };
	struct ubcore_stats_val val;
	struct ubcore_device *dev;
	union ubcore_eid eid;
	int ret;

	ret = ubcore_copy_from_user(&arg, (void __user *)(uintptr_t)hdr->args_addr,
				    sizeof(struct ubcore_cmd_query_stats));
	if (ret != 0)
		return ret;

	(void)memcpy(eid.raw, arg.in.eid, UBCORE_EID_SIZE);
	trans_type = (enum ubcore_transport_type)arg.in.tp_type;
	dev = ubcore_find_device(&eid, trans_type);
	if (dev == NULL || ubcore_check_dev_name_invalid(dev, arg.in.dev_name)) {
		ubcore_log_err("find dev failed, dev:%s, arg_in: %s.\n",
			       dev == NULL ? "NULL" : dev->dev_name, arg.in.dev_name);
		return -EINVAL;
	}

	key.type = (uint8_t)arg.in.type;
	key.key = arg.in.key;
	val.addr = (uint64_t)&com_val;
	val.len = sizeof(struct ubcore_stats_com_val);

	ret = ubcore_query_stats(dev, &key, &val);
	if (ret != 0) {
		ubcore_put_device(dev);
		return ret;
	}

	ubcore_put_device(dev);
	(void)memcpy(&arg.out, &com_val, sizeof(struct ubcore_stats_com_val));
	return ubcore_copy_to_user((void __user *)(uintptr_t)hdr->args_addr, &arg,
				   sizeof(struct ubcore_cmd_query_stats));
}

static int ubcore_cmd_parse(struct ubcore_cmd_hdr *hdr)
{
	switch (hdr->command) {
@@ -158,6 +201,8 @@ static int ubcore_cmd_parse(struct ubcore_cmd_hdr *hdr)
		return ubcore_cmd_set_uasid(hdr);
	case UBCORE_CMD_PUT_UASID:
		return ubcore_cmd_put_uasid(hdr);
	case UBCORE_CMD_QUERY_STATS:
		return ubcore_cmd_query_stats(hdr);
	default:
		ubcore_log_err("bad ubcore command: %d.\n", (int)hdr->command);
		return -EINVAL;
+43 −0
Original line number Diff line number Diff line
@@ -88,6 +88,40 @@ struct ubcore_net_addr {
	uint8_t mac[UBCORE_MAC_BYTES]; /* available for UBOE */
};

enum ubcore_stats_key_type {
	UBCORE_STATS_KEY_TP = 1,
	UBCORE_STATS_KEY_TPG = 2,
	UBCORE_STATS_KEY_JFS = 3,
	UBCORE_STATS_KEY_JFR = 4,
	UBCORE_STATS_KEY_JETTY = 5,
	UBCORE_STATS_KEY_JETTY_GROUP = 6
};

struct ubcore_stats_key {
	uint8_t type; /* stats type, refer to enum ubcore_stats_key_type */
	uint32_t key; /* key can be tpn/tpgn/jetty_id/token_id/ctx_id/etc */
};

struct ubcore_stats_com_val {
	uint64_t tx_pkt;
	uint64_t rx_pkt;
	uint64_t tx_bytes;
	uint64_t rx_bytes;
	uint64_t tx_pkt_err;
	uint64_t rx_pkt_err;
};

struct ubcore_stats_val {
	uint64_t addr; /* this addr is alloc and free by ubcore,
			* refer to struct ubcore_stats_com_val
			*/

	uint32_t len;	/* [in/out] real length filled when success
			 * to query and buffer length enough;
			 * expected length filled and return failure when buffer length not enough
			 */
};

struct ubcore_device;
struct ubcore_ops {
	struct module *owner; /* kernel driver module */
@@ -114,6 +148,15 @@ struct ubcore_ops {
	 * @return: 0 on success, other value on error
	 */
	int (*unset_net_addr)(struct ubcore_device *dev, const struct ubcore_net_addr *net_addr);
	/**
	 * query_stats. success to query and buffer length is enough
	 * @param[in] dev: the ub device handle;
	 * @param[in] key: type and key value of the ub device to query;
	 * @param[in/out] val: address and buffer length of query results
	 * @return: 0 on success, other value on error
	 */
	int (*query_stats)(const struct ubcore_device *dev, struct ubcore_stats_key *key,
			   struct ubcore_stats_val *val);
};

struct ubcore_device {
+10 −0
Original line number Diff line number Diff line
@@ -33,4 +33,14 @@
 */
int ubcore_set_eid(struct ubcore_device *dev, union ubcore_eid *eid);

/**
 * query stats
 * @param[in] dev: the ubcore_device handle;
 * @param[in] key: stats type and key;
 * @param[in/out] val: addr and len of value
 * @return: 0 on success, other value on error
 */
int ubcore_query_stats(const struct ubcore_device *dev, struct ubcore_stats_key *key,
		       struct ubcore_stats_val *val);

#endif