net/ethtool/mm.c

Source file repositories/reference/linux-study-clean/net/ethtool/mm.c

File Facts

System
Linux kernel
Corpus path
net/ethtool/mm.c
Extension
.c
Size
16806 bytes
Lines
563
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mm_req_info {
	struct ethnl_req_info		base;
};

struct mm_reply_data {
	struct ethnl_reply_data		base;
	struct ethtool_mm_state		state;
	struct ethtool_mm_stats		stats;
};

#define MM_REPDATA(__reply_base) \
	container_of(__reply_base, struct mm_reply_data, base)

#define ETHTOOL_MM_STAT_CNT \
	(__ETHTOOL_A_MM_STAT_CNT - (ETHTOOL_A_MM_STAT_PAD + 1))

const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1] = {
	[ETHTOOL_A_MM_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy_stats),
};

static int mm_prepare_data(const struct ethnl_req_info *req_base,
			   struct ethnl_reply_data *reply_base,
			   const struct genl_info *info)
{
	struct mm_reply_data *data = MM_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	const struct ethtool_ops *ops;
	int ret;

	ops = dev->ethtool_ops;

	if (!ops->get_mm)
		return -EOPNOTSUPP;

	ethtool_stats_init((u64 *)&data->stats,
			   sizeof(data->stats) / sizeof(u64));

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;

	ret = ops->get_mm(dev, &data->state);
	if (ret)
		goto out_complete;

	if (ops->get_mm_stats && (req_base->flags & ETHTOOL_FLAG_STATS))
		ops->get_mm_stats(dev, &data->stats);

out_complete:
	ethnl_ops_complete(dev);

	return ret;
}

static int mm_reply_size(const struct ethnl_req_info *req_base,
			 const struct ethnl_reply_data *reply_base)
{
	int len = 0;

	len += nla_total_size(sizeof(u8)); /* _MM_PMAC_ENABLED */
	len += nla_total_size(sizeof(u8)); /* _MM_TX_ENABLED */
	len += nla_total_size(sizeof(u8)); /* _MM_TX_ACTIVE */
	len += nla_total_size(sizeof(u8)); /* _MM_VERIFY_ENABLED */
	len += nla_total_size(sizeof(u8)); /* _MM_VERIFY_STATUS */
	len += nla_total_size(sizeof(u32)); /* _MM_VERIFY_TIME */
	len += nla_total_size(sizeof(u32)); /* _MM_MAX_VERIFY_TIME */
	len += nla_total_size(sizeof(u32)); /* _MM_TX_MIN_FRAG_SIZE */
	len += nla_total_size(sizeof(u32)); /* _MM_RX_MIN_FRAG_SIZE */

	if (req_base->flags & ETHTOOL_FLAG_STATS)
		len += nla_total_size(0) + /* _MM_STATS */
		       nla_total_size_64bit(sizeof(u64)) * ETHTOOL_MM_STAT_CNT;

	return len;
}

static int mm_put_stat(struct sk_buff *skb, u64 val, u16 attrtype)
{
	if (val == ETHTOOL_STAT_NOT_SET)
		return 0;
	if (nla_put_u64_64bit(skb, attrtype, val, ETHTOOL_A_MM_STAT_PAD))
		return -EMSGSIZE;
	return 0;
}

static int mm_put_stats(struct sk_buff *skb,
			const struct ethtool_mm_stats *stats)
{
	struct nlattr *nest;

Annotation

Implementation Notes