drivers/net/ethernet/micrel/ks8842.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/micrel/ks8842.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/micrel/ks8842.c
Extension
.c
Size
32574 bytes
Lines
1260
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 ks8842_netdev_ops = {
	.ndo_open		= ks8842_open,
	.ndo_stop		= ks8842_close,
	.ndo_start_xmit		= ks8842_xmit_frame,
	.ndo_set_mac_address	= ks8842_set_mac,
	.ndo_tx_timeout 	= ks8842_tx_timeout,
	.ndo_validate_addr	= eth_validate_addr
};

static const struct ethtool_ops ks8842_ethtool_ops = {
	.get_link		= ethtool_op_get_link,
};

static int ks8842_probe(struct platform_device *pdev)
{
	int err = -ENOMEM;
	struct resource *iomem;
	struct net_device *netdev;
	struct ks8842_adapter *adapter;
	struct ks8842_platform_data *pdata = dev_get_platdata(&pdev->dev);
	u16 id;
	unsigned i;

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iomem) {
		dev_err(&pdev->dev, "Invalid resource\n");
		return -EINVAL;
	}
	if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
		goto err_mem_region;

	netdev = alloc_etherdev(sizeof(struct ks8842_adapter));
	if (!netdev)
		goto err_alloc_etherdev;

	SET_NETDEV_DEV(netdev, &pdev->dev);

	adapter = netdev_priv(netdev);
	adapter->netdev = netdev;
	INIT_WORK(&adapter->timeout_work, ks8842_tx_timeout_work);
	adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
	adapter->conf_flags = iomem->flags;

	if (!adapter->hw_addr)
		goto err_ioremap;

	adapter->irq = platform_get_irq(pdev, 0);
	if (adapter->irq < 0) {
		err = adapter->irq;
		goto err_get_irq;
	}

	adapter->dev = (pdev->dev.parent) ? pdev->dev.parent : &pdev->dev;

	/* DMA is only supported when accessed via timberdale */
	if (!(adapter->conf_flags & MICREL_KS884X) && pdata &&
		(pdata->tx_dma_channel != -1) &&
		(pdata->rx_dma_channel != -1)) {
		adapter->dma_rx.channel = pdata->rx_dma_channel;
		adapter->dma_tx.channel = pdata->tx_dma_channel;
	} else {
		adapter->dma_rx.channel = -1;
		adapter->dma_tx.channel = -1;
	}

	tasklet_setup(&adapter->tasklet, ks8842_tasklet);
	spin_lock_init(&adapter->lock);

	netdev->netdev_ops = &ks8842_netdev_ops;
	netdev->ethtool_ops = &ks8842_ethtool_ops;

	/* Check if a mac address was given */
	i = netdev->addr_len;
	if (pdata) {
		for (i = 0; i < netdev->addr_len; i++)
			if (pdata->macaddr[i] != 0)
				break;

		if (i < netdev->addr_len)
			/* an address was passed, use it */
			eth_hw_addr_set(netdev, pdata->macaddr);
	}

	if (i == netdev->addr_len) {
		ks8842_init_mac_addr(adapter);

		if (!is_valid_ether_addr(netdev->dev_addr))
			eth_hw_addr_random(netdev);
	}

Annotation

Implementation Notes