0001
0002
0003
0004
0005 #include <linux/can/dev.h>
0006
0007
0008
0009 static const u8 dlc2len[] = {
0010 0, 1, 2, 3, 4, 5, 6, 7,
0011 8, 12, 16, 20, 24, 32, 48, 64
0012 };
0013
0014
0015 u8 can_fd_dlc2len(u8 dlc)
0016 {
0017 return dlc2len[dlc & 0x0F];
0018 }
0019 EXPORT_SYMBOL_GPL(can_fd_dlc2len);
0020
0021 static const u8 len2dlc[] = {
0022 0, 1, 2, 3, 4, 5, 6, 7, 8,
0023 9, 9, 9, 9,
0024 10, 10, 10, 10,
0025 11, 11, 11, 11,
0026 12, 12, 12, 12,
0027 13, 13, 13, 13, 13, 13, 13, 13,
0028 14, 14, 14, 14, 14, 14, 14, 14,
0029 14, 14, 14, 14, 14, 14, 14, 14,
0030 15, 15, 15, 15, 15, 15, 15, 15,
0031 15, 15, 15, 15, 15, 15, 15, 15
0032 };
0033
0034
0035 u8 can_fd_len2dlc(u8 len)
0036 {
0037
0038 BUILD_BUG_ON(ARRAY_SIZE(len2dlc) != CANFD_MAX_DLEN + 1);
0039
0040 if (unlikely(len > CANFD_MAX_DLEN))
0041 return CANFD_MAX_DLC;
0042
0043 return len2dlc[len];
0044 }
0045 EXPORT_SYMBOL_GPL(can_fd_len2dlc);
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 unsigned int can_skb_get_frame_len(const struct sk_buff *skb)
0070 {
0071 const struct canfd_frame *cf = (const struct canfd_frame *)skb->data;
0072 u8 len;
0073
0074 if (can_is_canfd_skb(skb))
0075 len = canfd_sanitize_len(cf->len);
0076 else if (cf->can_id & CAN_RTR_FLAG)
0077 len = 0;
0078 else
0079 len = cf->len;
0080
0081 if (can_is_canfd_skb(skb)) {
0082 if (cf->can_id & CAN_EFF_FLAG)
0083 len += CANFD_FRAME_OVERHEAD_EFF;
0084 else
0085 len += CANFD_FRAME_OVERHEAD_SFF;
0086 } else {
0087 if (cf->can_id & CAN_EFF_FLAG)
0088 len += CAN_FRAME_OVERHEAD_EFF;
0089 else
0090 len += CAN_FRAME_OVERHEAD_SFF;
0091 }
0092
0093 return len;
0094 }
0095 EXPORT_SYMBOL_GPL(can_skb_get_frame_len);