can: dev: add CAN XL support to virtual CAN
authorOliver Hartkopp <socketcan@hartkopp.net>
Mon, 12 Sep 2022 17:07:24 +0000 (19:07 +0200)
committerMarc Kleine-Budde <mkl@pengutronix.de>
Thu, 15 Sep 2022 07:08:09 +0000 (09:08 +0200)
Make use of new can_skb_get_data_len() helper.
Add support for variable CANXL MTU using the new can_is_canxl_dev_mtu().

Acked-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://lore.kernel.org/all/20220912170725.120748-7-socketcan@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
drivers/net/can/vcan.c
drivers/net/can/vxcan.c
include/linux/can/dev.h

index 36b6310a2e5b02e3c997f87e1b23180c288e2d9b..285635c234432ba92fb5d7233426c35ab799942e 100644 (file)
@@ -71,11 +71,10 @@ MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
 
 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 {
-       struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
        struct net_device_stats *stats = &dev->stats;
 
        stats->rx_packets++;
-       stats->rx_bytes += cfd->len;
+       stats->rx_bytes += can_skb_get_data_len(skb);
 
        skb->pkt_type  = PACKET_BROADCAST;
        skb->dev       = dev;
@@ -86,14 +85,14 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 
 static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 {
-       struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
        struct net_device_stats *stats = &dev->stats;
-       int loop, len;
+       unsigned int len;
+       int loop;
 
        if (can_dropped_invalid_skb(dev, skb))
                return NETDEV_TX_OK;
 
-       len = cfd->can_id & CAN_RTR_FLAG ? 0 : cfd->len;
+       len = can_skb_get_data_len(skb);
        stats->tx_packets++;
        stats->tx_bytes += len;
 
@@ -137,7 +136,8 @@ static int vcan_change_mtu(struct net_device *dev, int new_mtu)
        if (dev->flags & IFF_UP)
                return -EBUSY;
 
-       if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU)
+       if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
+           !can_is_canxl_dev_mtu(new_mtu))
                return -EINVAL;
 
        dev->mtu = new_mtu;
index cffd107d8b28293768588e02e9fbbb79c43f28dc..26a472d2ea583cbd5b5a40823d82847276627ea8 100644 (file)
@@ -38,10 +38,9 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
 {
        struct vxcan_priv *priv = netdev_priv(dev);
        struct net_device *peer;
-       struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
        struct net_device_stats *peerstats, *srcstats = &dev->stats;
        struct sk_buff *skb;
-       u8 len;
+       unsigned int len;
 
        if (can_dropped_invalid_skb(dev, oskb))
                return NETDEV_TX_OK;
@@ -70,7 +69,7 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *oskb, struct net_device *dev)
        skb->dev        = peer;
        skb->ip_summed  = CHECKSUM_UNNECESSARY;
 
-       len = cfd->can_id & CAN_RTR_FLAG ? 0 : cfd->len;
+       len = can_skb_get_data_len(skb);
        if (netif_rx(skb) == NET_RX_SUCCESS) {
                srcstats->tx_packets++;
                srcstats->tx_bytes += len;
@@ -132,7 +131,8 @@ static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
        if (dev->flags & IFF_UP)
                return -EBUSY;
 
-       if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU)
+       if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
+           !can_is_canxl_dev_mtu(new_mtu))
                return -EINVAL;
 
        dev->mtu = new_mtu;
index c3e50e537e397e0ce44aac9cb6641b76d2d8b91d..58f5431a555984a1683f70ddea5c63d40517322a 100644 (file)
@@ -147,6 +147,11 @@ static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
        return priv->ctrlmode & ~priv->ctrlmode_supported;
 }
 
+static inline bool can_is_canxl_dev_mtu(unsigned int mtu)
+{
+       return (mtu >= CANXL_MIN_MTU && mtu <= CANXL_MAX_MTU);
+}
+
 void can_setup(struct net_device *dev);
 
 struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,