Skip to contentSkip to conversation

canfd: add new data structures and constants

PATCH In review Oliver Hartkopp 3 participants 14 messages Jun 18, 2012 – Jun 19, 2012

Subsystems (3)
lore
Share & tools
lore

Oliver Hartkopp

author maintainer
#0 lore raw

PATCH 1/6 canfd: add new data structures and constants

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values

---
 include/linux/can.h      |   55 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
include/linux/can.h +49 -4
index 17334c0..25265e7 100644
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
 /**
  * struct can_frame - basic CAN frame structure
- * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
- * @can_dlc: the data length field of the CAN frame
- * @data:    the CAN frame payload.
+ * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *           mapping of the 'data length code' to the real payload length
+ * @data:    CAN frame payload (up to 8 byte)
  */
 struct can_frame {
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));
 };
 +/*
+ * defined bits for canfd_frame.flags
+ *
+ * As the default for CAN FD should be to support the high data rate in the
+ * payload section of the frame (HDR) and to support up to 64 byte in the
+ * data section (EDL) the bits are only set in the non-default case.
+ * Btw. as long as there's no real implementation for CAN FD network driver
+ * these bits are only preliminary.
+ *
+ * RX: NOHDR/NOEDL - info about received CAN FD frame
+ *     ESI         - bit from originating CAN controller
+ * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller
+ *     ESI         - bit is set by local CAN controller
+ */
+#define CANFD_NOHDR 0x01 /* frame without high data rate */
+#define CANFD_NOEDL 0x02 /* frame without extended data length */
+#define CANFD_ESI   0x04 /* error state indicator */
+
+/**
+ * struct canfd_frame - CAN flexible data rate frame structure
+ * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @len:    frame payload length in byte (0 .. 64)
+ * @flags:  additional flags for CAN FD
+ * @__res0: reserved / padding
+ * @__res1: reserved / padding
+ * @data:   CAN FD frame payload (up to 64 byte)
+ */
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+	__u8    len;     /* frame payload length in byte (0 .. 64) */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[64] __attribute__((aligned(8)));
+};
+
+#define CAN_MTU		(sizeof(struct can_frame))
+#define CANFD_MTU	(sizeof(struct canfd_frame))
+
 /* particular protocols of the protocol family PF_CAN */
 #define CAN_RAW		1 /* RAW sockets */
 #define CAN_BCM		2 /* Broadcast Manager */
include/linux/if_ether.h +2 -1
index 56d907a..260138b 100644
@@ -105,7 +105,8 @@
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009		/* Localtalk pseudo type 	*/
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* Controller Area Network (CAN)*/
+#define ETH_P_CANFD	0x000D		/* CAN FD 64 byte payload frames*/
 #define ETH_P_PPPTALK	0x0010		/* Dummy type for Atalk over PPP*/
 #define ETH_P_TR_802_2	0x0011		/* 802.2 frames 		*/
 #define ETH_P_MOBITEX	0x0015		/* Mobitex ([email protected])	*/
net/can/af_can.c +7 -0
index 6efcd37..c96140a 100644
@@ -41,6 +41,7 @@
  */
  #include <linux/module.h>
