arch/um/drivers/vector_kern.c

Source file repositories/reference/linux-study-clean/arch/um/drivers/vector_kern.c

File Facts

System
Linux kernel
Corpus path
arch/um/drivers/vector_kern.c
Extension
.c
Size
42846 bytes
Lines
1767
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct net_device_ops vector_netdev_ops = {
	.ndo_open		= vector_net_open,
	.ndo_stop		= vector_net_close,
	.ndo_start_xmit		= vector_net_start_xmit,
	.ndo_set_rx_mode	= vector_net_set_multicast_list,
	.ndo_tx_timeout		= vector_net_tx_timeout,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_fix_features	= vector_fix_features,
	.ndo_set_features	= vector_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = vector_net_poll_controller,
#endif
};

static void vector_timer_expire(struct timer_list *t)
{
	struct vector_private *vp = timer_container_of(vp, t, tl);

	vp->estats.tx_kicks++;
	napi_schedule(&vp->napi);
}

static void vector_setup_etheraddr(struct net_device *dev, char *str)
{
	u8 addr[ETH_ALEN];

	if (str == NULL)
		goto random;

	if (!mac_pton(str, addr)) {
		netdev_err(dev,
			"Failed to parse '%s' as an ethernet address\n", str);
		goto random;
	}
	if (is_multicast_ether_addr(addr)) {
		netdev_err(dev,
			"Attempt to assign a multicast ethernet address to a device disallowed\n");
		goto random;
	}
	if (!is_valid_ether_addr(addr)) {
		netdev_err(dev,
			"Attempt to assign an invalid ethernet address to a device disallowed\n");
		goto random;
	}
	if (!is_local_ether_addr(addr)) {
		netdev_warn(dev, "Warning: Assigning a globally valid ethernet address to a device\n");
		netdev_warn(dev, "You should set the 2nd rightmost bit in the first byte of the MAC,\n");
		netdev_warn(dev, "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n",
			addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]);
	}
	eth_hw_addr_set(dev, addr);
	return;

random:
	netdev_info(dev, "Choosing a random ethernet address\n");
	eth_hw_addr_random(dev);
}

static void vector_eth_configure(
		int n,
		struct arglist *def
	)
{
	struct vector_device *device;
	struct net_device *dev;
	struct vector_private *vp;
	int err;

	device = kzalloc_obj(*device);
	if (device == NULL) {
		pr_err("Failed to allocate struct vector_device for vec%d\n", n);
		return;
	}
	dev = alloc_etherdev(sizeof(struct vector_private));
	if (dev == NULL) {
		pr_err("Failed to allocate struct net_device for vec%d\n", n);
		goto out_free_device;
	}

	dev->mtu = get_mtu(def);

	INIT_LIST_HEAD(&device->list);
	device->unit = n;

	/* If this name ends up conflicting with an existing registered
	 * netdevice, that is OK, register_netdev{,ice}() will notice this
	 * and fail.
	 */
	snprintf(dev->name, sizeof(dev->name), "vec%d", n);

Annotation

Implementation Notes