drivers/net/ethernet/netronome/nfp/nfp_net_repr.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
Extension
.c
Size
13836 bytes
Lines
541
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

const struct net_device_ops nfp_repr_netdev_ops = {
	.ndo_init		= nfp_app_ndo_init,
	.ndo_uninit		= nfp_app_ndo_uninit,
	.ndo_open		= nfp_repr_open,
	.ndo_stop		= nfp_repr_stop,
	.ndo_start_xmit		= nfp_repr_xmit,
	.ndo_change_mtu		= nfp_repr_change_mtu,
	.ndo_get_stats64	= nfp_repr_get_stats64,
	.ndo_has_offload_stats	= nfp_repr_has_offload_stats,
	.ndo_get_offload_stats	= nfp_repr_get_offload_stats,
	.ndo_get_phys_port_name	= nfp_port_get_phys_port_name,
	.ndo_setup_tc		= nfp_port_setup_tc,
	.ndo_set_vf_mac		= nfp_app_set_vf_mac,
	.ndo_set_vf_vlan	= nfp_app_set_vf_vlan,
	.ndo_set_vf_spoofchk	= nfp_app_set_vf_spoofchk,
	.ndo_set_vf_trust	= nfp_app_set_vf_trust,
	.ndo_get_vf_config	= nfp_app_get_vf_config,
	.ndo_set_vf_link_state	= nfp_app_set_vf_link_state,
	.ndo_fix_features	= nfp_repr_fix_features,
	.ndo_set_features	= nfp_port_set_features,
	.ndo_set_mac_address    = eth_mac_addr,
	.ndo_get_port_parent_id	= nfp_port_get_port_parent_id,
};

void
nfp_repr_transfer_features(struct net_device *netdev, struct net_device *lower)
{
	struct nfp_repr *repr = netdev_priv(netdev);

	if (repr->dst->u.port_info.lower_dev != lower)
		return;

	netif_inherit_tso_max(netdev, lower);

	netdev_update_features(netdev);
}

static void nfp_repr_clean(struct nfp_repr *repr)
{
	unregister_netdev(repr->netdev);
	nfp_app_repr_clean(repr->app, repr->netdev);
	dst_release((struct dst_entry *)repr->dst);
	nfp_port_free(repr->port);
}

static struct lock_class_key nfp_repr_netdev_xmit_lock_key;

static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
					   struct netdev_queue *txq,
					   void *_unused)
{
	lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
}

static void nfp_repr_set_lockdep_class(struct net_device *dev)
{
	netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
}

int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
		  u32 cmsg_port_id, struct nfp_port *port,
		  struct net_device *pf_netdev)
{
	struct nfp_repr *repr = netdev_priv(netdev);
	struct nfp_net *nn = netdev_priv(pf_netdev);
	u32 repr_cap = nn->tlv_caps.repr_cap;
	int err;

	nfp_repr_set_lockdep_class(netdev);

	repr->port = port;
	repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
	if (!repr->dst)
		return -ENOMEM;
	repr->dst->u.port_info.port_id = cmsg_port_id;
	repr->dst->u.port_info.lower_dev = pf_netdev;

	netdev->netdev_ops = &nfp_repr_netdev_ops;
	netdev->ethtool_ops = &nfp_port_ethtool_ops;

	netdev->max_mtu = pf_netdev->max_mtu;

	/* Set features the lower device can support with representors */
	if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR)
		netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;

	netdev->hw_features = NETIF_F_HIGHDMA;
	if (repr_cap & NFP_NET_CFG_CTRL_RXCSUM_ANY)
		netdev->hw_features |= NETIF_F_RXCSUM;
	if (repr_cap & NFP_NET_CFG_CTRL_TXCSUM)

Annotation

Implementation Notes