+#include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
@@ -824,6 +825,12 @@ static struct notifier_block can_netdev_notifier __read_mostly = {
  static __init int can_init(void)
 {
+	/* check for correct padding to be able to use the structs similarly */
+	BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
+		     offsetof(struct canfd_frame, len) ||
+		     offsetof(struct can_frame, data) !=
+		     offsetof(struct canfd_frame, data));
+
 	printk(banner);
  	memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
Signature · 1 line
1.7.10.4
author maintainer
#1 lore raw

include/linux/can.h typedef __u32 canid_t; · line 50

Quoted 8 lines · Oliver Hartkopp
include/linux/can.h +2 -0
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+

Hm looks broken - but the patch and the repo content is ok.

Oh, well.

Anyone an idea how to set up imap with strato.de for git send-imap with a debian system ??

I tried this imapsslappend.pl script from

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572521

which obviously mangles the mails a bit :-(

Regards,
Oliver

#2 lore raw
Quoted 14 lines · Oliver Hartkopp

include/linux/can.h typedef __u32 canid_t; · line 50

Quoted 8 lines · Oliver Hartkopp
include/linux/can.h +2 -0
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+

Hm looks broken - but the patch and the repo content is ok.

I suggest to use git send-email. It can talk smtp with authentication and all bells and whistles you need. Yes, the repo is all-right.

Quoted 5 lines

Oh, well.

Anyone an idea how to set up imap with strato.de for git send-imap with a debian system ??

sudo aptitude install dovecot-imapd

Marc

Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
#3 lore raw
In reply to Oliver Hartkopp
Quoted 32 lines · Oliver Hartkopp

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values

---
 include/linux/can.h      |   55 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
include/linux/can.h +6 -3
index 17334c0..25265e7 100644
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
 /**
  * struct can_frame - basic CAN frame structure
- * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
- * @can_dlc: the data length field of the CAN frame
- * @data:    the CAN frame payload.
+ * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition

include/linux/can.h typedef __u32 canid_t; · line 65

Quoted 10 lines
include/linux/can.h +5 -1
+ * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *           mapping of the 'data length code' to the real payload length
+ * @data:    CAN frame payload (up to 8 byte)
  */
 struct can_frame {
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));

checkpatch complains:

WARNING: __aligned(size) is preferred over __attribute__((aligned(size))) #84: FILE: include/linux/can.h:102:
+ __u8 data[64] __attribute__((aligned(8)));

total: 0 errors, 1 warnings, 97 lines checked

Marc

Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
author maintainer
#4 lore raw
Quoted 12 lines · Marc Kleine-Budde

include/linux/can.h typedef __u32 canid_t; · line 65

Quoted 8 lines · Oliver Hartkopp

- add new struct canfd_frame

struct can_frame {

include/linux/can.h +1 -1
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));

checkpatch complains:

Quoted 6 lines

WARNING: __aligned(size) is preferred over __attribute__((aligned(size))) #84: FILE: include/linux/can.h:102:
+ __u8 data[64] __attribute__((aligned(8)));

total: 0 errors, 1 warnings, 97 lines checked

Hm, yes. I wanted to have it the same way as in struct can_frame.

I wonder if "__aligened(size)" is also compatible for backports - or alternative if we should also modify the original can_frame:

Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +1 -1
- 	__u8    data[8] __attribute__((aligned(8)));
+ 	__u8    data[8] __aligned(8);

???

Regards,
Oliver

#5 lore raw
Quoted 17 lines · Oliver Hartkopp
Quoted 15 lines · Marc Kleine-Budde

include/linux/can.h typedef __u32 canid_t; · line 65

Quoted 7 lines · Oliver Hartkopp

- add new struct canfd_frame

struct can_frame {

include/linux/can.h +1 -1
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));

checkpatch complains:

WARNING: __aligned(size) is preferred over __attribute__((aligned(size))) #84: FILE: include/linux/can.h:102:
+ __u8 data[64] __attribute__((aligned(8)));

Quoted 6 lines
Quoted 1 line

total: 0 errors, 1 warnings, 97 lines checked

Hm, yes. I wanted to have it the same way as in struct can_frame.

I wonder if "__aligened(size)" is also compatible for backports - or alternative if we should also modify the original can_frame:

__aligened(size) has been introduced in v2.6.21-rc1~91^2~274.

(How to figure out:

$ git blame include/linux/compiler-gcc.h
$ git describe 82ddcb04
v2.6.20-1507-g82ddcb0
$ git describe --contains 82ddcb04
v2.6.21-rc1~91^2~274
)
Quoted 2 lines
Quoted 2 lines

Review

Quoted 2 lines
(quoted diff) +1 -1
- 	__u8    data[8] __attribute__((aligned(8)));
+ 	__u8    data[8] __aligned(8);

If you want to be super clean you can first make a patch that changes the existing __attribute__((aligned(8))) to __aligned(8), and then add your canfd series. If not, just mention it in the patch description (While being here change can_fd to __aligned(8)).

Err..this is a userspace header, I just tested it, headers_install doesn't remove it. And userspace fails to compile with this. For now stick to __attribute__((aligned(8))).

Marc

Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
#6 lore raw
Quoted 8 lines · Marc Kleine-Budde

If you want to be super clean you can first make a patch that changes the existing __attribute__((aligned(8))) to __aligned(8), and then add your canfd series. If not, just mention it in the patch description (While being here change can_fd to __aligned(8)).

