net/ethtool/fec.c

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

File Facts

System
Linux kernel
Corpus path
net/ethtool/fec.c
Extension
.c
Size
10073 bytes
Lines
365
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 fec_req_info {
	struct ethnl_req_info		base;
};

struct fec_reply_data {
	struct ethnl_reply_data		base;
	__ETHTOOL_DECLARE_LINK_MODE_MASK(fec_link_modes);
	u32 active_fec;
	u8 fec_auto;
	struct fec_stat_grp {
		u64 stats[1 + ETHTOOL_MAX_LANES];
		u8 cnt;
	} corr, uncorr, corr_bits;
	struct ethtool_fec_hist fec_stat_hist;
};

#define FEC_REPDATA(__reply_base) \
	container_of(__reply_base, struct fec_reply_data, base)

#define ETHTOOL_FEC_MASK	((ETHTOOL_FEC_LLRS << 1) - 1)

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

static void
ethtool_fec_to_link_modes(u32 fec, unsigned long *link_modes, u8 *fec_auto)
{
	if (fec_auto)
		*fec_auto = !!(fec & ETHTOOL_FEC_AUTO);

	if (fec & ETHTOOL_FEC_OFF)
		__set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, link_modes);
	if (fec & ETHTOOL_FEC_RS)
		__set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, link_modes);
	if (fec & ETHTOOL_FEC_BASER)
		__set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, link_modes);
	if (fec & ETHTOOL_FEC_LLRS)
		__set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, link_modes);
}

static int
ethtool_link_modes_to_fecparam(struct ethtool_fecparam *fec,
			       unsigned long *link_modes, u8 fec_auto)
{
	memset(fec, 0, sizeof(*fec));

	if (fec_auto)
		fec->fec |= ETHTOOL_FEC_AUTO;

	if (__test_and_clear_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, link_modes))
		fec->fec |= ETHTOOL_FEC_OFF;
	if (__test_and_clear_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, link_modes))
		fec->fec |= ETHTOOL_FEC_RS;
	if (__test_and_clear_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, link_modes))
		fec->fec |= ETHTOOL_FEC_BASER;
	if (__test_and_clear_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, link_modes))
		fec->fec |= ETHTOOL_FEC_LLRS;

	if (!bitmap_empty(link_modes, __ETHTOOL_LINK_MODE_MASK_NBITS))
		return -EINVAL;

	return 0;
}

static void
fec_stats_recalc(struct fec_stat_grp *grp, struct ethtool_fec_stat *stats)
{
	int i;

	if (stats->lanes[0] == ETHTOOL_STAT_NOT_SET) {
		grp->stats[0] = stats->total;
		grp->cnt = stats->total != ETHTOOL_STAT_NOT_SET;
		return;
	}

	grp->cnt = 1;
	grp->stats[0] = 0;
	for (i = 0; i < ETHTOOL_MAX_LANES; i++) {
		if (stats->lanes[i] == ETHTOOL_STAT_NOT_SET)
			break;

		grp->stats[0] += stats->lanes[i];
		grp->stats[grp->cnt++] = stats->lanes[i];
	}
}

static int fec_prepare_data(const struct ethnl_req_info *req_base,
			    struct ethnl_reply_data *reply_base,
			    const struct genl_info *info)

Annotation

Implementation Notes