mirror of
https://github.com/torvalds/linux.git
synced 2024-11-12 23:23:03 +00:00
can: set CANFD_FDF flag in all CAN FD frame structures
To simplify the testing in user space all struct canfd_frame's provided by the CAN subsystem of the Linux kernel now have the CANFD_FDF flag set in canfd_frame::flags. NB: Handcrafted ETH_P_CANFD frames introduced via PF_PACKET socket might not set this bit correctly. During the check for sufficient headroom in PF_PACKET sk_buffs the uninitialized CAN sk_buff data structures are filled. In the case of a CAN FD frame the CANFD_FDF flag is set accordingly. As the CAN frame content is already zero initialized in alloc_canfd_skb() the obsolete initialization of cf->flags in the CTU CAN FD driver has been removed as it would overwrite the already set CANFD_FDF flag. Acked-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Link: https://lore.kernel.org/all/20220912170725.120748-4-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
467ef4c7b9
commit
061834624c
@ -657,7 +657,6 @@ static void ctucan_read_rx_frame(struct ctucan_priv *priv, struct canfd_frame *c
|
||||
cf->can_id = (idw >> 18) & CAN_SFF_MASK;
|
||||
|
||||
/* BRS, ESI, RTR Flags */
|
||||
cf->flags = 0;
|
||||
if (FIELD_GET(REG_FRAME_FORMAT_W_FDF, ffw)) {
|
||||
if (FIELD_GET(REG_FRAME_FORMAT_W_BRS, ffw))
|
||||
cf->flags |= CANFD_BRS;
|
||||
|
@ -244,6 +244,9 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
|
||||
|
||||
*cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
|
||||
|
||||
/* set CAN FD flag by default */
|
||||
(*cfd)->flags = CANFD_FDF;
|
||||
|
||||
return skb;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(alloc_canfd_skb);
|
||||
@ -287,6 +290,14 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
|
||||
skb_reset_mac_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_transport_header(skb);
|
||||
|
||||
/* set CANFD_FDF flag for CAN FD frames */
|
||||
if (can_is_canfd_skb(skb)) {
|
||||
struct canfd_frame *cfd;
|
||||
|
||||
cfd = (struct canfd_frame *)skb->data;
|
||||
cfd->flags |= CANFD_FDF;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -141,8 +141,8 @@ struct can_frame {
|
||||
* When this is done the former differentiation via CAN_MTU / CANFD_MTU gets
|
||||
* lost. CANFD_FDF allows programmers to mark CAN FD frames in the case of
|
||||
* using struct canfd_frame for mixed CAN / CAN FD content (dual use).
|
||||
* N.B. the Kernel APIs do NOT provide mixed CAN / CAN FD content inside of
|
||||
* struct canfd_frame therefore the CANFD_FDF flag is disregarded by Linux.
|
||||
* Since the introduction of CAN XL the CANFD_FDF flag is set in all CAN FD
|
||||
* frame structures provided by the CAN subsystem of the Linux kernel.
|
||||
*/
|
||||
#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
|
||||
#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
|
||||
|
@ -205,7 +205,12 @@ int can_send(struct sk_buff *skb, int loop)
|
||||
if (can_is_can_skb(skb)) {
|
||||
skb->protocol = htons(ETH_P_CAN);
|
||||
} else if (can_is_canfd_skb(skb)) {
|
||||
struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
|
||||
|
||||
skb->protocol = htons(ETH_P_CANFD);
|
||||
|
||||
/* set CAN FD flag for CAN FD frames by default */
|
||||
cfd->flags |= CANFD_FDF;
|
||||
} else {
|
||||
goto inval_skb;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user