Err..this is a userspace header, I just tested it, headers_install doesn't remove it. And userspace fails to compile with this. For now stick to __attribute__((aligned(8))).

BTW: and it fails to compile due to a __kernel_sa_family_t which isn't defined on my ubuntu with 2.6.32er headers

Marc

Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
author maintainer
#7 lore raw
Quoted 6 lines · Marc Kleine-Budde
Quoted 5 lines · Marc Kleine-Budde

If you want to be super clean you can first make a patch that changes the existing __attribute__((aligned(8))) to __aligned(8), and then add your canfd series. If not, just mention it in the patch description (While being here change can_fd to __aligned(8)).

Quoted 6 lines
Quoted 3 lines

Err..this is a userspace header, I just tested it, headers_install doesn't remove it. And userspace fails to compile with this. For now stick to __attribute__((aligned(8))).

BTW: and it fails to compile due to a __kernel_sa_family_t which isn't defined on my ubuntu with 2.6.32er headers

__kernel_sa_family_t is defined in include/linux/socket.h but with

#ifdef __KERNEL__

around it.

typedef __kernel_sa_family_t sa_family_t;

What do you compile?

If you compile a kernel -> it is defined. If you compile an application -> it is not needed.

Regards,
Oliver

#8 lore raw
Quoted 10 lines · Oliver Hartkopp
Quoted 6 lines
Quoted 3 lines

Err..this is a userspace header, I just tested it, headers_install doesn't remove it. And userspace fails to compile with this. For now stick to __attribute__((aligned(8))).

BTW: and it fails to compile due to a __kernel_sa_family_t which isn't defined on my ubuntu with 2.6.32er headers

__kernel_sa_family_t is defined in include/linux/socket.h but with

Quoted 7 lines

#ifdef __KERNEL__

around it.

typedef __kernel_sa_family_t sa_family_t;

What do you compile?

canutils, I used linux/can.h generated by install_headers.

Quoted 2 lines

If you compile a kernel -> it is defined. If you compile an application -> it is not needed.

You need recent kernel headers on your linux box to work. On the compiler machine in the office we have:

$ grep __kernel_sa_family_t /usr/include/linux/socket.h
typedef unsigned short __kernel_sa_family_t;
        __kernel_sa_family_t    ss_family;              /* address family */

Marc

Signature · 4 lines
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
#9 lore raw
In reply to Oliver Hartkopp

Hi Oliver,

Quoted 67 lines · Oliver Hartkopp

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values

---
 include/linux/can.h      |   55 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
include/linux/can.h +34 -4
index 17334c0..25265e7 100644
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
 /**
  * struct can_frame - basic CAN frame structure
- * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
- * @can_dlc: the data length field of the CAN frame
- * @data:    the CAN frame payload.
+ * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *           mapping of the 'data length code' to the real payload length
+ * @data:    CAN frame payload (up to 8 byte)
  */
 struct can_frame {
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));
 };
 +/*
+ * defined bits for canfd_frame.flags
+ *
+ * As the default for CAN FD should be to support the high data rate in the
+ * payload section of the frame (HDR) and to support up to 64 byte in the
+ * data section (EDL) the bits are only set in the non-default case.
+ * Btw. as long as there's no real implementation for CAN FD network driver
+ * these bits are only preliminary.
+ *
+ * RX: NOHDR/NOEDL - info about received CAN FD frame
+ *     ESI         - bit from originating CAN controller
+ * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller
+ *     ESI         - bit is set by local CAN controller
+ */
+#define CANFD_NOHDR 0x01 /* frame without high data rate */
+#define CANFD_NOEDL 0x02 /* frame without extended data length */
+#define CANFD_ESI   0x04 /* error state indicator */
+
+/**
+ * struct canfd_frame - CAN flexible data rate frame structure
+ * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @len:    frame payload length in byte (0 .. 64)
+ * @flags:  additional flags for CAN FD
+ * @__res0: reserved / padding

include/linux/can.h typedef __u32 canid_t; · line 100

Quoted 10 lines
include/linux/can.h +10 -0
+ * @__res1: reserved / padding
+ * @data:   CAN FD frame payload (up to 64 byte)
+ */
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+	__u8    len;     /* frame payload length in byte (0 .. 64) */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[64] __attribute__((aligned(8)));

