drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
Extension
.c
Size
97269 bytes
Lines
3629
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 *dpaa_ops,
			    u16 tx_timeout)
{
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct device *dev = net_dev->dev.parent;
	struct mac_device *mac_dev = priv->mac_dev;
	struct dpaa_percpu_priv *percpu_priv;
	const u8 *mac_addr;
	int i, err;

	/* Although we access another CPU's private data here
	 * we do it at initialization so it is safe
	 */
	for_each_possible_cpu(i) {
		percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
		percpu_priv->net_dev = net_dev;
	}

	net_dev->netdev_ops = dpaa_ops;
	mac_addr = mac_dev->addr;

	net_dev->mem_start = (unsigned long)priv->mac_dev->res->start;
	net_dev->mem_end = (unsigned long)priv->mac_dev->res->end;

	net_dev->min_mtu = ETH_MIN_MTU;
	net_dev->max_mtu = dpaa_get_max_mtu();

	net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
				 NETIF_F_RXHASH);

	net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
	/* The kernels enables GSO automatically, if we declare NETIF_F_SG.
	 * For conformity, we'll still declare GSO explicitly.
	 */
	net_dev->features |= NETIF_F_GSO;
	net_dev->features |= NETIF_F_RXCSUM;

	net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
	net_dev->lltx = true;
	/* we do not want shared skbs on TX */
	net_dev->priv_flags &= ~IFF_TX_SKB_SHARING;

	net_dev->features |= net_dev->hw_features;
	net_dev->vlan_features = net_dev->features;

	net_dev->xdp_features = NETDEV_XDP_ACT_BASIC |
				NETDEV_XDP_ACT_REDIRECT |
				NETDEV_XDP_ACT_NDO_XMIT;

	if (is_valid_ether_addr(mac_addr)) {
		memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
		eth_hw_addr_set(net_dev, mac_addr);
	} else {
		eth_hw_addr_random(net_dev);
		err = mac_dev->change_addr(mac_dev->fman_mac,
			(const enet_addr_t *)net_dev->dev_addr);
		if (err) {
			dev_err(dev, "Failed to set random MAC address\n");
			return -EINVAL;
		}
		dev_info(dev, "Using random MAC address: %pM\n",
			 net_dev->dev_addr);
	}

	net_dev->ethtool_ops = &dpaa_ethtool_ops;

	net_dev->needed_headroom = priv->tx_headroom;
	net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);

	/* The rest of the config is filled in by the mac device already */
	mac_dev->phylink_config.dev = &net_dev->dev;
	mac_dev->phylink_config.type = PHYLINK_NETDEV;
	mac_dev->update_speed = dpaa_eth_cgr_set_speed;
	mac_dev->phylink = phylink_create(&mac_dev->phylink_config,
					  dev_fwnode(mac_dev->dev),
					  mac_dev->phy_if,
					  mac_dev->phylink_ops);
	if (IS_ERR(mac_dev->phylink)) {
		err = PTR_ERR(mac_dev->phylink);
		dev_err_probe(dev, err, "Could not create phylink\n");
		return err;
	}

	/* start without the RUNNING flag, phylib controls it later */
	netif_carrier_off(net_dev);

	err = register_netdev(net_dev);
	if (err < 0) {
		dev_err(dev, "register_netdev() = %d\n", err);
		phylink_destroy(mac_dev->phylink);

Annotation

Implementation Notes