Commit | Line | Data |
---|---|---|
0a25e1f4 SG |
1 | /* |
2 | * CAN driver for PEAK System PCAN-USB FD / PCAN-USB Pro FD adapter | |
3 | * | |
4 | * Copyright (C) 2013-2014 Stephane Grosjean <s.grosjean@peak-system.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published | |
8 | * by the Free Software Foundation; version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License for more details. | |
14 | */ | |
15 | #include <linux/netdevice.h> | |
16 | #include <linux/usb.h> | |
17 | #include <linux/module.h> | |
18 | ||
19 | #include <linux/can.h> | |
20 | #include <linux/can/dev.h> | |
21 | #include <linux/can/error.h> | |
22 | ||
23 | #include "pcan_usb_core.h" | |
24 | #include "pcan_usb_pro.h" | |
25 | #include "pcan_ucan.h" | |
26 | ||
27 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB FD adapter"); | |
28 | MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB Pro FD adapter"); | |
29 | ||
30 | #define PCAN_USBPROFD_CHANNEL_COUNT 2 | |
31 | #define PCAN_USBFD_CHANNEL_COUNT 1 | |
32 | ||
33 | /* PCAN-USB Pro FD adapter internal clock (Hz) */ | |
34 | #define PCAN_UFD_CRYSTAL_HZ 80000000 | |
35 | ||
36 | #define PCAN_UFD_CMD_BUFFER_SIZE 512 | |
37 | #define PCAN_UFD_LOSPD_PKT_SIZE 64 | |
38 | ||
39 | /* PCAN-USB Pro FD command timeout (ms.) */ | |
40 | #define PCAN_UFD_CMD_TIMEOUT_MS 1000 | |
41 | ||
42 | /* PCAN-USB Pro FD rx/tx buffers size */ | |
43 | #define PCAN_UFD_RX_BUFFER_SIZE 2048 | |
44 | #define PCAN_UFD_TX_BUFFER_SIZE 512 | |
45 | ||
46 | /* read some versions info from the hw devcie */ | |
47 | struct __packed pcan_ufd_fw_info { | |
48 | __le16 size_of; /* sizeof this */ | |
49 | __le16 type; /* type of this structure */ | |
50 | u8 hw_type; /* Type of hardware (HW_TYPE_xxx) */ | |
51 | u8 bl_version[3]; /* Bootloader version */ | |
52 | u8 hw_version; /* Hardware version (PCB) */ | |
53 | u8 fw_version[3]; /* Firmware version */ | |
54 | __le32 dev_id[2]; /* "device id" per CAN */ | |
55 | __le32 ser_no; /* S/N */ | |
56 | __le32 flags; /* special functions */ | |
57 | }; | |
58 | ||
59 | /* handle device specific info used by the netdevices */ | |
60 | struct pcan_usb_fd_if { | |
61 | struct peak_usb_device *dev[PCAN_USB_MAX_CHANNEL]; | |
62 | struct pcan_ufd_fw_info fw_info; | |
63 | struct peak_time_ref time_ref; | |
64 | int cm_ignore_count; | |
65 | int dev_opened_count; | |
66 | }; | |
67 | ||
68 | /* device information */ | |
69 | struct pcan_usb_fd_device { | |
70 | struct peak_usb_device dev; | |
71 | struct can_berr_counter bec; | |
72 | struct pcan_usb_fd_if *usb_if; | |
73 | u8 *cmd_buffer_addr; | |
74 | }; | |
75 | ||
76 | /* Extended USB commands (non uCAN commands) */ | |
77 | ||
78 | /* Clock Modes command */ | |
79 | #define PCAN_UFD_CMD_CLK_SET 0x80 | |
80 | ||
81 | #define PCAN_UFD_CLK_80MHZ 0x0 | |
82 | #define PCAN_UFD_CLK_60MHZ 0x1 | |
83 | #define PCAN_UFD_CLK_40MHZ 0x2 | |
84 | #define PCAN_UFD_CLK_30MHZ 0x3 | |
85 | #define PCAN_UFD_CLK_24MHZ 0x4 | |
86 | #define PCAN_UFD_CLK_20MHZ 0x5 | |
87 | #define PCAN_UFD_CLK_DEF PCAN_UFD_CLK_80MHZ | |
88 | ||
89 | struct __packed pcan_ufd_clock { | |
90 | __le16 opcode_channel; | |
91 | ||
92 | u8 mode; | |
93 | u8 unused[5]; | |
94 | }; | |
95 | ||
96 | /* LED control command */ | |
97 | #define PCAN_UFD_CMD_LED_SET 0x86 | |
98 | ||
99 | #define PCAN_UFD_LED_DEV 0x00 | |
100 | #define PCAN_UFD_LED_FAST 0x01 | |
101 | #define PCAN_UFD_LED_SLOW 0x02 | |
102 | #define PCAN_UFD_LED_ON 0x03 | |
103 | #define PCAN_UFD_LED_OFF 0x04 | |
104 | #define PCAN_UFD_LED_DEF PCAN_UFD_LED_DEV | |
105 | ||
106 | struct __packed pcan_ufd_led { | |
107 | __le16 opcode_channel; | |
108 | ||
109 | u8 mode; | |
110 | u8 unused[5]; | |
111 | }; | |
112 | ||
3ef5247e | 113 | /* Extended usage of uCAN commands CMD_xxx_xx_OPTION for PCAN-USB Pro FD */ |
0a25e1f4 SG |
114 | #define PCAN_UFD_FLTEXT_CALIBRATION 0x8000 |
115 | ||
3ef5247e | 116 | struct __packed pcan_ufd_options { |
0a25e1f4 SG |
117 | __le16 opcode_channel; |
118 | ||
3ef5247e | 119 | __le16 ucan_mask; |
0a25e1f4 SG |
120 | u16 unused; |
121 | __le16 usb_mask; | |
122 | }; | |
123 | ||
124 | /* Extended usage of uCAN messages for PCAN-USB Pro FD */ | |
125 | #define PCAN_UFD_MSG_CALIBRATION 0x100 | |
126 | ||
127 | struct __packed pcan_ufd_ts_msg { | |
128 | __le16 size; | |
129 | __le16 type; | |
130 | __le32 ts_low; | |
131 | __le32 ts_high; | |
132 | __le16 usb_frame_index; | |
133 | u16 unused; | |
134 | }; | |
135 | ||
136 | #define PCAN_UFD_MSG_OVERRUN 0x101 | |
137 | ||
138 | #define PCAN_UFD_OVMSG_CHANNEL(o) ((o)->channel & 0xf) | |
139 | ||
140 | struct __packed pcan_ufd_ovr_msg { | |
141 | __le16 size; | |
142 | __le16 type; | |
143 | __le32 ts_low; | |
144 | __le32 ts_high; | |
145 | u8 channel; | |
146 | u8 unused[3]; | |
147 | }; | |
148 | ||
149 | static inline int pufd_omsg_get_channel(struct pcan_ufd_ovr_msg *om) | |
150 | { | |
151 | return om->channel & 0xf; | |
152 | } | |
153 | ||
154 | /* Clock mode frequency values */ | |
155 | static const u32 pcan_usb_fd_clk_freq[6] = { | |
156 | [PCAN_UFD_CLK_80MHZ] = 80000000, | |
157 | [PCAN_UFD_CLK_60MHZ] = 60000000, | |
158 | [PCAN_UFD_CLK_40MHZ] = 40000000, | |
159 | [PCAN_UFD_CLK_30MHZ] = 30000000, | |
160 | [PCAN_UFD_CLK_24MHZ] = 24000000, | |
161 | [PCAN_UFD_CLK_20MHZ] = 20000000 | |
162 | }; | |
163 | ||
164 | /* return a device USB interface */ | |
165 | static inline | |
166 | struct pcan_usb_fd_if *pcan_usb_fd_dev_if(struct peak_usb_device *dev) | |
167 | { | |
168 | struct pcan_usb_fd_device *pdev = | |
169 | container_of(dev, struct pcan_usb_fd_device, dev); | |
170 | return pdev->usb_if; | |
171 | } | |
172 | ||
173 | /* return a device USB commands buffer */ | |
174 | static inline void *pcan_usb_fd_cmd_buffer(struct peak_usb_device *dev) | |
175 | { | |
176 | struct pcan_usb_fd_device *pdev = | |
177 | container_of(dev, struct pcan_usb_fd_device, dev); | |
178 | return pdev->cmd_buffer_addr; | |
179 | } | |
180 | ||
181 | /* send PCAN-USB Pro FD commands synchronously */ | |
182 | static int pcan_usb_fd_send_cmd(struct peak_usb_device *dev, void *cmd_tail) | |
183 | { | |
184 | void *cmd_head = pcan_usb_fd_cmd_buffer(dev); | |
79d5eedd | 185 | int err = 0; |
0a25e1f4 SG |
186 | u8 *packet_ptr; |
187 | int i, n = 1, packet_len; | |
188 | ptrdiff_t cmd_len; | |
189 | ||
190 | /* usb device unregistered? */ | |
191 | if (!(dev->state & PCAN_USB_STATE_CONNECTED)) | |
192 | return 0; | |
193 | ||
194 | /* if a packet is not filled completely by commands, the command list | |
195 | * is terminated with an "end of collection" record. | |
196 | */ | |
197 | cmd_len = cmd_tail - cmd_head; | |
198 | if (cmd_len <= (PCAN_UFD_CMD_BUFFER_SIZE - sizeof(u64))) { | |
199 | memset(cmd_tail, 0xff, sizeof(u64)); | |
200 | cmd_len += sizeof(u64); | |
201 | } | |
202 | ||
203 | packet_ptr = cmd_head; | |
204 | ||
205 | /* firmware is not able to re-assemble 512 bytes buffer in full-speed */ | |
206 | if ((dev->udev->speed != USB_SPEED_HIGH) && | |
207 | (cmd_len > PCAN_UFD_LOSPD_PKT_SIZE)) { | |
208 | packet_len = PCAN_UFD_LOSPD_PKT_SIZE; | |
209 | n += cmd_len / packet_len; | |
210 | } else { | |
211 | packet_len = cmd_len; | |
212 | } | |
213 | ||
214 | for (i = 0; i < n; i++) { | |
215 | err = usb_bulk_msg(dev->udev, | |
216 | usb_sndbulkpipe(dev->udev, | |
217 | PCAN_USBPRO_EP_CMDOUT), | |
218 | packet_ptr, packet_len, | |
219 | NULL, PCAN_UFD_CMD_TIMEOUT_MS); | |
220 | if (err) { | |
221 | netdev_err(dev->netdev, | |
222 | "sending command failure: %d\n", err); | |
223 | break; | |
224 | } | |
225 | ||
226 | packet_ptr += packet_len; | |
227 | } | |
228 | ||
229 | return err; | |
230 | } | |
231 | ||
232 | /* build the commands list in the given buffer, to enter operational mode */ | |
233 | static int pcan_usb_fd_build_restart_cmd(struct peak_usb_device *dev, u8 *buf) | |
234 | { | |
235 | struct pucan_wr_err_cnt *prc; | |
236 | struct pucan_command *cmd; | |
237 | u8 *pc = buf; | |
238 | ||
239 | /* 1st, reset error counters: */ | |
240 | prc = (struct pucan_wr_err_cnt *)pc; | |
241 | prc->opcode_channel = pucan_cmd_opcode_channel(dev, | |
242 | PUCAN_CMD_WR_ERR_CNT); | |
243 | ||
244 | /* select both counters */ | |
245 | prc->sel_mask = cpu_to_le16(PUCAN_WRERRCNT_TE|PUCAN_WRERRCNT_RE); | |
246 | ||
247 | /* and reset their values */ | |
248 | prc->tx_counter = 0; | |
249 | prc->rx_counter = 0; | |
250 | ||
251 | /* moves the pointer forward */ | |
252 | pc += sizeof(struct pucan_wr_err_cnt); | |
253 | ||
0f251e45 SG |
254 | /* add command to switch from ISO to non-ISO mode, if fw allows it */ |
255 | if (dev->can.ctrlmode_supported & CAN_CTRLMODE_FD_NON_ISO) { | |
256 | struct pucan_options *puo = (struct pucan_options *)pc; | |
257 | ||
258 | puo->opcode_channel = | |
259 | (dev->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) ? | |
260 | pucan_cmd_opcode_channel(dev, | |
261 | PUCAN_CMD_CLR_DIS_OPTION) : | |
262 | pucan_cmd_opcode_channel(dev, PUCAN_CMD_SET_EN_OPTION); | |
263 | ||
264 | puo->options = cpu_to_le16(PUCAN_OPTION_CANDFDISO); | |
265 | ||
266 | /* to be sure that no other extended bits will be taken into | |
267 | * account | |
268 | */ | |
269 | puo->unused = 0; | |
270 | ||
271 | /* moves the pointer forward */ | |
272 | pc += sizeof(struct pucan_options); | |
273 | } | |
274 | ||
0a25e1f4 SG |
275 | /* next, go back to operational mode */ |
276 | cmd = (struct pucan_command *)pc; | |
277 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
278 | (dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) ? | |
279 | PUCAN_CMD_LISTEN_ONLY_MODE : | |
280 | PUCAN_CMD_NORMAL_MODE); | |
281 | pc += sizeof(struct pucan_command); | |
282 | ||
283 | return pc - buf; | |
284 | } | |
285 | ||
286 | /* set CAN bus on/off */ | |
287 | static int pcan_usb_fd_set_bus(struct peak_usb_device *dev, u8 onoff) | |
288 | { | |
289 | u8 *pc = pcan_usb_fd_cmd_buffer(dev); | |
290 | int l; | |
291 | ||
292 | if (onoff) { | |
293 | /* build the cmds list to enter operational mode */ | |
294 | l = pcan_usb_fd_build_restart_cmd(dev, pc); | |
295 | } else { | |
296 | struct pucan_command *cmd = (struct pucan_command *)pc; | |
297 | ||
298 | /* build cmd to go back to reset mode */ | |
299 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
300 | PUCAN_CMD_RESET_MODE); | |
301 | l = sizeof(struct pucan_command); | |
302 | } | |
303 | ||
304 | /* send the command */ | |
305 | return pcan_usb_fd_send_cmd(dev, pc + l); | |
306 | } | |
307 | ||
308 | /* set filtering masks: | |
309 | * | |
310 | * idx in range [0..63] selects a row #idx, all rows otherwise | |
311 | * mask in range [0..0xffffffff] defines up to 32 CANIDs in the row(s) | |
312 | * | |
313 | * Each bit of this 64 x 32 bits array defines a CANID value: | |
314 | * | |
315 | * bit[i,j] = 1 implies that CANID=(i x 32)+j will be received, while | |
316 | * bit[i,j] = 0 implies that CANID=(i x 32)+j will be discarded. | |
317 | */ | |
318 | static int pcan_usb_fd_set_filter_std(struct peak_usb_device *dev, int idx, | |
319 | u32 mask) | |
320 | { | |
321 | struct pucan_filter_std *cmd = pcan_usb_fd_cmd_buffer(dev); | |
322 | int i, n; | |
323 | ||
324 | /* select all rows when idx is out of range [0..63] */ | |
325 | if ((idx < 0) || (idx >= (1 << PUCAN_FLTSTD_ROW_IDX_BITS))) { | |
326 | n = 1 << PUCAN_FLTSTD_ROW_IDX_BITS; | |
327 | idx = 0; | |
328 | ||
329 | /* select the row (and only the row) otherwise */ | |
330 | } else { | |
331 | n = idx + 1; | |
332 | } | |
333 | ||
334 | for (i = idx; i < n; i++, cmd++) { | |
335 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
336 | PUCAN_CMD_FILTER_STD); | |
337 | cmd->idx = cpu_to_le16(i); | |
338 | cmd->mask = cpu_to_le32(mask); | |
339 | } | |
340 | ||
341 | /* send the command */ | |
342 | return pcan_usb_fd_send_cmd(dev, cmd); | |
343 | } | |
344 | ||
3ef5247e | 345 | /* set/unset options |
0a25e1f4 | 346 | * |
3ef5247e SG |
347 | * onoff set(1)/unset(0) options |
348 | * mask each bit defines a kind of options to set/unset | |
0a25e1f4 | 349 | */ |
3ef5247e SG |
350 | static int pcan_usb_fd_set_options(struct peak_usb_device *dev, |
351 | bool onoff, u16 ucan_mask, u16 usb_mask) | |
0a25e1f4 | 352 | { |
3ef5247e | 353 | struct pcan_ufd_options *cmd = pcan_usb_fd_cmd_buffer(dev); |
0a25e1f4 SG |
354 | |
355 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
3ef5247e SG |
356 | (onoff) ? PUCAN_CMD_SET_EN_OPTION : |
357 | PUCAN_CMD_CLR_DIS_OPTION); | |
0a25e1f4 | 358 | |
3ef5247e | 359 | cmd->ucan_mask = cpu_to_le16(ucan_mask); |
0a25e1f4 SG |
360 | cmd->usb_mask = cpu_to_le16(usb_mask); |
361 | ||
362 | /* send the command */ | |
363 | return pcan_usb_fd_send_cmd(dev, ++cmd); | |
364 | } | |
365 | ||
366 | /* setup LED control */ | |
367 | static int pcan_usb_fd_set_can_led(struct peak_usb_device *dev, u8 led_mode) | |
368 | { | |
369 | struct pcan_ufd_led *cmd = pcan_usb_fd_cmd_buffer(dev); | |
370 | ||
371 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
372 | PCAN_UFD_CMD_LED_SET); | |
373 | cmd->mode = led_mode; | |
374 | ||
375 | /* send the command */ | |
376 | return pcan_usb_fd_send_cmd(dev, ++cmd); | |
377 | } | |
378 | ||
379 | /* set CAN clock domain */ | |
380 | static int pcan_usb_fd_set_clock_domain(struct peak_usb_device *dev, | |
381 | u8 clk_mode) | |
382 | { | |
383 | struct pcan_ufd_clock *cmd = pcan_usb_fd_cmd_buffer(dev); | |
384 | ||
385 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
386 | PCAN_UFD_CMD_CLK_SET); | |
387 | cmd->mode = clk_mode; | |
388 | ||
389 | /* send the command */ | |
390 | return pcan_usb_fd_send_cmd(dev, ++cmd); | |
391 | } | |
392 | ||
393 | /* set bittiming for CAN and CAN-FD header */ | |
394 | static int pcan_usb_fd_set_bittiming_slow(struct peak_usb_device *dev, | |
395 | struct can_bittiming *bt) | |
396 | { | |
397 | struct pucan_timing_slow *cmd = pcan_usb_fd_cmd_buffer(dev); | |
398 | ||
399 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
400 | PUCAN_CMD_TIMING_SLOW); | |
401 | cmd->sjw_t = PUCAN_TSLOW_SJW_T(bt->sjw - 1, | |
402 | dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES); | |
403 | ||
404 | cmd->tseg2 = PUCAN_TSLOW_TSEG2(bt->phase_seg2 - 1); | |
405 | cmd->tseg1 = PUCAN_TSLOW_TSEG1(bt->prop_seg + bt->phase_seg1 - 1); | |
406 | cmd->brp = cpu_to_le16(PUCAN_TSLOW_BRP(bt->brp - 1)); | |
407 | ||
408 | cmd->ewl = 96; /* default */ | |
409 | ||
410 | /* send the command */ | |
411 | return pcan_usb_fd_send_cmd(dev, ++cmd); | |
412 | } | |
413 | ||
414 | /* set CAN-FD bittiming for data */ | |
415 | static int pcan_usb_fd_set_bittiming_fast(struct peak_usb_device *dev, | |
416 | struct can_bittiming *bt) | |
417 | { | |
418 | struct pucan_timing_fast *cmd = pcan_usb_fd_cmd_buffer(dev); | |
419 | ||
420 | cmd->opcode_channel = pucan_cmd_opcode_channel(dev, | |
421 | PUCAN_CMD_TIMING_FAST); | |
422 | cmd->sjw = PUCAN_TFAST_SJW(bt->sjw - 1); | |
423 | cmd->tseg2 = PUCAN_TFAST_TSEG2(bt->phase_seg2 - 1); | |
424 | cmd->tseg1 = PUCAN_TFAST_TSEG1(bt->prop_seg + bt->phase_seg1 - 1); | |
425 | cmd->brp = cpu_to_le16(PUCAN_TFAST_BRP(bt->brp - 1)); | |
426 | ||
427 | /* send the command */ | |
428 | return pcan_usb_fd_send_cmd(dev, ++cmd); | |
429 | } | |
430 | ||
431 | /* handle restart but in asynchronously way | |
432 | * (uses PCAN-USB Pro code to complete asynchronous request) | |
433 | */ | |
434 | static int pcan_usb_fd_restart_async(struct peak_usb_device *dev, | |
435 | struct urb *urb, u8 *buf) | |
436 | { | |
437 | u8 *pc = buf; | |
438 | ||
439 | /* build the entire cmds list in the provided buffer, to go back into | |
440 | * operational mode. | |
441 | */ | |
442 | pc += pcan_usb_fd_build_restart_cmd(dev, pc); | |
443 | ||
444 | /* add EOC */ | |
445 | memset(pc, 0xff, sizeof(struct pucan_command)); | |
446 | pc += sizeof(struct pucan_command); | |
447 | ||
448 | /* complete the URB */ | |
449 | usb_fill_bulk_urb(urb, dev->udev, | |
450 | usb_sndbulkpipe(dev->udev, PCAN_USBPRO_EP_CMDOUT), | |
451 | buf, pc - buf, | |
452 | pcan_usb_pro_restart_complete, dev); | |
453 | ||
454 | /* and submit it. */ | |
455 | return usb_submit_urb(urb, GFP_ATOMIC); | |
456 | } | |
457 | ||
458 | static int pcan_usb_fd_drv_loaded(struct peak_usb_device *dev, bool loaded) | |
459 | { | |
460 | struct pcan_usb_fd_device *pdev = | |
461 | container_of(dev, struct pcan_usb_fd_device, dev); | |
462 | ||
463 | pdev->cmd_buffer_addr[0] = 0; | |
464 | pdev->cmd_buffer_addr[1] = !!loaded; | |
465 | ||
466 | return pcan_usb_pro_send_req(dev, | |
467 | PCAN_USBPRO_REQ_FCT, | |
468 | PCAN_USBPRO_FCT_DRVLD, | |
469 | pdev->cmd_buffer_addr, | |
470 | PCAN_USBPRO_FCT_DRVLD_REQ_LEN); | |
471 | } | |
472 | ||
473 | static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if, | |
474 | struct pucan_msg *rx_msg) | |
475 | { | |
476 | struct pucan_rx_msg *rm = (struct pucan_rx_msg *)rx_msg; | |
477 | struct peak_usb_device *dev = usb_if->dev[pucan_msg_get_channel(rm)]; | |
478 | struct net_device *netdev = dev->netdev; | |
479 | struct canfd_frame *cfd; | |
480 | struct sk_buff *skb; | |
481 | const u16 rx_msg_flags = le16_to_cpu(rm->flags); | |
482 | ||
483 | if (rx_msg_flags & PUCAN_MSG_EXT_DATA_LEN) { | |
484 | /* CANFD frame case */ | |
485 | skb = alloc_canfd_skb(netdev, &cfd); | |
486 | if (!skb) | |
487 | return -ENOMEM; | |
488 | ||
489 | if (rx_msg_flags & PUCAN_MSG_BITRATE_SWITCH) | |
490 | cfd->flags |= CANFD_BRS; | |
491 | ||
492 | if (rx_msg_flags & PUCAN_MSG_ERROR_STATE_IND) | |
493 | cfd->flags |= CANFD_ESI; | |
494 | ||
495 | cfd->len = can_dlc2len(get_canfd_dlc(pucan_msg_get_dlc(rm))); | |
496 | } else { | |
497 | /* CAN 2.0 frame case */ | |
498 | skb = alloc_can_skb(netdev, (struct can_frame **)&cfd); | |
499 | if (!skb) | |
500 | return -ENOMEM; | |
501 | ||
502 | cfd->len = get_can_dlc(pucan_msg_get_dlc(rm)); | |
503 | } | |
504 | ||
505 | cfd->can_id = le32_to_cpu(rm->can_id); | |
506 | ||
507 | if (rx_msg_flags & PUCAN_MSG_EXT_ID) | |
508 | cfd->can_id |= CAN_EFF_FLAG; | |
509 | ||
510 | if (rx_msg_flags & PUCAN_MSG_RTR) | |
511 | cfd->can_id |= CAN_RTR_FLAG; | |
512 | else | |
513 | memcpy(cfd->data, rm->d, cfd->len); | |
514 | ||
515 | peak_usb_netif_rx(skb, &usb_if->time_ref, | |
516 | le32_to_cpu(rm->ts_low), le32_to_cpu(rm->ts_high)); | |
517 | ||
518 | netdev->stats.rx_packets++; | |
519 | netdev->stats.rx_bytes += cfd->len; | |
520 | ||
521 | return 0; | |
522 | } | |
523 | ||
524 | /* handle uCAN status message */ | |
525 | static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if, | |
526 | struct pucan_msg *rx_msg) | |
527 | { | |
528 | struct pucan_status_msg *sm = (struct pucan_status_msg *)rx_msg; | |
529 | struct peak_usb_device *dev = usb_if->dev[pucan_stmsg_get_channel(sm)]; | |
530 | struct pcan_usb_fd_device *pdev = | |
531 | container_of(dev, struct pcan_usb_fd_device, dev); | |
532 | enum can_state new_state = CAN_STATE_ERROR_ACTIVE; | |
533 | enum can_state rx_state, tx_state; | |
534 | struct net_device *netdev = dev->netdev; | |
535 | struct can_frame *cf; | |
536 | struct sk_buff *skb; | |
537 | ||
538 | /* nothing should be sent while in BUS_OFF state */ | |
539 | if (dev->can.state == CAN_STATE_BUS_OFF) | |
540 | return 0; | |
541 | ||
542 | if (sm->channel_p_w_b & PUCAN_BUS_BUSOFF) { | |
543 | new_state = CAN_STATE_BUS_OFF; | |
544 | } else if (sm->channel_p_w_b & PUCAN_BUS_PASSIVE) { | |
545 | new_state = CAN_STATE_ERROR_PASSIVE; | |
546 | } else if (sm->channel_p_w_b & PUCAN_BUS_WARNING) { | |
547 | new_state = CAN_STATE_ERROR_WARNING; | |
548 | } else { | |
549 | /* no error bit (so, no error skb, back to active state) */ | |
550 | dev->can.state = CAN_STATE_ERROR_ACTIVE; | |
551 | pdev->bec.txerr = 0; | |
552 | pdev->bec.rxerr = 0; | |
553 | return 0; | |
554 | } | |
555 | ||
556 | /* state hasn't changed */ | |
557 | if (new_state == dev->can.state) | |
558 | return 0; | |
559 | ||
560 | /* handle bus state change */ | |
561 | tx_state = (pdev->bec.txerr >= pdev->bec.rxerr) ? new_state : 0; | |
562 | rx_state = (pdev->bec.txerr <= pdev->bec.rxerr) ? new_state : 0; | |
563 | ||
564 | /* allocate an skb to store the error frame */ | |
565 | skb = alloc_can_err_skb(netdev, &cf); | |
566 | if (skb) | |
567 | can_change_state(netdev, cf, tx_state, rx_state); | |
568 | ||
569 | /* things must be done even in case of OOM */ | |
570 | if (new_state == CAN_STATE_BUS_OFF) | |
571 | can_bus_off(netdev); | |
572 | ||
573 | if (!skb) | |
574 | return -ENOMEM; | |
575 | ||
576 | peak_usb_netif_rx(skb, &usb_if->time_ref, | |
577 | le32_to_cpu(sm->ts_low), le32_to_cpu(sm->ts_high)); | |
578 | ||
579 | netdev->stats.rx_packets++; | |
580 | netdev->stats.rx_bytes += cf->can_dlc; | |
581 | ||
582 | return 0; | |
583 | } | |
584 | ||
585 | /* handle uCAN error message */ | |
586 | static int pcan_usb_fd_decode_error(struct pcan_usb_fd_if *usb_if, | |
587 | struct pucan_msg *rx_msg) | |
588 | { | |
589 | struct pucan_error_msg *er = (struct pucan_error_msg *)rx_msg; | |
590 | struct peak_usb_device *dev = usb_if->dev[pucan_ermsg_get_channel(er)]; | |
591 | struct pcan_usb_fd_device *pdev = | |
592 | container_of(dev, struct pcan_usb_fd_device, dev); | |
593 | ||
594 | /* keep a trace of tx and rx error counters for later use */ | |
595 | pdev->bec.txerr = er->tx_err_cnt; | |
596 | pdev->bec.rxerr = er->rx_err_cnt; | |
597 | ||
598 | return 0; | |
599 | } | |
600 | ||
601 | /* handle uCAN overrun message */ | |
602 | static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if, | |
603 | struct pucan_msg *rx_msg) | |
604 | { | |
605 | struct pcan_ufd_ovr_msg *ov = (struct pcan_ufd_ovr_msg *)rx_msg; | |
606 | struct peak_usb_device *dev = usb_if->dev[pufd_omsg_get_channel(ov)]; | |
607 | struct net_device *netdev = dev->netdev; | |
608 | struct can_frame *cf; | |
609 | struct sk_buff *skb; | |
610 | ||
611 | /* allocate an skb to store the error frame */ | |
612 | skb = alloc_can_err_skb(netdev, &cf); | |
613 | if (!skb) | |
614 | return -ENOMEM; | |
615 | ||
616 | cf->can_id |= CAN_ERR_CRTL; | |
617 | cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; | |
618 | ||
619 | peak_usb_netif_rx(skb, &usb_if->time_ref, | |
620 | le32_to_cpu(ov->ts_low), le32_to_cpu(ov->ts_high)); | |
621 | ||
622 | netdev->stats.rx_over_errors++; | |
623 | netdev->stats.rx_errors++; | |
624 | ||
625 | return 0; | |
626 | } | |
627 | ||
628 | /* handle USB calibration message */ | |
629 | static void pcan_usb_fd_decode_ts(struct pcan_usb_fd_if *usb_if, | |
630 | struct pucan_msg *rx_msg) | |
631 | { | |
632 | struct pcan_ufd_ts_msg *ts = (struct pcan_ufd_ts_msg *)rx_msg; | |
633 | ||
634 | /* should wait until clock is stabilized */ | |
635 | if (usb_if->cm_ignore_count > 0) | |
636 | usb_if->cm_ignore_count--; | |
637 | else | |
638 | peak_usb_set_ts_now(&usb_if->time_ref, le32_to_cpu(ts->ts_low)); | |
639 | } | |
640 | ||
641 | /* callback for bulk IN urb */ | |
642 | static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb) | |
643 | { | |
644 | struct pcan_usb_fd_if *usb_if = pcan_usb_fd_dev_if(dev); | |
645 | struct net_device *netdev = dev->netdev; | |
646 | struct pucan_msg *rx_msg; | |
647 | u8 *msg_ptr, *msg_end; | |
648 | int err = 0; | |
649 | ||
650 | /* loop reading all the records from the incoming message */ | |
651 | msg_ptr = urb->transfer_buffer; | |
652 | msg_end = urb->transfer_buffer + urb->actual_length; | |
653 | for (; msg_ptr < msg_end;) { | |
654 | u16 rx_msg_type, rx_msg_size; | |
655 | ||
656 | rx_msg = (struct pucan_msg *)msg_ptr; | |
657 | if (!rx_msg->size) { | |
658 | /* null packet found: end of list */ | |
659 | break; | |
660 | } | |
661 | ||
662 | rx_msg_size = le16_to_cpu(rx_msg->size); | |
663 | rx_msg_type = le16_to_cpu(rx_msg->type); | |
664 | ||
665 | /* check if the record goes out of current packet */ | |
666 | if (msg_ptr + rx_msg_size > msg_end) { | |
667 | netdev_err(netdev, | |
668 | "got frag rec: should inc usb rx buf sze\n"); | |
669 | err = -EBADMSG; | |
670 | break; | |
671 | } | |
672 | ||
673 | switch (rx_msg_type) { | |
674 | case PUCAN_MSG_CAN_RX: | |
675 | err = pcan_usb_fd_decode_canmsg(usb_if, rx_msg); | |
676 | if (err < 0) | |
677 | goto fail; | |
678 | break; | |
679 | ||
680 | case PCAN_UFD_MSG_CALIBRATION: | |
681 | pcan_usb_fd_decode_ts(usb_if, rx_msg); | |
682 | break; | |
683 | ||
684 | case PUCAN_MSG_ERROR: | |
685 | err = pcan_usb_fd_decode_error(usb_if, rx_msg); | |
686 | if (err < 0) | |
687 | goto fail; | |
688 | break; | |
689 | ||
690 | case PUCAN_MSG_STATUS: | |
691 | err = pcan_usb_fd_decode_status(usb_if, rx_msg); | |
692 | if (err < 0) | |
693 | goto fail; | |
694 | break; | |
695 | ||
696 | case PCAN_UFD_MSG_OVERRUN: | |
697 | err = pcan_usb_fd_decode_overrun(usb_if, rx_msg); | |
698 | if (err < 0) | |
699 | goto fail; | |
700 | break; | |
701 | ||
702 | default: | |
703 | netdev_err(netdev, | |
704 | "unhandled msg type 0x%02x (%d): ignored\n", | |
705 | rx_msg_type, rx_msg_type); | |
706 | break; | |
707 | } | |
708 | ||
709 | msg_ptr += rx_msg_size; | |
710 | } | |
711 | ||
712 | fail: | |
713 | if (err) | |
714 | pcan_dump_mem("received msg", | |
715 | urb->transfer_buffer, urb->actual_length); | |
716 | return err; | |
717 | } | |
718 | ||
719 | /* CAN/CANFD frames encoding callback */ | |
720 | static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev, | |
721 | struct sk_buff *skb, u8 *obuf, size_t *size) | |
722 | { | |
723 | struct pucan_tx_msg *tx_msg = (struct pucan_tx_msg *)obuf; | |
724 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; | |
725 | u16 tx_msg_size, tx_msg_flags; | |
726 | u8 can_dlc; | |
727 | ||
728 | tx_msg_size = ALIGN(sizeof(struct pucan_tx_msg) + cfd->len, 4); | |
729 | tx_msg->size = cpu_to_le16(tx_msg_size); | |
730 | tx_msg->type = cpu_to_le16(PUCAN_MSG_CAN_TX); | |
731 | ||
732 | tx_msg_flags = 0; | |
733 | if (cfd->can_id & CAN_EFF_FLAG) { | |
734 | tx_msg_flags |= PUCAN_MSG_EXT_ID; | |
735 | tx_msg->can_id = cpu_to_le32(cfd->can_id & CAN_EFF_MASK); | |
736 | } else { | |
737 | tx_msg->can_id = cpu_to_le32(cfd->can_id & CAN_SFF_MASK); | |
738 | } | |
739 | ||
740 | if (can_is_canfd_skb(skb)) { | |
741 | /* considering a CANFD frame */ | |
742 | can_dlc = can_len2dlc(cfd->len); | |
743 | ||
744 | tx_msg_flags |= PUCAN_MSG_EXT_DATA_LEN; | |
745 | ||
746 | if (cfd->flags & CANFD_BRS) | |
747 | tx_msg_flags |= PUCAN_MSG_BITRATE_SWITCH; | |
748 | ||
749 | if (cfd->flags & CANFD_ESI) | |
750 | tx_msg_flags |= PUCAN_MSG_ERROR_STATE_IND; | |
751 | } else { | |
752 | /* CAND 2.0 frames */ | |
753 | can_dlc = cfd->len; | |
754 | ||
755 | if (cfd->can_id & CAN_RTR_FLAG) | |
756 | tx_msg_flags |= PUCAN_MSG_RTR; | |
757 | } | |
758 | ||
759 | tx_msg->flags = cpu_to_le16(tx_msg_flags); | |
760 | tx_msg->channel_dlc = PUCAN_MSG_CHANNEL_DLC(dev->ctrl_idx, can_dlc); | |
761 | memcpy(tx_msg->d, cfd->data, cfd->len); | |
762 | ||
763 | /* add null size message to tag the end (messages are 32-bits aligned) | |
764 | */ | |
765 | tx_msg = (struct pucan_tx_msg *)(obuf + tx_msg_size); | |
766 | ||
767 | tx_msg->size = 0; | |
768 | ||
769 | /* set the whole size of the USB packet to send */ | |
770 | *size = tx_msg_size + sizeof(u32); | |
771 | ||
772 | return 0; | |
773 | } | |
774 | ||
775 | /* start the interface (last chance before set bus on) */ | |
776 | static int pcan_usb_fd_start(struct peak_usb_device *dev) | |
777 | { | |
778 | struct pcan_usb_fd_device *pdev = | |
779 | container_of(dev, struct pcan_usb_fd_device, dev); | |
780 | int err; | |
781 | ||
782 | /* set filter mode: all acceptance */ | |
783 | err = pcan_usb_fd_set_filter_std(dev, -1, 0xffffffff); | |
784 | if (err) | |
785 | return err; | |
786 | ||
787 | /* opening first device: */ | |
788 | if (pdev->usb_if->dev_opened_count == 0) { | |
789 | /* reset time_ref */ | |
790 | peak_usb_init_time_ref(&pdev->usb_if->time_ref, | |
791 | &pcan_usb_pro_fd); | |
792 | ||
793 | /* enable USB calibration messages */ | |
3ef5247e SG |
794 | err = pcan_usb_fd_set_options(dev, 1, |
795 | PUCAN_OPTION_ERROR, | |
796 | PCAN_UFD_FLTEXT_CALIBRATION); | |
0a25e1f4 SG |
797 | } |
798 | ||
799 | pdev->usb_if->dev_opened_count++; | |
800 | ||
801 | /* reset cached error counters */ | |
802 | pdev->bec.txerr = 0; | |
803 | pdev->bec.rxerr = 0; | |
804 | ||
805 | return err; | |
806 | } | |
807 | ||
808 | /* socket callback used to copy berr counters values receieved through USB */ | |
809 | static int pcan_usb_fd_get_berr_counter(const struct net_device *netdev, | |
810 | struct can_berr_counter *bec) | |
811 | { | |
812 | struct peak_usb_device *dev = netdev_priv(netdev); | |
813 | struct pcan_usb_fd_device *pdev = | |
814 | container_of(dev, struct pcan_usb_fd_device, dev); | |
815 | ||
816 | *bec = pdev->bec; | |
817 | ||
818 | /* must return 0 */ | |
819 | return 0; | |
820 | } | |
821 | ||
822 | /* stop interface (last chance before set bus off) */ | |
823 | static int pcan_usb_fd_stop(struct peak_usb_device *dev) | |
824 | { | |
825 | struct pcan_usb_fd_device *pdev = | |
826 | container_of(dev, struct pcan_usb_fd_device, dev); | |
827 | ||
828 | /* turn off special msgs for that interface if no other dev opened */ | |
829 | if (pdev->usb_if->dev_opened_count == 1) | |
3ef5247e SG |
830 | pcan_usb_fd_set_options(dev, 0, |
831 | PUCAN_OPTION_ERROR, | |
832 | PCAN_UFD_FLTEXT_CALIBRATION); | |
0a25e1f4 SG |
833 | pdev->usb_if->dev_opened_count--; |
834 | ||
835 | return 0; | |
836 | } | |
837 | ||
838 | /* called when probing, to initialize a device object */ | |
839 | static int pcan_usb_fd_init(struct peak_usb_device *dev) | |
840 | { | |
841 | struct pcan_usb_fd_device *pdev = | |
842 | container_of(dev, struct pcan_usb_fd_device, dev); | |
843 | int i, err = -ENOMEM; | |
844 | ||
845 | /* do this for 1st channel only */ | |
846 | if (!dev->prev_siblings) { | |
847 | /* allocate netdevices common structure attached to first one */ | |
848 | pdev->usb_if = kzalloc(sizeof(*pdev->usb_if), GFP_KERNEL); | |
849 | if (!pdev->usb_if) | |
850 | goto err_out; | |
851 | ||
852 | /* allocate command buffer once for all for the interface */ | |
853 | pdev->cmd_buffer_addr = kmalloc(PCAN_UFD_CMD_BUFFER_SIZE, | |
854 | GFP_KERNEL); | |
855 | if (!pdev->cmd_buffer_addr) | |
856 | goto err_out_1; | |
857 | ||
858 | /* number of ts msgs to ignore before taking one into account */ | |
859 | pdev->usb_if->cm_ignore_count = 5; | |
860 | ||
861 | err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO, | |
862 | PCAN_USBPRO_INFO_FW, | |
863 | &pdev->usb_if->fw_info, | |
864 | sizeof(pdev->usb_if->fw_info)); | |
865 | if (err) { | |
866 | dev_err(dev->netdev->dev.parent, | |
867 | "unable to read %s firmware info (err %d)\n", | |
868 | dev->adapter->name, err); | |
869 | goto err_out_2; | |
870 | } | |
871 | ||
872 | /* explicit use of dev_xxx() instead of netdev_xxx() here: | |
873 | * information displayed are related to the device itself, not | |
874 | * to the canx (channel) device. | |
875 | */ | |
876 | dev_info(dev->netdev->dev.parent, | |
877 | "PEAK-System %s v%u fw v%u.%u.%u (%u channels)\n", | |
878 | dev->adapter->name, pdev->usb_if->fw_info.hw_version, | |
879 | pdev->usb_if->fw_info.fw_version[0], | |
880 | pdev->usb_if->fw_info.fw_version[1], | |
881 | pdev->usb_if->fw_info.fw_version[2], | |
882 | dev->adapter->ctrl_count); | |
883 | ||
0f251e45 SG |
884 | /* check for ability to switch between ISO/non-ISO modes */ |
885 | if (pdev->usb_if->fw_info.fw_version[0] >= 2) { | |
886 | /* firmware >= 2.x supports ISO/non-ISO switching */ | |
887 | dev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO; | |
888 | } else { | |
889 | /* firmware < 2.x only supports fixed(!) non-ISO */ | |
890 | dev->can.ctrlmode |= CAN_CTRLMODE_FD_NON_ISO; | |
891 | } | |
0a25e1f4 SG |
892 | |
893 | /* tell the hardware the can driver is running */ | |
894 | err = pcan_usb_fd_drv_loaded(dev, 1); | |
895 | if (err) { | |
896 | dev_err(dev->netdev->dev.parent, | |
897 | "unable to tell %s driver is loaded (err %d)\n", | |
898 | dev->adapter->name, err); | |
899 | goto err_out_2; | |
900 | } | |
901 | } else { | |
902 | /* otherwise, simply copy previous sibling's values */ | |
903 | struct pcan_usb_fd_device *ppdev = | |
904 | container_of(dev->prev_siblings, | |
905 | struct pcan_usb_fd_device, dev); | |
906 | ||
907 | pdev->usb_if = ppdev->usb_if; | |
908 | pdev->cmd_buffer_addr = ppdev->cmd_buffer_addr; | |
b0d4724b SG |
909 | |
910 | /* do a copy of the ctrlmode[_supported] too */ | |
911 | dev->can.ctrlmode = ppdev->dev.can.ctrlmode; | |
912 | dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported; | |
0a25e1f4 SG |
913 | } |
914 | ||
915 | pdev->usb_if->dev[dev->ctrl_idx] = dev; | |
916 | dev->device_number = | |
917 | le32_to_cpu(pdev->usb_if->fw_info.dev_id[dev->ctrl_idx]); | |
918 | ||
919 | /* set clock domain */ | |
920 | for (i = 0; i < ARRAY_SIZE(pcan_usb_fd_clk_freq); i++) | |
921 | if (dev->adapter->clock.freq == pcan_usb_fd_clk_freq[i]) | |
922 | break; | |
923 | ||
924 | if (i >= ARRAY_SIZE(pcan_usb_fd_clk_freq)) { | |
925 | dev_warn(dev->netdev->dev.parent, | |
926 | "incompatible clock frequencies\n"); | |
927 | err = -EINVAL; | |
928 | goto err_out_2; | |
929 | } | |
930 | ||
931 | pcan_usb_fd_set_clock_domain(dev, i); | |
932 | ||
933 | /* set LED in default state (end of init phase) */ | |
934 | pcan_usb_fd_set_can_led(dev, PCAN_UFD_LED_DEF); | |
935 | ||
936 | return 0; | |
937 | ||
938 | err_out_2: | |
939 | kfree(pdev->cmd_buffer_addr); | |
940 | err_out_1: | |
941 | kfree(pdev->usb_if); | |
942 | err_out: | |
943 | return err; | |
944 | } | |
945 | ||
946 | /* called when driver module is being unloaded */ | |
947 | static void pcan_usb_fd_exit(struct peak_usb_device *dev) | |
948 | { | |
949 | struct pcan_usb_fd_device *pdev = | |
950 | container_of(dev, struct pcan_usb_fd_device, dev); | |
951 | ||
952 | /* when rmmod called before unplug and if down, should reset things | |
953 | * before leaving | |
954 | */ | |
955 | if (dev->can.state != CAN_STATE_STOPPED) { | |
956 | /* set bus off on the corresponding channel */ | |
957 | pcan_usb_fd_set_bus(dev, 0); | |
958 | } | |
959 | ||
960 | /* switch off corresponding CAN LEDs */ | |
961 | pcan_usb_fd_set_can_led(dev, PCAN_UFD_LED_OFF); | |
962 | ||
963 | /* if channel #0 (only) */ | |
964 | if (dev->ctrl_idx == 0) { | |
965 | /* turn off calibration message if any device were opened */ | |
966 | if (pdev->usb_if->dev_opened_count > 0) | |
3ef5247e SG |
967 | pcan_usb_fd_set_options(dev, 0, |
968 | PUCAN_OPTION_ERROR, | |
969 | PCAN_UFD_FLTEXT_CALIBRATION); | |
0a25e1f4 SG |
970 | |
971 | /* tell USB adapter that the driver is being unloaded */ | |
972 | pcan_usb_fd_drv_loaded(dev, 0); | |
973 | } | |
974 | } | |
975 | ||
976 | /* called when the USB adapter is unplugged */ | |
977 | static void pcan_usb_fd_free(struct peak_usb_device *dev) | |
978 | { | |
979 | /* last device: can free shared objects now */ | |
980 | if (!dev->prev_siblings && !dev->next_siblings) { | |
981 | struct pcan_usb_fd_device *pdev = | |
982 | container_of(dev, struct pcan_usb_fd_device, dev); | |
983 | ||
984 | /* free commands buffer */ | |
985 | kfree(pdev->cmd_buffer_addr); | |
986 | ||
987 | /* free usb interface object */ | |
988 | kfree(pdev->usb_if); | |
989 | } | |
990 | } | |
991 | ||
992 | /* describes the PCAN-USB FD adapter */ | |
06b23f7f MKB |
993 | static const struct can_bittiming_const pcan_usb_fd_const = { |
994 | .name = "pcan_usb_fd", | |
995 | .tseg1_min = 1, | |
996 | .tseg1_max = 64, | |
997 | .tseg2_min = 1, | |
998 | .tseg2_max = 16, | |
999 | .sjw_max = 16, | |
1000 | .brp_min = 1, | |
1001 | .brp_max = 1024, | |
1002 | .brp_inc = 1, | |
1003 | }; | |
1004 | ||
1005 | static const struct can_bittiming_const pcan_usb_fd_data_const = { | |
1006 | .name = "pcan_usb_fd", | |
1007 | .tseg1_min = 1, | |
1008 | .tseg1_max = 16, | |
1009 | .tseg2_min = 1, | |
1010 | .tseg2_max = 8, | |
1011 | .sjw_max = 4, | |
1012 | .brp_min = 1, | |
1013 | .brp_max = 1024, | |
1014 | .brp_inc = 1, | |
1015 | }; | |
1016 | ||
0a25e1f4 SG |
1017 | const struct peak_usb_adapter pcan_usb_fd = { |
1018 | .name = "PCAN-USB FD", | |
1019 | .device_id = PCAN_USBFD_PRODUCT_ID, | |
1020 | .ctrl_count = PCAN_USBFD_CHANNEL_COUNT, | |
1021 | .ctrlmode_supported = CAN_CTRLMODE_FD | | |
1022 | CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY, | |
1023 | .clock = { | |
1024 | .freq = PCAN_UFD_CRYSTAL_HZ, | |
1025 | }, | |
06b23f7f MKB |
1026 | .bittiming_const = &pcan_usb_fd_const, |
1027 | .data_bittiming_const = &pcan_usb_fd_data_const, | |
0a25e1f4 SG |
1028 | |
1029 | /* size of device private data */ | |
1030 | .sizeof_dev_private = sizeof(struct pcan_usb_fd_device), | |
1031 | ||
1032 | /* timestamps usage */ | |
1033 | .ts_used_bits = 32, | |
1034 | .ts_period = 1000000, /* calibration period in ts. */ | |
1035 | .us_per_ts_scale = 1, /* us = (ts * scale) >> shift */ | |
1036 | .us_per_ts_shift = 0, | |
1037 | ||
1038 | /* give here messages in/out endpoints */ | |
1039 | .ep_msg_in = PCAN_USBPRO_EP_MSGIN, | |
1040 | .ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0}, | |
1041 | ||
1042 | /* size of rx/tx usb buffers */ | |
1043 | .rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE, | |
1044 | .tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE, | |
1045 | ||
1046 | /* device callbacks */ | |
1047 | .intf_probe = pcan_usb_pro_probe, /* same as PCAN-USB Pro */ | |
1048 | .dev_init = pcan_usb_fd_init, | |
1049 | ||
1050 | .dev_exit = pcan_usb_fd_exit, | |
1051 | .dev_free = pcan_usb_fd_free, | |
1052 | .dev_set_bus = pcan_usb_fd_set_bus, | |
1053 | .dev_set_bittiming = pcan_usb_fd_set_bittiming_slow, | |
1054 | .dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast, | |
1055 | .dev_decode_buf = pcan_usb_fd_decode_buf, | |
1056 | .dev_start = pcan_usb_fd_start, | |
1057 | .dev_stop = pcan_usb_fd_stop, | |
1058 | .dev_restart_async = pcan_usb_fd_restart_async, | |
1059 | .dev_encode_msg = pcan_usb_fd_encode_msg, | |
1060 | ||
1061 | .do_get_berr_counter = pcan_usb_fd_get_berr_counter, | |
1062 | }; | |
1063 | ||
1064 | /* describes the PCAN-USB Pro FD adapter */ | |
06b23f7f MKB |
1065 | static const struct can_bittiming_const pcan_usb_pro_fd_const = { |
1066 | .name = "pcan_usb_pro_fd", | |
1067 | .tseg1_min = 1, | |
1068 | .tseg1_max = 64, | |
1069 | .tseg2_min = 1, | |
1070 | .tseg2_max = 16, | |
1071 | .sjw_max = 16, | |
1072 | .brp_min = 1, | |
1073 | .brp_max = 1024, | |
1074 | .brp_inc = 1, | |
1075 | }; | |
1076 | ||
1077 | static const struct can_bittiming_const pcan_usb_pro_fd_data_const = { | |
1078 | .name = "pcan_usb_pro_fd", | |
1079 | .tseg1_min = 1, | |
1080 | .tseg1_max = 16, | |
1081 | .tseg2_min = 1, | |
1082 | .tseg2_max = 8, | |
1083 | .sjw_max = 4, | |
1084 | .brp_min = 1, | |
1085 | .brp_max = 1024, | |
1086 | .brp_inc = 1, | |
1087 | }; | |
1088 | ||
0a25e1f4 SG |
1089 | const struct peak_usb_adapter pcan_usb_pro_fd = { |
1090 | .name = "PCAN-USB Pro FD", | |
1091 | .device_id = PCAN_USBPROFD_PRODUCT_ID, | |
1092 | .ctrl_count = PCAN_USBPROFD_CHANNEL_COUNT, | |
1093 | .ctrlmode_supported = CAN_CTRLMODE_FD | | |
1094 | CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY, | |
1095 | .clock = { | |
1096 | .freq = PCAN_UFD_CRYSTAL_HZ, | |
1097 | }, | |
06b23f7f MKB |
1098 | .bittiming_const = &pcan_usb_pro_fd_const, |
1099 | .data_bittiming_const = &pcan_usb_pro_fd_data_const, | |
0a25e1f4 SG |
1100 | |
1101 | /* size of device private data */ | |
1102 | .sizeof_dev_private = sizeof(struct pcan_usb_fd_device), | |
1103 | ||
1104 | /* timestamps usage */ | |
1105 | .ts_used_bits = 32, | |
1106 | .ts_period = 1000000, /* calibration period in ts. */ | |
1107 | .us_per_ts_scale = 1, /* us = (ts * scale) >> shift */ | |
1108 | .us_per_ts_shift = 0, | |
1109 | ||
1110 | /* give here messages in/out endpoints */ | |
1111 | .ep_msg_in = PCAN_USBPRO_EP_MSGIN, | |
1112 | .ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0, PCAN_USBPRO_EP_MSGOUT_1}, | |
1113 | ||
1114 | /* size of rx/tx usb buffers */ | |
1115 | .rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE, | |
1116 | .tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE, | |
1117 | ||
1118 | /* device callbacks */ | |
1119 | .intf_probe = pcan_usb_pro_probe, /* same as PCAN-USB Pro */ | |
1120 | .dev_init = pcan_usb_fd_init, | |
1121 | ||
1122 | .dev_exit = pcan_usb_fd_exit, | |
1123 | .dev_free = pcan_usb_fd_free, | |
1124 | .dev_set_bus = pcan_usb_fd_set_bus, | |
1125 | .dev_set_bittiming = pcan_usb_fd_set_bittiming_slow, | |
1126 | .dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast, | |
1127 | .dev_decode_buf = pcan_usb_fd_decode_buf, | |
1128 | .dev_start = pcan_usb_fd_start, | |
1129 | .dev_stop = pcan_usb_fd_stop, | |
1130 | .dev_restart_async = pcan_usb_fd_restart_async, | |
1131 | .dev_encode_msg = pcan_usb_fd_encode_msg, | |
1132 | ||
1133 | .do_get_berr_counter = pcan_usb_fd_get_berr_counter, | |
1134 | }; |