Shouldn't we use "CANFD_MAX_DLEN" here (... and maybe above as well)?. IIRC, CANFD_MAX_DLEN might be even 128 in the finalized standard.

Quoted 13 lines
include/linux/can.h +5 -0
+};
+
+#define CAN_MTU		(sizeof(struct can_frame))
+#define CANFD_MTU	(sizeof(struct canfd_frame))
+
 /* particular protocols of the protocol family PF_CAN */
 #define CAN_RAW		1 /* RAW sockets */
 #define CAN_BCM		2 /* Broadcast Manager */
include/linux/if_ether.h +0 -0
index 56d907a..260138b 100644

include/linux/if_ether.h line 109

Quoted 6 lines
include/linux/if_ether.h +2 -1
@@ -105,7 +105,8 @@
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009		/* Localtalk pseudo type 	*/
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* Controller Area Network (CAN)*/
+#define ETH_P_CANFD	0x000D		/* CAN FD 64 byte payload frames*/

Then hardcoding 64 here is also not be nice.

Quoted 25 lines
include/linux/if_ether.h +0 -0
 #define ETH_P_PPPTALK	0x0010		/* Dummy type for Atalk over PPP*/
 #define ETH_P_TR_802_2	0x0011		/* 802.2 frames 		*/
 #define ETH_P_MOBITEX	0x0015		/* Mobitex ([email protected])	*/
net/can/af_can.c +7 -0
index 6efcd37..c96140a 100644
@@ -41,6 +41,7 @@
  */
  #include <linux/module.h>
+#include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
@@ -824,6 +825,12 @@ static struct notifier_block can_netdev_notifier __read_mostly = {
  static __init int can_init(void)
 {
+	/* check for correct padding to be able to use the structs similarly */
+	BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
+		     offsetof(struct canfd_frame, len) ||
+		     offsetof(struct can_frame, data) !=
+		     offsetof(struct canfd_frame, data));
+
 	printk(banner);
  	memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
author maintainer
#10 lore raw
Quoted 29 lines · Wolfgang Grandegger

Hi Oliver,

Quoted 26 lines · Oliver Hartkopp

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values

---
 include/linux/can.h      |   55 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
include/linux/can.h +5 -0
index 17334c0..25265e7 100644
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+

(..)

Quoted 6 lines
Quoted 6 lines

struct can_frame {

include/linux/can.h +1 -1
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));
 };

(..)

Quoted 4 lines
Quoted 4 lines

+ * @data: CAN FD frame payload (up to 64 byte)
+ */

include/linux/can.h +2 -0
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
Quoted 9 lines

include/linux/can.h typedef __u32 canid_t; · line 100

Quoted 5 lines
include/linux/can.h +5 -0
+	__u8    len;     /* frame payload length in byte (0 .. 64) */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[64] __attribute__((aligned(8)));

Shouldn't we use "CANFD_MAX_DLEN" here (... and maybe above as well)?. IIRC, CANFD_MAX_DLEN might be even 128 in the finalized standard.

Yes. Good point.

(..)

Quoted 5 lines

include/linux/can.h

Quoted 3 lines
include/linux/can.h +2 -1
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* Controller Area Network (CAN)*/
+#define ETH_P_CANFD	0x000D		/* CAN FD 64 byte payload frames*/

Then hardcoding 64 here is also not be nice.

Yes. Will change that too.
Even if there's a little chance to have more than 64 bytes it's not the right place for this kind of information anyway.

I would wait until this evening if there are more of these remarks and send a v2 then. A review of the documentation would be nice - if everything seems clear to you.

Thanks,
Oliver

#11 lore raw
Quoted 70 lines · Oliver Hartkopp
Quoted 29 lines · Wolfgang Grandegger

Hi Oliver,

Quoted 26 lines · Oliver Hartkopp

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values

---
 include/linux/can.h      |   55 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 60 insertions(+), 5 deletions(-)
include/linux/can.h +5 -0
index 17334c0..25265e7 100644
@@ -46,18 +46,65 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 +#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+

(..)

Quoted 6 lines
Quoted 6 lines

