drivers/net/team/team_core.c

Source file repositories/reference/linux-study-clean/drivers/net/team/team_core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/team/team_core.c
Extension
.c
Size
78866 bytes
Lines
3268
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 team_netdev_ops = {
	.ndo_init		= team_init,
	.ndo_uninit		= team_uninit,
	.ndo_open		= team_open,
	.ndo_stop		= team_close,
	.ndo_start_xmit		= team_xmit,
	.ndo_select_queue	= team_select_queue,
	.ndo_change_rx_flags	= team_change_rx_flags,
	.ndo_set_rx_mode	= team_set_rx_mode,
	.ndo_set_mac_address	= team_set_mac_address,
	.ndo_change_mtu		= team_change_mtu,
	.ndo_get_stats64	= team_get_stats64,
	.ndo_vlan_rx_add_vid	= team_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= team_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= team_poll_controller,
	.ndo_netpoll_setup	= team_netpoll_setup,
	.ndo_netpoll_cleanup	= team_netpoll_cleanup,
#endif
	.ndo_add_slave		= team_add_slave,
	.ndo_del_slave		= team_del_slave,
	.ndo_fix_features	= team_fix_features,
	.ndo_change_carrier     = team_change_carrier,
	.ndo_features_check	= passthru_features_check,
};

/***********************
 * ethtool interface
 ***********************/

static void team_ethtool_get_drvinfo(struct net_device *dev,
				     struct ethtool_drvinfo *drvinfo)
{
	strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
}

static int team_ethtool_get_link_ksettings(struct net_device *dev,
					   struct ethtool_link_ksettings *cmd)
{
	struct team *team= netdev_priv(dev);
	unsigned long speed = 0;
	struct team_port *port;

	cmd->base.duplex = DUPLEX_UNKNOWN;
	cmd->base.port = PORT_OTHER;

	rcu_read_lock();
	list_for_each_entry_rcu(port, &team->port_list, list) {
		if (team_port_txable(port)) {
			if (port->state.speed != SPEED_UNKNOWN)
				speed += port->state.speed;
			if (cmd->base.duplex == DUPLEX_UNKNOWN &&
			    port->state.duplex != DUPLEX_UNKNOWN)
				cmd->base.duplex = port->state.duplex;
		}
	}
	rcu_read_unlock();

	cmd->base.speed = speed ? : SPEED_UNKNOWN;

	return 0;
}

static const struct ethtool_ops team_ethtool_ops = {
	.get_drvinfo		= team_ethtool_get_drvinfo,
	.get_link		= ethtool_op_get_link,
	.get_link_ksettings	= team_ethtool_get_link_ksettings,
};

/***********************
 * rt netlink interface
 ***********************/

/* For tx path we need a linkup && enabled port and for parse any port
 * suffices.
 */
static struct team_port *team_header_port_get_rcu(struct team *team,
						  bool txable)
{
	struct team_port *port;

	list_for_each_entry_rcu(port, &team->port_list, list) {
		if (!txable || team_port_txable(port))
			return port;
	}

	return NULL;
}

static int team_header_create(struct sk_buff *skb, struct net_device *team_dev,

Annotation

Implementation Notes