drivers/net/can/usb/etas_es58x/es581_4.c

Source file repositories/reference/linux-study-clean/drivers/net/can/usb/etas_es58x/es581_4.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/usb/etas_es58x/es581_4.c
Extension
.c
Size
15583 bytes
Lines
508
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source 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

if (tmp_idx == packet_idx - 1) {
			if (net_ratelimit())
				netdev_warn(netdev,
					    "Received echo packet idx %u twice\n",
					    packet_idx - 1);
			dropped++;
			continue;
		}
		if (tmp_idx != packet_idx) {
			netdev_err(netdev, "Echo packet idx jumped from %u to %u\n",
				   packet_idx - 1, echo_msg->packet_idx);
			return -EBADMSG;
		}

		tstamps[i] = get_unaligned_le64(&echo_msg->timestamp);
		packet_idx++;
	}

	netdev->stats.tx_dropped += dropped;
	return es58x_can_get_echo_skb(netdev, first_packet_idx,
				      tstamps, num_element - dropped);
}

static int es581_4_rx_can_msg(struct es58x_device *es58x_dev,
			      const struct es581_4_urb_cmd *es581_4_urb_cmd,
			      u16 msg_len)
{
	const struct device *dev = es58x_dev->dev;
	struct net_device *netdev;
	int pkts, num_element, channel_no, ret;

	num_element = es58x_msg_num_element(dev, es581_4_urb_cmd->rx_can_msg,
					    msg_len);
	if (num_element <= 0)
		return num_element;

	channel_no = es581_4_urb_cmd->rx_can_msg[0].channel_no;
	ret = es58x_get_netdev(es58x_dev, channel_no,
			       ES581_4_CHANNEL_IDX_OFFSET, &netdev);
	if (ret)
		return ret;

	if (!netif_running(netdev)) {
		if (net_ratelimit())
			netdev_info(netdev,
				    "%s: %s is down, dropping %d rx packets\n",
				    __func__, netdev->name, num_element);
		netdev->stats.rx_dropped += num_element;
		return 0;
	}

	for (pkts = 0; pkts < num_element; pkts++) {
		const struct es581_4_rx_can_msg *rx_can_msg =
		    &es581_4_urb_cmd->rx_can_msg[pkts];
		u64 tstamp = get_unaligned_le64(&rx_can_msg->timestamp);
		canid_t can_id = get_unaligned_le32(&rx_can_msg->can_id);

		if (channel_no != rx_can_msg->channel_no)
			return -EBADMSG;

		ret = es58x_rx_can_msg(netdev, tstamp, rx_can_msg->data,
				       can_id, rx_can_msg->flags,
				       rx_can_msg->dlc);
		if (ret)
			break;
	}

	return ret;
}

static int es581_4_rx_err_msg(struct es58x_device *es58x_dev,
			      const struct es581_4_rx_err_msg *rx_err_msg)
{
	struct net_device *netdev;
	enum es58x_err error = get_unaligned_le32(&rx_err_msg->error);
	int ret;

	ret = es58x_get_netdev(es58x_dev, rx_err_msg->channel_no,
			       ES581_4_CHANNEL_IDX_OFFSET, &netdev);
	if (ret)
		return ret;

	return es58x_rx_err_msg(netdev, error, 0,
				get_unaligned_le64(&rx_err_msg->timestamp));
}

static int es581_4_rx_event_msg(struct es58x_device *es58x_dev,
				const struct es581_4_rx_event_msg *rx_event_msg)
{
	struct net_device *netdev;

Annotation

Implementation Notes