struct can_frame {

include/linux/can.h +1 -1
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
+	__u8    can_dlc; /* frame payload length in byte (0 .. 8) */
 	__u8    data[8] __attribute__((aligned(8)));
 };

(..)

Quoted 4 lines
Quoted 4 lines

+ * @data: CAN FD frame payload (up to 64 byte)
+ */

include/linux/can.h +2 -0
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
Quoted 9 lines

include/linux/can.h typedef __u32 canid_t; · line 100

Quoted 5 lines
include/linux/can.h +5 -0
+	__u8    len;     /* frame payload length in byte (0 .. 64) */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[64] __attribute__((aligned(8)));

Shouldn't we use "CANFD_MAX_DLEN" here (... and maybe above as well)?. IIRC, CANFD_MAX_DLEN might be even 128 in the finalized standard.

Yes. Good point.

(..)

Quoted 5 lines

include/linux/can.h

Quoted 3 lines
include/linux/can.h +2 -1
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* Controller Area Network (CAN)*/
+#define ETH_P_CANFD	0x000D		/* CAN FD 64 byte payload frames*/

Then hardcoding 64 here is also not be nice.

Quoted 7 lines

Yes. Will change that too.
Even if there's a little chance to have more than 64 bytes it's not the right place for this kind of information anyway.

I would wait until this evening if there are more of these remarks and send a v2 then. A review of the documentation would be nice - if everything seems clear to you.

Where can I pull/fetch the patches from? IIUC, the latest patch series you sent is broken.

Wolfgang.

author maintainer
#12 lore raw
Quoted 7 lines
Quoted 4 lines

I would wait until this evening if there are more of these remarks and send a v2 then. A review of the documentation would be nice - if everything seems clear to you.

Where can I pull/fetch the patches from? IIUC, the latest patch series you sent is broken.

No. It was only the mail representation which was broken.

The following changes since commit 4670fd819e7f47392c7c6fc6168ea2857c66d163:

tcp: Get rid of inetpeer special cases. (2012-06-09 01:25:47 -0700)

are available in the git repository at:

git://gitorious.org/~hartkopp/linux-can/ollis-can-next.git canfd

for you to fetch changes up to d55c45913f93ccbd4378195e2d6ca96b2d14573b:

canfd: update documentation according to CAN FD extensions (2012-06-17 21:23:55 +0200)

----------------------------------------------------------------

Oliver Hartkopp (6):
canfd: add new data structures and constants
canfd: add support for CAN FD in PF_CAN core
canfd: add support for CAN FD in CAN_RAW sockets
candev: add/update helpers for CAN FD
vcan: add CAN FD support
canfd: update documentation according to CAN FD extensions

(..)

author maintainer
#13 lore raw
In reply to Oliver Hartkopp
Quoted 28 lines · Oliver Hartkopp
Quoted 4 lines · Wolfgang Grandegger
Quoted 4 lines

+ * @data: CAN FD frame payload (up to 64 byte)
+ */

(quoted diff) +2 -0
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
Quoted 9 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+	__u8    len;     /* frame payload length in byte (0 .. 64) */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[64] __attribute__((aligned(8)));

Shouldn't we use "CANFD_MAX_DLEN" here (... and maybe above as well)?. IIRC, CANFD_MAX_DLEN might be even 128 in the finalized standard.

Yes. Good point.

(..)

Quoted 5 lines

Review

Quoted 3 lines
(quoted diff) +2 -1
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* Controller Area Network (CAN)*/
+#define ETH_P_CANFD	0x000D		/* CAN FD 64 byte payload frames*/

Then hardcoding 64 here is also not be nice.

Quoted 4 lines

Yes. Will change that too.
Even if there's a little chance to have more than 64 bytes it's not the right place for this kind of information anyway.

Here is the updated patch.

I also changed the structure definition of struct can_frame to use the defined CAN_MAX_DLEN (==8) but i preserved the struct documentation to remain readable.

Regards,
Oliver

From 561a5c55627bb54a50784aca5c9de6352c1303ee Mon Sep 17 00:00:00 2001
From: Oliver Hartkopp <[email protected]>
Date: Wed, 13 Jun 2012 20:04:33 +0200
Subject: [PATCH 1/6] canfd: add new data structures and constants

