drivers/net/slip/slip.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/slip/slip.c
Extension
.c
Size
34038 bytes
Lines
1442
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 sl_netdev_ops = {
	.ndo_init		= sl_init,
	.ndo_uninit	  	= sl_uninit,
	.ndo_open		= sl_open,
	.ndo_stop		= sl_close,
	.ndo_start_xmit		= sl_xmit,
	.ndo_get_stats64        = sl_get_stats64,
	.ndo_change_mtu		= sl_change_mtu,
	.ndo_tx_timeout		= sl_tx_timeout,
#ifdef CONFIG_SLIP_SMART
	.ndo_siocdevprivate	= sl_siocdevprivate,
#endif
};


static void sl_setup(struct net_device *dev)
{
	dev->netdev_ops		= &sl_netdev_ops;
	dev->needs_free_netdev	= true;
	dev->priv_destructor	= sl_free_netdev;

	dev->hard_header_len	= 0;
	dev->addr_len		= 0;
	dev->tx_queue_len	= 10;

	/* MTU range: 68 - 65534 */
	dev->min_mtu = 68;
	dev->max_mtu = 65534;

	/* New-style flags. */
	dev->flags		= IFF_NOARP|IFF_POINTOPOINT|IFF_MULTICAST;
}

/******************************************
  Routines looking at TTY side.
 ******************************************/


/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of SLIP data has been received, which can now be decapsulated
 * and sent on to some IP layer for further processing. This will not
 * be re-entered while running but other ldisc functions may be called
 * in parallel
 */

static void slip_receive_buf(struct tty_struct *tty, const u8 *cp, const u8 *fp,
			     size_t count)
{
	struct slip *sl = tty->disc_data;

	if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
		return;

	/* Read the characters out of the buffer */
	while (count--) {
		if (fp && *fp++) {
			if (!test_and_set_bit(SLF_ERROR, &sl->flags))
				sl->dev->stats.rx_errors++;
			cp++;
			continue;
		}
#ifdef CONFIG_SLIP_MODE_SLIP6
		if (sl->mode & SL_MODE_SLIP6)
			slip_unesc6(sl, *cp++);
		else
#endif
			slip_unesc(sl, *cp++);
	}
}

/************************************
 *  slip_open helper routines.
 ************************************/

/* Collect hanged up channels */
static void sl_sync(void)
{
	int i;
	struct net_device *dev;
	struct slip	  *sl;

	for (i = 0; i < slip_maxdev; i++) {
		dev = slip_devs[i];
		if (dev == NULL)
			break;

		sl = netdev_priv(dev);
		if (sl->tty || sl->leased)

Annotation

Implementation Notes