Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * CAN driver for PEAK System micro-CAN based adapters
0004  *
0005  * Copyright (C) 2003-2011 PEAK System-Technik GmbH
0006  * Copyright (C) 2011-2013 Stephane Grosjean <s.grosjean@peak-system.com>
0007  */
0008 #ifndef PUCAN_H
0009 #define PUCAN_H
0010 
0011 /* uCAN commands opcodes list (low-order 10 bits) */
0012 #define PUCAN_CMD_NOP           0x000
0013 #define PUCAN_CMD_RESET_MODE        0x001
0014 #define PUCAN_CMD_NORMAL_MODE       0x002
0015 #define PUCAN_CMD_LISTEN_ONLY_MODE  0x003
0016 #define PUCAN_CMD_TIMING_SLOW       0x004
0017 #define PUCAN_CMD_TIMING_FAST       0x005
0018 #define PUCAN_CMD_SET_STD_FILTER    0x006
0019 #define PUCAN_CMD_RESERVED2     0x007
0020 #define PUCAN_CMD_FILTER_STD        0x008
0021 #define PUCAN_CMD_TX_ABORT      0x009
0022 #define PUCAN_CMD_WR_ERR_CNT        0x00a
0023 #define PUCAN_CMD_SET_EN_OPTION     0x00b
0024 #define PUCAN_CMD_CLR_DIS_OPTION    0x00c
0025 #define PUCAN_CMD_RX_BARRIER        0x010
0026 #define PUCAN_CMD_END_OF_COLLECTION 0x3ff
0027 
0028 /* uCAN received messages list */
0029 #define PUCAN_MSG_CAN_RX        0x0001
0030 #define PUCAN_MSG_ERROR         0x0002
0031 #define PUCAN_MSG_STATUS        0x0003
0032 #define PUCAN_MSG_BUSLOAD       0x0004
0033 
0034 #define PUCAN_MSG_CACHE_CRITICAL    0x0102
0035 
0036 /* uCAN transmitted messages */
0037 #define PUCAN_MSG_CAN_TX        0x1000
0038 
0039 /* uCAN command common header */
0040 struct __packed pucan_command {
0041     __le16  opcode_channel;
0042     u16 args[3];
0043 };
0044 
0045 /* return the opcode from the opcode_channel field of a command */
0046 static inline u16 pucan_cmd_get_opcode(struct pucan_command *c)
0047 {
0048     return le16_to_cpu(c->opcode_channel) & 0x3ff;
0049 }
0050 
0051 #define PUCAN_TSLOW_BRP_BITS        10
0052 #define PUCAN_TSLOW_TSGEG1_BITS     8
0053 #define PUCAN_TSLOW_TSGEG2_BITS     7
0054 #define PUCAN_TSLOW_SJW_BITS        7
0055 
0056 #define PUCAN_TSLOW_BRP_MASK        ((1 << PUCAN_TSLOW_BRP_BITS) - 1)
0057 #define PUCAN_TSLOW_TSEG1_MASK      ((1 << PUCAN_TSLOW_TSGEG1_BITS) - 1)
0058 #define PUCAN_TSLOW_TSEG2_MASK      ((1 << PUCAN_TSLOW_TSGEG2_BITS) - 1)
0059 #define PUCAN_TSLOW_SJW_MASK        ((1 << PUCAN_TSLOW_SJW_BITS) - 1)
0060 
0061 /* uCAN TIMING_SLOW command fields */
0062 #define PUCAN_TSLOW_SJW_T(s, t)     (((s) & PUCAN_TSLOW_SJW_MASK) | \
0063                                 ((!!(t)) << 7))
0064 #define PUCAN_TSLOW_TSEG2(t)        ((t) & PUCAN_TSLOW_TSEG2_MASK)
0065 #define PUCAN_TSLOW_TSEG1(t)        ((t) & PUCAN_TSLOW_TSEG1_MASK)
0066 #define PUCAN_TSLOW_BRP(b)      ((b) & PUCAN_TSLOW_BRP_MASK)
0067 
0068 struct __packed pucan_timing_slow {
0069     __le16  opcode_channel;
0070 
0071     u8  ewl;        /* Error Warning limit */
0072     u8  sjw_t;      /* Sync Jump Width + Triple sampling */
0073     u8  tseg2;      /* Timing SEGment 2 */
0074     u8  tseg1;      /* Timing SEGment 1 */
0075 
0076     __le16  brp;        /* BaudRate Prescaler */
0077 };
0078 
0079 #define PUCAN_TFAST_BRP_BITS        10
0080 #define PUCAN_TFAST_TSGEG1_BITS     5
0081 #define PUCAN_TFAST_TSGEG2_BITS     4
0082 #define PUCAN_TFAST_SJW_BITS        4
0083 
0084 #define PUCAN_TFAST_BRP_MASK        ((1 << PUCAN_TFAST_BRP_BITS) - 1)
0085 #define PUCAN_TFAST_TSEG1_MASK      ((1 << PUCAN_TFAST_TSGEG1_BITS) - 1)
0086 #define PUCAN_TFAST_TSEG2_MASK      ((1 << PUCAN_TFAST_TSGEG2_BITS) - 1)
0087 #define PUCAN_TFAST_SJW_MASK        ((1 << PUCAN_TFAST_SJW_BITS) - 1)
0088 
0089 /* uCAN TIMING_FAST command fields */
0090 #define PUCAN_TFAST_SJW(s)      ((s) & PUCAN_TFAST_SJW_MASK)
0091 #define PUCAN_TFAST_TSEG2(t)        ((t) & PUCAN_TFAST_TSEG2_MASK)
0092 #define PUCAN_TFAST_TSEG1(t)        ((t) & PUCAN_TFAST_TSEG1_MASK)
0093 #define PUCAN_TFAST_BRP(b)      ((b) & PUCAN_TFAST_BRP_MASK)
0094 
0095 struct __packed pucan_timing_fast {
0096     __le16  opcode_channel;
0097 
0098     u8  unused;
0099     u8  sjw;        /* Sync Jump Width */
0100     u8  tseg2;      /* Timing SEGment 2 */
0101     u8  tseg1;      /* Timing SEGment 1 */
0102 
0103     __le16  brp;        /* BaudRate Prescaler */
0104 };
0105 
0106 /* uCAN FILTER_STD command fields */
0107 #define PUCAN_FLTSTD_ROW_IDX_BITS   6
0108 
0109 struct __packed pucan_filter_std {
0110     __le16  opcode_channel;
0111 
0112     __le16  idx;
0113     __le32  mask;       /* CAN-ID bitmask in idx range */
0114 };
0115 
0116 #define PUCAN_FLTSTD_ROW_IDX_MAX    ((1 << PUCAN_FLTSTD_ROW_IDX_BITS) - 1)
0117 
0118 /* uCAN SET_STD_FILTER command fields */
0119 struct __packed pucan_std_filter {
0120     __le16  opcode_channel;
0121 
0122     u8  unused;
0123     u8  idx;
0124     __le32  mask;       /* CAN-ID bitmask in idx range */
0125 };
0126 
0127 /* uCAN TX_ABORT commands fields */
0128 #define PUCAN_TX_ABORT_FLUSH        0x0001
0129 
0130 struct __packed pucan_tx_abort {
0131     __le16  opcode_channel;
0132 
0133     __le16  flags;
0134     u32 unused;
0135 };
0136 
0137 /* uCAN WR_ERR_CNT command fields */
0138 #define PUCAN_WRERRCNT_TE       0x4000  /* Tx error cntr write Enable */
0139 #define PUCAN_WRERRCNT_RE       0x8000  /* Rx error cntr write Enable */
0140 
0141 struct __packed pucan_wr_err_cnt {
0142     __le16  opcode_channel;
0143 
0144     __le16  sel_mask;
0145     u8  tx_counter; /* Tx error counter new value */
0146     u8  rx_counter; /* Rx error counter new value */
0147 
0148     u16 unused;
0149 };
0150 
0151 /* uCAN SET_EN/CLR_DIS _OPTION command fields */
0152 #define PUCAN_OPTION_ERROR      0x0001
0153 #define PUCAN_OPTION_BUSLOAD        0x0002
0154 #define PUCAN_OPTION_CANDFDISO      0x0004
0155 
0156 struct __packed pucan_options {
0157     __le16  opcode_channel;
0158 
0159     __le16  options;
0160     u32 unused;
0161 };
0162 
0163 /* uCAN received messages global format */
0164 struct __packed pucan_msg {
0165     __le16  size;
0166     __le16  type;
0167     __le32  ts_low;
0168     __le32  ts_high;
0169 };
0170 
0171 /* uCAN flags for CAN/CANFD messages */
0172 #define PUCAN_MSG_SELF_RECEIVE      0x80
0173 #define PUCAN_MSG_ERROR_STATE_IND   0x40    /* error state indicator */
0174 #define PUCAN_MSG_BITRATE_SWITCH    0x20    /* bitrate switch */
0175 #define PUCAN_MSG_EXT_DATA_LEN      0x10    /* extended data length */
0176 #define PUCAN_MSG_SINGLE_SHOT       0x08
0177 #define PUCAN_MSG_LOOPED_BACK       0x04
0178 #define PUCAN_MSG_EXT_ID        0x02
0179 #define PUCAN_MSG_RTR           0x01
0180 
0181 struct __packed pucan_rx_msg {
0182     __le16  size;
0183     __le16  type;
0184     __le32  ts_low;
0185     __le32  ts_high;
0186     __le32  tag_low;
0187     __le32  tag_high;
0188     u8  channel_dlc;
0189     u8  client;
0190     __le16  flags;
0191     __le32  can_id;
0192     u8  d[];
0193 };
0194 
0195 /* uCAN error types */
0196 #define PUCAN_ERMSG_BIT_ERROR       0
0197 #define PUCAN_ERMSG_FORM_ERROR      1
0198 #define PUCAN_ERMSG_STUFF_ERROR     2
0199 #define PUCAN_ERMSG_OTHER_ERROR     3
0200 #define PUCAN_ERMSG_ERR_CNT_DEC     4
0201 
0202 struct __packed pucan_error_msg {
0203     __le16  size;
0204     __le16  type;
0205     __le32  ts_low;
0206     __le32  ts_high;
0207     u8  channel_type_d;
0208     u8  code_g;
0209     u8  tx_err_cnt;
0210     u8  rx_err_cnt;
0211 };
0212 
0213 static inline int pucan_error_get_channel(const struct pucan_error_msg *msg)
0214 {
0215     return msg->channel_type_d & 0x0f;
0216 }
0217 
0218 #define PUCAN_RX_BARRIER        0x10
0219 #define PUCAN_BUS_PASSIVE       0x20
0220 #define PUCAN_BUS_WARNING       0x40
0221 #define PUCAN_BUS_BUSOFF        0x80
0222 
0223 struct __packed pucan_status_msg {
0224     __le16  size;
0225     __le16  type;
0226     __le32  ts_low;
0227     __le32  ts_high;
0228     u8  channel_p_w_b;
0229     u8  unused[3];
0230 };
0231 
0232 static inline int pucan_status_get_channel(const struct pucan_status_msg *msg)
0233 {
0234     return msg->channel_p_w_b & 0x0f;
0235 }
0236 
0237 static inline int pucan_status_is_rx_barrier(const struct pucan_status_msg *msg)
0238 {
0239     return msg->channel_p_w_b & PUCAN_RX_BARRIER;
0240 }
0241 
0242 static inline int pucan_status_is_passive(const struct pucan_status_msg *msg)
0243 {
0244     return msg->channel_p_w_b & PUCAN_BUS_PASSIVE;
0245 }
0246 
0247 static inline int pucan_status_is_warning(const struct pucan_status_msg *msg)
0248 {
0249     return msg->channel_p_w_b & PUCAN_BUS_WARNING;
0250 }
0251 
0252 static inline int pucan_status_is_busoff(const struct pucan_status_msg *msg)
0253 {
0254     return msg->channel_p_w_b & PUCAN_BUS_BUSOFF;
0255 }
0256 
0257 /* uCAN transmitted message format */
0258 #define PUCAN_MSG_CHANNEL_DLC(c, d) (((c) & 0xf) | ((d) << 4))
0259 
0260 struct __packed pucan_tx_msg {
0261     __le16  size;
0262     __le16  type;
0263     __le32  tag_low;
0264     __le32  tag_high;
0265     u8  channel_dlc;
0266     u8  client;
0267     __le16  flags;
0268     __le32  can_id;
0269     u8  d[];
0270 };
0271 
0272 /* build the cmd opcode_channel field with respect to the correct endianness */
0273 static inline __le16 pucan_cmd_opcode_channel(int index, int opcode)
0274 {
0275     return cpu_to_le16(((index) << 12) | ((opcode) & 0x3ff));
0276 }
0277 
0278 /* return the channel number part from any received message channel_dlc field */
0279 static inline int pucan_msg_get_channel(const struct pucan_rx_msg *msg)
0280 {
0281     return msg->channel_dlc & 0xf;
0282 }
0283 
0284 /* return the dlc value from any received message channel_dlc field */
0285 static inline u8 pucan_msg_get_dlc(const struct pucan_rx_msg *msg)
0286 {
0287     return msg->channel_dlc >> 4;
0288 }
0289 
0290 static inline int pucan_ermsg_get_channel(const struct pucan_error_msg *msg)
0291 {
0292     return msg->channel_type_d & 0x0f;
0293 }
0294 
0295 static inline int pucan_stmsg_get_channel(const struct pucan_status_msg *msg)
0296 {
0297     return msg->channel_p_w_b & 0x0f;
0298 }
0299 
0300 #endif