- add new struct canfd_frame
- check identical element offsets in struct can_frame and struct canfd_frame
- new ETH_P_CANFD definition to tag CAN FD skbs correctly
- add CAN_MTU and CANFD_MTU definitions for easy frame and mode detection
- add CAN[FD]_MAX_[DLC|DLEN] helper constants to remove hard coded values
- update existing struct can_frame with helper constants and comments

---
 include/linux/can.h      |   59 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/if_ether.h |    3 ++-
 net/can/af_can.c         |    7 ++++++
 3 files changed, 63 insertions(+), 6 deletions(-)
include/linux/can.h +54 -5
index 17334c0..1a66cf61 100644
@@ -46,18 +46,67 @@ typedef __u32 canid_t;
  */
 typedef __u32 can_err_mask_t;
 
+/* CAN payload length and DLC definitions according to ISO 11898-1 */
+#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
 /**
  * struct can_frame - basic CAN frame structure
- * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
- * @can_dlc: the data length field of the CAN frame
- * @data:    the CAN frame payload.
+ * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *           mapping of the 'data length code' to the real payload length
+ * @data:    CAN frame payload (up to 8 byte)
  */
 struct can_frame {
 	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	__u8    can_dlc; /* data length code: 0 .. 8 */
-	__u8    data[8] __attribute__((aligned(8)));
+	__u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
+	__u8    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
 };
 
+/*
+ * defined bits for canfd_frame.flags
+ *
+ * As the default for CAN FD should be to support the high data rate in the
+ * payload section of the frame (HDR) and to support up to 64 byte in the
+ * data section (EDL) the bits are only set in the non-default case.
+ * Btw. as long as there's no real implementation for CAN FD network driver
+ * these bits are only preliminary.
+ *
+ * RX: NOHDR/NOEDL - info about received CAN FD frame
+ *     ESI         - bit from originating CAN controller
+ * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller
+ *     ESI         - bit is set by local CAN controller
+ */
+#define CANFD_NOHDR 0x01 /* frame without high data rate */
+#define CANFD_NOEDL 0x02 /* frame without extended data length */
+#define CANFD_ESI   0x04 /* error state indicator */
+
+/**
+ * struct canfd_frame - CAN flexible data rate frame structure
+ * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @len:    frame payload length in byte (0 .. CANFD_MAX_DLEN)
+ * @flags:  additional flags for CAN FD
+ * @__res0: reserved / padding
+ * @__res1: reserved / padding
+ * @data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte)
+ */
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+	__u8    len;     /* frame payload length in byte */
+	__u8    flags;   /* additional flags for CAN FD */
+	__u8    __res0;  /* reserved / padding */
+	__u8    __res1;  /* reserved / padding */
+	__u8    data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
+};
+
+#define CAN_MTU		(sizeof(struct can_frame))
+#define CANFD_MTU	(sizeof(struct canfd_frame))
+
 /* particular protocols of the protocol family PF_CAN */
 #define CAN_RAW		1 /* RAW sockets */
 #define CAN_BCM		2 /* Broadcast Manager */
include/linux/if_ether.h +2 -1
index 56d907a..ff423d7 100644
@@ -105,7 +105,8 @@
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009		/* Localtalk pseudo type 	*/
-#define ETH_P_CAN	0x000C		/* Controller Area Network      */
+#define ETH_P_CAN	0x000C		/* CAN: Controller Area Network */
+#define ETH_P_CANFD	0x000D		/* CAN FD: CAN w flexi datarate */
 #define ETH_P_PPPTALK	0x0010		/* Dummy type for Atalk over PPP*/
 #define ETH_P_TR_802_2	0x0011		/* 802.2 frames 		*/
 #define ETH_P_MOBITEX	0x0015		/* Mobitex ([email protected])	*/
net/can/af_can.c +7 -0
index 6efcd37..c96140a 100644
@@ -41,6 +41,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
@@ -824,6 +825,12 @@ static struct notifier_block can_netdev_notifier __read_mostly = {
 
 static __init int can_init(void)
 {
+	/* check for correct padding to be able to use the structs similarly */
+	BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
+		     offsetof(struct canfd_frame, len) ||
+		     offsetof(struct can_frame, data) !=
+		     offsetof(struct canfd_frame, data));
+
 	printk(banner);
 
 	memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
Signature · 1 line
1.7.10.4