drivers/net/ethernet/dec/tulip/uli526x.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dec/tulip/uli526x.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dec/tulip/uli526x.c
Extension
.c
Size
46369 bytes
Lines
1802
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 netdev_ops = {
	.ndo_open		= uli526x_open,
	.ndo_stop		= uli526x_stop,
	.ndo_start_xmit		= uli526x_start_xmit,
	.ndo_set_rx_mode	= uli526x_set_filter_mode,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller 	= uli526x_poll,
#endif
};

/*
 *	Search ULI526X board, allocate space and register it
 */

static int uli526x_init_one(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{
	struct uli526x_board_info *db;	/* board information structure */
	struct net_device *dev;
	void __iomem *ioaddr;
	u8 addr[ETH_ALEN];
	int i, err;

	ULI526X_DBUG(0, "uli526x_init_one()", 0);

	/* Init network device */
	dev = alloc_etherdev(sizeof(*db));
	if (dev == NULL)
		return -ENOMEM;
	SET_NETDEV_DEV(dev, &pdev->dev);

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
		pr_warn("32-bit PCI DMA not available\n");
		err = -ENODEV;
		goto err_out_free;
	}

	/* Enable Master/IO access, Disable memory access */
	err = pci_enable_device(pdev);
	if (err)
		goto err_out_free;

	if (!pci_resource_start(pdev, 0)) {
		pr_err("I/O base is zero\n");
		err = -ENODEV;
		goto err_out_disable;
	}

	if (pci_resource_len(pdev, 0) < (ULI526X_IO_SIZE) ) {
		pr_err("Allocated I/O size too small\n");
		err = -ENODEV;
		goto err_out_disable;
	}

	err = pci_request_regions(pdev, DRV_NAME);
	if (err < 0) {
		pr_err("Failed to request PCI regions\n");
		goto err_out_disable;
	}

	/* Init system & device */
	db = netdev_priv(dev);

	/* Allocate Tx/Rx descriptor memory */
	err = -ENOMEM;

	db->desc_pool_ptr = dma_alloc_coherent(&pdev->dev,
					       sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
					       &db->desc_pool_dma_ptr, GFP_KERNEL);
	if (!db->desc_pool_ptr)
		goto err_out_release;

	db->buf_pool_ptr = dma_alloc_coherent(&pdev->dev,
					      TX_BUF_ALLOC * TX_DESC_CNT + 4,
					      &db->buf_pool_dma_ptr, GFP_KERNEL);
	if (!db->buf_pool_ptr)
		goto err_out_free_tx_desc;

	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
	db->buf_pool_start = db->buf_pool_ptr;
	db->buf_pool_dma_start = db->buf_pool_dma_ptr;

	switch (ent->driver_data) {
	case PCI_ULI5263_ID:
		db->phy.write	= phy_writeby_cr10;
		db->phy.read	= phy_readby_cr10;
		break;

Annotation

Implementation Notes