can-dev: implement len8_dlc in some CAN USB adapters for testing
PATCH v2 1/1 can-dev: implement len8_dlc in some CAN USB adapters for testing
Namely those that are in mainline and I currently have on my desk ...
v2: fix introduced can_frame pointer assingment in pcan_usb_fd.c
Signed-off-by Oliver Hartkopp <[email protected]>
--- drivers/net/can/usb/gs_usb.c | 8 ++++++-- drivers/net/can/usb/peak_usb/pcan_usb.c | 8 ++++++-- drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 17 ++++++++++++----- drivers/net/can/usb/usb_8dev.c | 9 ++++++--- include/linux/can/dev.h | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 12 deletions(-)
drivers/net/can/usb/gs_usb.c +6 -2
@@ -330,10 +330,13 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)return ; cf->can_id = hf->can_id; cf->len =can_get_cc_len (hf->len); + cf->len8_dlc =can_get_len8_dlc (dev->can.ctrlmode, cf->len, + hf->len); +memcpy (cf->data, hf->data,8 );/* ERROR frames tell us information about the controller */ if (hf->can_id &CAN_ERR_FLAG )gs_update_state (dev, cf);
@@ -502,11 +505,12 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, hf->channel = dev->channel; cf = (struct can_frame *)skb->data; hf->can_id = cf->can_id; - hf->len = cf->len; + hf->len =can_get_cc_dlc (dev->can.ctrlmode, cf->len, cf->len8_dlc); +memcpy (hf->data, cf->data, cf->len); usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, GSUSB_ENDPOINT_OUT), hf,
@@ -856,11 +860,11 @@ static struct gs_can *gs_make_candev(unsigned int channel, dev->can.state =CAN_STATE_STOPPED ; dev->can.clock.freq = bt_const->fclk_can; dev->can.bittiming_const = &dev->bt_const; dev->can.do_set_bittiming = gs_usb_set_bittiming; - dev->can.ctrlmode_supported =0 ; + dev->can.ctrlmode_supported =CAN_CTRLMODE_CC_LEN8_DLC ;if (bt_const->feature &GS_CAN_FEATURE_LISTEN_ONLY ) dev->can.ctrlmode_supported |=CAN_CTRLMODE_LISTENONLY ;if (bt_const->feature &GS_CAN_FEATURE_LOOP_BACK )
drivers/net/can/usb/peak_usb/pcan_usb.c +6 -2
@@ -733,10 +733,12 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) cf->can_id =le16_to_cpu (tmp16) >>5 ; } cf->len =can_get_cc_len (rec_len); + cf->len8_dlc =can_get_len8_dlc (mc->pdev->dev.can.ctrlmode, cf->len, + rec_len);/* Only first packet timestamp is a word */ if (pcan_usb_decode_ts (mc, !mc->rec_ts_idx)) goto decode_failed;
@@ -836,11 +838,12 @@ static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb, obuf[1 ] =1 ; pc = obuf +PCAN_USB_MSG_HEADER_LEN ;/* status/len byte */ - *pc = cf->len; + *pc =can_get_cc_dlc (dev->can.ctrlmode, cf->len, cf->len8_dlc); +if (cf->can_id &CAN_RTR_FLAG ) *pc |=PCAN_USB_STATUSLEN_RTR ;/* can id */ if (cf->can_id &CAN_EFF_FLAG ) {
@@ -990,11 +993,12 @@ static const struct can_bittiming_const pcan_usb_const = {const struct peak_usb_adapter pcan_usb = { .name ="PCAN-USB" , .device_id =PCAN_USB_PRODUCT_ID , .ctrl_count =1 , .ctrlmode_supported =CAN_CTRLMODE_3_SAMPLES |CAN_CTRLMODE_LISTENONLY | -CAN_CTRLMODE_BERR_REPORTING , +CAN_CTRLMODE_BERR_REPORTING | +CAN_CTRLMODE_CC_LEN8_DLC , .clock = { .freq =PCAN_USB_CRYSTAL_HZ /2 , }, .bittiming_const = &pcan_usb_const,
drivers/net/can/usb/peak_usb/pcan_usb_fd.c +12 -5
@@ -492,16 +492,21 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,if (rx_msg_flags &PUCAN_MSG_ERROR_STATE_IND ) cfd->flags |=CANFD_ESI ; cfd->len =can_dlc2len (pucan_msg_get_dlc (rm)); }else { +struct can_frame *cf; +/* CAN 2.0 frame case */ skb =alloc_can_skb (netdev, (struct can_frame **)&cfd);if (!skb)return -ENOMEM ; cfd->len =can_get_cc_len (pucan_msg_get_dlc (rm)); + cf = (struct can_frame *)cfd; + cf->len8_dlc =can_get_len8_dlc (dev->can.ctrlmode, cf->len, +pucan_msg_get_dlc (rm)); } cfd->can_id =le32_to_cpu (rm->can_id);if (rx_msg_flags &PUCAN_MSG_EXT_ID )
@@ -764,12 +769,14 @@ static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev, tx_msg_flags |=PUCAN_MSG_BITRATE_SWITCH ;if (cfd->flags &CANFD_ESI ) tx_msg_flags |=PUCAN_MSG_ERROR_STATE_IND ; }else { +struct can_frame *cf = (struct can_frame *)cfd; +/* CAND 2.0 frames */ - len = cfd->len; + len =can_get_cc_dlc (dev->can.ctrlmode, cf->len, cf->len8_dlc);if (cfd->can_id &CAN_RTR_FLAG ) tx_msg_flags |=PUCAN_MSG_RTR ; }
@@ -1033,11 +1040,11 @@ static const struct can_bittiming_const pcan_usb_fd_data_const = {const struct peak_usb_adapter pcan_usb_fd = { .name ="PCAN-USB FD" , .device_id =PCAN_USBFD_PRODUCT_ID , .ctrl_count =PCAN_USBFD_CHANNEL_COUNT , - .ctrlmode_supported =CAN_CTRLMODE_FD | + .ctrlmode_supported =CAN_CTRLMODE_FD |CAN_CTRLMODE_CC_LEN8_DLC |CAN_CTRLMODE_3_SAMPLES |CAN_CTRLMODE_LISTENONLY , .clock = { .freq =PCAN_UFD_CRYSTAL_HZ , }, .bittiming_const = &pcan_usb_fd_const,
@@ -1105,11 +1112,11 @@ static const struct can_bittiming_const pcan_usb_chip_data_const = {const struct peak_usb_adapter pcan_usb_chip = { .name ="PCAN-Chip USB" , .device_id =PCAN_USBCHIP_PRODUCT_ID , .ctrl_count =PCAN_USBFD_CHANNEL_COUNT , - .ctrlmode_supported =CAN_CTRLMODE_FD | + .ctrlmode_supported =CAN_CTRLMODE_FD |CAN_CTRLMODE_CC_LEN8_DLC |CAN_CTRLMODE_3_SAMPLES |CAN_CTRLMODE_LISTENONLY , .clock = { .freq =PCAN_UFD_CRYSTAL_HZ , }, .bittiming_const = &pcan_usb_chip_const,
@@ -1177,11 +1184,11 @@ static const struct can_bittiming_const pcan_usb_pro_fd_data_const = {const struct peak_usb_adapter pcan_usb_pro_fd = { .name ="PCAN-USB Pro FD" , .device_id =PCAN_USBPROFD_PRODUCT_ID , .ctrl_count =PCAN_USBPROFD_CHANNEL_COUNT , - .ctrlmode_supported =CAN_CTRLMODE_FD | + .ctrlmode_supported =CAN_CTRLMODE_FD |CAN_CTRLMODE_CC_LEN8_DLC |CAN_CTRLMODE_3_SAMPLES |CAN_CTRLMODE_LISTENONLY , .clock = { .freq =PCAN_UFD_CRYSTAL_HZ , }, .bittiming_const = &pcan_usb_pro_fd_const,
@@ -1249,11 +1256,11 @@ static const struct can_bittiming_const pcan_usb_x6_data_const = {const struct peak_usb_adapter pcan_usb_x6 = { .name ="PCAN-USB X6" , .device_id =PCAN_USBX6_PRODUCT_ID , .ctrl_count =PCAN_USBPROFD_CHANNEL_COUNT , - .ctrlmode_supported =CAN_CTRLMODE_FD | + .ctrlmode_supported =CAN_CTRLMODE_FD |CAN_CTRLMODE_CC_LEN8_DLC |CAN_CTRLMODE_3_SAMPLES |CAN_CTRLMODE_LISTENONLY , .clock = { .freq =PCAN_UFD_CRYSTAL_HZ , }, .bittiming_const = &pcan_usb_x6_const,
drivers/net/can/usb/usb_8dev.c +6 -3
@@ -469,10 +469,12 @@ static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv,if (!skb)return ; cf->can_id =be32_to_cpu (msg->id); cf->len =can_get_cc_len (msg->dlc &0xF ); + cf->len8_dlc =can_get_len8_dlc (priv->can.ctrlmode, cf->len, + msg->dlc &0xF );if (msg->flags &USB_8DEV_EXTID ) cf->can_id |=CAN_EFF_FLAG ;if (msg->flags &USB_8DEV_RTR )
@@ -635,11 +637,11 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,if (cf->can_id &CAN_EFF_FLAG ) msg->flags |=USB_8DEV_EXTID ; msg->id =cpu_to_be32 (cf->can_id &CAN_ERR_MASK ); - msg->dlc = cf->len; + msg->dlc =can_get_cc_dlc (priv->can.ctrlmode, cf->len, cf->len8_dlc);memcpy (msg->data, cf->data, cf->len); msg->end =USB_8DEV_DATA_END ;for (i =0 ; i <MAX_TX_URBS ; i++) {if (priv->tx_contexts[i].echo_index ==MAX_TX_URBS ) {
@@ -925,12 +927,13 @@ static int usb_8dev_probe(struct usb_interface *intf, priv->can.clock.freq =USB_8DEV_ABP_CLOCK ; priv->can.bittiming_const = &usb_8dev_bittiming_const; priv->can.do_set_mode = usb_8dev_set_mode; priv->can.do_get_berr_counter = usb_8dev_get_berr_counter; priv->can.ctrlmode_supported =CAN_CTRLMODE_LOOPBACK | -CAN_CTRLMODE_LISTENONLY | -CAN_CTRLMODE_ONE_SHOT ; +CAN_CTRLMODE_LISTENONLY | +CAN_CTRLMODE_ONE_SHOT | +CAN_CTRLMODE_CC_LEN8_DLC ; netdev->netdev_ops = &usb_8dev_netdev_ops; netdev->flags |=IFF_ECHO ;/* we support local echo */
include/linux/can/dev.h +15 -0
@@ -168,10 +168,25 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb) {/* the CAN specific type of skb is identified by its data length */ return skb->len ==CANFD_MTU ; } +static inline u8 can_check_len8_dlc (u32 ctrlmode,u8 len,u8 dlc,u8 ret) +{ +/* return value for len8_dlc only if all conditions apply */ +if ((ctrlmode &CAN_CTRLMODE_CC_LEN8_DLC ) && + (len ==CAN_MAX_DLEN ) && + (dlc >CAN_MAX_DLEN && dlc <=CAN_MAX_RAW_DLC )) + ret = dlc; + +/* no valid len8_dlc value -> return provided default value */ +return ret; +} + +#define can_get_len8_dlc (cm, len, dlc) can_check_len8_dlc(cm, len, dlc, 0) +#define can_get_cc_dlc (cm, len, dlc) can_check_len8_dlc(cm, len, dlc, len) +/* helper to define static CAN controller features at device creation time */ static inline void can_set_static_ctrlmode (struct net_device *dev,u32 static_mode) {struct can_priv *priv =netdev_priv (dev);
Signature · 1 line
2.28.0