drivers/net/usb/aqc111.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/usb/aqc111.c
Extension
.c
Size
39288 bytes
Lines
1494
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 aqc111_netdev_ops = {
	.ndo_open		= usbnet_open,
	.ndo_stop		= usbnet_stop,
	.ndo_start_xmit		= usbnet_start_xmit,
	.ndo_tx_timeout		= usbnet_tx_timeout,
	.ndo_get_stats64	= dev_get_tstats64,
	.ndo_change_mtu		= aqc111_change_mtu,
	.ndo_set_mac_address	= aqc111_set_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_vlan_rx_add_vid	= aqc111_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid	= aqc111_vlan_rx_kill_vid,
	.ndo_set_rx_mode	= aqc111_set_rx_mode,
	.ndo_set_features	= aqc111_set_features,
};

static int aqc111_read_perm_mac(struct usbnet *dev)
{
	u8 buf[ETH_ALEN];
	int ret;

	ret = aqc111_read_cmd(dev, AQ_FLASH_PARAMETERS, 0, 0, ETH_ALEN, buf);
	if (ret < 0)
		goto out;

	ether_addr_copy(dev->net->perm_addr, buf);

	return 0;
out:
	return ret;
}

static void aqc111_read_fw_version(struct usbnet *dev,
				   struct aqc111_data *aqc111_data)
{
	aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_MAJOR,
			1, 1, &aqc111_data->fw_ver.major);
	aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_MINOR,
			1, 1, &aqc111_data->fw_ver.minor);
	aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_REV,
			1, 1, &aqc111_data->fw_ver.rev);

	if (aqc111_data->fw_ver.major & 0x80)
		aqc111_data->fw_ver.major &= ~0x80;
}

static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	enum usb_device_speed usb_speed = udev->speed;
	struct aqc111_data *aqc111_data;
	int ret;

	/* Check if vendor configuration */
	if (udev->actconfig->desc.bConfigurationValue != 1) {
		usb_driver_set_configuration(udev, 1);
		return -ENODEV;
	}

	usb_reset_configuration(dev->udev);

	ret = usbnet_get_endpoints(dev, intf);
	if (ret < 0) {
		netdev_dbg(dev->net, "usbnet_get_endpoints failed");
		return ret;
	}

	aqc111_data = kzalloc_obj(*aqc111_data);
	if (!aqc111_data)
		return -ENOMEM;

	/* store aqc111_data pointer in device data field */
	dev->driver_priv = aqc111_data;

	/* Init the MAC address */
	ret = aqc111_read_perm_mac(dev);
	if (ret)
		goto out;

	eth_hw_addr_set(dev->net, dev->net->perm_addr);

	/* Set Rx urb size */
	dev->rx_urb_size = URB_SIZE;

	/* Set TX needed headroom & tailroom */
	dev->net->needed_headroom += sizeof(u64);
	dev->net->needed_tailroom += sizeof(u64);

	dev->net->max_mtu = 16334;

	dev->net->netdev_ops = &aqc111_netdev_ops;

Annotation

Implementation Notes