drivers/net/ethernet/ti/netcp_core.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/ti/netcp_core.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/ti/netcp_core.c
Extension
.c
Size
62668 bytes
Lines
2338
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 netcp_netdev_ops = {
	.ndo_open		= netcp_ndo_open,
	.ndo_stop		= netcp_ndo_stop,
	.ndo_start_xmit		= netcp_ndo_start_xmit,
	.ndo_set_rx_mode	= netcp_set_rx_mode,
	.ndo_eth_ioctl           = netcp_ndo_ioctl,
	.ndo_get_stats64        = netcp_get_stats,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_vlan_rx_add_vid	= netcp_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= netcp_rx_kill_vid,
	.ndo_tx_timeout		= netcp_ndo_tx_timeout,
	.ndo_select_queue	= dev_pick_tx_zero,
	.ndo_setup_tc		= netcp_setup_tc,
	.ndo_hwtstamp_get	= netcp_ndo_hwtstamp_get,
	.ndo_hwtstamp_set	= netcp_ndo_hwtstamp_set,
};

static int netcp_create_interface(struct netcp_device *netcp_device,
				  struct device_node *node_interface)
{
	struct device *dev = netcp_device->device;
	struct device_node *node = dev->of_node;
	struct netcp_intf *netcp;
	struct net_device *ndev;
	resource_size_t size;
	struct resource res;
	void __iomem *efuse = NULL;
	u32 efuse_mac = 0;
	u8 efuse_mac_addr[6];
	u32 temp[2];
	int ret = 0;

	ndev = alloc_etherdev_mqs(sizeof(*netcp), 1, 1);
	if (!ndev) {
		dev_err(dev, "Error allocating netdev\n");
		return -ENOMEM;
	}

	ndev->features |= NETIF_F_SG;
	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
	ndev->hw_features = ndev->features;
	ndev->vlan_features |=  NETIF_F_SG;

	/* MTU range: 68 - 9486 */
	ndev->min_mtu = ETH_MIN_MTU;
	ndev->max_mtu = NETCP_MAX_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN);

	netcp = netdev_priv(ndev);
	spin_lock_init(&netcp->lock);
	INIT_LIST_HEAD(&netcp->module_head);
	INIT_LIST_HEAD(&netcp->txhook_list_head);
	INIT_LIST_HEAD(&netcp->rxhook_list_head);
	INIT_LIST_HEAD(&netcp->addr_list);
	u64_stats_init(&netcp->stats.syncp_rx);
	u64_stats_init(&netcp->stats.syncp_tx);
	netcp->netcp_device = netcp_device;
	netcp->dev = netcp_device->device;
	netcp->ndev = ndev;
	netcp->ndev_dev  = &ndev->dev;
	netcp->msg_enable = netif_msg_init(netcp_debug_level, NETCP_DEBUG);
	netcp->tx_pause_threshold = MAX_SKB_FRAGS;
	netcp->tx_resume_threshold = netcp->tx_pause_threshold;
	netcp->node_interface = node_interface;

	ret = of_property_read_u32(node_interface, "efuse-mac", &efuse_mac);
	if (efuse_mac) {
		if (of_address_to_resource(node, NETCP_EFUSE_REG_INDEX, &res)) {
			dev_err(dev, "could not find efuse-mac reg resource\n");
			ret = -ENODEV;
			goto quit;
		}
		size = resource_size(&res);

		if (!devm_request_mem_region(dev, res.start, size,
					     dev_name(dev))) {
			dev_err(dev, "could not reserve resource\n");
			ret = -ENOMEM;
			goto quit;
		}

		efuse = devm_ioremap(dev, res.start, size);
		if (!efuse) {
			dev_err(dev, "could not map resource\n");
			devm_release_mem_region(dev, res.start, size);
			ret = -ENOMEM;
			goto quit;
		}

		emac_arch_get_mac_addr(efuse_mac_addr, efuse, efuse_mac);

Annotation

Implementation Notes