drivers/net/wan/lapbether.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wan/lapbether.c
Extension
.c
Size
12479 bytes
Lines
532
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 lapbeth_netdev_ops = {
	.ndo_open	     = lapbeth_open,
	.ndo_stop	     = lapbeth_close,
	.ndo_start_xmit	     = lapbeth_xmit,
	.ndo_set_mac_address = lapbeth_set_mac_address,
};

static void lapbeth_setup(struct net_device *dev)
{
	netdev_lockdep_set_classes(dev);
	dev->netdev_ops	     = &lapbeth_netdev_ops;
	dev->needs_free_netdev = true;
	dev->type            = ARPHRD_X25;
	dev->hard_header_len = 0;
	dev->mtu             = 1000;
	dev->addr_len        = 0;
}

/*	Setup a new device.
 */
static int lapbeth_new_device(struct net_device *dev)
{
	struct net_device *ndev;
	struct lapbethdev *lapbeth;
	int rc = -ENOMEM;

	ASSERT_RTNL();

	if (dev->type != ARPHRD_ETHER)
		return -EINVAL;

	ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN,
			    lapbeth_setup);
	if (!ndev)
		goto out;

	/* When transmitting data:
	 * first this driver removes a pseudo header of 1 byte,
	 * then the lapb module prepends an LAPB header of at most 3 bytes,
	 * then this driver prepends a length field of 2 bytes,
	 * then the underlying Ethernet device prepends its own header.
	 */
	ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len
					   + dev->needed_headroom;
	ndev->needed_tailroom = dev->needed_tailroom;

	lapbeth = netdev_priv(ndev);
	lapbeth->axdev = ndev;

	dev_hold(dev);
	lapbeth->ethdev = dev;

	lapbeth->up = false;
	spin_lock_init(&lapbeth->up_lock);

	skb_queue_head_init(&lapbeth->rx_queue);
	netif_napi_add_weight(ndev, &lapbeth->napi, lapbeth_napi_poll, 16);

	rc = -EIO;
	if (register_netdevice(ndev))
		goto fail;

	list_add_rcu(&lapbeth->node, &lapbeth_devices);
	rc = 0;
out:
	return rc;
fail:
	dev_put(dev);
	free_netdev(ndev);
	goto out;
}

/*	Free a lapb network device.
 */
static void lapbeth_free_device(struct lapbethdev *lapbeth)
{
	dev_put(lapbeth->ethdev);
	list_del_rcu(&lapbeth->node);
	unregister_netdevice(lapbeth->axdev);
}

/*	Handle device status changes.
 *
 * Called from notifier with RTNL held.
 */
static int lapbeth_device_event(struct notifier_block *this,
				unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct lapbethdev *lapbeth;

Annotation

Implementation Notes