candev: add/update helpers for CAN FD
PATCH 4/6 candev: add/update helpers for CAN FD
- update sanity checks
- add DLC to length conversion helpers
- can_dlc2len() - get data length from can_dlc with sanitized can_dlc
- can_len2dlc() - map the sanitized data length to an appropriate DLC
Signed-off-by Oliver Hartkopp <[email protected]>
--- drivers/net/can/dev.c | 35 ++++++++++++++++++++++++++++++++++- include/linux/can/dev.h | 33 +++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 9 deletions(-)
drivers/net/can/dev.c +32 -0
@@ -33,6 +33,39 @@ MODULE_DESCRIPTION(MOD_DESC);MODULE_LICENSE ("GPL v2" );MODULE_AUTHOR ("Wolfgang Grandegger <[email protected]>" ); +/* CAN DLC to real data length conversion helpers */ + +static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, +8 ,12 ,16 ,20 ,24 ,32 ,48 ,64 }; + +/* get data length from can_dlc with sanitized can_dlc */ +u8 can_dlc2len (u8 can_dlc) +{ +return dlc2len[can_dlc &0x0F ]; +} +EXPORT_SYMBOL_GPL (can_dlc2len); + +static const u8 len2dlc[] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,/* 0 - 8 */ +9 ,9 ,9 ,9 ,/* 9 - 12 */ +10 ,10 ,10 ,10 ,/* 13 - 16 */ +11 ,11 ,11 ,11 ,/* 17 - 20 */ +12 ,12 ,12 ,12 ,/* 21 - 24 */ +13 ,13 ,13 ,13 ,13 ,13 ,13 ,13 ,/* 25 - 32 */ +14 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,/* 33 - 40 */ +14 ,14 ,14 ,14 ,14 ,14 ,14 ,14 ,/* 41 - 48 */ +15 ,15 ,15 ,15 ,15 ,15 ,15 ,15 ,/* 49 - 56 */ +15 ,15 ,15 ,15 ,15 ,15 ,15 ,15 };/* 57 - 64 */ + +/* map the sanitized data length to an appropriate data length code */ +u8 can_len2dlc (u8 len) +{ +if (unlikely (len >64 )) +return 0xF ; + +return len2dlc[len]; +} +EXPORT_SYMBOL_GPL (can_len2dlc); +#ifdef CONFIG_CAN_CALC_BITTIMING #define CAN_CALC_MAX_ERROR 50/* in one-tenth of a percent */ @@ -454,7 +487,7 @@ EXPORT_SYMBOL_GPL(can_bus_off);
static void can_setup(struct net_device *dev)
{
dev->type = ARPHRD_CAN;
- dev->mtu = sizeof(struct can_frame);
+ dev->mtu = CAN_MTU;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->tx_queue_len = 10;
include/linux/can/dev.h +24 -8
@@ -61,23 +61,40 @@ struct can_priv {* To be used in the CAN netdriver receive path to ensure conformance with * ISO 11898-1 Chapter 8.4.2.3 (DLC field) */ -#define get_can_dlc (i) (min_t(__u8, (i), 8)) +#define get_can_dlc (i) (min_t(__u8, (i), CAN_MAX_DLC)) +#define get_canfd_dlc (i) (min_t(__u8, (i), CANFD_MAX_DLC))/* Drop a given socketbuffer if it does not contain a valid CAN frame. */ static inline int can_dropped_invalid_skb (struct net_device *dev,struct sk_buff *skb) { -const struct can_frame *cf = (struct can_frame *)skb->data; - -if (unlikely (skb->len !=sizeof (*cf) || cf->can_dlc >8 )) { -kfree_skb (skb); - dev->stats.tx_dropped++; -return 1 ; - } +const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + +if (skb->protocol ==htons (ETH_P_CAN )) { +if (unlikely (skb->len !=CAN_MTU || + cfd->len >CAN_MAX_DLEN )) + goto inval_skb; + }else if (skb->protocol ==htons (ETH_P_CANFD )) { +if (unlikely (skb->len !=CANFD_MTU || + cfd->len >CANFD_MAX_DLEN )) + goto inval_skb; + }else + goto inval_skb;return 0 ; + +inval_skb: +kfree_skb (skb); + dev->stats.tx_dropped++; +return 1 ; } +/* get data length from can_dlc with sanitized can_dlc */ +u8 can_dlc2len(u8 can_dlc); + +/* map the sanitized data length to an appropriate data length code */ +u8 can_len2dlc (u8 len); +struct net_device *alloc_candev (int sizeof_priv,unsigned int echo_skb_max);void free_candev (struct net_device *dev); -- 1.7.10.4