mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-07 13:13:57 +08:00
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.de Signed-off-by: Peter Fink <pfink@christ-es.de> Signed-off-by: Christoph Möhring <cmoehring@christ-es.de> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
b00ca070e0
commit
6679f4c5e5
@ -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 {
|
|||||||
#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 {
|
|||||||
#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 {
|
|||||||
__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 {
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user