drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
Extension
.c
Size
136194 bytes
Lines
5168
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 dpaa2_eth_ops = {
	.ndo_open = dpaa2_eth_open,
	.ndo_start_xmit = dpaa2_eth_tx,
	.ndo_stop = dpaa2_eth_stop,
	.ndo_set_mac_address = dpaa2_eth_set_addr,
	.ndo_get_stats64 = dpaa2_eth_get_stats,
	.ndo_set_rx_mode = dpaa2_eth_set_rx_mode,
	.ndo_set_features = dpaa2_eth_set_features,
	.ndo_eth_ioctl = dpaa2_eth_ioctl,
	.ndo_change_mtu = dpaa2_eth_change_mtu,
	.ndo_bpf = dpaa2_eth_xdp,
	.ndo_xdp_xmit = dpaa2_eth_xdp_xmit,
	.ndo_xsk_wakeup = dpaa2_xsk_wakeup,
	.ndo_setup_tc = dpaa2_eth_setup_tc,
	.ndo_vlan_rx_add_vid = dpaa2_eth_rx_add_vid,
	.ndo_vlan_rx_kill_vid = dpaa2_eth_rx_kill_vid,
	.ndo_hwtstamp_get = dpaa2_eth_hwtstamp_get,
	.ndo_hwtstamp_set = dpaa2_eth_hwtstamp_set,
};

static void dpaa2_eth_cdan_cb(struct dpaa2_io_notification_ctx *ctx)
{
	struct dpaa2_eth_channel *ch;

	ch = container_of(ctx, struct dpaa2_eth_channel, nctx);

	/* Update NAPI statistics */
	ch->stats.cdan++;

	/* NAPI can also be scheduled from the AF_XDP Tx path. Mark a missed
	 * so that it can be rescheduled again.
	 */
	if (!napi_if_scheduled_mark_missed(&ch->napi))
		napi_schedule(&ch->napi);
}

/* Allocate and configure a DPCON object */
static struct fsl_mc_device *dpaa2_eth_setup_dpcon(struct dpaa2_eth_priv *priv)
{
	struct fsl_mc_device *dpcon;
	struct device *dev = priv->net_dev->dev.parent;
	int err;

	err = fsl_mc_object_allocate(to_fsl_mc_device(dev),
				     FSL_MC_POOL_DPCON, &dpcon);
	if (err) {
		if (err == -ENXIO) {
			dev_dbg(dev, "Waiting for DPCON\n");
			err = -EPROBE_DEFER;
		} else {
			dev_info(dev, "Not enough DPCONs, will go on as-is\n");
		}
		return ERR_PTR(err);
	}

	err = dpcon_open(priv->mc_io, 0, dpcon->obj_desc.id, &dpcon->mc_handle);
	if (err) {
		dev_err(dev, "dpcon_open() failed\n");
		goto free;
	}

	err = dpcon_reset(priv->mc_io, 0, dpcon->mc_handle);
	if (err) {
		dev_err(dev, "dpcon_reset() failed\n");
		goto close;
	}

	err = dpcon_enable(priv->mc_io, 0, dpcon->mc_handle);
	if (err) {
		dev_err(dev, "dpcon_enable() failed\n");
		goto close;
	}

	return dpcon;

close:
	dpcon_close(priv->mc_io, 0, dpcon->mc_handle);
free:
	fsl_mc_object_free(dpcon);

	return ERR_PTR(err);
}

static void dpaa2_eth_free_dpcon(struct dpaa2_eth_priv *priv,
				 struct fsl_mc_device *dpcon)
{
	dpcon_disable(priv->mc_io, 0, dpcon->mc_handle);
	dpcon_close(priv->mc_io, 0, dpcon->mc_handle);
	fsl_mc_object_free(dpcon);
}

Annotation

Implementation Notes