can: dev: add CAN XL support to virtual CAN

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>
This commit is contained in:
Oliver Hartkopp 2022-09-12 19:07:24 +02:00 committed by Marc Kleine-Budde
parent fb08cba12b
commit ebf87fc728
3 changed files with 15 additions and 10 deletions

View 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) 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; struct net_device_stats *stats = &dev->stats;
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += cfd->len; stats->rx_bytes += can_skb_get_data_len(skb);
skb->pkt_type = PACKET_BROADCAST; skb->pkt_type = PACKET_BROADCAST;
skb->dev = dev; 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) 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; struct net_device_stats *stats = &dev->stats;
int loop, len; unsigned int len;
int loop;
if (can_dropped_invalid_skb(dev, skb)) if (can_dropped_invalid_skb(dev, skb))
return NETDEV_TX_OK; 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_packets++;
stats->tx_bytes += len; 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) if (dev->flags & IFF_UP)
return -EBUSY; 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; return -EINVAL;
dev->mtu = new_mtu; dev->mtu = new_mtu;

View 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 vxcan_priv *priv = netdev_priv(dev);
struct net_device *peer; struct net_device *peer;
struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
struct net_device_stats *peerstats, *srcstats = &dev->stats; struct net_device_stats *peerstats, *srcstats = &dev->stats;
struct sk_buff *skb; struct sk_buff *skb;
u8 len; unsigned int len;
if (can_dropped_invalid_skb(dev, oskb)) if (can_dropped_invalid_skb(dev, oskb))
return NETDEV_TX_OK; 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->dev = peer;
skb->ip_summed = CHECKSUM_UNNECESSARY; 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) { if (netif_rx(skb) == NET_RX_SUCCESS) {
srcstats->tx_packets++; srcstats->tx_packets++;
srcstats->tx_bytes += len; 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) if (dev->flags & IFF_UP)
return -EBUSY; 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; return -EINVAL;
dev->mtu = new_mtu; dev->mtu = new_mtu;

View File

@ -147,6 +147,11 @@ static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
return priv->ctrlmode & ~priv->ctrlmode_supported; 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); void can_setup(struct net_device *dev);
struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,