Commit 6679f4c5 authored by Peter Fink's avatar Peter Fink Committed by Marc Kleine-Budde

can: gs_usb: add extended bt_const feature

For example CANext FD needs to distinguish between bittiming constants
valid for arbitration phase and data phase to reach maximum
performance at higher speeds.

Link: https://lore.kernel.org/all/20220309124132.291861-20-mkl@pengutronix.deSigned-off-by: default avatarPeter Fink <pfink@christ-es.de>
Signed-off-by: default avatarChristoph Möhring <cmoehring@christ-es.de>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent b00ca070
...@@ -45,6 +45,7 @@ enum gs_usb_breq { ...@@ -45,6 +45,7 @@ enum gs_usb_breq {
GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING = GS_USB_BREQ_GET_USER_ID, GS_USB_BREQ_QUIRK_CANTACT_PRO_DATA_BITTIMING = GS_USB_BREQ_GET_USER_ID,
GS_USB_BREQ_SET_USER_ID, GS_USB_BREQ_SET_USER_ID,
GS_USB_BREQ_DATA_BITTIMING, GS_USB_BREQ_DATA_BITTIMING,
GS_USB_BREQ_BT_CONST_EXT,
}; };
enum gs_can_mode { enum gs_can_mode {
...@@ -103,6 +104,7 @@ struct gs_device_config { ...@@ -103,6 +104,7 @@ struct gs_device_config {
#define GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7) #define GS_CAN_MODE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
#define GS_CAN_MODE_FD BIT(8) #define GS_CAN_MODE_FD BIT(8)
/* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */ /* GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) */
/* GS_CAN_FEATURE_BT_CONST_EXT BIT(10) */
struct gs_device_mode { struct gs_device_mode {
__le32 mode; __le32 mode;
...@@ -137,7 +139,8 @@ struct gs_identify_mode { ...@@ -137,7 +139,8 @@ struct gs_identify_mode {
#define GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7) #define GS_CAN_FEATURE_PAD_PKTS_TO_MAX_PKT_SIZE BIT(7)
#define GS_CAN_FEATURE_FD BIT(8) #define GS_CAN_FEATURE_FD BIT(8)
#define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9) #define GS_CAN_FEATURE_REQ_USB_QUIRK_LPC546XX BIT(9)
#define GS_CAN_FEATURE_MASK GENMASK(9, 0) #define GS_CAN_FEATURE_BT_CONST_EXT BIT(10)
#define GS_CAN_FEATURE_MASK GENMASK(10, 0)
/* internal quirks - keep in GS_CAN_FEATURE space for now */ /* internal quirks - keep in GS_CAN_FEATURE space for now */
...@@ -159,6 +162,28 @@ struct gs_device_bt_const { ...@@ -159,6 +162,28 @@ struct gs_device_bt_const {
__le32 brp_inc; __le32 brp_inc;
} __packed; } __packed;
struct gs_device_bt_const_extended {
__le32 feature;
__le32 fclk_can;
__le32 tseg1_min;
__le32 tseg1_max;
__le32 tseg2_min;
__le32 tseg2_max;
__le32 sjw_max;
__le32 brp_min;
__le32 brp_max;
__le32 brp_inc;
__le32 dtseg1_min;
__le32 dtseg1_max;
__le32 dtseg2_min;
__le32 dtseg2_max;
__le32 dsjw_max;
__le32 dbrp_min;
__le32 dbrp_max;
__le32 dbrp_inc;
} __packed;
#define GS_CAN_FLAG_OVERFLOW BIT(0) #define GS_CAN_FLAG_OVERFLOW BIT(0)
#define GS_CAN_FLAG_FD BIT(1) #define GS_CAN_FLAG_FD BIT(1)
#define GS_CAN_FLAG_BRS BIT(2) #define GS_CAN_FLAG_BRS BIT(2)
...@@ -225,7 +250,7 @@ struct gs_can { ...@@ -225,7 +250,7 @@ struct gs_can {
struct usb_device *udev; struct usb_device *udev;
struct usb_interface *iface; struct usb_interface *iface;
struct can_bittiming_const bt_const; struct can_bittiming_const bt_const, data_bt_const;
unsigned int channel; /* channel number */ unsigned int channel; /* channel number */
u32 feature; u32 feature;
...@@ -906,6 +931,7 @@ static struct gs_can *gs_make_candev(unsigned int channel, ...@@ -906,6 +931,7 @@ static struct gs_can *gs_make_candev(unsigned int channel,
struct net_device *netdev; struct net_device *netdev;
int rc; int rc;
struct gs_device_bt_const *bt_const; struct gs_device_bt_const *bt_const;
struct gs_device_bt_const_extended *bt_const_extended;
u32 feature; u32 feature;
bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL); bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL);
...@@ -989,6 +1015,9 @@ static struct gs_can *gs_make_candev(unsigned int channel, ...@@ -989,6 +1015,9 @@ static struct gs_can *gs_make_candev(unsigned int channel,
if (feature & GS_CAN_FEATURE_FD) { if (feature & GS_CAN_FEATURE_FD) {
dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD; dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
/* The data bit timing will be overwritten, if
* GS_CAN_FEATURE_BT_CONST_EXT is set.
*/
dev->can.data_bittiming_const = &dev->bt_const; dev->can.data_bittiming_const = &dev->bt_const;
dev->can.do_set_data_bittiming = gs_usb_set_data_bittiming; dev->can.do_set_data_bittiming = gs_usb_set_data_bittiming;
} }
...@@ -1022,6 +1051,43 @@ static struct gs_can *gs_make_candev(unsigned int channel, ...@@ -1022,6 +1051,43 @@ static struct gs_can *gs_make_candev(unsigned int channel,
kfree(bt_const); kfree(bt_const);
/* fetch extended bit timing constants if device has feature
* GS_CAN_FEATURE_FD and GS_CAN_FEATURE_BT_CONST_EXT
*/
if (feature & GS_CAN_FEATURE_FD &&
feature & GS_CAN_FEATURE_BT_CONST_EXT) {
bt_const_extended = kmalloc(sizeof(*bt_const_extended), GFP_KERNEL);
if (!bt_const_extended)
return ERR_PTR(-ENOMEM);
rc = usb_control_msg(interface_to_usbdev(intf),
usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
GS_USB_BREQ_BT_CONST_EXT,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
channel, 0, bt_const_extended,
sizeof(*bt_const_extended),
1000);
if (rc < 0) {
dev_err(&intf->dev,
"Couldn't get extended bit timing const for channel (err=%d)\n",
rc);
kfree(bt_const_extended);
return ERR_PTR(rc);
}
strcpy(dev->data_bt_const.name, "gs_usb");
dev->data_bt_const.tseg1_min = le32_to_cpu(bt_const_extended->dtseg1_min);
dev->data_bt_const.tseg1_max = le32_to_cpu(bt_const_extended->dtseg1_max);
dev->data_bt_const.tseg2_min = le32_to_cpu(bt_const_extended->dtseg2_min);
dev->data_bt_const.tseg2_max = le32_to_cpu(bt_const_extended->dtseg2_max);
dev->data_bt_const.sjw_max = le32_to_cpu(bt_const_extended->dsjw_max);
dev->data_bt_const.brp_min = le32_to_cpu(bt_const_extended->dbrp_min);
dev->data_bt_const.brp_max = le32_to_cpu(bt_const_extended->dbrp_max);
dev->data_bt_const.brp_inc = le32_to_cpu(bt_const_extended->dbrp_inc);
dev->can.data_bittiming_const = &dev->data_bt_const;
}
SET_NETDEV_DEV(netdev, &intf->dev); SET_NETDEV_DEV(netdev, &intf->dev);
rc = register_candev(dev->netdev); rc = register_candev(dev->netdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment