drivers/net/ethernet/tehuti/tn40.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/tehuti/tn40.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/tehuti/tn40.c
Extension
.c
Size
53254 bytes
Lines
1858
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops tn40_netdev_ops = {
	.ndo_open = tn40_open,
	.ndo_stop = tn40_close,
	.ndo_start_xmit = tn40_start_xmit,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_set_rx_mode = tn40_setmulti,
	.ndo_get_stats64 = tn40_get_stats,
	.ndo_set_mac_address = tn40_set_mac,
	.ndo_vlan_rx_add_vid = tn40_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid = tn40_vlan_rx_kill_vid,
};

static int tn40_ethtool_get_link_ksettings(struct net_device *ndev,
					   struct ethtool_link_ksettings *cmd)
{
	struct tn40_priv *priv = netdev_priv(ndev);

	return phylink_ethtool_ksettings_get(priv->phylink, cmd);
}

static const struct ethtool_ops tn40_ethtool_ops = {
	.get_link = ethtool_op_get_link,
	.get_link_ksettings = tn40_ethtool_get_link_ksettings,
};

static void tn40_get_queue_stats_rx(struct net_device *ndev, int idx,
				    struct netdev_queue_stats_rx *stats)
{
	struct tn40_priv *priv = netdev_priv(ndev);
	unsigned int start;

	do {
		start = u64_stats_fetch_begin(&priv->syncp);

		stats->packets = priv->stats.rx_packets;
		stats->bytes = priv->stats.rx_bytes;
		stats->alloc_fail = priv->alloc_fail;
	} while (u64_stats_fetch_retry(&priv->syncp, start));
}

static void tn40_get_queue_stats_tx(struct net_device *ndev, int idx,
				    struct netdev_queue_stats_tx *stats)
{
	struct tn40_priv *priv = netdev_priv(ndev);
	unsigned int start;

	do {
		start = u64_stats_fetch_begin(&priv->syncp);

		stats->packets = priv->stats.tx_packets;
		stats->bytes = priv->stats.tx_bytes;
	} while (u64_stats_fetch_retry(&priv->syncp, start));
}

static void tn40_get_base_stats(struct net_device *ndev,
				struct netdev_queue_stats_rx *rx,
				struct netdev_queue_stats_tx *tx)
{
	rx->packets = 0;
	rx->bytes = 0;
	rx->alloc_fail = 0;

	tx->packets = 0;
	tx->bytes = 0;
}

static const struct netdev_stat_ops tn40_stat_ops = {
	.get_queue_stats_rx = tn40_get_queue_stats_rx,
	.get_queue_stats_tx = tn40_get_queue_stats_tx,
	.get_base_stats = tn40_get_base_stats,
};

static int tn40_priv_init(struct tn40_priv *priv)
{
	int ret;

	tn40_set_link_speed(priv, 0);

	/* Set GPIO[9:0] to output 0 */
	tn40_write_reg(priv, 0x51E0, 0x30010006);	/* GPIO_OE_ WR CMD */
	tn40_write_reg(priv, 0x51F0, 0x0);	/* GPIO_OE_ DATA */
	tn40_write_reg(priv, TN40_REG_MDIO_CMD_STAT, 0x3ec8);

	/* we use tx descriptors to load a firmware. */
	ret = tn40_create_tx_ring(priv);
	if (ret)
		return ret;
	ret = tn40_fw_load(priv);
	tn40_destroy_tx_ring(priv);
	return ret;

Annotation

Implementation Notes