drivers/net/ethernet/sun/cassini.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sun/cassini.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sun/cassini.c
Extension
.c
Size
140354 bytes
Lines
5213
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 cas_netdev_ops = {
	.ndo_open		= cas_open,
	.ndo_stop		= cas_close,
	.ndo_start_xmit		= cas_start_xmit,
	.ndo_get_stats 		= cas_get_stats,
	.ndo_set_rx_mode	= cas_set_multicast,
	.ndo_eth_ioctl		= cas_ioctl,
	.ndo_tx_timeout		= cas_tx_timeout,
	.ndo_change_mtu		= cas_change_mtu,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= cas_netpoll,
#endif
};

static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	static int cas_version_printed = 0;
	unsigned long casreg_len;
	struct net_device *dev;
	struct cas *cp;
	u16 pci_cmd;
	int i, err;
	u8 orig_cacheline_size = 0, cas_cacheline_size = 0;

	if (cas_version_printed++ == 0)
		pr_info("%s", version);

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
		return err;
	}

	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
		dev_err(&pdev->dev, "Cannot find proper PCI device "
		       "base address, aborting\n");
		err = -ENODEV;
		goto err_out_disable_pdev;
	}

	dev = alloc_etherdev(sizeof(*cp));
	if (!dev) {
		err = -ENOMEM;
		goto err_out_disable_pdev;
	}
	SET_NETDEV_DEV(dev, &pdev->dev);

	err = pci_request_regions(pdev, dev->name);
	if (err) {
		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
		goto err_out_free_netdev;
	}
	pci_set_master(pdev);

	/* we must always turn on parity response or else parity
	 * doesn't get generated properly. disable SERR/PERR as well.
	 * in addition, we want to turn MWI on.
	 */
	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
	pci_cmd &= ~PCI_COMMAND_SERR;
	pci_cmd |= PCI_COMMAND_PARITY;
	pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
	if (pci_try_set_mwi(pdev))
		pr_warn("Could not enable MWI for %s\n", pci_name(pdev));

	cas_program_bridge(pdev);

	/*
	 * On some architectures, the default cache line size set
	 * by pci_try_set_mwi reduces performance.  We have to increase
	 * it for this case.  To start, we'll print some configuration
	 * data.
	 */
#if 1
	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
			     &orig_cacheline_size);
	if (orig_cacheline_size < CAS_PREF_CACHELINE_SIZE) {
		cas_cacheline_size =
			(CAS_PREF_CACHELINE_SIZE < SMP_CACHE_BYTES) ?
			CAS_PREF_CACHELINE_SIZE : SMP_CACHE_BYTES;
		if (pci_write_config_byte(pdev,
					  PCI_CACHE_LINE_SIZE,
					  cas_cacheline_size)) {
			dev_err(&pdev->dev, "Could not set PCI cache "
			       "line size\n");
			goto err_out_free_res;
		}
	}

Annotation

Implementation Notes