net/ethtool/coalesce.c

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

File Facts

System
Linux kernel
Corpus path
net/ethtool/coalesce.c
Extension
.c
Size
24198 bytes
Lines
669
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source 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 coalesce_req_info {
	struct ethnl_req_info		base;
};

struct coalesce_reply_data {
	struct ethnl_reply_data		base;
	struct ethtool_coalesce		coalesce;
	struct kernel_ethtool_coalesce	kernel_coalesce;
	u32				supported_params;
};

#define COALESCE_REPDATA(__reply_base) \
	container_of(__reply_base, struct coalesce_reply_data, base)

#define __SUPPORTED_OFFSET ETHTOOL_A_COALESCE_RX_USECS
static u32 attr_to_mask(unsigned int attr_type)
{
	return BIT(attr_type - __SUPPORTED_OFFSET);
}

/* build time check that indices in ethtool_ops::supported_coalesce_params
 * match corresponding attribute types with an offset
 */
#define __CHECK_SUPPORTED_OFFSET(x) \
	static_assert((ETHTOOL_ ## x) == \
		      BIT((ETHTOOL_A_ ## x) - __SUPPORTED_OFFSET))
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_USECS);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_MAX_FRAMES);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_USECS_IRQ);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_MAX_FRAMES_IRQ);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_IRQ);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_IRQ);
__CHECK_SUPPORTED_OFFSET(COALESCE_STATS_BLOCK_USECS);
__CHECK_SUPPORTED_OFFSET(COALESCE_USE_ADAPTIVE_RX);
__CHECK_SUPPORTED_OFFSET(COALESCE_USE_ADAPTIVE_TX);
__CHECK_SUPPORTED_OFFSET(COALESCE_PKT_RATE_LOW);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_USECS_LOW);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_MAX_FRAMES_LOW);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_LOW);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_LOW);
__CHECK_SUPPORTED_OFFSET(COALESCE_PKT_RATE_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_USECS_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_RX_MAX_FRAMES_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_HIGH);
__CHECK_SUPPORTED_OFFSET(COALESCE_RATE_SAMPLE_INTERVAL);

const struct nla_policy ethnl_coalesce_get_policy[] = {
	[ETHTOOL_A_COALESCE_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy),
};

static int coalesce_prepare_data(const struct ethnl_req_info *req_base,
				 struct ethnl_reply_data *reply_base,
				 const struct genl_info *info)
{
	struct coalesce_reply_data *data = COALESCE_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	int ret;

	if (!dev->ethtool_ops->get_coalesce)
		return -EOPNOTSUPP;
	data->supported_params = dev->ethtool_ops->supported_coalesce_params;
	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;
	ret = dev->ethtool_ops->get_coalesce(dev, &data->coalesce,
					     &data->kernel_coalesce,
					     info->extack);
	ethnl_ops_complete(dev);

	return ret;
}

static int coalesce_reply_size(const struct ethnl_req_info *req_base,
			       const struct ethnl_reply_data *reply_base)
{
	int modersz = nla_total_size(0) + /* _PROFILE_IRQ_MODERATION, nest */
		      nla_total_size(sizeof(u32)) + /* _IRQ_MODERATION_USEC */
		      nla_total_size(sizeof(u32)) + /* _IRQ_MODERATION_PKTS */
		      nla_total_size(sizeof(u32));  /* _IRQ_MODERATION_COMPS */

	int total_modersz = nla_total_size(0) +  /* _{R,T}X_PROFILE, nest */
			modersz * NET_DIM_PARAMS_NUM_PROFILES;

	return nla_total_size(sizeof(u32)) +	/* _RX_USECS */
	       nla_total_size(sizeof(u32)) +	/* _RX_MAX_FRAMES */
	       nla_total_size(sizeof(u32)) +	/* _RX_USECS_IRQ */

Annotation

Implementation Notes