drivers/net/ethernet/marvell/prestera/prestera_main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/prestera/prestera_main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/prestera/prestera_main.c
Extension
.c
Size
36122 bytes
Lines
1527
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 prestera_netdev_ops = {
	.ndo_open = prestera_port_open,
	.ndo_stop = prestera_port_close,
	.ndo_start_xmit = prestera_port_xmit,
	.ndo_setup_tc = prestera_port_setup_tc,
	.ndo_change_mtu = prestera_port_change_mtu,
	.ndo_get_stats64 = prestera_port_get_stats64,
	.ndo_set_mac_address = prestera_port_set_mac_address,
};

int prestera_port_autoneg_set(struct prestera_port *port, u64 link_modes)
{
	int err;

	if (port->autoneg && port->adver_link_modes == link_modes)
		return 0;

	err = prestera_hw_port_phy_mode_set(port, port->cfg_phy.admin,
					    true, 0, link_modes,
					    port->cfg_phy.mdix);
	if (err)
		return err;

	port->adver_fec = BIT(PRESTERA_PORT_FEC_OFF);
	port->adver_link_modes = link_modes;
	port->cfg_phy.mode = 0;
	port->autoneg = true;

	return 0;
}

static void prestera_port_list_add(struct prestera_port *port)
{
	write_lock(&port->sw->port_list_lock);
	list_add(&port->list, &port->sw->port_list);
	write_unlock(&port->sw->port_list_lock);
}

static void prestera_port_list_del(struct prestera_port *port)
{
	write_lock(&port->sw->port_list_lock);
	list_del(&port->list);
	write_unlock(&port->sw->port_list_lock);
}

static int prestera_port_create(struct prestera_switch *sw, u32 id)
{
	struct prestera_port_mac_config cfg_mac;
	struct prestera_port *port;
	struct net_device *dev;
	int err;

	dev = alloc_etherdev(sizeof(*port));
	if (!dev)
		return -ENOMEM;

	port = netdev_priv(dev);

	INIT_LIST_HEAD(&port->vlans_list);
	port->pvid = PRESTERA_DEFAULT_VID;
	port->lag = NULL;
	port->dev = dev;
	port->id = id;
	port->sw = sw;

	spin_lock_init(&port->state_mac_lock);

	err = prestera_hw_port_info_get(port, &port->dev_id, &port->hw_id,
					&port->fp_id);
	if (err) {
		dev_err(prestera_dev(sw), "Failed to get port(%u) info\n", id);
		goto err_port_info_get;
	}

	err = prestera_devlink_port_register(port);
	if (err)
		goto err_dl_port_register;

	dev->features |= NETIF_F_HW_TC;
	dev->netns_immutable = true;
	dev->netdev_ops = &prestera_netdev_ops;
	dev->ethtool_ops = &prestera_ethtool_ops;
	SET_NETDEV_DEV(dev, sw->dev->dev);
	SET_NETDEV_DEVLINK_PORT(dev, &port->dl_port);

	if (port->caps.transceiver != PRESTERA_PORT_TCVR_SFP)
		netif_carrier_off(dev);

	dev->mtu = min_t(unsigned int, sw->mtu_max, PRESTERA_MTU_DEFAULT);
	dev->min_mtu = sw->mtu_min;

Annotation

Implementation Notes