drivers/net/can/usb/esd_usb.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/can/usb/esd_usb.c
Extension
.c
Size
37253 bytes
Lines
1410
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 esd_usb_netdev_ops = {
	.ndo_open = esd_usb_open,
	.ndo_stop = esd_usb_close,
	.ndo_start_xmit = esd_usb_start_xmit,
};

static const struct ethtool_ops esd_usb_ethtool_ops = {
	.get_ts_info = ethtool_op_get_ts_info,
};

static const struct can_bittiming_const esd_usb_2_bittiming_const = {
	.name = "esd_usb_2",
	.tseg1_min = 1,
	.tseg1_max = 16,
	.tseg2_min = 1,
	.tseg2_max = 8,
	.sjw_max = 4,
	.brp_min = 1,
	.brp_max = 1024,
	.brp_inc = 1,
};

static int esd_usb_2_set_bittiming(struct net_device *netdev)
{
	const struct can_bittiming_const *btc = &esd_usb_2_bittiming_const;
	struct esd_usb_net_priv *priv = netdev_priv(netdev);
	struct can_bittiming *bt = &priv->can.bittiming;
	union esd_usb_msg *msg;
	int err;
	u32 canbtr;
	int sjw_shift;

	canbtr = ESD_USB_UBR;
	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
		canbtr |= ESD_USB_LOM;

	canbtr |= (bt->brp - 1) & (btc->brp_max - 1);

	if (le16_to_cpu(priv->usb->udev->descriptor.idProduct) ==
	    ESD_USB_CANUSBM_PRODUCT_ID)
		sjw_shift = ESD_USB_M_SJW_SHIFT;
	else
		sjw_shift = ESD_USB_2_SJW_SHIFT;

	canbtr |= ((bt->sjw - 1) & (btc->sjw_max - 1))
		<< sjw_shift;
	canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1)
		   & (btc->tseg1_max - 1))
		<< ESD_USB_2_TSEG1_SHIFT;
	canbtr |= ((bt->phase_seg2 - 1) & (btc->tseg2_max - 1))
		<< ESD_USB_2_TSEG2_SHIFT;
	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
		canbtr |= ESD_USB_TRIPLE_SAMPLES;

	msg = kmalloc_obj(*msg);
	if (!msg)
		return -ENOMEM;

	msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */
	msg->hdr.cmd = ESD_USB_CMD_SETBAUD;
	msg->setbaud.net = priv->index;
	msg->setbaud.rsvd = 0;
	msg->setbaud.baud = cpu_to_le32(canbtr);

	netdev_dbg(netdev, "setting BTR=%#x\n", canbtr);

	err = esd_usb_send_msg(priv->usb, msg);

	kfree(msg);
	return err;
}

/* Nominal bittiming constants, see
 * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022
 * 48.6.8 MCAN Nominal Bit Timing and Prescaler Register
 */
static const struct can_bittiming_const esd_usb_3_nom_bittiming_const = {
	.name = "esd_usb_3",
	.tseg1_min = 2,
	.tseg1_max = 256,
	.tseg2_min = 2,
	.tseg2_max = 128,
	.sjw_max = 128,
	.brp_min = 1,
	.brp_max = 512,
	.brp_inc = 1,
};

/* Data bittiming constants, see
 * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022

Annotation

Implementation Notes