summaryrefslogtreecommitdiff
path: root/include/linux/can
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2022-09-12 19:07:23 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2022-09-15 09:08:09 +0200
commitfb08cba12b52cba4366e858932307649dc5304e2 (patch)
tree56d3c61f52a39ff9c574ed18da0edbdb5a81b6d9 /include/linux/can
parent1a3e3034c049503ec6992a4a7d573e7fff31fac4 (diff)
can: canxl: update CAN infrastructure for CAN XL frames
- add new ETH_P_CANXL ethernet protocol type - update skb checks for CAN XL - add alloc_canxl_skb() which now needs a data length parameter - introduce init_can_skb_reserve() to reduce code duplication Acked-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Link: https://lore.kernel.org/all/20220912170725.120748-6-socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'include/linux/can')
-rw-r--r--include/linux/can/skb.h23
1 files changed, 22 insertions, 1 deletions
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index ddffc2fc008c..1abc25a8d144 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -30,6 +30,9 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx,
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
struct sk_buff *alloc_canfd_skb(struct net_device *dev,
struct canfd_frame **cfd);
+struct sk_buff *alloc_canxl_skb(struct net_device *dev,
+ struct canxl_frame **cxl,
+ unsigned int data_len);
struct sk_buff *alloc_can_err_skb(struct net_device *dev,
struct can_frame **cf);
bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb);
@@ -114,11 +117,29 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb)
return (skb->len == CANFD_MTU && cfd->len <= CANFD_MAX_DLEN);
}
-/* get length element value from can[fd]_frame structure */
+static inline bool can_is_canxl_skb(const struct sk_buff *skb)
+{
+ const struct canxl_frame *cxl = (struct canxl_frame *)skb->data;
+
+ if (skb->len < CANXL_HDR_SIZE + CANXL_MIN_DLEN || skb->len > CANXL_MTU)
+ return false;
+
+ /* this also checks valid CAN XL data length boundaries */
+ if (skb->len != CANXL_HDR_SIZE + cxl->len)
+ return false;
+
+ return cxl->flags & CANXL_XLF;
+}
+
+/* get length element value from can[|fd|xl]_frame structure */
static inline unsigned int can_skb_get_len_val(struct sk_buff *skb)
{
+ const struct canxl_frame *cxl = (struct canxl_frame *)skb->data;
const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+ if (can_is_canxl_skb(skb))
+ return cxl->len;
+
return cfd->len;
}