162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <socketcan@esd.eu> 662306a36Sopenharmony_ci * Copyright (C) 2022-2023 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/can.h> 1062306a36Sopenharmony_ci#include <linux/can/dev.h> 1162306a36Sopenharmony_ci#include <linux/can/error.h> 1262306a36Sopenharmony_ci#include <linux/ethtool.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/netdevice.h> 1562306a36Sopenharmony_ci#include <linux/signal.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/units.h> 1862306a36Sopenharmony_ci#include <linux/usb.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciMODULE_AUTHOR("Matthias Fuchs <socketcan@esd.eu>"); 2162306a36Sopenharmony_ciMODULE_AUTHOR("Frank Jungclaus <frank.jungclaus@esd.eu>"); 2262306a36Sopenharmony_ciMODULE_DESCRIPTION("CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro interfaces"); 2362306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* USB vendor and product ID */ 2662306a36Sopenharmony_ci#define ESD_USB_ESDGMBH_VENDOR_ID 0x0ab4 2762306a36Sopenharmony_ci#define ESD_USB_CANUSB2_PRODUCT_ID 0x0010 2862306a36Sopenharmony_ci#define ESD_USB_CANUSBM_PRODUCT_ID 0x0011 2962306a36Sopenharmony_ci#define ESD_USB_CANUSB3_PRODUCT_ID 0x0014 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* CAN controller clock frequencies */ 3262306a36Sopenharmony_ci#define ESD_USB_2_CAN_CLOCK (60 * MEGA) /* Hz */ 3362306a36Sopenharmony_ci#define ESD_USB_M_CAN_CLOCK (36 * MEGA) /* Hz */ 3462306a36Sopenharmony_ci#define ESD_USB_3_CAN_CLOCK (80 * MEGA) /* Hz */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* Maximum number of CAN nets */ 3762306a36Sopenharmony_ci#define ESD_USB_MAX_NETS 2 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* USB commands */ 4062306a36Sopenharmony_ci#define ESD_USB_CMD_VERSION 1 /* also used for VERSION_REPLY */ 4162306a36Sopenharmony_ci#define ESD_USB_CMD_CAN_RX 2 /* device to host only */ 4262306a36Sopenharmony_ci#define ESD_USB_CMD_CAN_TX 3 /* also used for TX_DONE */ 4362306a36Sopenharmony_ci#define ESD_USB_CMD_SETBAUD 4 /* also used for SETBAUD_REPLY */ 4462306a36Sopenharmony_ci#define ESD_USB_CMD_TS 5 /* also used for TS_REPLY */ 4562306a36Sopenharmony_ci#define ESD_USB_CMD_IDADD 6 /* also used for IDADD_REPLY */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci/* esd CAN message flags - dlc field */ 4862306a36Sopenharmony_ci#define ESD_USB_RTR BIT(4) 4962306a36Sopenharmony_ci#define ESD_USB_NO_BRS BIT(4) 5062306a36Sopenharmony_ci#define ESD_USB_ESI BIT(5) 5162306a36Sopenharmony_ci#define ESD_USB_FD BIT(7) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* esd CAN message flags - id field */ 5462306a36Sopenharmony_ci#define ESD_USB_EXTID BIT(29) 5562306a36Sopenharmony_ci#define ESD_USB_EVENT BIT(30) 5662306a36Sopenharmony_ci#define ESD_USB_IDMASK GENMASK(28, 0) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* esd CAN event ids */ 5962306a36Sopenharmony_ci#define ESD_USB_EV_CAN_ERROR_EXT 2 /* CAN controller specific diagnostic data */ 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* baudrate message flags */ 6262306a36Sopenharmony_ci#define ESD_USB_LOM BIT(30) /* Listen Only Mode */ 6362306a36Sopenharmony_ci#define ESD_USB_UBR BIT(31) /* User Bit Rate (controller BTR) in bits 0..27 */ 6462306a36Sopenharmony_ci#define ESD_USB_NO_BAUDRATE GENMASK(30, 0) /* bit rate unconfigured */ 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* bit timing esd CAN-USB */ 6762306a36Sopenharmony_ci#define ESD_USB_2_TSEG1_SHIFT 16 6862306a36Sopenharmony_ci#define ESD_USB_2_TSEG2_SHIFT 20 6962306a36Sopenharmony_ci#define ESD_USB_2_SJW_SHIFT 14 7062306a36Sopenharmony_ci#define ESD_USB_M_SJW_SHIFT 24 7162306a36Sopenharmony_ci#define ESD_USB_TRIPLE_SAMPLES BIT(23) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* Transmitter Delay Compensation */ 7462306a36Sopenharmony_ci#define ESD_USB_3_TDC_MODE_AUTO 0 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* esd IDADD message */ 7762306a36Sopenharmony_ci#define ESD_USB_ID_ENABLE BIT(7) 7862306a36Sopenharmony_ci#define ESD_USB_MAX_ID_SEGMENT 64 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/* SJA1000 ECC register (emulated by usb firmware) */ 8162306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_SEG GENMASK(4, 0) 8262306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_DIR BIT(5) 8362306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_ERR BIT(2, 1) 8462306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_BIT 0x00 8562306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_FORM BIT(6) 8662306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_STUFF BIT(7) 8762306a36Sopenharmony_ci#define ESD_USB_SJA1000_ECC_MASK GENMASK(7, 6) 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* esd bus state event codes */ 9062306a36Sopenharmony_ci#define ESD_USB_BUSSTATE_MASK GENMASK(7, 6) 9162306a36Sopenharmony_ci#define ESD_USB_BUSSTATE_WARN BIT(6) 9262306a36Sopenharmony_ci#define ESD_USB_BUSSTATE_ERRPASSIVE BIT(7) 9362306a36Sopenharmony_ci#define ESD_USB_BUSSTATE_BUSOFF GENMASK(7, 6) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#define ESD_USB_RX_BUFFER_SIZE 1024 9662306a36Sopenharmony_ci#define ESD_USB_MAX_RX_URBS 4 9762306a36Sopenharmony_ci#define ESD_USB_MAX_TX_URBS 16 /* must be power of 2 */ 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* Modes for CAN-USB/3, to be used for esd_usb_3_set_baudrate_msg_x.mode */ 10062306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_DISABLE 0 /* remove from bus */ 10162306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_INDEX 1 /* ESD (CiA) bit rate idx */ 10262306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_BTR_CTRL 2 /* BTR values (controller)*/ 10362306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_BTR_CANONICAL 3 /* BTR values (canonical) */ 10462306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_NUM 4 /* numerical bit rate */ 10562306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_MODE_AUTOBAUD 5 /* autobaud */ 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* Flags for CAN-USB/3, to be used for esd_usb_3_set_baudrate_msg_x.flags */ 10862306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_FLAG_FD BIT(0) /* enable CAN FD mode */ 10962306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_FLAG_LOM BIT(1) /* enable listen only mode */ 11062306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_FLAG_STM BIT(2) /* enable self test mode */ 11162306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_FLAG_TRS BIT(3) /* enable triple sampling */ 11262306a36Sopenharmony_ci#define ESD_USB_3_BAUDRATE_FLAG_TXP BIT(4) /* enable transmit pause */ 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistruct esd_usb_header_msg { 11562306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 11662306a36Sopenharmony_ci u8 cmd; 11762306a36Sopenharmony_ci u8 rsvd[2]; 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistruct esd_usb_version_msg { 12162306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 12262306a36Sopenharmony_ci u8 cmd; 12362306a36Sopenharmony_ci u8 rsvd; 12462306a36Sopenharmony_ci u8 flags; 12562306a36Sopenharmony_ci __le32 drv_version; 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistruct esd_usb_version_reply_msg { 12962306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 13062306a36Sopenharmony_ci u8 cmd; 13162306a36Sopenharmony_ci u8 nets; 13262306a36Sopenharmony_ci u8 features; 13362306a36Sopenharmony_ci __le32 version; 13462306a36Sopenharmony_ci u8 name[16]; 13562306a36Sopenharmony_ci __le32 rsvd; 13662306a36Sopenharmony_ci __le32 ts; 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistruct esd_usb_rx_msg { 14062306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 14162306a36Sopenharmony_ci u8 cmd; 14262306a36Sopenharmony_ci u8 net; 14362306a36Sopenharmony_ci u8 dlc; 14462306a36Sopenharmony_ci __le32 ts; 14562306a36Sopenharmony_ci __le32 id; /* upper 3 bits contain flags */ 14662306a36Sopenharmony_ci union { 14762306a36Sopenharmony_ci u8 data[CAN_MAX_DLEN]; 14862306a36Sopenharmony_ci u8 data_fd[CANFD_MAX_DLEN]; 14962306a36Sopenharmony_ci struct { 15062306a36Sopenharmony_ci u8 status; /* CAN Controller Status */ 15162306a36Sopenharmony_ci u8 ecc; /* Error Capture Register */ 15262306a36Sopenharmony_ci u8 rec; /* RX Error Counter */ 15362306a36Sopenharmony_ci u8 tec; /* TX Error Counter */ 15462306a36Sopenharmony_ci } ev_can_err_ext; /* For ESD_EV_CAN_ERROR_EXT */ 15562306a36Sopenharmony_ci }; 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistruct esd_usb_tx_msg { 15962306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 16062306a36Sopenharmony_ci u8 cmd; 16162306a36Sopenharmony_ci u8 net; 16262306a36Sopenharmony_ci u8 dlc; 16362306a36Sopenharmony_ci u32 hnd; /* opaque handle, not used by device */ 16462306a36Sopenharmony_ci __le32 id; /* upper 3 bits contain flags */ 16562306a36Sopenharmony_ci union { 16662306a36Sopenharmony_ci u8 data[CAN_MAX_DLEN]; 16762306a36Sopenharmony_ci u8 data_fd[CANFD_MAX_DLEN]; 16862306a36Sopenharmony_ci }; 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistruct esd_usb_tx_done_msg { 17262306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 17362306a36Sopenharmony_ci u8 cmd; 17462306a36Sopenharmony_ci u8 net; 17562306a36Sopenharmony_ci u8 status; 17662306a36Sopenharmony_ci u32 hnd; /* opaque handle, not used by device */ 17762306a36Sopenharmony_ci __le32 ts; 17862306a36Sopenharmony_ci}; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_cistruct esd_usb_id_filter_msg { 18162306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 18262306a36Sopenharmony_ci u8 cmd; 18362306a36Sopenharmony_ci u8 net; 18462306a36Sopenharmony_ci u8 option; 18562306a36Sopenharmony_ci __le32 mask[ESD_USB_MAX_ID_SEGMENT + 1]; /* +1 for 29bit extended IDs */ 18662306a36Sopenharmony_ci}; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistruct esd_usb_set_baudrate_msg { 18962306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 19062306a36Sopenharmony_ci u8 cmd; 19162306a36Sopenharmony_ci u8 net; 19262306a36Sopenharmony_ci u8 rsvd; 19362306a36Sopenharmony_ci __le32 baud; 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* CAN-USB/3 baudrate configuration, used for nominal as well as for data bit rate */ 19762306a36Sopenharmony_cistruct esd_usb_3_baudrate_cfg { 19862306a36Sopenharmony_ci __le16 brp; /* bit rate pre-scaler */ 19962306a36Sopenharmony_ci __le16 tseg1; /* time segment before sample point */ 20062306a36Sopenharmony_ci __le16 tseg2; /* time segment after sample point */ 20162306a36Sopenharmony_ci __le16 sjw; /* synchronization jump Width */ 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* In principle, the esd CAN-USB/3 supports Transmitter Delay Compensation (TDC), 20562306a36Sopenharmony_ci * but currently only the automatic TDC mode is supported by this driver. 20662306a36Sopenharmony_ci * An implementation for manual TDC configuration will follow. 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * For information about struct esd_usb_3_tdc_cfg, see 20962306a36Sopenharmony_ci * NTCAN Application Developers Manual, 6.2.25 NTCAN_TDC_CFG + related chapters 21062306a36Sopenharmony_ci * https://esd.eu/fileadmin/esd/docs/manuals/NTCAN_Part1_Function_API_Manual_en_56.pdf 21162306a36Sopenharmony_ci */ 21262306a36Sopenharmony_cistruct esd_usb_3_tdc_cfg { 21362306a36Sopenharmony_ci u8 tdc_mode; /* transmitter delay compensation mode */ 21462306a36Sopenharmony_ci u8 ssp_offset; /* secondary sample point offset in mtq */ 21562306a36Sopenharmony_ci s8 ssp_shift; /* secondary sample point shift in mtq */ 21662306a36Sopenharmony_ci u8 tdc_filter; /* TDC filter in mtq */ 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci/* Extended version of the above set_baudrate_msg for a CAN-USB/3 22062306a36Sopenharmony_ci * to define the CAN bit timing configuration of the CAN controller in 22162306a36Sopenharmony_ci * CAN FD mode as well as in Classical CAN mode. 22262306a36Sopenharmony_ci * 22362306a36Sopenharmony_ci * The payload of this command is a NTCAN_BAUDRATE_X structure according to 22462306a36Sopenharmony_ci * esd electronics gmbh, NTCAN Application Developers Manual, 6.2.15 NTCAN_BAUDRATE_X 22562306a36Sopenharmony_ci * https://esd.eu/fileadmin/esd/docs/manuals/NTCAN_Part1_Function_API_Manual_en_56.pdf 22662306a36Sopenharmony_ci */ 22762306a36Sopenharmony_cistruct esd_usb_3_set_baudrate_msg_x { 22862306a36Sopenharmony_ci u8 len; /* total message length in 32bit words */ 22962306a36Sopenharmony_ci u8 cmd; 23062306a36Sopenharmony_ci u8 net; 23162306a36Sopenharmony_ci u8 rsvd; /*reserved */ 23262306a36Sopenharmony_ci /* Payload ... */ 23362306a36Sopenharmony_ci __le16 mode; /* mode word, see ESD_USB_3_BAUDRATE_MODE_xxx */ 23462306a36Sopenharmony_ci __le16 flags; /* control flags, see ESD_USB_3_BAUDRATE_FLAG_xxx */ 23562306a36Sopenharmony_ci struct esd_usb_3_tdc_cfg tdc; /* TDC configuration */ 23662306a36Sopenharmony_ci struct esd_usb_3_baudrate_cfg nom; /* nominal bit rate */ 23762306a36Sopenharmony_ci struct esd_usb_3_baudrate_cfg data; /* data bit rate */ 23862306a36Sopenharmony_ci}; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* Main message type used between library and application */ 24162306a36Sopenharmony_ciunion __packed esd_usb_msg { 24262306a36Sopenharmony_ci struct esd_usb_header_msg hdr; 24362306a36Sopenharmony_ci struct esd_usb_version_msg version; 24462306a36Sopenharmony_ci struct esd_usb_version_reply_msg version_reply; 24562306a36Sopenharmony_ci struct esd_usb_rx_msg rx; 24662306a36Sopenharmony_ci struct esd_usb_tx_msg tx; 24762306a36Sopenharmony_ci struct esd_usb_tx_done_msg txdone; 24862306a36Sopenharmony_ci struct esd_usb_set_baudrate_msg setbaud; 24962306a36Sopenharmony_ci struct esd_usb_3_set_baudrate_msg_x setbaud_x; 25062306a36Sopenharmony_ci struct esd_usb_id_filter_msg filter; 25162306a36Sopenharmony_ci}; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic struct usb_device_id esd_usb_table[] = { 25462306a36Sopenharmony_ci {USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSB2_PRODUCT_ID)}, 25562306a36Sopenharmony_ci {USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSBM_PRODUCT_ID)}, 25662306a36Sopenharmony_ci {USB_DEVICE(ESD_USB_ESDGMBH_VENDOR_ID, ESD_USB_CANUSB3_PRODUCT_ID)}, 25762306a36Sopenharmony_ci {} 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, esd_usb_table); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistruct esd_usb_net_priv; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistruct esd_tx_urb_context { 26462306a36Sopenharmony_ci struct esd_usb_net_priv *priv; 26562306a36Sopenharmony_ci u32 echo_index; 26662306a36Sopenharmony_ci}; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cistruct esd_usb { 26962306a36Sopenharmony_ci struct usb_device *udev; 27062306a36Sopenharmony_ci struct esd_usb_net_priv *nets[ESD_USB_MAX_NETS]; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci struct usb_anchor rx_submitted; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci int net_count; 27562306a36Sopenharmony_ci u32 version; 27662306a36Sopenharmony_ci int rxinitdone; 27762306a36Sopenharmony_ci void *rxbuf[ESD_USB_MAX_RX_URBS]; 27862306a36Sopenharmony_ci dma_addr_t rxbuf_dma[ESD_USB_MAX_RX_URBS]; 27962306a36Sopenharmony_ci}; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistruct esd_usb_net_priv { 28262306a36Sopenharmony_ci struct can_priv can; /* must be the first member */ 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci atomic_t active_tx_jobs; 28562306a36Sopenharmony_ci struct usb_anchor tx_submitted; 28662306a36Sopenharmony_ci struct esd_tx_urb_context tx_contexts[ESD_USB_MAX_TX_URBS]; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci struct esd_usb *usb; 28962306a36Sopenharmony_ci struct net_device *netdev; 29062306a36Sopenharmony_ci int index; 29162306a36Sopenharmony_ci u8 old_state; 29262306a36Sopenharmony_ci struct can_berr_counter bec; 29362306a36Sopenharmony_ci}; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic void esd_usb_rx_event(struct esd_usb_net_priv *priv, 29662306a36Sopenharmony_ci union esd_usb_msg *msg) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci struct net_device_stats *stats = &priv->netdev->stats; 29962306a36Sopenharmony_ci struct can_frame *cf; 30062306a36Sopenharmony_ci struct sk_buff *skb; 30162306a36Sopenharmony_ci u32 id = le32_to_cpu(msg->rx.id) & ESD_USB_IDMASK; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci if (id == ESD_USB_EV_CAN_ERROR_EXT) { 30462306a36Sopenharmony_ci u8 state = msg->rx.ev_can_err_ext.status; 30562306a36Sopenharmony_ci u8 ecc = msg->rx.ev_can_err_ext.ecc; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci priv->bec.rxerr = msg->rx.ev_can_err_ext.rec; 30862306a36Sopenharmony_ci priv->bec.txerr = msg->rx.ev_can_err_ext.tec; 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci netdev_dbg(priv->netdev, 31162306a36Sopenharmony_ci "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n", 31262306a36Sopenharmony_ci msg->rx.dlc, state, ecc, 31362306a36Sopenharmony_ci priv->bec.rxerr, priv->bec.txerr); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* if berr-reporting is off, only pass through on state change ... */ 31662306a36Sopenharmony_ci if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && 31762306a36Sopenharmony_ci state == priv->old_state) 31862306a36Sopenharmony_ci return; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci skb = alloc_can_err_skb(priv->netdev, &cf); 32162306a36Sopenharmony_ci if (!skb) 32262306a36Sopenharmony_ci stats->rx_dropped++; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (state != priv->old_state) { 32562306a36Sopenharmony_ci enum can_state tx_state, rx_state; 32662306a36Sopenharmony_ci enum can_state new_state = CAN_STATE_ERROR_ACTIVE; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci priv->old_state = state; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci switch (state & ESD_USB_BUSSTATE_MASK) { 33162306a36Sopenharmony_ci case ESD_USB_BUSSTATE_BUSOFF: 33262306a36Sopenharmony_ci new_state = CAN_STATE_BUS_OFF; 33362306a36Sopenharmony_ci can_bus_off(priv->netdev); 33462306a36Sopenharmony_ci break; 33562306a36Sopenharmony_ci case ESD_USB_BUSSTATE_WARN: 33662306a36Sopenharmony_ci new_state = CAN_STATE_ERROR_WARNING; 33762306a36Sopenharmony_ci break; 33862306a36Sopenharmony_ci case ESD_USB_BUSSTATE_ERRPASSIVE: 33962306a36Sopenharmony_ci new_state = CAN_STATE_ERROR_PASSIVE; 34062306a36Sopenharmony_ci break; 34162306a36Sopenharmony_ci default: 34262306a36Sopenharmony_ci new_state = CAN_STATE_ERROR_ACTIVE; 34362306a36Sopenharmony_ci priv->bec.txerr = 0; 34462306a36Sopenharmony_ci priv->bec.rxerr = 0; 34562306a36Sopenharmony_ci break; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (new_state != priv->can.state) { 34962306a36Sopenharmony_ci tx_state = (priv->bec.txerr >= priv->bec.rxerr) ? new_state : 0; 35062306a36Sopenharmony_ci rx_state = (priv->bec.txerr <= priv->bec.rxerr) ? new_state : 0; 35162306a36Sopenharmony_ci can_change_state(priv->netdev, cf, 35262306a36Sopenharmony_ci tx_state, rx_state); 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci } else if (skb) { 35562306a36Sopenharmony_ci priv->can.can_stats.bus_error++; 35662306a36Sopenharmony_ci stats->rx_errors++; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci switch (ecc & ESD_USB_SJA1000_ECC_MASK) { 36162306a36Sopenharmony_ci case ESD_USB_SJA1000_ECC_BIT: 36262306a36Sopenharmony_ci cf->data[2] |= CAN_ERR_PROT_BIT; 36362306a36Sopenharmony_ci break; 36462306a36Sopenharmony_ci case ESD_USB_SJA1000_ECC_FORM: 36562306a36Sopenharmony_ci cf->data[2] |= CAN_ERR_PROT_FORM; 36662306a36Sopenharmony_ci break; 36762306a36Sopenharmony_ci case ESD_USB_SJA1000_ECC_STUFF: 36862306a36Sopenharmony_ci cf->data[2] |= CAN_ERR_PROT_STUFF; 36962306a36Sopenharmony_ci break; 37062306a36Sopenharmony_ci default: 37162306a36Sopenharmony_ci break; 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* Error occurred during transmission? */ 37562306a36Sopenharmony_ci if (!(ecc & ESD_USB_SJA1000_ECC_DIR)) 37662306a36Sopenharmony_ci cf->data[2] |= CAN_ERR_PROT_TX; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci /* Bit stream position in CAN frame as the error was detected */ 37962306a36Sopenharmony_ci cf->data[3] = ecc & ESD_USB_SJA1000_ECC_SEG; 38062306a36Sopenharmony_ci } 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci if (skb) { 38362306a36Sopenharmony_ci cf->can_id |= CAN_ERR_CNT; 38462306a36Sopenharmony_ci cf->data[6] = priv->bec.txerr; 38562306a36Sopenharmony_ci cf->data[7] = priv->bec.rxerr; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci netif_rx(skb); 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci } 39062306a36Sopenharmony_ci} 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_cistatic void esd_usb_rx_can_msg(struct esd_usb_net_priv *priv, 39362306a36Sopenharmony_ci union esd_usb_msg *msg) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci struct net_device_stats *stats = &priv->netdev->stats; 39662306a36Sopenharmony_ci struct can_frame *cf; 39762306a36Sopenharmony_ci struct canfd_frame *cfd; 39862306a36Sopenharmony_ci struct sk_buff *skb; 39962306a36Sopenharmony_ci u32 id; 40062306a36Sopenharmony_ci u8 len; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci if (!netif_device_present(priv->netdev)) 40362306a36Sopenharmony_ci return; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci id = le32_to_cpu(msg->rx.id); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci if (id & ESD_USB_EVENT) { 40862306a36Sopenharmony_ci esd_usb_rx_event(priv, msg); 40962306a36Sopenharmony_ci } else { 41062306a36Sopenharmony_ci if (msg->rx.dlc & ESD_USB_FD) { 41162306a36Sopenharmony_ci skb = alloc_canfd_skb(priv->netdev, &cfd); 41262306a36Sopenharmony_ci } else { 41362306a36Sopenharmony_ci skb = alloc_can_skb(priv->netdev, &cf); 41462306a36Sopenharmony_ci cfd = (struct canfd_frame *)cf; 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci if (skb == NULL) { 41862306a36Sopenharmony_ci stats->rx_dropped++; 41962306a36Sopenharmony_ci return; 42062306a36Sopenharmony_ci } 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci cfd->can_id = id & ESD_USB_IDMASK; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci if (msg->rx.dlc & ESD_USB_FD) { 42562306a36Sopenharmony_ci /* masking by 0x0F is already done within can_fd_dlc2len() */ 42662306a36Sopenharmony_ci cfd->len = can_fd_dlc2len(msg->rx.dlc); 42762306a36Sopenharmony_ci len = cfd->len; 42862306a36Sopenharmony_ci if ((msg->rx.dlc & ESD_USB_NO_BRS) == 0) 42962306a36Sopenharmony_ci cfd->flags |= CANFD_BRS; 43062306a36Sopenharmony_ci if (msg->rx.dlc & ESD_USB_ESI) 43162306a36Sopenharmony_ci cfd->flags |= CANFD_ESI; 43262306a36Sopenharmony_ci } else { 43362306a36Sopenharmony_ci can_frame_set_cc_len(cf, msg->rx.dlc & ~ESD_USB_RTR, priv->can.ctrlmode); 43462306a36Sopenharmony_ci len = cf->len; 43562306a36Sopenharmony_ci if (msg->rx.dlc & ESD_USB_RTR) { 43662306a36Sopenharmony_ci cf->can_id |= CAN_RTR_FLAG; 43762306a36Sopenharmony_ci len = 0; 43862306a36Sopenharmony_ci } 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci if (id & ESD_USB_EXTID) 44262306a36Sopenharmony_ci cfd->can_id |= CAN_EFF_FLAG; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci memcpy(cfd->data, msg->rx.data_fd, len); 44562306a36Sopenharmony_ci stats->rx_bytes += len; 44662306a36Sopenharmony_ci stats->rx_packets++; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci netif_rx(skb); 44962306a36Sopenharmony_ci } 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_cistatic void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv, 45362306a36Sopenharmony_ci union esd_usb_msg *msg) 45462306a36Sopenharmony_ci{ 45562306a36Sopenharmony_ci struct net_device_stats *stats = &priv->netdev->stats; 45662306a36Sopenharmony_ci struct net_device *netdev = priv->netdev; 45762306a36Sopenharmony_ci struct esd_tx_urb_context *context; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci if (!netif_device_present(netdev)) 46062306a36Sopenharmony_ci return; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci context = &priv->tx_contexts[msg->txdone.hnd & (ESD_USB_MAX_TX_URBS - 1)]; 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci if (!msg->txdone.status) { 46562306a36Sopenharmony_ci stats->tx_packets++; 46662306a36Sopenharmony_ci stats->tx_bytes += can_get_echo_skb(netdev, context->echo_index, 46762306a36Sopenharmony_ci NULL); 46862306a36Sopenharmony_ci } else { 46962306a36Sopenharmony_ci stats->tx_errors++; 47062306a36Sopenharmony_ci can_free_echo_skb(netdev, context->echo_index, NULL); 47162306a36Sopenharmony_ci } 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci /* Release context */ 47462306a36Sopenharmony_ci context->echo_index = ESD_USB_MAX_TX_URBS; 47562306a36Sopenharmony_ci atomic_dec(&priv->active_tx_jobs); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci netif_wake_queue(netdev); 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_cistatic void esd_usb_read_bulk_callback(struct urb *urb) 48162306a36Sopenharmony_ci{ 48262306a36Sopenharmony_ci struct esd_usb *dev = urb->context; 48362306a36Sopenharmony_ci int retval; 48462306a36Sopenharmony_ci int pos = 0; 48562306a36Sopenharmony_ci int i; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci switch (urb->status) { 48862306a36Sopenharmony_ci case 0: /* success */ 48962306a36Sopenharmony_ci break; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci case -ENOENT: 49262306a36Sopenharmony_ci case -EPIPE: 49362306a36Sopenharmony_ci case -EPROTO: 49462306a36Sopenharmony_ci case -ESHUTDOWN: 49562306a36Sopenharmony_ci return; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci default: 49862306a36Sopenharmony_ci dev_info(dev->udev->dev.parent, 49962306a36Sopenharmony_ci "Rx URB aborted (%d)\n", urb->status); 50062306a36Sopenharmony_ci goto resubmit_urb; 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci while (pos < urb->actual_length) { 50462306a36Sopenharmony_ci union esd_usb_msg *msg; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci msg = (union esd_usb_msg *)(urb->transfer_buffer + pos); 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci switch (msg->hdr.cmd) { 50962306a36Sopenharmony_ci case ESD_USB_CMD_CAN_RX: 51062306a36Sopenharmony_ci if (msg->rx.net >= dev->net_count) { 51162306a36Sopenharmony_ci dev_err(dev->udev->dev.parent, "format error\n"); 51262306a36Sopenharmony_ci break; 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci esd_usb_rx_can_msg(dev->nets[msg->rx.net], msg); 51662306a36Sopenharmony_ci break; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci case ESD_USB_CMD_CAN_TX: 51962306a36Sopenharmony_ci if (msg->txdone.net >= dev->net_count) { 52062306a36Sopenharmony_ci dev_err(dev->udev->dev.parent, "format error\n"); 52162306a36Sopenharmony_ci break; 52262306a36Sopenharmony_ci } 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci esd_usb_tx_done_msg(dev->nets[msg->txdone.net], 52562306a36Sopenharmony_ci msg); 52662306a36Sopenharmony_ci break; 52762306a36Sopenharmony_ci } 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci pos += msg->hdr.len * sizeof(u32); /* convert to # of bytes */ 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci if (pos > urb->actual_length) { 53262306a36Sopenharmony_ci dev_err(dev->udev->dev.parent, "format error\n"); 53362306a36Sopenharmony_ci break; 53462306a36Sopenharmony_ci } 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ciresubmit_urb: 53862306a36Sopenharmony_ci usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), 53962306a36Sopenharmony_ci urb->transfer_buffer, ESD_USB_RX_BUFFER_SIZE, 54062306a36Sopenharmony_ci esd_usb_read_bulk_callback, dev); 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci retval = usb_submit_urb(urb, GFP_ATOMIC); 54362306a36Sopenharmony_ci if (retval == -ENODEV) { 54462306a36Sopenharmony_ci for (i = 0; i < dev->net_count; i++) { 54562306a36Sopenharmony_ci if (dev->nets[i]) 54662306a36Sopenharmony_ci netif_device_detach(dev->nets[i]->netdev); 54762306a36Sopenharmony_ci } 54862306a36Sopenharmony_ci } else if (retval) { 54962306a36Sopenharmony_ci dev_err(dev->udev->dev.parent, 55062306a36Sopenharmony_ci "failed resubmitting read bulk urb: %d\n", retval); 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci/* callback for bulk IN urb */ 55562306a36Sopenharmony_cistatic void esd_usb_write_bulk_callback(struct urb *urb) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci struct esd_tx_urb_context *context = urb->context; 55862306a36Sopenharmony_ci struct esd_usb_net_priv *priv; 55962306a36Sopenharmony_ci struct net_device *netdev; 56062306a36Sopenharmony_ci size_t size = sizeof(union esd_usb_msg); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci WARN_ON(!context); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci priv = context->priv; 56562306a36Sopenharmony_ci netdev = priv->netdev; 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci /* free up our allocated buffer */ 56862306a36Sopenharmony_ci usb_free_coherent(urb->dev, size, 56962306a36Sopenharmony_ci urb->transfer_buffer, urb->transfer_dma); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci if (!netif_device_present(netdev)) 57262306a36Sopenharmony_ci return; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci if (urb->status) 57562306a36Sopenharmony_ci netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci netif_trans_update(netdev); 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic ssize_t firmware_show(struct device *d, 58162306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci struct usb_interface *intf = to_usb_interface(d); 58462306a36Sopenharmony_ci struct esd_usb *dev = usb_get_intfdata(intf); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci return sprintf(buf, "%d.%d.%d\n", 58762306a36Sopenharmony_ci (dev->version >> 12) & 0xf, 58862306a36Sopenharmony_ci (dev->version >> 8) & 0xf, 58962306a36Sopenharmony_ci dev->version & 0xff); 59062306a36Sopenharmony_ci} 59162306a36Sopenharmony_cistatic DEVICE_ATTR_RO(firmware); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_cistatic ssize_t hardware_show(struct device *d, 59462306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 59562306a36Sopenharmony_ci{ 59662306a36Sopenharmony_ci struct usb_interface *intf = to_usb_interface(d); 59762306a36Sopenharmony_ci struct esd_usb *dev = usb_get_intfdata(intf); 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci return sprintf(buf, "%d.%d.%d\n", 60062306a36Sopenharmony_ci (dev->version >> 28) & 0xf, 60162306a36Sopenharmony_ci (dev->version >> 24) & 0xf, 60262306a36Sopenharmony_ci (dev->version >> 16) & 0xff); 60362306a36Sopenharmony_ci} 60462306a36Sopenharmony_cistatic DEVICE_ATTR_RO(hardware); 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_cistatic ssize_t nets_show(struct device *d, 60762306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 60862306a36Sopenharmony_ci{ 60962306a36Sopenharmony_ci struct usb_interface *intf = to_usb_interface(d); 61062306a36Sopenharmony_ci struct esd_usb *dev = usb_get_intfdata(intf); 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci return sprintf(buf, "%d", dev->net_count); 61362306a36Sopenharmony_ci} 61462306a36Sopenharmony_cistatic DEVICE_ATTR_RO(nets); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic int esd_usb_send_msg(struct esd_usb *dev, union esd_usb_msg *msg) 61762306a36Sopenharmony_ci{ 61862306a36Sopenharmony_ci int actual_length; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci return usb_bulk_msg(dev->udev, 62162306a36Sopenharmony_ci usb_sndbulkpipe(dev->udev, 2), 62262306a36Sopenharmony_ci msg, 62362306a36Sopenharmony_ci msg->hdr.len * sizeof(u32), /* convert to # of bytes */ 62462306a36Sopenharmony_ci &actual_length, 62562306a36Sopenharmony_ci 1000); 62662306a36Sopenharmony_ci} 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_cistatic int esd_usb_wait_msg(struct esd_usb *dev, 62962306a36Sopenharmony_ci union esd_usb_msg *msg) 63062306a36Sopenharmony_ci{ 63162306a36Sopenharmony_ci int actual_length; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci return usb_bulk_msg(dev->udev, 63462306a36Sopenharmony_ci usb_rcvbulkpipe(dev->udev, 1), 63562306a36Sopenharmony_ci msg, 63662306a36Sopenharmony_ci sizeof(*msg), 63762306a36Sopenharmony_ci &actual_length, 63862306a36Sopenharmony_ci 1000); 63962306a36Sopenharmony_ci} 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_cistatic int esd_usb_setup_rx_urbs(struct esd_usb *dev) 64262306a36Sopenharmony_ci{ 64362306a36Sopenharmony_ci int i, err = 0; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci if (dev->rxinitdone) 64662306a36Sopenharmony_ci return 0; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci for (i = 0; i < ESD_USB_MAX_RX_URBS; i++) { 64962306a36Sopenharmony_ci struct urb *urb = NULL; 65062306a36Sopenharmony_ci u8 *buf = NULL; 65162306a36Sopenharmony_ci dma_addr_t buf_dma; 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci /* create a URB, and a buffer for it */ 65462306a36Sopenharmony_ci urb = usb_alloc_urb(0, GFP_KERNEL); 65562306a36Sopenharmony_ci if (!urb) { 65662306a36Sopenharmony_ci err = -ENOMEM; 65762306a36Sopenharmony_ci break; 65862306a36Sopenharmony_ci } 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci buf = usb_alloc_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE, GFP_KERNEL, 66162306a36Sopenharmony_ci &buf_dma); 66262306a36Sopenharmony_ci if (!buf) { 66362306a36Sopenharmony_ci dev_warn(dev->udev->dev.parent, 66462306a36Sopenharmony_ci "No memory left for USB buffer\n"); 66562306a36Sopenharmony_ci err = -ENOMEM; 66662306a36Sopenharmony_ci goto freeurb; 66762306a36Sopenharmony_ci } 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci urb->transfer_dma = buf_dma; 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci usb_fill_bulk_urb(urb, dev->udev, 67262306a36Sopenharmony_ci usb_rcvbulkpipe(dev->udev, 1), 67362306a36Sopenharmony_ci buf, ESD_USB_RX_BUFFER_SIZE, 67462306a36Sopenharmony_ci esd_usb_read_bulk_callback, dev); 67562306a36Sopenharmony_ci urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 67662306a36Sopenharmony_ci usb_anchor_urb(urb, &dev->rx_submitted); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_ci err = usb_submit_urb(urb, GFP_KERNEL); 67962306a36Sopenharmony_ci if (err) { 68062306a36Sopenharmony_ci usb_unanchor_urb(urb); 68162306a36Sopenharmony_ci usb_free_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE, buf, 68262306a36Sopenharmony_ci urb->transfer_dma); 68362306a36Sopenharmony_ci goto freeurb; 68462306a36Sopenharmony_ci } 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci dev->rxbuf[i] = buf; 68762306a36Sopenharmony_ci dev->rxbuf_dma[i] = buf_dma; 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_cifreeurb: 69062306a36Sopenharmony_ci /* Drop reference, USB core will take care of freeing it */ 69162306a36Sopenharmony_ci usb_free_urb(urb); 69262306a36Sopenharmony_ci if (err) 69362306a36Sopenharmony_ci break; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci /* Did we submit any URBs */ 69762306a36Sopenharmony_ci if (i == 0) { 69862306a36Sopenharmony_ci dev_err(dev->udev->dev.parent, "couldn't setup read URBs\n"); 69962306a36Sopenharmony_ci return err; 70062306a36Sopenharmony_ci } 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci /* Warn if we've couldn't transmit all the URBs */ 70362306a36Sopenharmony_ci if (i < ESD_USB_MAX_RX_URBS) { 70462306a36Sopenharmony_ci dev_warn(dev->udev->dev.parent, 70562306a36Sopenharmony_ci "rx performance may be slow\n"); 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci dev->rxinitdone = 1; 70962306a36Sopenharmony_ci return 0; 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci/* Start interface */ 71362306a36Sopenharmony_cistatic int esd_usb_start(struct esd_usb_net_priv *priv) 71462306a36Sopenharmony_ci{ 71562306a36Sopenharmony_ci struct esd_usb *dev = priv->usb; 71662306a36Sopenharmony_ci struct net_device *netdev = priv->netdev; 71762306a36Sopenharmony_ci union esd_usb_msg *msg; 71862306a36Sopenharmony_ci int err, i; 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci msg = kmalloc(sizeof(*msg), GFP_KERNEL); 72162306a36Sopenharmony_ci if (!msg) { 72262306a36Sopenharmony_ci err = -ENOMEM; 72362306a36Sopenharmony_ci goto out; 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* Enable all IDs 72762306a36Sopenharmony_ci * The IDADD message takes up to 64 32 bit bitmasks (2048 bits). 72862306a36Sopenharmony_ci * Each bit represents one 11 bit CAN identifier. A set bit 72962306a36Sopenharmony_ci * enables reception of the corresponding CAN identifier. A cleared 73062306a36Sopenharmony_ci * bit disabled this identifier. An additional bitmask value 73162306a36Sopenharmony_ci * following the CAN 2.0A bits is used to enable reception of 73262306a36Sopenharmony_ci * extended CAN frames. Only the LSB of this final mask is checked 73362306a36Sopenharmony_ci * for the complete 29 bit ID range. The IDADD message also allows 73462306a36Sopenharmony_ci * filter configuration for an ID subset. In this case you can add 73562306a36Sopenharmony_ci * the number of the starting bitmask (0..64) to the filter.option 73662306a36Sopenharmony_ci * field followed by only some bitmasks. 73762306a36Sopenharmony_ci */ 73862306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_IDADD; 73962306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_id_filter_msg) / sizeof(u32); /* # of 32bit words */ 74062306a36Sopenharmony_ci msg->filter.net = priv->index; 74162306a36Sopenharmony_ci msg->filter.option = ESD_USB_ID_ENABLE; /* start with segment 0 */ 74262306a36Sopenharmony_ci for (i = 0; i < ESD_USB_MAX_ID_SEGMENT; i++) 74362306a36Sopenharmony_ci msg->filter.mask[i] = cpu_to_le32(GENMASK(31, 0)); 74462306a36Sopenharmony_ci /* enable 29bit extended IDs */ 74562306a36Sopenharmony_ci msg->filter.mask[ESD_USB_MAX_ID_SEGMENT] = cpu_to_le32(BIT(0)); 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci err = esd_usb_send_msg(dev, msg); 74862306a36Sopenharmony_ci if (err) 74962306a36Sopenharmony_ci goto out; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci err = esd_usb_setup_rx_urbs(dev); 75262306a36Sopenharmony_ci if (err) 75362306a36Sopenharmony_ci goto out; 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci priv->can.state = CAN_STATE_ERROR_ACTIVE; 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ciout: 75862306a36Sopenharmony_ci if (err == -ENODEV) 75962306a36Sopenharmony_ci netif_device_detach(netdev); 76062306a36Sopenharmony_ci if (err) 76162306a36Sopenharmony_ci netdev_err(netdev, "couldn't start device: %d\n", err); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci kfree(msg); 76462306a36Sopenharmony_ci return err; 76562306a36Sopenharmony_ci} 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_cistatic void unlink_all_urbs(struct esd_usb *dev) 76862306a36Sopenharmony_ci{ 76962306a36Sopenharmony_ci struct esd_usb_net_priv *priv; 77062306a36Sopenharmony_ci int i, j; 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci usb_kill_anchored_urbs(&dev->rx_submitted); 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci for (i = 0; i < ESD_USB_MAX_RX_URBS; ++i) 77562306a36Sopenharmony_ci usb_free_coherent(dev->udev, ESD_USB_RX_BUFFER_SIZE, 77662306a36Sopenharmony_ci dev->rxbuf[i], dev->rxbuf_dma[i]); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci for (i = 0; i < dev->net_count; i++) { 77962306a36Sopenharmony_ci priv = dev->nets[i]; 78062306a36Sopenharmony_ci if (priv) { 78162306a36Sopenharmony_ci usb_kill_anchored_urbs(&priv->tx_submitted); 78262306a36Sopenharmony_ci atomic_set(&priv->active_tx_jobs, 0); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci for (j = 0; j < ESD_USB_MAX_TX_URBS; j++) 78562306a36Sopenharmony_ci priv->tx_contexts[j].echo_index = ESD_USB_MAX_TX_URBS; 78662306a36Sopenharmony_ci } 78762306a36Sopenharmony_ci } 78862306a36Sopenharmony_ci} 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_cistatic int esd_usb_open(struct net_device *netdev) 79162306a36Sopenharmony_ci{ 79262306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 79362306a36Sopenharmony_ci int err; 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci /* common open */ 79662306a36Sopenharmony_ci err = open_candev(netdev); 79762306a36Sopenharmony_ci if (err) 79862306a36Sopenharmony_ci return err; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci /* finally start device */ 80162306a36Sopenharmony_ci err = esd_usb_start(priv); 80262306a36Sopenharmony_ci if (err) { 80362306a36Sopenharmony_ci netdev_warn(netdev, "couldn't start device: %d\n", err); 80462306a36Sopenharmony_ci close_candev(netdev); 80562306a36Sopenharmony_ci return err; 80662306a36Sopenharmony_ci } 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci netif_start_queue(netdev); 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ci return 0; 81162306a36Sopenharmony_ci} 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_cistatic netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, 81462306a36Sopenharmony_ci struct net_device *netdev) 81562306a36Sopenharmony_ci{ 81662306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 81762306a36Sopenharmony_ci struct esd_usb *dev = priv->usb; 81862306a36Sopenharmony_ci struct esd_tx_urb_context *context = NULL; 81962306a36Sopenharmony_ci struct net_device_stats *stats = &netdev->stats; 82062306a36Sopenharmony_ci struct canfd_frame *cfd = (struct canfd_frame *)skb->data; 82162306a36Sopenharmony_ci union esd_usb_msg *msg; 82262306a36Sopenharmony_ci struct urb *urb; 82362306a36Sopenharmony_ci u8 *buf; 82462306a36Sopenharmony_ci int i, err; 82562306a36Sopenharmony_ci int ret = NETDEV_TX_OK; 82662306a36Sopenharmony_ci size_t size = sizeof(union esd_usb_msg); 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci if (can_dev_dropped_skb(netdev, skb)) 82962306a36Sopenharmony_ci return NETDEV_TX_OK; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci /* create a URB, and a buffer for it, and copy the data to the URB */ 83262306a36Sopenharmony_ci urb = usb_alloc_urb(0, GFP_ATOMIC); 83362306a36Sopenharmony_ci if (!urb) { 83462306a36Sopenharmony_ci stats->tx_dropped++; 83562306a36Sopenharmony_ci dev_kfree_skb(skb); 83662306a36Sopenharmony_ci goto nourbmem; 83762306a36Sopenharmony_ci } 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, 84062306a36Sopenharmony_ci &urb->transfer_dma); 84162306a36Sopenharmony_ci if (!buf) { 84262306a36Sopenharmony_ci netdev_err(netdev, "No memory left for USB buffer\n"); 84362306a36Sopenharmony_ci stats->tx_dropped++; 84462306a36Sopenharmony_ci dev_kfree_skb(skb); 84562306a36Sopenharmony_ci goto nobufmem; 84662306a36Sopenharmony_ci } 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci msg = (union esd_usb_msg *)buf; 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci /* minimal length as # of 32bit words */ 85162306a36Sopenharmony_ci msg->hdr.len = offsetof(struct esd_usb_tx_msg, data) / sizeof(u32); 85262306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_CAN_TX; 85362306a36Sopenharmony_ci msg->tx.net = priv->index; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci if (can_is_canfd_skb(skb)) { 85662306a36Sopenharmony_ci msg->tx.dlc = can_fd_len2dlc(cfd->len); 85762306a36Sopenharmony_ci msg->tx.dlc |= ESD_USB_FD; 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci if ((cfd->flags & CANFD_BRS) == 0) 86062306a36Sopenharmony_ci msg->tx.dlc |= ESD_USB_NO_BRS; 86162306a36Sopenharmony_ci } else { 86262306a36Sopenharmony_ci msg->tx.dlc = can_get_cc_dlc((struct can_frame *)cfd, priv->can.ctrlmode); 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci if (cfd->can_id & CAN_RTR_FLAG) 86562306a36Sopenharmony_ci msg->tx.dlc |= ESD_USB_RTR; 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_ci msg->tx.id = cpu_to_le32(cfd->can_id & CAN_ERR_MASK); 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci if (cfd->can_id & CAN_EFF_FLAG) 87162306a36Sopenharmony_ci msg->tx.id |= cpu_to_le32(ESD_USB_EXTID); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci memcpy(msg->tx.data_fd, cfd->data, cfd->len); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci /* round up, then divide by 4 to add the payload length as # of 32bit words */ 87662306a36Sopenharmony_ci msg->hdr.len += DIV_ROUND_UP(cfd->len, sizeof(u32)); 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci for (i = 0; i < ESD_USB_MAX_TX_URBS; i++) { 87962306a36Sopenharmony_ci if (priv->tx_contexts[i].echo_index == ESD_USB_MAX_TX_URBS) { 88062306a36Sopenharmony_ci context = &priv->tx_contexts[i]; 88162306a36Sopenharmony_ci break; 88262306a36Sopenharmony_ci } 88362306a36Sopenharmony_ci } 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci /* This may never happen */ 88662306a36Sopenharmony_ci if (!context) { 88762306a36Sopenharmony_ci netdev_warn(netdev, "couldn't find free context\n"); 88862306a36Sopenharmony_ci ret = NETDEV_TX_BUSY; 88962306a36Sopenharmony_ci goto releasebuf; 89062306a36Sopenharmony_ci } 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci context->priv = priv; 89362306a36Sopenharmony_ci context->echo_index = i; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci /* hnd must not be 0 - MSB is stripped in txdone handling */ 89662306a36Sopenharmony_ci msg->tx.hnd = BIT(31) | i; /* returned in TX done message */ 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, 89962306a36Sopenharmony_ci msg->hdr.len * sizeof(u32), /* convert to # of bytes */ 90062306a36Sopenharmony_ci esd_usb_write_bulk_callback, context); 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci usb_anchor_urb(urb, &priv->tx_submitted); 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci can_put_echo_skb(skb, netdev, context->echo_index, 0); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci atomic_inc(&priv->active_tx_jobs); 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci /* Slow down tx path */ 91162306a36Sopenharmony_ci if (atomic_read(&priv->active_tx_jobs) >= ESD_USB_MAX_TX_URBS) 91262306a36Sopenharmony_ci netif_stop_queue(netdev); 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci err = usb_submit_urb(urb, GFP_ATOMIC); 91562306a36Sopenharmony_ci if (err) { 91662306a36Sopenharmony_ci can_free_echo_skb(netdev, context->echo_index, NULL); 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci atomic_dec(&priv->active_tx_jobs); 91962306a36Sopenharmony_ci usb_unanchor_urb(urb); 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci stats->tx_dropped++; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci if (err == -ENODEV) 92462306a36Sopenharmony_ci netif_device_detach(netdev); 92562306a36Sopenharmony_ci else 92662306a36Sopenharmony_ci netdev_warn(netdev, "failed tx_urb %d\n", err); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci goto releasebuf; 92962306a36Sopenharmony_ci } 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ci netif_trans_update(netdev); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci /* Release our reference to this URB, the USB core will eventually free 93462306a36Sopenharmony_ci * it entirely. 93562306a36Sopenharmony_ci */ 93662306a36Sopenharmony_ci usb_free_urb(urb); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci return NETDEV_TX_OK; 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_cireleasebuf: 94162306a36Sopenharmony_ci usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_cinobufmem: 94462306a36Sopenharmony_ci usb_free_urb(urb); 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_cinourbmem: 94762306a36Sopenharmony_ci return ret; 94862306a36Sopenharmony_ci} 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_cistatic int esd_usb_close(struct net_device *netdev) 95162306a36Sopenharmony_ci{ 95262306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 95362306a36Sopenharmony_ci union esd_usb_msg *msg; 95462306a36Sopenharmony_ci int i; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci msg = kmalloc(sizeof(*msg), GFP_KERNEL); 95762306a36Sopenharmony_ci if (!msg) 95862306a36Sopenharmony_ci return -ENOMEM; 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci /* Disable all IDs (see esd_usb_start()) */ 96162306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_IDADD; 96262306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_id_filter_msg) / sizeof(u32);/* # of 32bit words */ 96362306a36Sopenharmony_ci msg->filter.net = priv->index; 96462306a36Sopenharmony_ci msg->filter.option = ESD_USB_ID_ENABLE; /* start with segment 0 */ 96562306a36Sopenharmony_ci for (i = 0; i <= ESD_USB_MAX_ID_SEGMENT; i++) 96662306a36Sopenharmony_ci msg->filter.mask[i] = 0; 96762306a36Sopenharmony_ci if (esd_usb_send_msg(priv->usb, msg) < 0) 96862306a36Sopenharmony_ci netdev_err(netdev, "sending idadd message failed\n"); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci /* set CAN controller to reset mode */ 97162306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */ 97262306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_SETBAUD; 97362306a36Sopenharmony_ci msg->setbaud.net = priv->index; 97462306a36Sopenharmony_ci msg->setbaud.rsvd = 0; 97562306a36Sopenharmony_ci msg->setbaud.baud = cpu_to_le32(ESD_USB_NO_BAUDRATE); 97662306a36Sopenharmony_ci if (esd_usb_send_msg(priv->usb, msg) < 0) 97762306a36Sopenharmony_ci netdev_err(netdev, "sending setbaud message failed\n"); 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci priv->can.state = CAN_STATE_STOPPED; 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci netif_stop_queue(netdev); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci close_candev(netdev); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci kfree(msg); 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci return 0; 98862306a36Sopenharmony_ci} 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_cistatic const struct net_device_ops esd_usb_netdev_ops = { 99162306a36Sopenharmony_ci .ndo_open = esd_usb_open, 99262306a36Sopenharmony_ci .ndo_stop = esd_usb_close, 99362306a36Sopenharmony_ci .ndo_start_xmit = esd_usb_start_xmit, 99462306a36Sopenharmony_ci .ndo_change_mtu = can_change_mtu, 99562306a36Sopenharmony_ci}; 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_cistatic const struct ethtool_ops esd_usb_ethtool_ops = { 99862306a36Sopenharmony_ci .get_ts_info = ethtool_op_get_ts_info, 99962306a36Sopenharmony_ci}; 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_cistatic const struct can_bittiming_const esd_usb_2_bittiming_const = { 100262306a36Sopenharmony_ci .name = "esd_usb_2", 100362306a36Sopenharmony_ci .tseg1_min = 1, 100462306a36Sopenharmony_ci .tseg1_max = 16, 100562306a36Sopenharmony_ci .tseg2_min = 1, 100662306a36Sopenharmony_ci .tseg2_max = 8, 100762306a36Sopenharmony_ci .sjw_max = 4, 100862306a36Sopenharmony_ci .brp_min = 1, 100962306a36Sopenharmony_ci .brp_max = 1024, 101062306a36Sopenharmony_ci .brp_inc = 1, 101162306a36Sopenharmony_ci}; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_cistatic int esd_usb_2_set_bittiming(struct net_device *netdev) 101462306a36Sopenharmony_ci{ 101562306a36Sopenharmony_ci const struct can_bittiming_const *btc = &esd_usb_2_bittiming_const; 101662306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 101762306a36Sopenharmony_ci struct can_bittiming *bt = &priv->can.bittiming; 101862306a36Sopenharmony_ci union esd_usb_msg *msg; 101962306a36Sopenharmony_ci int err; 102062306a36Sopenharmony_ci u32 canbtr; 102162306a36Sopenharmony_ci int sjw_shift; 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci canbtr = ESD_USB_UBR; 102462306a36Sopenharmony_ci if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) 102562306a36Sopenharmony_ci canbtr |= ESD_USB_LOM; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci canbtr |= (bt->brp - 1) & (btc->brp_max - 1); 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci if (le16_to_cpu(priv->usb->udev->descriptor.idProduct) == 103062306a36Sopenharmony_ci ESD_USB_CANUSBM_PRODUCT_ID) 103162306a36Sopenharmony_ci sjw_shift = ESD_USB_M_SJW_SHIFT; 103262306a36Sopenharmony_ci else 103362306a36Sopenharmony_ci sjw_shift = ESD_USB_2_SJW_SHIFT; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci canbtr |= ((bt->sjw - 1) & (btc->sjw_max - 1)) 103662306a36Sopenharmony_ci << sjw_shift; 103762306a36Sopenharmony_ci canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1) 103862306a36Sopenharmony_ci & (btc->tseg1_max - 1)) 103962306a36Sopenharmony_ci << ESD_USB_2_TSEG1_SHIFT; 104062306a36Sopenharmony_ci canbtr |= ((bt->phase_seg2 - 1) & (btc->tseg2_max - 1)) 104162306a36Sopenharmony_ci << ESD_USB_2_TSEG2_SHIFT; 104262306a36Sopenharmony_ci if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 104362306a36Sopenharmony_ci canbtr |= ESD_USB_TRIPLE_SAMPLES; 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci msg = kmalloc(sizeof(*msg), GFP_KERNEL); 104662306a36Sopenharmony_ci if (!msg) 104762306a36Sopenharmony_ci return -ENOMEM; 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_set_baudrate_msg) / sizeof(u32); /* # of 32bit words */ 105062306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_SETBAUD; 105162306a36Sopenharmony_ci msg->setbaud.net = priv->index; 105262306a36Sopenharmony_ci msg->setbaud.rsvd = 0; 105362306a36Sopenharmony_ci msg->setbaud.baud = cpu_to_le32(canbtr); 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci netdev_dbg(netdev, "setting BTR=%#x\n", canbtr); 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_ci err = esd_usb_send_msg(priv->usb, msg); 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci kfree(msg); 106062306a36Sopenharmony_ci return err; 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci/* Nominal bittiming constants, see 106462306a36Sopenharmony_ci * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022 106562306a36Sopenharmony_ci * 48.6.8 MCAN Nominal Bit Timing and Prescaler Register 106662306a36Sopenharmony_ci */ 106762306a36Sopenharmony_cistatic const struct can_bittiming_const esd_usb_3_nom_bittiming_const = { 106862306a36Sopenharmony_ci .name = "esd_usb_3", 106962306a36Sopenharmony_ci .tseg1_min = 2, 107062306a36Sopenharmony_ci .tseg1_max = 256, 107162306a36Sopenharmony_ci .tseg2_min = 2, 107262306a36Sopenharmony_ci .tseg2_max = 128, 107362306a36Sopenharmony_ci .sjw_max = 128, 107462306a36Sopenharmony_ci .brp_min = 1, 107562306a36Sopenharmony_ci .brp_max = 512, 107662306a36Sopenharmony_ci .brp_inc = 1, 107762306a36Sopenharmony_ci}; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci/* Data bittiming constants, see 108062306a36Sopenharmony_ci * Microchip SAM E70/S70/V70/V71, Data Sheet, Rev. G - 07/2022 108162306a36Sopenharmony_ci * 48.6.4 MCAN Data Bit Timing and Prescaler Register 108262306a36Sopenharmony_ci */ 108362306a36Sopenharmony_cistatic const struct can_bittiming_const esd_usb_3_data_bittiming_const = { 108462306a36Sopenharmony_ci .name = "esd_usb_3", 108562306a36Sopenharmony_ci .tseg1_min = 2, 108662306a36Sopenharmony_ci .tseg1_max = 32, 108762306a36Sopenharmony_ci .tseg2_min = 1, 108862306a36Sopenharmony_ci .tseg2_max = 16, 108962306a36Sopenharmony_ci .sjw_max = 8, 109062306a36Sopenharmony_ci .brp_min = 1, 109162306a36Sopenharmony_ci .brp_max = 32, 109262306a36Sopenharmony_ci .brp_inc = 1, 109362306a36Sopenharmony_ci}; 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_cistatic int esd_usb_3_set_bittiming(struct net_device *netdev) 109662306a36Sopenharmony_ci{ 109762306a36Sopenharmony_ci const struct can_bittiming_const *nom_btc = &esd_usb_3_nom_bittiming_const; 109862306a36Sopenharmony_ci const struct can_bittiming_const *data_btc = &esd_usb_3_data_bittiming_const; 109962306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 110062306a36Sopenharmony_ci struct can_bittiming *nom_bt = &priv->can.bittiming; 110162306a36Sopenharmony_ci struct can_bittiming *data_bt = &priv->can.data_bittiming; 110262306a36Sopenharmony_ci struct esd_usb_3_set_baudrate_msg_x *baud_x; 110362306a36Sopenharmony_ci union esd_usb_msg *msg; 110462306a36Sopenharmony_ci u16 flags = 0; 110562306a36Sopenharmony_ci int err; 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci msg = kmalloc(sizeof(*msg), GFP_KERNEL); 110862306a36Sopenharmony_ci if (!msg) 110962306a36Sopenharmony_ci return -ENOMEM; 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_ci baud_x = &msg->setbaud_x; 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci /* Canonical is the most reasonable mode for SocketCAN on CAN-USB/3 ... */ 111462306a36Sopenharmony_ci baud_x->mode = cpu_to_le16(ESD_USB_3_BAUDRATE_MODE_BTR_CANONICAL); 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) 111762306a36Sopenharmony_ci flags |= ESD_USB_3_BAUDRATE_FLAG_LOM; 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 112062306a36Sopenharmony_ci flags |= ESD_USB_3_BAUDRATE_FLAG_TRS; 112162306a36Sopenharmony_ci 112262306a36Sopenharmony_ci baud_x->nom.brp = cpu_to_le16(nom_bt->brp & (nom_btc->brp_max - 1)); 112362306a36Sopenharmony_ci baud_x->nom.sjw = cpu_to_le16(nom_bt->sjw & (nom_btc->sjw_max - 1)); 112462306a36Sopenharmony_ci baud_x->nom.tseg1 = cpu_to_le16((nom_bt->prop_seg + nom_bt->phase_seg1) 112562306a36Sopenharmony_ci & (nom_btc->tseg1_max - 1)); 112662306a36Sopenharmony_ci baud_x->nom.tseg2 = cpu_to_le16(nom_bt->phase_seg2 & (nom_btc->tseg2_max - 1)); 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { 112962306a36Sopenharmony_ci baud_x->data.brp = cpu_to_le16(data_bt->brp & (data_btc->brp_max - 1)); 113062306a36Sopenharmony_ci baud_x->data.sjw = cpu_to_le16(data_bt->sjw & (data_btc->sjw_max - 1)); 113162306a36Sopenharmony_ci baud_x->data.tseg1 = cpu_to_le16((data_bt->prop_seg + data_bt->phase_seg1) 113262306a36Sopenharmony_ci & (data_btc->tseg1_max - 1)); 113362306a36Sopenharmony_ci baud_x->data.tseg2 = cpu_to_le16(data_bt->phase_seg2 & (data_btc->tseg2_max - 1)); 113462306a36Sopenharmony_ci flags |= ESD_USB_3_BAUDRATE_FLAG_FD; 113562306a36Sopenharmony_ci } 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci /* Currently this driver only supports the automatic TDC mode */ 113862306a36Sopenharmony_ci baud_x->tdc.tdc_mode = ESD_USB_3_TDC_MODE_AUTO; 113962306a36Sopenharmony_ci baud_x->tdc.ssp_offset = 0; 114062306a36Sopenharmony_ci baud_x->tdc.ssp_shift = 0; 114162306a36Sopenharmony_ci baud_x->tdc.tdc_filter = 0; 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci baud_x->flags = cpu_to_le16(flags); 114462306a36Sopenharmony_ci baud_x->net = priv->index; 114562306a36Sopenharmony_ci baud_x->rsvd = 0; 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_ci /* set len as # of 32bit words */ 114862306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_3_set_baudrate_msg_x) / sizeof(u32); 114962306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_SETBAUD; 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci netdev_dbg(netdev, 115262306a36Sopenharmony_ci "ctrlmode=%#x/%#x, esd-net=%u, esd-mode=%#x, esd-flags=%#x\n", 115362306a36Sopenharmony_ci priv->can.ctrlmode, priv->can.ctrlmode_supported, 115462306a36Sopenharmony_ci priv->index, le16_to_cpu(baud_x->mode), flags); 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci err = esd_usb_send_msg(priv->usb, msg); 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_ci kfree(msg); 115962306a36Sopenharmony_ci return err; 116062306a36Sopenharmony_ci} 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_cistatic int esd_usb_get_berr_counter(const struct net_device *netdev, 116362306a36Sopenharmony_ci struct can_berr_counter *bec) 116462306a36Sopenharmony_ci{ 116562306a36Sopenharmony_ci struct esd_usb_net_priv *priv = netdev_priv(netdev); 116662306a36Sopenharmony_ci 116762306a36Sopenharmony_ci bec->txerr = priv->bec.txerr; 116862306a36Sopenharmony_ci bec->rxerr = priv->bec.rxerr; 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_ci return 0; 117162306a36Sopenharmony_ci} 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_cistatic int esd_usb_set_mode(struct net_device *netdev, enum can_mode mode) 117462306a36Sopenharmony_ci{ 117562306a36Sopenharmony_ci switch (mode) { 117662306a36Sopenharmony_ci case CAN_MODE_START: 117762306a36Sopenharmony_ci netif_wake_queue(netdev); 117862306a36Sopenharmony_ci break; 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci default: 118162306a36Sopenharmony_ci return -EOPNOTSUPP; 118262306a36Sopenharmony_ci } 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci return 0; 118562306a36Sopenharmony_ci} 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_cistatic int esd_usb_probe_one_net(struct usb_interface *intf, int index) 118862306a36Sopenharmony_ci{ 118962306a36Sopenharmony_ci struct esd_usb *dev = usb_get_intfdata(intf); 119062306a36Sopenharmony_ci struct net_device *netdev; 119162306a36Sopenharmony_ci struct esd_usb_net_priv *priv; 119262306a36Sopenharmony_ci int err = 0; 119362306a36Sopenharmony_ci int i; 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci netdev = alloc_candev(sizeof(*priv), ESD_USB_MAX_TX_URBS); 119662306a36Sopenharmony_ci if (!netdev) { 119762306a36Sopenharmony_ci dev_err(&intf->dev, "couldn't alloc candev\n"); 119862306a36Sopenharmony_ci err = -ENOMEM; 119962306a36Sopenharmony_ci goto done; 120062306a36Sopenharmony_ci } 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci priv = netdev_priv(netdev); 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_ci init_usb_anchor(&priv->tx_submitted); 120562306a36Sopenharmony_ci atomic_set(&priv->active_tx_jobs, 0); 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci for (i = 0; i < ESD_USB_MAX_TX_URBS; i++) 120862306a36Sopenharmony_ci priv->tx_contexts[i].echo_index = ESD_USB_MAX_TX_URBS; 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci priv->usb = dev; 121162306a36Sopenharmony_ci priv->netdev = netdev; 121262306a36Sopenharmony_ci priv->index = index; 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci priv->can.state = CAN_STATE_STOPPED; 121562306a36Sopenharmony_ci priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY | 121662306a36Sopenharmony_ci CAN_CTRLMODE_CC_LEN8_DLC | 121762306a36Sopenharmony_ci CAN_CTRLMODE_BERR_REPORTING; 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci switch (le16_to_cpu(dev->udev->descriptor.idProduct)) { 122062306a36Sopenharmony_ci case ESD_USB_CANUSB3_PRODUCT_ID: 122162306a36Sopenharmony_ci priv->can.clock.freq = ESD_USB_3_CAN_CLOCK; 122262306a36Sopenharmony_ci priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; 122362306a36Sopenharmony_ci priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; 122462306a36Sopenharmony_ci priv->can.bittiming_const = &esd_usb_3_nom_bittiming_const; 122562306a36Sopenharmony_ci priv->can.data_bittiming_const = &esd_usb_3_data_bittiming_const; 122662306a36Sopenharmony_ci priv->can.do_set_bittiming = esd_usb_3_set_bittiming; 122762306a36Sopenharmony_ci priv->can.do_set_data_bittiming = esd_usb_3_set_bittiming; 122862306a36Sopenharmony_ci break; 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci case ESD_USB_CANUSBM_PRODUCT_ID: 123162306a36Sopenharmony_ci priv->can.clock.freq = ESD_USB_M_CAN_CLOCK; 123262306a36Sopenharmony_ci priv->can.bittiming_const = &esd_usb_2_bittiming_const; 123362306a36Sopenharmony_ci priv->can.do_set_bittiming = esd_usb_2_set_bittiming; 123462306a36Sopenharmony_ci break; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci case ESD_USB_CANUSB2_PRODUCT_ID: 123762306a36Sopenharmony_ci default: 123862306a36Sopenharmony_ci priv->can.clock.freq = ESD_USB_2_CAN_CLOCK; 123962306a36Sopenharmony_ci priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; 124062306a36Sopenharmony_ci priv->can.bittiming_const = &esd_usb_2_bittiming_const; 124162306a36Sopenharmony_ci priv->can.do_set_bittiming = esd_usb_2_set_bittiming; 124262306a36Sopenharmony_ci break; 124362306a36Sopenharmony_ci } 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci priv->can.do_set_mode = esd_usb_set_mode; 124662306a36Sopenharmony_ci priv->can.do_get_berr_counter = esd_usb_get_berr_counter; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci netdev->flags |= IFF_ECHO; /* we support local echo */ 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci netdev->netdev_ops = &esd_usb_netdev_ops; 125162306a36Sopenharmony_ci netdev->ethtool_ops = &esd_usb_ethtool_ops; 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci SET_NETDEV_DEV(netdev, &intf->dev); 125462306a36Sopenharmony_ci netdev->dev_id = index; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci err = register_candev(netdev); 125762306a36Sopenharmony_ci if (err) { 125862306a36Sopenharmony_ci dev_err(&intf->dev, "couldn't register CAN device: %d\n", err); 125962306a36Sopenharmony_ci free_candev(netdev); 126062306a36Sopenharmony_ci err = -ENOMEM; 126162306a36Sopenharmony_ci goto done; 126262306a36Sopenharmony_ci } 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci dev->nets[index] = priv; 126562306a36Sopenharmony_ci netdev_info(netdev, "device %s registered\n", netdev->name); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_cidone: 126862306a36Sopenharmony_ci return err; 126962306a36Sopenharmony_ci} 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci/* probe function for new USB devices 127262306a36Sopenharmony_ci * 127362306a36Sopenharmony_ci * check version information and number of available 127462306a36Sopenharmony_ci * CAN interfaces 127562306a36Sopenharmony_ci */ 127662306a36Sopenharmony_cistatic int esd_usb_probe(struct usb_interface *intf, 127762306a36Sopenharmony_ci const struct usb_device_id *id) 127862306a36Sopenharmony_ci{ 127962306a36Sopenharmony_ci struct esd_usb *dev; 128062306a36Sopenharmony_ci union esd_usb_msg *msg; 128162306a36Sopenharmony_ci int i, err; 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci dev = kzalloc(sizeof(*dev), GFP_KERNEL); 128462306a36Sopenharmony_ci if (!dev) { 128562306a36Sopenharmony_ci err = -ENOMEM; 128662306a36Sopenharmony_ci goto done; 128762306a36Sopenharmony_ci } 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci dev->udev = interface_to_usbdev(intf); 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci init_usb_anchor(&dev->rx_submitted); 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci usb_set_intfdata(intf, dev); 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci msg = kmalloc(sizeof(*msg), GFP_KERNEL); 129662306a36Sopenharmony_ci if (!msg) { 129762306a36Sopenharmony_ci err = -ENOMEM; 129862306a36Sopenharmony_ci goto free_msg; 129962306a36Sopenharmony_ci } 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_ci /* query number of CAN interfaces (nets) */ 130262306a36Sopenharmony_ci msg->hdr.cmd = ESD_USB_CMD_VERSION; 130362306a36Sopenharmony_ci msg->hdr.len = sizeof(struct esd_usb_version_msg) / sizeof(u32); /* # of 32bit words */ 130462306a36Sopenharmony_ci msg->version.rsvd = 0; 130562306a36Sopenharmony_ci msg->version.flags = 0; 130662306a36Sopenharmony_ci msg->version.drv_version = 0; 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci err = esd_usb_send_msg(dev, msg); 130962306a36Sopenharmony_ci if (err < 0) { 131062306a36Sopenharmony_ci dev_err(&intf->dev, "sending version message failed\n"); 131162306a36Sopenharmony_ci goto free_msg; 131262306a36Sopenharmony_ci } 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci err = esd_usb_wait_msg(dev, msg); 131562306a36Sopenharmony_ci if (err < 0) { 131662306a36Sopenharmony_ci dev_err(&intf->dev, "no version message answer\n"); 131762306a36Sopenharmony_ci goto free_msg; 131862306a36Sopenharmony_ci } 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ci dev->net_count = (int)msg->version_reply.nets; 132162306a36Sopenharmony_ci dev->version = le32_to_cpu(msg->version_reply.version); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci if (device_create_file(&intf->dev, &dev_attr_firmware)) 132462306a36Sopenharmony_ci dev_err(&intf->dev, 132562306a36Sopenharmony_ci "Couldn't create device file for firmware\n"); 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci if (device_create_file(&intf->dev, &dev_attr_hardware)) 132862306a36Sopenharmony_ci dev_err(&intf->dev, 132962306a36Sopenharmony_ci "Couldn't create device file for hardware\n"); 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci if (device_create_file(&intf->dev, &dev_attr_nets)) 133262306a36Sopenharmony_ci dev_err(&intf->dev, 133362306a36Sopenharmony_ci "Couldn't create device file for nets\n"); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci /* do per device probing */ 133662306a36Sopenharmony_ci for (i = 0; i < dev->net_count; i++) 133762306a36Sopenharmony_ci esd_usb_probe_one_net(intf, i); 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_cifree_msg: 134062306a36Sopenharmony_ci kfree(msg); 134162306a36Sopenharmony_ci if (err) 134262306a36Sopenharmony_ci kfree(dev); 134362306a36Sopenharmony_cidone: 134462306a36Sopenharmony_ci return err; 134562306a36Sopenharmony_ci} 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci/* called by the usb core when the device is removed from the system */ 134862306a36Sopenharmony_cistatic void esd_usb_disconnect(struct usb_interface *intf) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci struct esd_usb *dev = usb_get_intfdata(intf); 135162306a36Sopenharmony_ci struct net_device *netdev; 135262306a36Sopenharmony_ci int i; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci device_remove_file(&intf->dev, &dev_attr_firmware); 135562306a36Sopenharmony_ci device_remove_file(&intf->dev, &dev_attr_hardware); 135662306a36Sopenharmony_ci device_remove_file(&intf->dev, &dev_attr_nets); 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_ci usb_set_intfdata(intf, NULL); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci if (dev) { 136162306a36Sopenharmony_ci for (i = 0; i < dev->net_count; i++) { 136262306a36Sopenharmony_ci if (dev->nets[i]) { 136362306a36Sopenharmony_ci netdev = dev->nets[i]->netdev; 136462306a36Sopenharmony_ci unregister_netdev(netdev); 136562306a36Sopenharmony_ci free_candev(netdev); 136662306a36Sopenharmony_ci } 136762306a36Sopenharmony_ci } 136862306a36Sopenharmony_ci unlink_all_urbs(dev); 136962306a36Sopenharmony_ci kfree(dev); 137062306a36Sopenharmony_ci } 137162306a36Sopenharmony_ci} 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci/* usb specific object needed to register this driver with the usb subsystem */ 137462306a36Sopenharmony_cistatic struct usb_driver esd_usb_driver = { 137562306a36Sopenharmony_ci .name = KBUILD_MODNAME, 137662306a36Sopenharmony_ci .probe = esd_usb_probe, 137762306a36Sopenharmony_ci .disconnect = esd_usb_disconnect, 137862306a36Sopenharmony_ci .id_table = esd_usb_table, 137962306a36Sopenharmony_ci}; 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_cimodule_usb_driver(esd_usb_driver); 1382