0001
0002
0003
0004
0005
0006
0007
0008 #ifndef PUCAN_H
0009 #define PUCAN_H
0010
0011
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
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
0037 #define PUCAN_MSG_CAN_TX 0x1000
0038
0039
0040 struct __packed pucan_command {
0041 __le16 opcode_channel;
0042 u16 args[3];
0043 };
0044
0045
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
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;
0072 u8 sjw_t;
0073 u8 tseg2;
0074 u8 tseg1;
0075
0076 __le16 brp;
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
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;
0100 u8 tseg2;
0101 u8 tseg1;
0102
0103 __le16 brp;
0104 };
0105
0106
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;
0114 };
0115
0116 #define PUCAN_FLTSTD_ROW_IDX_MAX ((1 << PUCAN_FLTSTD_ROW_IDX_BITS) - 1)
0117
0118
0119 struct __packed pucan_std_filter {
0120 __le16 opcode_channel;
0121
0122 u8 unused;
0123 u8 idx;
0124 __le32 mask;
0125 };
0126
0127
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
0138 #define PUCAN_WRERRCNT_TE 0x4000
0139 #define PUCAN_WRERRCNT_RE 0x8000
0140
0141 struct __packed pucan_wr_err_cnt {
0142 __le16 opcode_channel;
0143
0144 __le16 sel_mask;
0145 u8 tx_counter;
0146 u8 rx_counter;
0147
0148 u16 unused;
0149 };
0150
0151
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
0164 struct __packed pucan_msg {
0165 __le16 size;
0166 __le16 type;
0167 __le32 ts_low;
0168 __le32 ts_high;
0169 };
0170
0171
0172 #define PUCAN_MSG_SELF_RECEIVE 0x80
0173 #define PUCAN_MSG_ERROR_STATE_IND 0x40
0174 #define PUCAN_MSG_BITRATE_SWITCH 0x20
0175 #define PUCAN_MSG_EXT_DATA_LEN 0x10
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
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
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
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
0279 static inline int pucan_msg_get_channel(const struct pucan_rx_msg *msg)
0280 {
0281 return msg->channel_dlc & 0xf;
0282 }
0283
0284
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