- add IXXAT_USB_BRD_CMD_GET_FWINFO support to retrieve firmware info and promote all legacy adapters with up-to-date firmware to communication layer cl2 (backported from upstream driver ix_usb_can_2.0.366-REL) Signed-off-by: Peter Seiderer <ps.report@xxxxxxx> --- Changes v9 -> v10 (Peter Seiderer <ps.report@xxxxxxx>): - new patch --- drivers/net/can/usb/ixxat_usb/ixxat_usb_cl2.c | 40 +++++++++++++++++ .../net/can/usb/ixxat_usb/ixxat_usb_core.c | 44 +++++++++++++++++++ .../net/can/usb/ixxat_usb/ixxat_usb_core.h | 35 +++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/drivers/net/can/usb/ixxat_usb/ixxat_usb_cl2.c b/drivers/net/can/usb/ixxat_usb/ixxat_usb_cl2.c index 3c9d05c4b34f..07853607282f 100644 --- a/drivers/net/can/usb/ixxat_usb/ixxat_usb_cl2.c +++ b/drivers/net/can/usb/ixxat_usb/ixxat_usb_cl2.c @@ -12,6 +12,8 @@ #define IXXAT_USB_CLOCK (80 * MEGA /* Hz */) +#define IXXAT_USBV2_CLOCK (36 * MEGA /* Hz */) + #define IXXAT_USB_BUFFER_SIZE_RX 512 #define IXXAT_USB_BUFFER_SIZE_TX 512 @@ -41,6 +43,18 @@ static const struct can_bittiming_const usb2can_btd = { .brp_inc = 1, }; +static const struct can_bittiming_const usb2can_v2_bt = { + .name = IXXAT_USB_CTRL_NAME, + .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 const struct can_bittiming_const canidm_bt = { .name = IXXAT_USB_CTRL_NAME, .tseg1_min = 1, @@ -149,6 +163,32 @@ const struct ixxat_usb_adapter usb2can_cl2 = { .init_ctrl = ixxat_usb_init_ctrl }; +const struct ixxat_usb_adapter usb2can_v2 = { + .clock = IXXAT_USBV2_CLOCK, + .bt = &usb2can_v2_bt, + .btd = NULL, + .modes = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_BERR_REPORTING, + .buffer_size_rx = IXXAT_USB_BUFFER_SIZE_RX, + .buffer_size_tx = IXXAT_USB_BUFFER_SIZE_TX, + .ep_msg_in = { + 1 | USB_DIR_IN, + 2 | USB_DIR_IN, + 3 | USB_DIR_IN, + 4 | USB_DIR_IN, + 5 | USB_DIR_IN + }, + .ep_msg_out = { + 1 | USB_DIR_IN, + 2 | USB_DIR_IN, + 3 | USB_DIR_IN, + 4 | USB_DIR_IN, + 5 | USB_DIR_IN + }, + .ep_offs = 0, + .init_ctrl = ixxat_usb_init_ctrl +}; + const struct ixxat_usb_adapter can_idm = { .clock = IXXAT_USB_CLOCK, .bt = &canidm_bt, diff --git a/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.c b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.c index 894836bdeed3..85514655e03c 100644 --- a/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.c +++ b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.c @@ -223,6 +223,37 @@ static int ixxat_usb_get_dev_info(struct usb_device *dev, return 0; } +static int ixxat_usb_get_fw_info(struct usb_device *dev, + struct ixxat_fw_info *dev_info) +{ + int err; + struct ixxat_usb_fwinfo_cmd *cmd; + + cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + ixxat_usb_setup_cmd(&cmd->req, &cmd->res); + cmd->req.code = cpu_to_le32(IXXAT_USB_BRD_CMD_GET_FWINFO); + cmd->res.res_size = cpu_to_le32(IXXAT_USB_RES_SIZE(cmd)); + + err = ixxat_usb_send_cmd(dev, le16_to_cpu(cmd->req.port), cmd, + sizeof(cmd->req) + sizeof(cmd->res), + &cmd->res, IXXAT_USB_RES_SIZE(cmd)); + if (err) { + kfree(cmd); + return err; + } + + dev_info->firmware_type = cmd->fw_info.firmware_type; + dev_info->major_version = cmd->fw_info.major_version; + dev_info->minor_version = cmd->fw_info.minor_version; + dev_info->build_version = cmd->fw_info.build_version; + + kfree(cmd); + return 0; +} + static int ixxat_usb_start_ctrl(struct ixxat_usb_device *dev, u32 *time_ref) { const u16 port = dev->ctrl_index; @@ -1185,6 +1216,7 @@ static int ixxat_usb_probe(struct usb_interface *intf, struct usb_host_interface *host_intf = intf->altsetting; const struct ixxat_usb_adapter *adapter; struct ixxat_dev_caps dev_caps; + struct ixxat_fw_info dev_fwinfo = { 0 }; u16 i; int err; @@ -1192,6 +1224,18 @@ static int ixxat_usb_probe(struct usb_interface *intf, adapter = (const struct ixxat_usb_adapter *)id->driver_info; + if (!ixxat_usb_get_fw_info(udev, &dev_fwinfo)) { + if (adapter == &usb2can_cl1 && + (id->idVendor == USB2CAN_COMPACT_PRODUCT_ID || + id->idVendor == USB2CAN_EMBEDDED_PRODUCT_ID || + id->idVendor == USB2CAN_PROFESSIONAL_PRODUCT_ID || + id->idVendor == USB2CAN_AUTOMOTIVE_PRODUCT_ID || + id->idVendor == USB2CAN_PLUGIN_PRODUCT_ID) && + le16_to_cpu(dev_fwinfo.major_version) >= 1 && + le16_to_cpu(dev_fwinfo.minor_version) >= 6) + adapter = &usb2can_v2; + } + for (i = 0; i < host_intf->desc.bNumEndpoints; i++) { const u8 epaddr = host_intf->endpoint[i].desc.bEndpointAddress; int match; diff --git a/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h index 5810c481a875..1c53d989d8fa 100644 --- a/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h +++ b/drivers/net/can/usb/ixxat_usb/ixxat_usb_core.h @@ -101,6 +101,7 @@ #define IXXAT_USB_CAN_CMD_STOP 0x327 #define IXXAT_USB_CAN_CMD_RESET 0x328 +#define IXXAT_USB_BRD_CMD_GET_FWINFO 0x400 #define IXXAT_USB_BRD_CMD_GET_DEVCAPS 0x401 #define IXXAT_USB_BRD_CMD_GET_DEVINFO 0x402 #define IXXAT_USB_BRD_CMD_POWER 0x421 @@ -217,6 +218,25 @@ struct ixxat_dev_info { __le32 device_fpga_version; } __packed; +/** + * struct ixxat_fw_info IXXAT usb firmware information + * @firmware_type: type of currently running firmware + * @reserved: reserved bytes + * @major_version: major firmware version number + * @minor_version: minor firmware version number + * @build_version: build firmware version number + * + * Contains firmware information of IXXAT USB devices + */ + +struct ixxat_fw_info { + __le32 firmware_type; + u8 reserved[2]; + __le16 major_version; + __le16 minor_version; + __le16 build_version; +} __packed; + /** * struct ixxat_time_ref Time reference * @kt_host_0: Latest time on the host @@ -449,6 +469,20 @@ struct ixxat_usb_info_cmd { struct ixxat_dev_info info; } __packed; +/** + * struct ixxat_usb_fwinfo_cmd Firmware information command + * @req: Request block + * @res: Response block + * @fw_info: Firmware information + * + * Can be sent to a device to request its firmware information + */ +struct ixxat_usb_fwinfo_cmd { + struct ixxat_usb_dal_req req; + struct ixxat_usb_dal_res res; + struct ixxat_fw_info fw_info; +} __packed; + /** * struct ixxat_usb_adapter IXXAT USB device adapter * @clock: Clock frequency @@ -478,6 +512,7 @@ struct ixxat_usb_adapter { extern const struct ixxat_usb_adapter usb2can_cl1; extern const struct ixxat_usb_adapter usb2can_cl2; +extern const struct ixxat_usb_adapter usb2can_v2; extern const struct ixxat_usb_adapter can_idm; /** -- 2.41.0