drivers/net/arcnet/arcnet.c

Source file repositories/reference/linux-study-clean/drivers/net/arcnet/arcnet.c

File Facts

System
Linux kernel
Corpus path
drivers/net/arcnet/arcnet.c
Extension
.c
Size
34207 bytes
Lines
1218
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 arcnet_netdev_ops = {
	.ndo_open	= arcnet_open,
	.ndo_stop	= arcnet_close,
	.ndo_start_xmit = arcnet_send_packet,
	.ndo_tx_timeout = arcnet_timeout,
};

/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct net_device *dev)
{
	dev->type = ARPHRD_ARCNET;
	dev->netdev_ops = &arcnet_netdev_ops;
	dev->header_ops = &arcnet_header_ops;
	dev->hard_header_len = sizeof(struct arc_hardware);
	dev->mtu = choose_mtu();

	dev->addr_len = ARCNET_ALEN;
	dev->tx_queue_len = 100;
	dev->broadcast[0] = 0x00;	/* for us, broadcasts are address 0 */
	dev->watchdog_timeo = TX_TIMEOUT;

	/* New-style flags. */
	dev->flags = IFF_BROADCAST;
}

static void arcnet_timer(struct timer_list *t)
{
	struct arcnet_local *lp = timer_container_of(lp, t, timer);
	struct net_device *dev = lp->dev;

	spin_lock_irq(&lp->lock);

	if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
		netif_carrier_on(dev);
		netdev_info(dev, "link up\n");
	}

	spin_unlock_irq(&lp->lock);
}

static void reset_device_work(struct work_struct *work)
{
	struct arcnet_local *lp;
	struct net_device *dev;

	lp = container_of(work, struct arcnet_local, reset_work);
	dev = lp->dev;

	/* Do not bring the network interface back up if an ifdown
	 * was already done.
	 */
	if (!netif_running(dev) || !lp->reset_in_progress)
		return;

	rtnl_lock();

	/* Do another check, in case of an ifdown that was triggered in
	 * the small race window between the exit condition above and
	 * acquiring RTNL.
	 */
	if (!netif_running(dev) || !lp->reset_in_progress)
		goto out;

	dev_close(dev);
	dev_open(dev, NULL);

out:
	rtnl_unlock();
}

static void arcnet_reply_work(struct work_struct *t)
{
	struct arcnet_local *lp = from_work(lp, t, reply_work);

	struct sk_buff *ackskb, *skb;
	struct sock_exterr_skb *serr;
	struct sock *sk;
	int ret;

	local_irq_disable();
	skb = lp->outgoing.skb;
	if (!skb || !skb->sk) {
		local_irq_enable();
		return;
	}

	sock_hold(skb->sk);
	sk = skb->sk;
	ackskb = skb_clone_sk(skb);
	sock_put(skb->sk);

Annotation

Implementation Notes