2023-07-07 17:24:16

by Peter Seiderer

[permalink] [raw]
Subject: [PATCH v10 3/3] can: usb: ixxat_usb: promote legacy adapters with up-todate firmware to cl2

- 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 <[email protected]>
---
Changes v9 -> v10 (Peter Seiderer <[email protected]>):
- 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