drivers/net/ethernet/realtek/8139cp.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/realtek/8139cp.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/realtek/8139cp.c
Extension
.c
Size
57023 bytes
Lines
2122
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 cp_netdev_ops = {
	.ndo_open		= cp_open,
	.ndo_stop		= cp_close,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address 	= cp_set_mac_address,
	.ndo_set_rx_mode	= cp_set_rx_mode,
	.ndo_get_stats		= cp_get_stats,
	.ndo_eth_ioctl		= cp_ioctl,
	.ndo_start_xmit		= cp_start_xmit,
	.ndo_tx_timeout		= cp_tx_timeout,
	.ndo_set_features	= cp_set_features,
	.ndo_change_mtu		= cp_change_mtu,
	.ndo_features_check	= cp_features_check,

#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= cp_poll_controller,
#endif
};

static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct cp_private *cp;
	int rc;
	void __iomem *regs;
	resource_size_t pciaddr;
	unsigned int addr_len, i, pci_using_dac;
	__le16 addr[ETH_ALEN / 2];

	pr_info_once("%s", version);

	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
		dev_info(&pdev->dev,
			 "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
			 pdev->vendor, pdev->device, pdev->revision);
		return -ENODEV;
	}

	dev = alloc_etherdev(sizeof(struct cp_private));
	if (!dev)
		return -ENOMEM;
	SET_NETDEV_DEV(dev, &pdev->dev);

	cp = netdev_priv(dev);
	cp->pdev = pdev;
	cp->dev = dev;
	cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
	spin_lock_init (&cp->lock);
	cp->mii_if.dev = dev;
	cp->mii_if.mdio_read = mdio_read;
	cp->mii_if.mdio_write = mdio_write;
	cp->mii_if.phy_id = CP_INTERNAL_PHY;
	cp->mii_if.phy_id_mask = 0x1f;
	cp->mii_if.reg_num_mask = 0x1f;
	cp_set_rxbufsize(cp);

	rc = pci_enable_device(pdev);
	if (rc)
		goto err_out_free;

	rc = pci_set_mwi(pdev);
	if (rc)
		goto err_out_disable;

	rc = pci_request_regions(pdev, DRV_NAME);
	if (rc)
		goto err_out_mwi;

	pciaddr = pci_resource_start(pdev, 1);
	if (!pciaddr) {
		rc = -EIO;
		dev_err(&pdev->dev, "no MMIO resource\n");
		goto err_out_res;
	}
	if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) {
		rc = -EIO;
		dev_err(&pdev->dev, "MMIO resource (%llx) too small\n",
		       (unsigned long long)pci_resource_len(pdev, 1));
		goto err_out_res;
	}

	/* Configure DMA attributes. */
	if ((sizeof(dma_addr_t) > 4) &&
	    !dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
		pci_using_dac = 1;
	} else {
		pci_using_dac = 0;

		rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));

Annotation

Implementation Notes