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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
Extension
.c
Size
93297 bytes
Lines
3652
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_switch_port_ops = {
	.ndo_open		= dpaa2_switch_port_open,
	.ndo_stop		= dpaa2_switch_port_stop,

	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_get_stats64	= dpaa2_switch_port_get_stats,
	.ndo_change_mtu		= dpaa2_switch_port_change_mtu,
	.ndo_has_offload_stats	= dpaa2_switch_port_has_offload_stats,
	.ndo_get_offload_stats	= dpaa2_switch_port_get_offload_stats,
	.ndo_fdb_dump		= dpaa2_switch_port_fdb_dump,
	.ndo_vlan_rx_add_vid	= dpaa2_switch_port_vlan_add,
	.ndo_vlan_rx_kill_vid	= dpaa2_switch_port_vlan_kill,

	.ndo_start_xmit		= dpaa2_switch_port_tx,
	.ndo_get_port_parent_id	= dpaa2_switch_port_parent_id,
	.ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name,
	.ndo_setup_tc		= dpaa2_switch_port_setup_tc,
};

bool dpaa2_switch_port_dev_check(const struct net_device *netdev)
{
	return netdev->netdev_ops == &dpaa2_switch_port_ops;
}

static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv)
{
	struct fsl_mc_device *dpsw_port_dev, *dpmac_dev;
	struct dpaa2_mac *mac;
	int err;

	dpsw_port_dev = to_fsl_mc_device(port_priv->netdev->dev.parent);
	dpmac_dev = fsl_mc_get_endpoint(dpsw_port_dev, port_priv->idx);

	if (PTR_ERR(dpmac_dev) == -EPROBE_DEFER)
		return PTR_ERR(dpmac_dev);

	if (IS_ERR(dpmac_dev))
		return 0;

	if (dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) {
		err = 0;
		goto out_put_device;
	}

	mac = kzalloc_obj(*mac);
	if (!mac) {
		err = -ENOMEM;
		goto out_put_device;
	}

	mac->mc_dev = dpmac_dev;
	mac->mc_io = port_priv->ethsw_data->mc_io;
	mac->net_dev = port_priv->netdev;

	err = dpaa2_mac_open(mac);
	if (err)
		goto err_free_mac;

	if (dpaa2_mac_is_type_phy(mac)) {
		err = dpaa2_mac_connect(mac);
		if (err) {
			netdev_err(port_priv->netdev,
				   "Error connecting to the MAC endpoint %pe\n",
				   ERR_PTR(err));
			goto err_close_mac;
		}
	}

	mutex_lock(&port_priv->mac_lock);
	port_priv->mac = mac;
	mutex_unlock(&port_priv->mac_lock);

	return 0;

err_close_mac:
	dpaa2_mac_close(mac);
err_free_mac:
	kfree(mac);
out_put_device:
	put_device(&dpmac_dev->dev);
	return err;
}

static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv)
{
	struct dpaa2_mac *mac;

	mutex_lock(&port_priv->mac_lock);
	mac = port_priv->mac;
	port_priv->mac = NULL;

Annotation

Implementation Notes