1 /** @file 2 * @brief IPv6 Networking over CAN definitions. 3 * 4 * Definitions for IPv6 Networking over CAN support. 5 */ 6 7 /* 8 * Copyright (c) 2019 Alexander Wachter 9 * 10 * SPDX-License-Identifier: Apache-2.0 11 */ 12 13 #ifndef ZEPHYR_INCLUDE_NET_CAN_H_ 14 #define ZEPHYR_INCLUDE_NET_CAN_H_ 15 16 #include <zephyr/types.h> 17 #include <net/net_ip.h> 18 #include <net/net_if.h> 19 #include <drivers/can.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 26 /** 27 * @brief IPv6 over CAN library 28 * @defgroup net_can Network Core Library 29 * @ingroup networking 30 * @{ 31 */ 32 33 /** 34 * CAN L2 driver API. Used by 6loCAN. 35 */ 36 37 /* 38 * Abbreviations 39 * BS Block Size 40 * CAN_DL CAN LL data size 41 * CF Consecutive Frame 42 * CTS Continue to send 43 * DLC Data length code 44 * FC Flow Control 45 * FF First Frame 46 * FS Flow Status 47 */ 48 49 /** @cond INTERNAL_HIDDEN */ 50 51 #define NET_CAN_DL 8 52 #define NET_CAN_MTU 0x0FFF 53 54 /* 0x3DFF - bit 4 to 10 must not be zero. Also prevent stuffing bit*/ 55 #define NET_CAN_MULTICAST_ADDR 0x3DFF 56 #define NET_CAN_DAD_ADDR 0x3DFE 57 #define NET_CAN_ETH_TRANSLATOR_ADDR 0x3DF0 58 #define NET_CAN_MAX_ADDR 0x3DEF 59 #define NET_CAN_MIN_ADDR 0x0100 60 61 #define CAN_NET_IF_ADDR_MASK 0x3FFF 62 #define CAN_NET_IF_ADDR_BYTE_LEN 2U 63 #define CAN_NET_IF_ADDR_DEST_POS 14U 64 #define CAN_NET_IF_ADDR_DEST_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_DEST_POS) 65 #define CAN_NET_IF_ADDR_SRC_POS 0U 66 #define CAN_NET_IF_ADDR_SRC_MASK (CAN_NET_IF_ADDR_MASK << CAN_NET_IF_ADDR_SRC_POS) 67 #define CAN_NET_IF_ADDR_MCAST_POS 28U 68 #define CAN_NET_IF_ADDR_MCAST_MASK (1UL << CAN_NET_IF_ADDR_MCAST_POS) 69 70 #define CAN_NET_IF_IS_MCAST_BIT (1U << 14) 71 72 #define CAN_NET_FILTER_NOT_SET -1 73 74 /** @endcond */ 75 76 /* 77 * +-----------+ +-----------+ 78 * | | | | 79 * | IPv6 | | IPv6 | 80 * | 6LoCAN | | 6LoCAN | 81 * | | | | 82 * +----+-+----+ +----+-+----+ 83 * | | | | +---+ 84 * +----+ | | | | / \ +-+ 85 * | | | | | | +--+ / \_/ \ 86 * +++ +---+ +--+----+ +-------+ +--+----+ +--/ \_/ \ 87 * | | \ / | \ / \ / | \ / / | 88 * | | X | X CAN X | X | Internet | 89 * | | / \ | / \ / \ | / \ \ / 90 * +++ +---+ +----+--+ +-------+ +----+--+ +--+ / 91 * | | +-------------------+ 92 * +----+ 93 */ 94 struct net_can_api { 95 /** 96 * The net_if_api must be placed in first position in this 97 * struct so that we are compatible with network interface API. 98 */ 99 struct net_if_api iface_api; 100 101 /** Send a single CAN frame */ 102 int (*send)(const struct device *dev, const struct zcan_frame *frame, 103 can_tx_callback_t cb, void *cb_arg, k_timeout_t timeout); 104 /** Attach a filter with it's callback */ 105 int (*attach_filter)(const struct device *dev, can_rx_callback_t cb, 106 void *cb_arg, const struct zcan_filter *filter); 107 /** Detach a filter */ 108 void (*detach_filter)(const struct device *dev, int filter_id); 109 /** Enable or disable the reception of frames for net CAN */ 110 int (*enable)(const struct device *dev, bool enable); 111 }; 112 113 /* Make sure that the network interface API is properly setup inside 114 * net_can_api struct (it is the first one). 115 */ 116 BUILD_ASSERT(offsetof(struct net_can_api, iface_api) == 0); 117 118 /** @cond INTERNAL_HIDDEN */ 119 120 #define CANBUS_L2_CTX_TYPE struct net_canbus_context * 121 122 /** 123 * Context for canbus net device. 124 */ 125 struct canbus_net_ctx { 126 /** Filter ID for link layer duplicate address detection. */ 127 int dad_filter_id; 128 /** Work item for responding to link layer DAD requests. */ 129 struct k_work dad_work; 130 /** The interface associated with this device */ 131 struct net_if *iface; 132 /** The link layer address chosen for this interface */ 133 uint16_t ll_addr; 134 /** TX queue */ 135 struct k_fifo tx_queue; 136 /** RX error queue */ 137 struct k_fifo rx_err_queue; 138 /** Queue handler thread */ 139 struct k_thread queue_handler; 140 /** Queue handler thread stack */ 141 K_KERNEL_STACK_MEMBER(queue_stack, 512); 142 }; 143 144 /** 145 * Canbus link layer addresses have a length of 14 bit for source and destination. 146 * Both together are 28 bit to fit a CAN extended identifier with 29 bit length. 147 */ 148 struct net_canbus_lladdr { 149 uint16_t addr : 14; 150 }; 151 152 /** 153 * STmin is split in two valid ranges: 154 * 0-127: 0ms-127ms 155 * 128-240: Reserved 156 * 241-249: 100us-900us (multiples of 100us) 157 * 250- : Reserved 158 */ 159 struct canbus_fc_opts { 160 /** Block size. Number of CF PDUs before next CF is sent */ 161 uint8_t bs; 162 /**< Minimum separation time. Min time between frames */ 163 uint8_t stmin; 164 }; 165 166 /** 167 * Context for a transmission of messages that didn't fit in a single frame. 168 * These messages Start with a FF (First Frame) that is in case of unicast 169 * acknowledged by a FC (Frame Control). After that, one or more CF 170 * (Consecutive frames) carry the rest of the message. 171 */ 172 struct canbus_isotp_tx_ctx { 173 /** Pkt containing the data to transmit */ 174 struct net_pkt *pkt; 175 /** Timeout for TX Timeout and separation time */ 176 struct _timeout timeout; 177 /** Frame Control options received from FC frame */ 178 struct canbus_fc_opts opts; 179 /** CAN destination address */ 180 struct net_canbus_lladdr dest_addr; 181 /** Remaining data to transmit in bytes */ 182 uint16_t rem_len; 183 /** Number of bytes in the tx queue */ 184 int8_t tx_backlog; 185 /** State of the transmission */ 186 uint8_t state; 187 /** Actual block number that is transmitted. Counts from BS to 0 */ 188 uint8_t act_block_nr; 189 /** Number of WAIT frames received */ 190 uint8_t wft; 191 /** Sequence number that is added to CF */ 192 uint8_t sn : 4; 193 /** Transmission is multicast */ 194 uint8_t is_mcast : 1; 195 }; 196 197 /** 198 * Context for reception of messages that are not single frames. 199 * This is the counterpart of the canbus_isotp_tx_ctx. 200 */ 201 struct canbus_isotp_rx_ctx { 202 /** Pkt that is large enough to hold the entire message */ 203 struct net_pkt *pkt; 204 /** Timeout for RX timeout*/ 205 struct _timeout timeout; 206 /** Remaining data to receive. Goes from message length to zero */ 207 uint16_t rem_len; 208 /** State of the reception */ 209 uint8_t state; 210 /** Number of frames received in this block. Counts from BS to 0 */ 211 uint8_t act_block_nr; 212 /** Number of WAIT frames transmitted */ 213 uint8_t wft; 214 /** Expected sequence number in CF */ 215 uint8_t sn : 4; 216 }; 217 218 /** 219 * Initialization of the canbus L2. 220 * 221 * This function starts the TX workqueue and does some initialization. 222 */ 223 void net_6locan_init(struct net_if *iface); 224 225 /** 226 * Ethernet frame input function for Ethernet to 6LoCAN translation 227 * 228 * This function checks the destination link layer address for addresses 229 * that has to be forwarded. Frames that need to be forwarded are forwarded here. 230 */ 231 enum net_verdict net_canbus_translate_eth_frame(struct net_if *iface, 232 struct net_pkt *pkt); 233 234 /** @endcond */ 235 236 /** 237 * @} 238 */ 239 240 #ifdef __cplusplus 241 } 242 #endif 243 244 #endif /* ZEPHYR_INCLUDE_NET_CAN_H_ */ 245