drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
Extension
.c
Size
25568 bytes
Lines
1070
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 fs_enet_netdev_ops = {
	.ndo_open		= fs_enet_open,
	.ndo_stop		= fs_enet_close,
	.ndo_start_xmit		= fs_enet_start_xmit,
	.ndo_tx_timeout		= fs_timeout,
	.ndo_set_rx_mode	= fs_set_multicast_list,
	.ndo_eth_ioctl		= fs_eth_ioctl,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= fs_enet_netpoll,
#endif
};

static const struct phylink_mac_ops fs_enet_phylink_mac_ops = {
	.mac_config = fs_mac_config,
	.mac_link_down = fs_mac_link_down,
	.mac_link_up = fs_mac_link_up,
};

static int fs_enet_probe(struct platform_device *ofdev)
{
	int privsize, len, ret = -ENODEV;
	struct fs_platform_info *fpi;
	struct fs_enet_private *fep;
	phy_interface_t phy_mode;
	const struct fs_ops *ops;
	struct net_device *ndev;
	struct phylink *phylink;
	const u32 *data;
	struct clk *clk;

	ops = device_get_match_data(&ofdev->dev);
	if (!ops)
		return -EINVAL;

	fpi = kzalloc_obj(*fpi);
	if (!fpi)
		return -ENOMEM;

	if (!IS_FEC(ops)) {
		data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len);
		if (!data || len != 4)
			goto out_free_fpi;

		fpi->cp_command = *data;
	}

	ret = of_get_phy_mode(ofdev->dev.of_node, &phy_mode);
	if (ret) {
		/* For compatibility, if the mode isn't specified in DT,
		 * assume MII
		 */
		phy_mode = PHY_INTERFACE_MODE_MII;
	}

	fpi->rx_ring = RX_RING_SIZE;
	fpi->tx_ring = TX_RING_SIZE;
	fpi->rx_copybreak = 240;
	fpi->napi_weight = 17;

	/* make clock lookup non-fatal (the driver is shared among platforms),
	 * but require enable to succeed when a clock was specified/found,
	 * keep a reference to the clock upon successful acquisition
	 */
	clk = devm_clk_get_optional_enabled(&ofdev->dev, "per");
	if (IS_ERR(clk))
		goto out_free_fpi;

	privsize = sizeof(*fep) +
		   sizeof(struct sk_buff **) *
		     (fpi->rx_ring + fpi->tx_ring) +
		   sizeof(char) * fpi->tx_ring;

	ndev = alloc_etherdev(privsize);
	if (!ndev) {
		ret = -ENOMEM;
		goto out_free_fpi;
	}

	SET_NETDEV_DEV(ndev, &ofdev->dev);
	platform_set_drvdata(ofdev, ndev);

	fep = netdev_priv(ndev);
	fep->dev = &ofdev->dev;
	fep->ndev = ndev;
	fep->fpi = fpi;
	fep->ops = ops;

	fep->phylink_config.dev = &ndev->dev;

Annotation

Implementation Notes