drivers/net/dsa/xrs700x/xrs700x.c

Source file repositories/reference/linux-study-clean/drivers/net/dsa/xrs700x/xrs700x.c

File Facts

System
Linux kernel
Corpus path
drivers/net/dsa/xrs700x/xrs700x.c
Extension
.c
Size
21956 bytes
Lines
861
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct xrs700x_regfield {
	struct reg_field rf;
	struct regmap_field **rmf;
};

struct xrs700x_mib {
	unsigned int offset;
	const char *name;
	int stats64_offset;
};

#define XRS700X_MIB_ETHTOOL_ONLY(o, n) {o, n, -1}
#define XRS700X_MIB(o, n, m) {o, n, offsetof(struct rtnl_link_stats64, m)}

static const struct xrs700x_mib xrs700x_mibs[] = {
	XRS700X_MIB(XRS_RX_GOOD_OCTETS_L, "rx_good_octets", rx_bytes),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_BAD_OCTETS_L, "rx_bad_octets"),
	XRS700X_MIB(XRS_RX_UNICAST_L, "rx_unicast", rx_packets),
	XRS700X_MIB(XRS_RX_BROADCAST_L, "rx_broadcast", rx_packets),
	XRS700X_MIB(XRS_RX_MULTICAST_L, "rx_multicast", multicast),
	XRS700X_MIB(XRS_RX_UNDERSIZE_L, "rx_undersize", rx_length_errors),
	XRS700X_MIB(XRS_RX_FRAGMENTS_L, "rx_fragments", rx_length_errors),
	XRS700X_MIB(XRS_RX_OVERSIZE_L, "rx_oversize", rx_length_errors),
	XRS700X_MIB(XRS_RX_JABBER_L, "rx_jabber", rx_length_errors),
	XRS700X_MIB(XRS_RX_ERR_L, "rx_err", rx_errors),
	XRS700X_MIB(XRS_RX_CRC_L, "rx_crc", rx_crc_errors),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_64_L, "rx_64"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_65_127_L, "rx_65_127"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_128_255_L, "rx_128_255"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_256_511_L, "rx_256_511"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_512_1023_L, "rx_512_1023"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_1024_1536_L, "rx_1024_1536"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_HSR_PRP_L, "rx_hsr_prp"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_WRONGLAN_L, "rx_wronglan"),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_RX_DUPLICATE_L, "rx_duplicate"),
	XRS700X_MIB(XRS_TX_OCTETS_L, "tx_octets", tx_bytes),
	XRS700X_MIB(XRS_TX_UNICAST_L, "tx_unicast", tx_packets),
	XRS700X_MIB(XRS_TX_BROADCAST_L, "tx_broadcast", tx_packets),
	XRS700X_MIB(XRS_TX_MULTICAST_L, "tx_multicast", tx_packets),
	XRS700X_MIB_ETHTOOL_ONLY(XRS_TX_HSR_PRP_L, "tx_hsr_prp"),
	XRS700X_MIB(XRS_PRIQ_DROP_L, "priq_drop", tx_dropped),
	XRS700X_MIB(XRS_EARLY_DROP_L, "early_drop", tx_dropped),
};

static const u8 eth_hsrsup_addr[ETH_ALEN] = {
	0x01, 0x15, 0x4e, 0x00, 0x01, 0x00};

static void xrs700x_get_strings(struct dsa_switch *ds, int port,
				u32 stringset, u8 *data)
{
	int i;

	if (stringset != ETH_SS_STATS)
		return;

	for (i = 0; i < ARRAY_SIZE(xrs700x_mibs); i++)
		ethtool_puts(&data, xrs700x_mibs[i].name);
}

static int xrs700x_get_sset_count(struct dsa_switch *ds, int port, int sset)
{
	if (sset != ETH_SS_STATS)
		return -EOPNOTSUPP;

	return ARRAY_SIZE(xrs700x_mibs);
}

static void xrs700x_read_port_counters(struct xrs700x *priv, int port)
{
	struct xrs700x_port *p = &priv->ports[port];
	struct rtnl_link_stats64 stats;
	unsigned long flags;
	int i;

	memset(&stats, 0, sizeof(stats));

	mutex_lock(&p->mib_mutex);

	/* Capture counter values */
	regmap_write(priv->regmap, XRS_CNT_CTRL(port), 1);

	for (i = 0; i < ARRAY_SIZE(xrs700x_mibs); i++) {
		unsigned int high = 0, low = 0, reg;

		reg = xrs700x_mibs[i].offset + XRS_PORT_OFFSET * port;
		regmap_read(priv->regmap, reg, &low);
		regmap_read(priv->regmap, reg + 2, &high);

		p->mib_data[i] += (high << 16) | low;

Annotation

Implementation Notes