Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: add optional DLC element to Classical CAN frame structure

ISO 11898-1 Chapter 8.4.2.3 defines a 4 bit data length code (DLC) table which
maps the DLC to the payload length of the CAN frame in bytes:

DLC -> payload length
0 .. 8 -> 0 .. 8
9 .. 15 -> 8

Although the DLC values 8 .. 15 in Classical CAN always result in a payload
length of 8 bytes these DLC values are transparently transmitted on the CAN
bus. As the struct can_frame only provides a 'len' element (formerly 'can_dlc')
which contains the plain payload length ( 0 .. 8 ) of the CAN frame, the raw
DLC is not visible to the application programmer, e.g. for testing use-cases.

To access the raw DLC values 9 .. 15 the len8_dlc element is introduced, which
is only valid when the payload length 'len' is 8 and the DLC is greater than 8.

The len8_dlc element is filled by the CAN interface driver and used for CAN
frame creation by the CAN driver when the CAN_CTRLMODE_CC_LEN8_DLC flag is
supported by the driver and enabled via netlink configuration interface.

Reported-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://lore.kernel.org/r/20201110101852.1973-2-socketcan@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Oliver Hartkopp and committed by
Marc Kleine-Budde
ea780056 b7d3c0e5

+25 -14
+24 -14
include/uapi/linux/can.h
··· 84 84 85 85 /* CAN payload length and DLC definitions according to ISO 11898-1 */ 86 86 #define CAN_MAX_DLC 8 87 + #define CAN_MAX_RAW_DLC 15 87 88 #define CAN_MAX_DLEN 8 88 89 89 90 /* CAN FD payload length and DLC definitions according to ISO 11898-7 */ ··· 92 91 #define CANFD_MAX_DLEN 64 93 92 94 93 /** 95 - * struct can_frame - basic CAN frame structure 96 - * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition 97 - * @can_dlc: frame payload length in byte (0 .. 8) aka data length code 98 - * N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1 99 - * mapping of the 'data length code' to the real payload length 100 - * @__pad: padding 101 - * @__res0: reserved / padding 102 - * @__res1: reserved / padding 103 - * @data: CAN frame payload (up to 8 byte) 94 + * struct can_frame - Classical CAN frame structure (aka CAN 2.0B) 95 + * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition 96 + * @len: CAN frame payload length in byte (0 .. 8) 97 + * @can_dlc: deprecated name for CAN frame payload length in byte (0 .. 8) 98 + * @__pad: padding 99 + * @__res0: reserved / padding 100 + * @len8_dlc: optional DLC value (9 .. 15) at 8 byte payload length 101 + * len8_dlc contains values from 9 .. 15 when the payload length is 102 + * 8 bytes but the DLC value (see ISO 11898-1) is greater then 8. 103 + * CAN_CTRLMODE_CC_LEN8_DLC flag has to be enabled in CAN driver. 104 + * @data: CAN frame payload (up to 8 byte) 104 105 */ 105 106 struct can_frame { 106 107 canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ 107 - __u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ 108 - __u8 __pad; /* padding */ 109 - __u8 __res0; /* reserved / padding */ 110 - __u8 __res1; /* reserved / padding */ 111 - __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); 108 + union { 109 + /* CAN frame payload length in byte (0 .. CAN_MAX_DLEN) 110 + * was previously named can_dlc so we need to carry that 111 + * name for legacy support 112 + */ 113 + __u8 len; 114 + __u8 can_dlc; /* deprecated */ 115 + }; 116 + __u8 __pad; /* padding */ 117 + __u8 __res0; /* reserved / padding */ 118 + __u8 len8_dlc; /* optional DLC for 8 byte payload length (9 .. 15) */ 119 + __u8 data[CAN_MAX_DLEN] __attribute__((aligned(8))); 112 120 }; 113 121 114 122 /*
+1
include/uapi/linux/can/netlink.h
··· 100 100 #define CAN_CTRLMODE_FD 0x20 /* CAN FD mode */ 101 101 #define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */ 102 102 #define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */ 103 + #define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */ 103 104 104 105 /* 105 106 * CAN device statistics