drivers/net/ethernet/seeq/ether3.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/seeq/ether3.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/seeq/ether3.c
Extension
.c
Size
23564 bytes
Lines
899
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 ether3_netdev_ops = {
	.ndo_open		= ether3_open,
	.ndo_stop		= ether3_close,
	.ndo_start_xmit		= ether3_sendpacket,
	.ndo_set_rx_mode	= ether3_setmulticastlist,
	.ndo_tx_timeout		= ether3_timeout,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
};

static int
ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	const struct ether3_data *data = id->data;
	struct net_device *dev;
	int bus_type, ret;
	u8 addr[ETH_ALEN];

	ether3_banner();

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	dev = alloc_etherdev(sizeof(struct dev_priv));
	if (!dev) {
		ret = -ENOMEM;
		goto release;
	}

	SET_NETDEV_DEV(dev, &ec->dev);

	priv(dev)->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
	if (!priv(dev)->base) {
		ret = -ENOMEM;
		goto free;
	}

	ec->irqaddr = priv(dev)->base + data->base_offset;
	ec->irqmask = 0xf0;

	priv(dev)->seeq = priv(dev)->base + data->base_offset;
	dev->irq = ec->irq;

	ether3_addr(addr, ec);
	eth_hw_addr_set(dev, addr);

	priv(dev)->dev = dev;
	timer_setup(&priv(dev)->timer, ether3_ledoff, 0);

	/* Reset card...
	 */
	ether3_outb(0x80, REG_CONFIG2 + 4);
	bus_type = BUS_UNKNOWN;
	udelay(4);

	/* Test using Receive Pointer (16-bit register) to find out
	 * how the ether3 is connected to the bus...
	 */
	if (ether3_probe_bus_8(dev, 0x100) &&
	    ether3_probe_bus_8(dev, 0x201))
		bus_type = BUS_8;

	if (bus_type == BUS_UNKNOWN &&
	    ether3_probe_bus_16(dev, 0x101) &&
	    ether3_probe_bus_16(dev, 0x201))
		bus_type = BUS_16;

	switch (bus_type) {
	case BUS_UNKNOWN:
		printk(KERN_ERR "%s: unable to identify bus width\n", dev->name);
		ret = -ENODEV;
		goto free;

	case BUS_8:
		printk(KERN_ERR "%s: %s found, but is an unsupported "
			"8-bit card\n", dev->name, data->name);
		ret = -ENODEV;
		goto free;

	default:
		break;
	}

	if (ether3_init_2(dev)) {
		ret = -ENODEV;
		goto free;
	}

	dev->netdev_ops		= &ether3_netdev_ops;

Annotation

Implementation Notes