drivers/net/ethernet/ti/am65-cpsw-nuss.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/ti/am65-cpsw-nuss.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/ti/am65-cpsw-nuss.c
Extension
.c
Size
105594 bytes
Lines
3825
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 am65_cpsw_nuss_netdev_ops = {
	.ndo_open		= am65_cpsw_nuss_ndo_slave_open,
	.ndo_stop		= am65_cpsw_nuss_ndo_slave_stop,
	.ndo_start_xmit		= am65_cpsw_nuss_ndo_slave_xmit,
	.ndo_set_rx_mode	= am65_cpsw_nuss_ndo_slave_set_rx_mode,
	.ndo_get_stats64        = am65_cpsw_nuss_ndo_get_stats,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= am65_cpsw_nuss_ndo_slave_set_mac_address,
	.ndo_tx_timeout		= am65_cpsw_nuss_ndo_host_tx_timeout,
	.ndo_vlan_rx_add_vid	= am65_cpsw_nuss_ndo_slave_add_vid,
	.ndo_vlan_rx_kill_vid	= am65_cpsw_nuss_ndo_slave_kill_vid,
	.ndo_eth_ioctl		= am65_cpsw_nuss_ndo_slave_ioctl,
	.ndo_setup_tc           = am65_cpsw_qos_ndo_setup_tc,
	.ndo_set_tx_maxrate	= am65_cpsw_qos_ndo_tx_p0_set_maxrate,
	.ndo_bpf		= am65_cpsw_ndo_bpf,
	.ndo_xdp_xmit		= am65_cpsw_ndo_xdp_xmit,
	.ndo_hwtstamp_get       = am65_cpsw_nuss_hwtstamp_get,
	.ndo_hwtstamp_set       = am65_cpsw_nuss_hwtstamp_set,
};

static void am65_cpsw_disable_phy(struct phy *phy)
{
	phy_power_off(phy);
	phy_exit(phy);
}

static int am65_cpsw_enable_phy(struct phy *phy)
{
	int ret;

	ret = phy_init(phy);
	if (ret < 0)
		return ret;

	ret = phy_power_on(phy);
	if (ret < 0) {
		phy_exit(phy);
		return ret;
	}

	return 0;
}

static void am65_cpsw_disable_serdes_phy(struct am65_cpsw_common *common)
{
	struct am65_cpsw_port *port;
	struct phy *phy;
	int i;

	for (i = 0; i < common->port_num; i++) {
		port = &common->ports[i];
		phy = port->slave.serdes_phy;
		if (phy)
			am65_cpsw_disable_phy(phy);
	}
}

static int am65_cpsw_init_serdes_phy(struct device *dev, struct device_node *port_np,
				     struct am65_cpsw_port *port)
{
	const char *name = "serdes";
	struct phy *phy;
	int ret;

	phy = devm_of_phy_optional_get(dev, port_np, name);
	if (IS_ERR_OR_NULL(phy))
		return PTR_ERR_OR_ZERO(phy);

	/* Serdes PHY exists. Store it. */
	port->slave.serdes_phy = phy;

	ret =  am65_cpsw_enable_phy(phy);
	if (ret < 0)
		goto err_phy;

	return 0;

err_phy:
	devm_phy_put(dev, phy);
	return ret;
}

static void am65_cpsw_nuss_mac_config(struct phylink_config *config, unsigned int mode,
				      const struct phylink_link_state *state)
{
	struct am65_cpsw_slave_data *slave = container_of(config, struct am65_cpsw_slave_data,
							  phylink_config);
	struct am65_cpsw_port *port = container_of(slave, struct am65_cpsw_port, slave);
	struct am65_cpsw_common *common = port->common;

Annotation

Implementation Notes