drivers/net/ethernet/amd/pcnet32.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/amd/pcnet32.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/amd/pcnet32.c
Extension
.c
Size
86747 bytes
Lines
3047
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 pcnet32_netdev_ops = {
	.ndo_open		= pcnet32_open,
	.ndo_stop 		= pcnet32_close,
	.ndo_start_xmit		= pcnet32_start_xmit,
	.ndo_tx_timeout		= pcnet32_tx_timeout,
	.ndo_get_stats		= pcnet32_get_stats,
	.ndo_set_rx_mode	= pcnet32_set_multicast_list,
	.ndo_eth_ioctl		= pcnet32_ioctl,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= pcnet32_poll_controller,
#endif
};

/* pcnet32_probe1
 *  Called from both pcnet32_probe_vlbus and pcnet_probe_pci.
 *  pdev will be NULL when called from pcnet32_probe_vlbus.
 */
static int
pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
{
	struct pcnet32_private *lp;
	int i, media;
	int fdx, mii, fset, dxsuflo, sram;
	int chip_version;
	char *chipname;
	struct net_device *dev;
	const struct pcnet32_access *a = NULL;
	u8 promaddr[ETH_ALEN];
	u8 addr[ETH_ALEN];
	int ret = -ENODEV;

	/* reset the chip */
	pcnet32_wio_reset(ioaddr);

	/* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */
	if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) {
		a = &pcnet32_wio;
	} else {
		pcnet32_dwio_reset(ioaddr);
		if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 &&
		    pcnet32_dwio_check(ioaddr)) {
			a = &pcnet32_dwio;
		} else {
			if (pcnet32_debug & NETIF_MSG_PROBE)
				pr_err("No access methods\n");
			goto err_release_region;
		}
	}

	chip_version =
	    a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
	if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW))
		pr_info("  PCnet chip version is %#x\n", chip_version);
	if ((chip_version & 0xfff) != 0x003) {
		if (pcnet32_debug & NETIF_MSG_PROBE)
			pr_info("Unsupported chip version\n");
		goto err_release_region;
	}

	/* initialize variables */
	fdx = mii = fset = dxsuflo = sram = 0;
	chip_version = (chip_version >> 12) & 0xffff;

	switch (chip_version) {
	case 0x2420:
		chipname = "PCnet/PCI 79C970";	/* PCI */
		break;
	case 0x2430:
		if (shared)
			chipname = "PCnet/PCI 79C970";	/* 970 gives the wrong chip id back */
		else
			chipname = "PCnet/32 79C965";	/* 486/VL bus */
		break;
	case 0x2621:
		chipname = "PCnet/PCI II 79C970A";	/* PCI */
		fdx = 1;
		break;
	case 0x2623:
		chipname = "PCnet/FAST 79C971";	/* PCI */
		fdx = 1;
		mii = 1;
		fset = 1;
		break;
	case 0x2624:
		chipname = "PCnet/FAST+ 79C972";	/* PCI */
		fdx = 1;
		mii = 1;
		fset = 1;

Annotation

Implementation Notes