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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- 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





[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux