drivers/net/ethernet/8390/etherh.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/8390/etherh.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/8390/etherh.c
Extension
.c
Size
20419 bytes
Lines
859
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 etherh_netdev_ops = {
	.ndo_open		= etherh_open,
	.ndo_stop		= etherh_close,
	.ndo_set_config		= etherh_set_config,
	.ndo_start_xmit		= __ei_start_xmit,
	.ndo_tx_timeout		= __ei_tx_timeout,
	.ndo_get_stats		= __ei_get_stats,
	.ndo_set_rx_mode	= __ei_set_multicast_list,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= __ei_poll,
#endif
};

static u32 etherh_regoffsets[16];
static u32 etherm_regoffsets[16];

static int
etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	const struct etherh_data *data = id->data;
	struct ei_device *ei_local;
	struct net_device *dev;
	struct etherh_priv *eh;
	u8 addr[ETH_ALEN];
	int ret;

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

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

	SET_NETDEV_DEV(dev, &ec->dev);

	dev->netdev_ops		= &etherh_netdev_ops;
	dev->irq		= ec->irq;
	dev->ethtool_ops	= &etherh_ethtool_ops;

	if (data->supported & SUPPORTED_Autoneg)
		dev->flags |= IFF_AUTOMEDIA;
	if (data->supported & SUPPORTED_TP) {
		dev->flags |= IFF_PORTSEL;
		dev->if_port = IF_PORT_10BASET;
	} else if (data->supported & SUPPORTED_BNC) {
		dev->flags |= IFF_PORTSEL;
		dev->if_port = IF_PORT_10BASE2;
	} else
		dev->if_port = IF_PORT_UNKNOWN;

	eh = etherh_priv(dev);
	eh->supported		= data->supported;
	eh->ctrl		= 0;
	eh->id			= ec->cid.product;
	eh->memc		= ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE);
	if (!eh->memc) {
		ret = -ENOMEM;
		goto free;
	}

	eh->ctrl_port = eh->memc;
	if (data->ctrl_ioc) {
		eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, PAGE_SIZE);
		if (!eh->ioc_fast) {
			ret = -ENOMEM;
			goto free;
		}
		eh->ctrl_port = eh->ioc_fast;
	}

	dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
	eh->dma_base = eh->memc + data->dataport_offset;
	eh->ctrl_port += data->ctrlport_offset;

	/*
	 * IRQ and control port handling - only for non-NIC slot cards.
	 */
	if (ec->slot_no != 8) {
		ecard_setirq(ec, &etherh_ops, eh);
	} else {
		/*
		 * If we're in the NIC slot, make sure the IRQ is enabled
		 */
		etherh_set_ctrl(eh, ETHERH_CP_IE);
	}

Annotation

Implementation Notes