drivers/net/usb/sr9800.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/usb/sr9800.c
Extension
.c
Size
20442 bytes
Lines
854
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 sr9800_netdev_ops = {
	.ndo_open		= usbnet_open,
	.ndo_stop		= usbnet_stop,
	.ndo_start_xmit		= usbnet_start_xmit,
	.ndo_tx_timeout		= usbnet_tx_timeout,
	.ndo_change_mtu		= usbnet_change_mtu,
	.ndo_get_stats64	= dev_get_tstats64,
	.ndo_set_mac_address	= sr_set_mac_address,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_eth_ioctl		= usbnet_mii_ioctl,
	.ndo_set_rx_mode        = sr_set_multicast,
};

static int sr9800_phy_powerup(struct usbnet *dev)
{
	int ret;

	/* set the embedded Ethernet PHY in power-down state */
	ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL);
	if (ret < 0) {
		netdev_err(dev->net, "Failed to power down PHY : %d\n", ret);
		return ret;
	}
	msleep(20);

	/* set the embedded Ethernet PHY in power-up state */
	ret = sr_sw_reset(dev, SR_SWRESET_IPRL);
	if (ret < 0) {
		netdev_err(dev->net, "Failed to reset PHY: %d\n", ret);
		return ret;
	}
	msleep(600);

	/* set the embedded Ethernet PHY in reset state */
	ret = sr_sw_reset(dev, SR_SWRESET_CLEAR);
	if (ret < 0) {
		netdev_err(dev->net, "Failed to power up PHY: %d\n", ret);
		return ret;
	}
	msleep(20);

	/* set the embedded Ethernet PHY in power-up state */
	ret = sr_sw_reset(dev, SR_SWRESET_IPRL);
	if (ret < 0) {
		netdev_err(dev->net, "Failed to reset PHY: %d\n", ret);
		return ret;
	}

	return 0;
}

static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf)
{
	struct sr_data *data = (struct sr_data *)&dev->data;
	u16 led01_mux, led23_mux;
	int ret, embd_phy;
	u8 addr[ETH_ALEN];
	u32 phyid;
	u16 rx_ctl;

	data->eeprom_len = SR9800_EEPROM_LEN;

	ret = usbnet_get_endpoints(dev, intf);
	if (ret)
		goto out;

	/* LED Setting Rule :
	 * AABB:CCDD
	 * AA : MFA0(LED0)
	 * BB : MFA1(LED1)
	 * CC : MFA2(LED2), Reserved for SR9800
	 * DD : MFA3(LED3), Reserved for SR9800
	 */
	led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK;
	led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE;
	ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL);
	if (ret < 0) {
			netdev_err(dev->net, "set LINK LED failed : %d\n", ret);
			goto out;
	}

	/* Get the MAC address */
	ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, addr);
	if (ret < 0) {
		netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret);
		return ret;
	}
	eth_hw_addr_set(dev->net, addr);
	netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr);

Annotation

Implementation Notes