[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260121182429.16624-1-rakuram.e96@gmail.com>
Date: Wed, 21 Jan 2026 23:54:25 +0530
From: Rakuram Eswaran <rakuram.e96@...il.com>
To: socketcan@...tkopp.net
Cc: corbet@....net,
linux-can@...r.kernel.org,
linux-doc@...r.kernel.org,
mailhol@...nel.org,
mkl@...gutronix.de,
netdev@...r.kernel.org,
rakuram.e96@...il.com
Subject: Re: [PATCH 2/2] docs: can: update SocketCAN documentation for CAN XL
On Sun, 18 Jan 2026 at 23:53, Oliver Hartkopp <socketcan@...tkopp.net> wrote:
>
>
> On 18.01.26 15:41, Rakuram Eswaran wrote:
> > On Tue, 13 Jan 2026 at 21:45, Oliver Hartkopp <socketcan@...tkopp.net> wrote:
> >>
>
> >>> The length of the two CAN(FD) frame structures define the maximum transfer
> >>> unit (MTU) of the CAN(FD) network interface and skbuff data length. Two
> >>> -definitions are specified for CAN specific MTUs in include/linux/can.h:
> >>> +definitions are specified for CAN specific MTUs in include/uapi/linux/can.h:
> >>
> >> No.
> >> From the user perspective he has to include include/linux/can.h
> >>
> >> Better "MTUs in the linux/can.h include file:"
> >>
> >
> > Can I just incude linux/can.h or include/linux/can.h? As in the current
> > document include/linux/can.h is used.
> >
>
> If you look into the code you need e.g.
>
> #include <linux/can.h>
> #include <linux/can/raw.h>
>
> So I would name it the linux/can.h include file.
>
Hi Oliver,
Ah, now I understand what I did wrong in my interpretation. I replaced
all instances of include/linux/can.h to linux/can.h include file.
> >>
> >> What about the PWM settings here?
> >> When TMS is "on" the PWM values can be automatically calculated or set
> >> manually. There's also no CAN XL TDC when TMS=on as the TDC is a
> >> mixed-mode requirement for non-TMS transceivers.
> >>
> >
> > Can I add the PWM settings under new heading (CAN XL PWM) or is it fine
> > to keep the content under the same heading (CAN XL TDC)?
> >
>
> Yes. I would propose a new section
>
> CAN XL TMS (Transceiver Mode Setting / PWM)
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> The Transceiver Mode Setting (TMS) switches the RX/TX lines between the
> CAN XL controller and the CAN XL transceiver into the "Fast Mode" by
> enabling a PWM protocol.
>
> In the Fast Mode a different sample point is used and the PWM ratio is
> calculated automatically or can be set manually.
>
Ok, will add this section. In the below article, I saw a table named
"CAN transceiver modes signaled". Can I add them here or above content
is fine?
https://www.can-cia.org/can-knowledge/can-xl
> >> There's one big difference between CC/FD and XL frames when you
> >> read/write it to CAN_RAW sockets:
> >>
> >> For CAN CC and CAN FD you write struct can(fd)_frame's with CAN_MTU
> >> resp. CANFD_MTU lengths - no matter about the data length (cf->len).
> >>
> >> When you read/write CAN XL frames you are reading and writing the
> >> CANXL_HDR_SIZE + the length of the data.
> >>
> >> So only in the case of writing 2048 byte data, you write 2060 bytes.
> >>
> >> The minimum size for read/write is CANXL_HDR_SIZE + CANXL_MIN_DLEN == 13
> >>
> >
> > Good point! I will add this information along with an example. I will go
> > through your code and decide what to add. Does the example code should
> > focus only on CAN XL frames or also on CC/FD frames?
>
Here, I added a updated content for PWM section and Application considerations
for CAN XL section.
CAN XL TMS (Transceiver Mode Setting / PWM)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Transceiver Mode Setting (TMS) switches the RX/TX lines between the
CAN XL controller and the CAN SIC XL transceiver into the "Fast Mode" by
enabling a PWM protocol.
In the Fast Mode, a different sample point is used and the PWM ratio is
either calculated automatically or can be set manually.
Application considerations for CAN XL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For user space applications the following rules are important when
handling CAN XL:
- Use ``struct canxl_frame`` as basic data structure when CAN XL traffic
is expected.
- Set CANXL_XLF in ``canxl_frame.flags`` for all valid CAN XL frames.
- Ensure that undefined bits in ``canxl_frame.flags`` are kept at zero.
- Respect the configured device MTU; do not send frames larger than
the MTU announced by the kernel.
- For mixed-mode controllers, be prepared to handle Classical CAN,
CAN FD and CAN XL frames on the same interface and choose the frame
structure according to the socket/protocol semantics (e.g. dedicated
CAN XL APIs when available).
- There's one big difference between CC/FD and XL frames when you
read/write it to CAN_RAW sockets:
- For CAN CC and CAN FD, struct can(fd)_frame's with CAN_MTU/CANFD_MTU
lengths.
- Read/write of CAN XL frames you are reading and writing the
CANXL_HDR_SIZE + the length of the data.
- The minimum size for read/write is CANXL_HDR_SIZE + CANXL_MIN_DLEN == 13.
> When the CAN_RAW socket enables the CAN XL support you have to deal with
> all kind of CAN frames. IMO is makes sense to show an example that deals
> with all three types of frames.
>
> >> Here is an example that I've been implemented recently that shows a good
> >> example how to handle CC/FD/XL frames, when they are all enabled on the
> >> CAN_RAW socket:
> >>
> >> https://github.com/hartkopp/can-utils/commit/bf0cae218af9b1c1f5eabad7f3704b88ab642e00
> >>
> >> Feel free to pick the code for some example.
> >>
> >> But please do not reference the commit as it is in my private repo and
> >> not yet integrated in the official can-utils repo.
> >>
I had gone through the code and picked the below code for example. I add the
code here. Kindly let me know if I need to add anything extra.
/* CAN CC/FD/XL frame union */
union cfu {
struct can_frame cc;
struct canfd_frame fd;
struct canxl_frame xl;
};
struct sockaddr_can addr;
static union cfu cu;
// open CAN_RAW socket
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
/* try to switch the socket into CAN FD mode */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfx_on, sizeof(canfx_on));
setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES, &canfx_on, sizeof(canfx_on));
/* try to enable the CAN XL VCID pass through mode */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS, &vcid_opts, sizeof(vcid_opts));
addr.can_family = AF_CAN;
// create the sockaddr binding
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return 1;
}
// The minimum size for read/write is CANXL_HDR_SIZE + CANXL_MIN_DLEN == 13 bytes
// (12 bytes of header + minimum 1 byte data)
if (cu.xl.flags & CANXL_XLF) {
if (nbytes != (int)CANXL_HDR_SIZE + cu.xl.len) {
printf("nbytes = %d\n", nbytes);
fprintf(stderr, "read: no CAN XL frame\n");
return 1;
}
rx_id = cu.xl.prio & CANXL_PRIO_MASK; /* remove VCID value */
data = cu.xl.data;
framelen = cu.xl.len;
} else {
/* mark dual-use struct canfd_frame */
if (nbytes == CAN_MTU)
cu.fd.flags = 0;
else if (nbytes == CANFD_MTU)
cu.fd.flags |= CANFD_FDF;
else {
fprintf(stderr, "read: incomplete CAN CC/FD frame\n");
return 1;
}
rx_id = cu.fd.can_id;
data = cu.fd.data;
framelen = cu.fd.len;
}
>
> Best regards,
> Oliver
>
Best Regards,
Rakuram.
Powered by blists - more mailing lists