drivers/net/fjes/fjes_ethtool.c

Source file repositories/reference/linux-study-clean/drivers/net/fjes/fjes_ethtool.c

File Facts

System
Linux kernel
Corpus path
drivers/net/fjes/fjes_ethtool.c
Extension
.c
Size
7879 bytes
Lines
281
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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 fjes_stats {
	char stat_string[ETH_GSTRING_LEN];
	int sizeof_stat;
	int stat_offset;
};

#define FJES_STAT(name, stat) { \
	.stat_string = name, \
	.sizeof_stat = sizeof_field(struct fjes_adapter, stat), \
	.stat_offset = offsetof(struct fjes_adapter, stat) \
}

static const struct fjes_stats fjes_gstrings_stats[] = {
	FJES_STAT("rx_packets", stats64.rx_packets),
	FJES_STAT("tx_packets", stats64.tx_packets),
	FJES_STAT("rx_bytes", stats64.rx_bytes),
	FJES_STAT("tx_bytes", stats64.rx_bytes),
	FJES_STAT("rx_dropped", stats64.rx_dropped),
	FJES_STAT("tx_dropped", stats64.tx_dropped),
};

#define FJES_EP_STATS_LEN 14
#define FJES_STATS_LEN \
	(ARRAY_SIZE(fjes_gstrings_stats) + \
	 ((&((struct fjes_adapter *)netdev_priv(netdev))->hw)->max_epid - 1) * \
	 FJES_EP_STATS_LEN)

static void fjes_get_ethtool_stats(struct net_device *netdev,
				   struct ethtool_stats *stats, u64 *data)
{
	struct fjes_adapter *adapter = netdev_priv(netdev);
	struct fjes_hw *hw = &adapter->hw;
	int epidx;
	char *p;
	int i;

	for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++) {
		p = (char *)adapter + fjes_gstrings_stats[i].stat_offset;
		data[i] = (fjes_gstrings_stats[i].sizeof_stat == sizeof(u64))
			? *(u64 *)p : *(u32 *)p;
	}
	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx == hw->my_epid)
			continue;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.com_regist_buf_exec;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.com_unregist_buf_exec;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.send_intr_rx;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.send_intr_unshare;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.send_intr_zoneupdate;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_rx;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_unshare;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_stop;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.recv_intr_zoneupdate;
		data[i++] = hw->ep_shm_info[epidx].ep_stats.tx_buffer_full;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.tx_dropped_not_shared;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.tx_dropped_ver_mismatch;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.tx_dropped_buf_size_mismatch;
		data[i++] = hw->ep_shm_info[epidx].ep_stats
				.tx_dropped_vlanid_mismatch;
	}
}

static void fjes_get_strings(struct net_device *netdev,
			     u32 stringset, u8 *data)
{
	struct fjes_adapter *adapter = netdev_priv(netdev);
	struct fjes_hw *hw = &adapter->hw;
	int i;

	if (stringset != ETH_SS_STATS)
		return;

	for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++)
		ethtool_puts(&data, fjes_gstrings_stats[i].stat_string);

	for (i = 0; i < hw->max_epid; i++) {
		if (i == hw->my_epid)
			continue;
		ethtool_sprintf(&data, "ep%u_com_regist_buf_exec", i);
		ethtool_sprintf(&data, "ep%u_com_unregist_buf_exec", i);
		ethtool_sprintf(&data, "ep%u_send_intr_rx", i);
		ethtool_sprintf(&data, "ep%u_send_intr_unshare", i);
		ethtool_sprintf(&data, "ep%u_send_intr_zoneupdate", i);

Annotation

Implementation Notes