1 | // SPDX-License-Identifier: GPL-2.0-only |
---|---|
2 | /* |
3 | * CAN driver for PEAK System PCAN-USB adapter |
4 | * Derived from the PCAN project file driver/src/pcan_usb.c |
5 | * |
6 | * Copyright (C) 2003-2010 PEAK System-Technik GmbH |
7 | * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com> |
8 | * |
9 | * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de> |
10 | */ |
11 | #include <asm/unaligned.h> |
12 | |
13 | #include <linux/ethtool.h> |
14 | #include <linux/module.h> |
15 | #include <linux/netdevice.h> |
16 | #include <linux/usb.h> |
17 | |
18 | #include <linux/can.h> |
19 | #include <linux/can/dev.h> |
20 | #include <linux/can/error.h> |
21 | |
22 | #include "pcan_usb_core.h" |
23 | |
24 | /* PCAN-USB Endpoints */ |
25 | #define PCAN_USB_EP_CMDOUT 1 |
26 | #define PCAN_USB_EP_CMDIN (PCAN_USB_EP_CMDOUT | USB_DIR_IN) |
27 | #define PCAN_USB_EP_MSGOUT 2 |
28 | #define PCAN_USB_EP_MSGIN (PCAN_USB_EP_MSGOUT | USB_DIR_IN) |
29 | |
30 | /* PCAN-USB command struct */ |
31 | #define PCAN_USB_CMD_FUNC 0 |
32 | #define PCAN_USB_CMD_NUM 1 |
33 | #define PCAN_USB_CMD_ARGS 2 |
34 | #define PCAN_USB_CMD_ARGS_LEN 14 |
35 | #define PCAN_USB_CMD_LEN (PCAN_USB_CMD_ARGS + \ |
36 | PCAN_USB_CMD_ARGS_LEN) |
37 | |
38 | /* PCAN-USB commands */ |
39 | #define PCAN_USB_CMD_BITRATE 1 |
40 | #define PCAN_USB_CMD_SET_BUS 3 |
41 | #define PCAN_USB_CMD_DEVID 4 |
42 | #define PCAN_USB_CMD_SN 6 |
43 | #define PCAN_USB_CMD_REGISTER 9 |
44 | #define PCAN_USB_CMD_EXT_VCC 10 |
45 | #define PCAN_USB_CMD_ERR_FR 11 |
46 | #define PCAN_USB_CMD_LED 12 |
47 | |
48 | /* PCAN_USB_CMD_SET_BUS number arg */ |
49 | #define PCAN_USB_BUS_XCVER 2 |
50 | #define PCAN_USB_BUS_SILENT_MODE 3 |
51 | |
52 | /* PCAN_USB_CMD_xxx functions */ |
53 | #define PCAN_USB_GET 1 |
54 | #define PCAN_USB_SET 2 |
55 | |
56 | /* PCAN-USB command timeout (ms.) */ |
57 | #define PCAN_USB_COMMAND_TIMEOUT 1000 |
58 | |
59 | /* PCAN-USB startup timeout (ms.) */ |
60 | #define PCAN_USB_STARTUP_TIMEOUT 10 |
61 | |
62 | /* PCAN-USB rx/tx buffers size */ |
63 | #define PCAN_USB_RX_BUFFER_SIZE 64 |
64 | #define PCAN_USB_TX_BUFFER_SIZE 64 |
65 | |
66 | #define PCAN_USB_MSG_HEADER_LEN 2 |
67 | |
68 | #define PCAN_USB_MSG_TX_CAN 2 /* Tx msg is a CAN frame */ |
69 | |
70 | /* PCAN-USB adapter internal clock (MHz) */ |
71 | #define PCAN_USB_CRYSTAL_HZ 16000000 |
72 | |
73 | /* PCAN-USB USB message record status/len field */ |
74 | #define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7) |
75 | #define PCAN_USB_STATUSLEN_INTERNAL (1 << 6) |
76 | #define PCAN_USB_STATUSLEN_EXT_ID (1 << 5) |
77 | #define PCAN_USB_STATUSLEN_RTR (1 << 4) |
78 | #define PCAN_USB_STATUSLEN_DLC (0xf) |
79 | |
80 | /* PCAN-USB 4.1 CAN Id tx extended flags */ |
81 | #define PCAN_USB_TX_SRR 0x01 /* SJA1000 SRR command */ |
82 | #define PCAN_USB_TX_AT 0x02 /* SJA1000 AT command */ |
83 | |
84 | /* PCAN-USB error flags */ |
85 | #define PCAN_USB_ERROR_TXFULL 0x01 |
86 | #define PCAN_USB_ERROR_RXQOVR 0x02 |
87 | #define PCAN_USB_ERROR_BUS_LIGHT 0x04 |
88 | #define PCAN_USB_ERROR_BUS_HEAVY 0x08 |
89 | #define PCAN_USB_ERROR_BUS_OFF 0x10 |
90 | #define PCAN_USB_ERROR_RXQEMPTY 0x20 |
91 | #define PCAN_USB_ERROR_QOVR 0x40 |
92 | #define PCAN_USB_ERROR_TXQFULL 0x80 |
93 | |
94 | #define PCAN_USB_ERROR_BUS (PCAN_USB_ERROR_BUS_LIGHT | \ |
95 | PCAN_USB_ERROR_BUS_HEAVY | \ |
96 | PCAN_USB_ERROR_BUS_OFF) |
97 | |
98 | /* SJA1000 modes */ |
99 | #define SJA1000_MODE_NORMAL 0x00 |
100 | #define SJA1000_MODE_INIT 0x01 |
101 | |
102 | /* |
103 | * tick duration = 42.666 us => |
104 | * (tick_number * 44739243) >> 20 ~ (tick_number * 42666) / 1000 |
105 | * accuracy = 10^-7 |
106 | */ |
107 | #define PCAN_USB_TS_DIV_SHIFTER 20 |
108 | #define PCAN_USB_TS_US_PER_TICK 44739243 |
109 | |
110 | /* PCAN-USB messages record types */ |
111 | #define PCAN_USB_REC_ERROR 1 |
112 | #define PCAN_USB_REC_ANALOG 2 |
113 | #define PCAN_USB_REC_BUSLOAD 3 |
114 | #define PCAN_USB_REC_TS 4 |
115 | #define PCAN_USB_REC_BUSEVT 5 |
116 | |
117 | /* CAN bus events notifications selection mask */ |
118 | #define PCAN_USB_ERR_RXERR 0x02 /* ask for rxerr counter */ |
119 | #define PCAN_USB_ERR_TXERR 0x04 /* ask for txerr counter */ |
120 | |
121 | /* This mask generates an usb packet each time the state of the bus changes. |
122 | * In other words, its interest is to know which side among rx and tx is |
123 | * responsible of the change of the bus state. |
124 | */ |
125 | #define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR) |
126 | |
127 | /* identify bus event packets with rx/tx error counters */ |
128 | #define PCAN_USB_ERR_CNT_DEC 0x00 /* counters are decreasing */ |
129 | #define PCAN_USB_ERR_CNT_INC 0x80 /* counters are increasing */ |
130 | |
131 | /* private to PCAN-USB adapter */ |
132 | struct pcan_usb { |
133 | struct peak_usb_device dev; |
134 | struct peak_time_ref time_ref; |
135 | struct timer_list restart_timer; |
136 | struct can_berr_counter bec; |
137 | }; |
138 | |
139 | /* incoming message context for decoding */ |
140 | struct pcan_usb_msg_context { |
141 | u16 ts16; |
142 | u8 prev_ts8; |
143 | u8 *ptr; |
144 | u8 *end; |
145 | u8 rec_cnt; |
146 | u8 rec_idx; |
147 | u8 rec_ts_idx; |
148 | struct net_device *netdev; |
149 | struct pcan_usb *pdev; |
150 | }; |
151 | |
152 | /* |
153 | * send a command |
154 | */ |
155 | static int pcan_usb_send_cmd(struct peak_usb_device *dev, u8 f, u8 n, u8 *p) |
156 | { |
157 | int err; |
158 | int actual_length; |
159 | |
160 | /* usb device unregistered? */ |
161 | if (!(dev->state & PCAN_USB_STATE_CONNECTED)) |
162 | return 0; |
163 | |
164 | dev->cmd_buf[PCAN_USB_CMD_FUNC] = f; |
165 | dev->cmd_buf[PCAN_USB_CMD_NUM] = n; |
166 | |
167 | if (p) |
168 | memcpy(dev->cmd_buf + PCAN_USB_CMD_ARGS, |
169 | p, PCAN_USB_CMD_ARGS_LEN); |
170 | |
171 | err = usb_bulk_msg(usb_dev: dev->udev, |
172 | usb_sndbulkpipe(dev->udev, PCAN_USB_EP_CMDOUT), |
173 | data: dev->cmd_buf, PCAN_USB_CMD_LEN, actual_length: &actual_length, |
174 | PCAN_USB_COMMAND_TIMEOUT); |
175 | if (err) |
176 | netdev_err(dev: dev->netdev, |
177 | format: "sending cmd f=0x%x n=0x%x failure: %d\n", |
178 | f, n, err); |
179 | return err; |
180 | } |
181 | |
182 | /* |
183 | * send a command then wait for its response |
184 | */ |
185 | static int pcan_usb_wait_rsp(struct peak_usb_device *dev, u8 f, u8 n, u8 *p) |
186 | { |
187 | int err; |
188 | int actual_length; |
189 | |
190 | /* usb device unregistered? */ |
191 | if (!(dev->state & PCAN_USB_STATE_CONNECTED)) |
192 | return 0; |
193 | |
194 | /* first, send command */ |
195 | err = pcan_usb_send_cmd(dev, f, n, NULL); |
196 | if (err) |
197 | return err; |
198 | |
199 | err = usb_bulk_msg(usb_dev: dev->udev, |
200 | usb_rcvbulkpipe(dev->udev, PCAN_USB_EP_CMDIN), |
201 | data: dev->cmd_buf, PCAN_USB_CMD_LEN, actual_length: &actual_length, |
202 | PCAN_USB_COMMAND_TIMEOUT); |
203 | if (err) |
204 | netdev_err(dev: dev->netdev, |
205 | format: "waiting rsp f=0x%x n=0x%x failure: %d\n", f, n, err); |
206 | else if (p) |
207 | memcpy(p, dev->cmd_buf + PCAN_USB_CMD_ARGS, |
208 | PCAN_USB_CMD_ARGS_LEN); |
209 | |
210 | return err; |
211 | } |
212 | |
213 | static int pcan_usb_set_sja1000(struct peak_usb_device *dev, u8 mode) |
214 | { |
215 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
216 | [1] = mode, |
217 | }; |
218 | |
219 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_REGISTER, PCAN_USB_SET, |
220 | p: args); |
221 | } |
222 | |
223 | static int pcan_usb_set_bus(struct peak_usb_device *dev, u8 onoff) |
224 | { |
225 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
226 | [0] = !!onoff, |
227 | }; |
228 | |
229 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_SET_BUS, PCAN_USB_BUS_XCVER, |
230 | p: args); |
231 | } |
232 | |
233 | static int pcan_usb_set_silent(struct peak_usb_device *dev, u8 onoff) |
234 | { |
235 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
236 | [0] = !!onoff, |
237 | }; |
238 | |
239 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_SET_BUS, |
240 | PCAN_USB_BUS_SILENT_MODE, p: args); |
241 | } |
242 | |
243 | /* send the cmd to be notified from bus errors */ |
244 | static int pcan_usb_set_err_frame(struct peak_usb_device *dev, u8 err_mask) |
245 | { |
246 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
247 | [0] = err_mask, |
248 | }; |
249 | |
250 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_ERR_FR, PCAN_USB_SET, p: args); |
251 | } |
252 | |
253 | static int pcan_usb_set_ext_vcc(struct peak_usb_device *dev, u8 onoff) |
254 | { |
255 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
256 | [0] = !!onoff, |
257 | }; |
258 | |
259 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_EXT_VCC, PCAN_USB_SET, p: args); |
260 | } |
261 | |
262 | static int pcan_usb_set_led(struct peak_usb_device *dev, u8 onoff) |
263 | { |
264 | u8 args[PCAN_USB_CMD_ARGS_LEN] = { |
265 | [0] = !!onoff, |
266 | }; |
267 | |
268 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_LED, PCAN_USB_SET, p: args); |
269 | } |
270 | |
271 | /* |
272 | * set bittiming value to can |
273 | */ |
274 | static int pcan_usb_set_bittiming(struct peak_usb_device *dev, |
275 | struct can_bittiming *bt) |
276 | { |
277 | u8 args[PCAN_USB_CMD_ARGS_LEN]; |
278 | u8 btr0, btr1; |
279 | |
280 | btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); |
281 | btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | |
282 | (((bt->phase_seg2 - 1) & 0x7) << 4); |
283 | if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) |
284 | btr1 |= 0x80; |
285 | |
286 | netdev_info(dev: dev->netdev, format: "setting BTR0=0x%02x BTR1=0x%02x\n", |
287 | btr0, btr1); |
288 | |
289 | args[0] = btr1; |
290 | args[1] = btr0; |
291 | |
292 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_BITRATE, PCAN_USB_SET, p: args); |
293 | } |
294 | |
295 | /* |
296 | * init/reset can |
297 | */ |
298 | static int pcan_usb_write_mode(struct peak_usb_device *dev, u8 onoff) |
299 | { |
300 | int err; |
301 | |
302 | err = pcan_usb_set_bus(dev, onoff); |
303 | if (err) |
304 | return err; |
305 | |
306 | if (!onoff) { |
307 | err = pcan_usb_set_sja1000(dev, SJA1000_MODE_INIT); |
308 | } else { |
309 | /* the PCAN-USB needs time to init */ |
310 | set_current_state(TASK_INTERRUPTIBLE); |
311 | schedule_timeout(timeout: msecs_to_jiffies(PCAN_USB_STARTUP_TIMEOUT)); |
312 | } |
313 | |
314 | return err; |
315 | } |
316 | |
317 | /* |
318 | * handle end of waiting for the device to reset |
319 | */ |
320 | static void pcan_usb_restart(struct timer_list *t) |
321 | { |
322 | struct pcan_usb *pdev = from_timer(pdev, t, restart_timer); |
323 | struct peak_usb_device *dev = &pdev->dev; |
324 | |
325 | /* notify candev and netdev */ |
326 | peak_usb_restart_complete(dev); |
327 | } |
328 | |
329 | /* |
330 | * handle the submission of the restart urb |
331 | */ |
332 | static void pcan_usb_restart_pending(struct urb *urb) |
333 | { |
334 | struct pcan_usb *pdev = urb->context; |
335 | |
336 | /* the PCAN-USB needs time to restart */ |
337 | mod_timer(timer: &pdev->restart_timer, |
338 | expires: jiffies + msecs_to_jiffies(PCAN_USB_STARTUP_TIMEOUT)); |
339 | |
340 | /* can delete usb resources */ |
341 | peak_usb_async_complete(urb); |
342 | } |
343 | |
344 | /* |
345 | * handle asynchronous restart |
346 | */ |
347 | static int pcan_usb_restart_async(struct peak_usb_device *dev, struct urb *urb, |
348 | u8 *buf) |
349 | { |
350 | struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev); |
351 | |
352 | if (timer_pending(timer: &pdev->restart_timer)) |
353 | return -EBUSY; |
354 | |
355 | /* set bus on */ |
356 | buf[PCAN_USB_CMD_FUNC] = 3; |
357 | buf[PCAN_USB_CMD_NUM] = 2; |
358 | buf[PCAN_USB_CMD_ARGS] = 1; |
359 | |
360 | usb_fill_bulk_urb(urb, dev: dev->udev, |
361 | usb_sndbulkpipe(dev->udev, PCAN_USB_EP_CMDOUT), |
362 | transfer_buffer: buf, PCAN_USB_CMD_LEN, |
363 | complete_fn: pcan_usb_restart_pending, context: pdev); |
364 | |
365 | return usb_submit_urb(urb, GFP_ATOMIC); |
366 | } |
367 | |
368 | /* |
369 | * read serial number from device |
370 | */ |
371 | static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number) |
372 | { |
373 | u8 args[PCAN_USB_CMD_ARGS_LEN]; |
374 | int err; |
375 | |
376 | err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_SN, PCAN_USB_GET, p: args); |
377 | if (err) |
378 | return err; |
379 | *serial_number = le32_to_cpup(p: (__le32 *)args); |
380 | |
381 | return 0; |
382 | } |
383 | |
384 | /* |
385 | * read can channel id from device |
386 | */ |
387 | static int pcan_usb_get_can_channel_id(struct peak_usb_device *dev, u32 *can_ch_id) |
388 | { |
389 | u8 args[PCAN_USB_CMD_ARGS_LEN]; |
390 | int err; |
391 | |
392 | err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_DEVID, PCAN_USB_GET, p: args); |
393 | if (err) |
394 | netdev_err(dev: dev->netdev, format: "getting can channel id failure: %d\n", err); |
395 | |
396 | else |
397 | *can_ch_id = args[0]; |
398 | |
399 | return err; |
400 | } |
401 | |
402 | /* set a new CAN channel id in the flash memory of the device */ |
403 | static int pcan_usb_set_can_channel_id(struct peak_usb_device *dev, u32 can_ch_id) |
404 | { |
405 | u8 args[PCAN_USB_CMD_ARGS_LEN]; |
406 | |
407 | /* this kind of device supports 8-bit values only */ |
408 | if (can_ch_id > U8_MAX) |
409 | return -EINVAL; |
410 | |
411 | /* during the flash process the device disconnects during ~1.25 s.: |
412 | * prohibit access when interface is UP |
413 | */ |
414 | if (dev->netdev->flags & IFF_UP) |
415 | return -EBUSY; |
416 | |
417 | args[0] = can_ch_id; |
418 | return pcan_usb_send_cmd(dev, PCAN_USB_CMD_DEVID, PCAN_USB_SET, p: args); |
419 | } |
420 | |
421 | /* |
422 | * update current time ref with received timestamp |
423 | */ |
424 | static int pcan_usb_update_ts(struct pcan_usb_msg_context *mc) |
425 | { |
426 | if ((mc->ptr + 2) > mc->end) |
427 | return -EINVAL; |
428 | |
429 | mc->ts16 = get_unaligned_le16(p: mc->ptr); |
430 | |
431 | if (mc->rec_idx > 0) |
432 | peak_usb_update_ts_now(time_ref: &mc->pdev->time_ref, ts_now: mc->ts16); |
433 | else |
434 | peak_usb_set_ts_now(time_ref: &mc->pdev->time_ref, ts_now: mc->ts16); |
435 | |
436 | return 0; |
437 | } |
438 | |
439 | /* |
440 | * decode received timestamp |
441 | */ |
442 | static int pcan_usb_decode_ts(struct pcan_usb_msg_context *mc, u8 first_packet) |
443 | { |
444 | /* only 1st packet supplies a word timestamp */ |
445 | if (first_packet) { |
446 | if ((mc->ptr + 2) > mc->end) |
447 | return -EINVAL; |
448 | |
449 | mc->ts16 = get_unaligned_le16(p: mc->ptr); |
450 | mc->prev_ts8 = mc->ts16 & 0x00ff; |
451 | |
452 | mc->ptr += 2; |
453 | } else { |
454 | u8 ts8; |
455 | |
456 | if ((mc->ptr + 1) > mc->end) |
457 | return -EINVAL; |
458 | |
459 | ts8 = *mc->ptr++; |
460 | |
461 | if (ts8 < mc->prev_ts8) |
462 | mc->ts16 += 0x100; |
463 | |
464 | mc->ts16 &= 0xff00; |
465 | mc->ts16 |= ts8; |
466 | mc->prev_ts8 = ts8; |
467 | } |
468 | |
469 | return 0; |
470 | } |
471 | |
472 | static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, |
473 | u8 status_len) |
474 | { |
475 | struct sk_buff *skb; |
476 | struct can_frame *cf; |
477 | enum can_state new_state = CAN_STATE_ERROR_ACTIVE; |
478 | |
479 | /* ignore this error until 1st ts received */ |
480 | if (n == PCAN_USB_ERROR_QOVR) |
481 | if (!mc->pdev->time_ref.tick_count) |
482 | return 0; |
483 | |
484 | /* allocate an skb to store the error frame */ |
485 | skb = alloc_can_err_skb(dev: mc->netdev, cf: &cf); |
486 | |
487 | if (n & PCAN_USB_ERROR_RXQOVR) { |
488 | /* data overrun interrupt */ |
489 | netdev_dbg(mc->netdev, "data overrun interrupt\n"); |
490 | mc->netdev->stats.rx_over_errors++; |
491 | mc->netdev->stats.rx_errors++; |
492 | if (cf) { |
493 | cf->can_id |= CAN_ERR_CRTL; |
494 | cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW; |
495 | } |
496 | } |
497 | |
498 | if (n & PCAN_USB_ERROR_TXQFULL) |
499 | netdev_dbg(mc->netdev, "device Tx queue full)\n"); |
500 | |
501 | if (n & PCAN_USB_ERROR_BUS_OFF) { |
502 | new_state = CAN_STATE_BUS_OFF; |
503 | } else if (n & PCAN_USB_ERROR_BUS_HEAVY) { |
504 | new_state = ((mc->pdev->bec.txerr >= 128) || |
505 | (mc->pdev->bec.rxerr >= 128)) ? |
506 | CAN_STATE_ERROR_PASSIVE : |
507 | CAN_STATE_ERROR_WARNING; |
508 | } else { |
509 | new_state = CAN_STATE_ERROR_ACTIVE; |
510 | } |
511 | |
512 | /* handle change of state */ |
513 | if (new_state != mc->pdev->dev.can.state) { |
514 | enum can_state tx_state = |
515 | (mc->pdev->bec.txerr >= mc->pdev->bec.rxerr) ? |
516 | new_state : 0; |
517 | enum can_state rx_state = |
518 | (mc->pdev->bec.txerr <= mc->pdev->bec.rxerr) ? |
519 | new_state : 0; |
520 | |
521 | can_change_state(dev: mc->netdev, cf, tx_state, rx_state); |
522 | |
523 | if (new_state == CAN_STATE_BUS_OFF) { |
524 | can_bus_off(dev: mc->netdev); |
525 | } else if (cf && (cf->can_id & CAN_ERR_CRTL)) { |
526 | /* Supply TX/RX error counters in case of |
527 | * controller error. |
528 | */ |
529 | cf->can_id = CAN_ERR_CNT; |
530 | cf->data[6] = mc->pdev->bec.txerr; |
531 | cf->data[7] = mc->pdev->bec.rxerr; |
532 | } |
533 | } |
534 | |
535 | if (!skb) |
536 | return -ENOMEM; |
537 | |
538 | if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { |
539 | struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); |
540 | |
541 | peak_usb_get_ts_time(time_ref: &mc->pdev->time_ref, ts: mc->ts16, |
542 | tv: &hwts->hwtstamp); |
543 | } |
544 | |
545 | netif_rx(skb); |
546 | |
547 | return 0; |
548 | } |
549 | |
550 | /* decode bus event usb packet: first byte contains rxerr while 2nd one contains |
551 | * txerr. |
552 | */ |
553 | static int pcan_usb_handle_bus_evt(struct pcan_usb_msg_context *mc, u8 ir) |
554 | { |
555 | struct pcan_usb *pdev = mc->pdev; |
556 | |
557 | /* according to the content of the packet */ |
558 | switch (ir) { |
559 | case PCAN_USB_ERR_CNT_DEC: |
560 | case PCAN_USB_ERR_CNT_INC: |
561 | |
562 | /* save rx/tx error counters from in the device context */ |
563 | pdev->bec.rxerr = mc->ptr[1]; |
564 | pdev->bec.txerr = mc->ptr[2]; |
565 | break; |
566 | |
567 | default: |
568 | /* reserved */ |
569 | break; |
570 | } |
571 | |
572 | return 0; |
573 | } |
574 | |
575 | /* |
576 | * decode non-data usb message |
577 | */ |
578 | static int pcan_usb_decode_status(struct pcan_usb_msg_context *mc, |
579 | u8 status_len) |
580 | { |
581 | u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC; |
582 | u8 f, n; |
583 | int err; |
584 | |
585 | /* check whether function and number can be read */ |
586 | if ((mc->ptr + 2) > mc->end) |
587 | return -EINVAL; |
588 | |
589 | f = mc->ptr[PCAN_USB_CMD_FUNC]; |
590 | n = mc->ptr[PCAN_USB_CMD_NUM]; |
591 | mc->ptr += PCAN_USB_CMD_ARGS; |
592 | |
593 | if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { |
594 | int err = pcan_usb_decode_ts(mc, first_packet: !mc->rec_ts_idx); |
595 | |
596 | if (err) |
597 | return err; |
598 | |
599 | /* Next packet in the buffer will have a timestamp on a single |
600 | * byte |
601 | */ |
602 | mc->rec_ts_idx++; |
603 | } |
604 | |
605 | switch (f) { |
606 | case PCAN_USB_REC_ERROR: |
607 | err = pcan_usb_decode_error(mc, n, status_len); |
608 | if (err) |
609 | return err; |
610 | break; |
611 | |
612 | case PCAN_USB_REC_ANALOG: |
613 | /* analog values (ignored) */ |
614 | rec_len = 2; |
615 | break; |
616 | |
617 | case PCAN_USB_REC_BUSLOAD: |
618 | /* bus load (ignored) */ |
619 | rec_len = 1; |
620 | break; |
621 | |
622 | case PCAN_USB_REC_TS: |
623 | /* only timestamp */ |
624 | if (pcan_usb_update_ts(mc)) |
625 | return -EINVAL; |
626 | break; |
627 | |
628 | case PCAN_USB_REC_BUSEVT: |
629 | /* bus event notifications (get rxerr/txerr) */ |
630 | err = pcan_usb_handle_bus_evt(mc, ir: n); |
631 | if (err) |
632 | return err; |
633 | break; |
634 | default: |
635 | netdev_err(dev: mc->netdev, format: "unexpected function %u\n", f); |
636 | break; |
637 | } |
638 | |
639 | if ((mc->ptr + rec_len) > mc->end) |
640 | return -EINVAL; |
641 | |
642 | mc->ptr += rec_len; |
643 | |
644 | return 0; |
645 | } |
646 | |
647 | /* |
648 | * decode data usb message |
649 | */ |
650 | static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) |
651 | { |
652 | u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC; |
653 | struct sk_buff *skb; |
654 | struct can_frame *cf; |
655 | struct skb_shared_hwtstamps *hwts; |
656 | u32 can_id_flags; |
657 | |
658 | skb = alloc_can_skb(dev: mc->netdev, cf: &cf); |
659 | if (!skb) |
660 | return -ENOMEM; |
661 | |
662 | if (status_len & PCAN_USB_STATUSLEN_EXT_ID) { |
663 | if ((mc->ptr + 4) > mc->end) |
664 | goto decode_failed; |
665 | |
666 | can_id_flags = get_unaligned_le32(p: mc->ptr); |
667 | cf->can_id = can_id_flags >> 3 | CAN_EFF_FLAG; |
668 | mc->ptr += 4; |
669 | } else { |
670 | if ((mc->ptr + 2) > mc->end) |
671 | goto decode_failed; |
672 | |
673 | can_id_flags = get_unaligned_le16(p: mc->ptr); |
674 | cf->can_id = can_id_flags >> 5; |
675 | mc->ptr += 2; |
676 | } |
677 | |
678 | can_frame_set_cc_len(cf, dlc: rec_len, ctrlmode: mc->pdev->dev.can.ctrlmode); |
679 | |
680 | /* Only first packet timestamp is a word */ |
681 | if (pcan_usb_decode_ts(mc, first_packet: !mc->rec_ts_idx)) |
682 | goto decode_failed; |
683 | |
684 | /* Next packet in the buffer will have a timestamp on a single byte */ |
685 | mc->rec_ts_idx++; |
686 | |
687 | /* read data */ |
688 | memset(cf->data, 0x0, sizeof(cf->data)); |
689 | if (status_len & PCAN_USB_STATUSLEN_RTR) { |
690 | cf->can_id |= CAN_RTR_FLAG; |
691 | } else { |
692 | if ((mc->ptr + rec_len) > mc->end) |
693 | goto decode_failed; |
694 | |
695 | memcpy(cf->data, mc->ptr, cf->len); |
696 | mc->ptr += rec_len; |
697 | |
698 | /* Ignore next byte (client private id) if SRR bit is set */ |
699 | if (can_id_flags & PCAN_USB_TX_SRR) |
700 | mc->ptr++; |
701 | |
702 | /* update statistics */ |
703 | mc->netdev->stats.rx_bytes += cf->len; |
704 | } |
705 | mc->netdev->stats.rx_packets++; |
706 | |
707 | /* convert timestamp into kernel time */ |
708 | hwts = skb_hwtstamps(skb); |
709 | peak_usb_get_ts_time(time_ref: &mc->pdev->time_ref, ts: mc->ts16, tv: &hwts->hwtstamp); |
710 | |
711 | /* push the skb */ |
712 | netif_rx(skb); |
713 | |
714 | return 0; |
715 | |
716 | decode_failed: |
717 | dev_kfree_skb(skb); |
718 | return -EINVAL; |
719 | } |
720 | |
721 | /* |
722 | * process incoming message |
723 | */ |
724 | static int pcan_usb_decode_msg(struct peak_usb_device *dev, u8 *ibuf, u32 lbuf) |
725 | { |
726 | struct pcan_usb_msg_context mc = { |
727 | .rec_cnt = ibuf[1], |
728 | .ptr = ibuf + PCAN_USB_MSG_HEADER_LEN, |
729 | .end = ibuf + lbuf, |
730 | .netdev = dev->netdev, |
731 | .pdev = container_of(dev, struct pcan_usb, dev), |
732 | }; |
733 | int err; |
734 | |
735 | for (err = 0; mc.rec_idx < mc.rec_cnt && !err; mc.rec_idx++) { |
736 | u8 sl = *mc.ptr++; |
737 | |
738 | /* handle status and error frames here */ |
739 | if (sl & PCAN_USB_STATUSLEN_INTERNAL) { |
740 | err = pcan_usb_decode_status(mc: &mc, status_len: sl); |
741 | /* handle normal can frames here */ |
742 | } else { |
743 | err = pcan_usb_decode_data(mc: &mc, status_len: sl); |
744 | } |
745 | } |
746 | |
747 | return err; |
748 | } |
749 | |
750 | /* |
751 | * process any incoming buffer |
752 | */ |
753 | static int pcan_usb_decode_buf(struct peak_usb_device *dev, struct urb *urb) |
754 | { |
755 | int err = 0; |
756 | |
757 | if (urb->actual_length > PCAN_USB_MSG_HEADER_LEN) { |
758 | err = pcan_usb_decode_msg(dev, ibuf: urb->transfer_buffer, |
759 | lbuf: urb->actual_length); |
760 | |
761 | } else if (urb->actual_length > 0) { |
762 | netdev_err(dev: dev->netdev, format: "usb message length error (%u)\n", |
763 | urb->actual_length); |
764 | err = -EINVAL; |
765 | } |
766 | |
767 | return err; |
768 | } |
769 | |
770 | /* |
771 | * process outgoing packet |
772 | */ |
773 | static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb, |
774 | u8 *obuf, size_t *size) |
775 | { |
776 | struct net_device *netdev = dev->netdev; |
777 | struct net_device_stats *stats = &netdev->stats; |
778 | struct can_frame *cf = (struct can_frame *)skb->data; |
779 | u32 can_id_flags = cf->can_id & CAN_ERR_MASK; |
780 | u8 *pc; |
781 | |
782 | obuf[0] = PCAN_USB_MSG_TX_CAN; |
783 | obuf[1] = 1; /* only one CAN frame is stored in the packet */ |
784 | |
785 | pc = obuf + PCAN_USB_MSG_HEADER_LEN; |
786 | |
787 | /* status/len byte */ |
788 | *pc = can_get_cc_dlc(cf, ctrlmode: dev->can.ctrlmode); |
789 | |
790 | if (cf->can_id & CAN_RTR_FLAG) |
791 | *pc |= PCAN_USB_STATUSLEN_RTR; |
792 | |
793 | /* can id */ |
794 | if (cf->can_id & CAN_EFF_FLAG) { |
795 | *pc |= PCAN_USB_STATUSLEN_EXT_ID; |
796 | pc++; |
797 | |
798 | can_id_flags <<= 3; |
799 | |
800 | if (dev->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
801 | can_id_flags |= PCAN_USB_TX_SRR; |
802 | |
803 | if (dev->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) |
804 | can_id_flags |= PCAN_USB_TX_AT; |
805 | |
806 | put_unaligned_le32(val: can_id_flags, p: pc); |
807 | pc += 4; |
808 | } else { |
809 | pc++; |
810 | |
811 | can_id_flags <<= 5; |
812 | |
813 | if (dev->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
814 | can_id_flags |= PCAN_USB_TX_SRR; |
815 | |
816 | if (dev->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT) |
817 | can_id_flags |= PCAN_USB_TX_AT; |
818 | |
819 | put_unaligned_le16(val: can_id_flags, p: pc); |
820 | pc += 2; |
821 | } |
822 | |
823 | /* can data */ |
824 | if (!(cf->can_id & CAN_RTR_FLAG)) { |
825 | memcpy(pc, cf->data, cf->len); |
826 | pc += cf->len; |
827 | } |
828 | |
829 | /* SRR bit needs a writer id (useless here) */ |
830 | if (can_id_flags & PCAN_USB_TX_SRR) |
831 | *pc++ = 0x80; |
832 | |
833 | obuf[(*size)-1] = (u8)(stats->tx_packets & 0xff); |
834 | |
835 | return 0; |
836 | } |
837 | |
838 | /* socket callback used to copy berr counters values received through USB */ |
839 | static int pcan_usb_get_berr_counter(const struct net_device *netdev, |
840 | struct can_berr_counter *bec) |
841 | { |
842 | struct peak_usb_device *dev = netdev_priv(dev: netdev); |
843 | struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev); |
844 | |
845 | *bec = pdev->bec; |
846 | |
847 | /* must return 0 */ |
848 | return 0; |
849 | } |
850 | |
851 | /* |
852 | * start interface |
853 | */ |
854 | static int pcan_usb_start(struct peak_usb_device *dev) |
855 | { |
856 | struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev); |
857 | int err; |
858 | |
859 | /* number of bits used in timestamps read from adapter struct */ |
860 | peak_usb_init_time_ref(time_ref: &pdev->time_ref, adapter: &pcan_usb); |
861 | |
862 | pdev->bec.rxerr = 0; |
863 | pdev->bec.txerr = 0; |
864 | |
865 | /* always ask the device for BERR reporting, to be able to switch from |
866 | * WARNING to PASSIVE state |
867 | */ |
868 | err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK); |
869 | if (err) |
870 | netdev_warn(dev: dev->netdev, |
871 | format: "Asking for BERR reporting error %u\n", |
872 | err); |
873 | |
874 | /* if revision greater than 3, can put silent mode on/off */ |
875 | if (dev->device_rev > 3) { |
876 | err = pcan_usb_set_silent(dev, |
877 | onoff: dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY); |
878 | if (err) |
879 | return err; |
880 | } |
881 | |
882 | return pcan_usb_set_ext_vcc(dev, onoff: 0); |
883 | } |
884 | |
885 | static int pcan_usb_init(struct peak_usb_device *dev) |
886 | { |
887 | struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev); |
888 | u32 serial_number; |
889 | int err; |
890 | |
891 | /* initialize a timer needed to wait for hardware restart */ |
892 | timer_setup(&pdev->restart_timer, pcan_usb_restart, 0); |
893 | |
894 | /* |
895 | * explicit use of dev_xxx() instead of netdev_xxx() here: |
896 | * information displayed are related to the device itself, not |
897 | * to the canx netdevice. |
898 | */ |
899 | err = pcan_usb_get_serial(dev, serial_number: &serial_number); |
900 | if (err) { |
901 | dev_err(dev->netdev->dev.parent, |
902 | "unable to read %s serial number (err %d)\n", |
903 | pcan_usb.name, err); |
904 | return err; |
905 | } |
906 | |
907 | dev_info(dev->netdev->dev.parent, |
908 | "PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n", |
909 | pcan_usb.name, dev->device_rev, serial_number, |
910 | pcan_usb.ctrl_count); |
911 | |
912 | /* Since rev 4.1, PCAN-USB is able to make single-shot as well as |
913 | * looped back frames. |
914 | */ |
915 | if (dev->device_rev >= 41) { |
916 | struct can_priv *priv = netdev_priv(dev: dev->netdev); |
917 | |
918 | priv->ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT | |
919 | CAN_CTRLMODE_LOOPBACK; |
920 | } else { |
921 | dev_info(dev->netdev->dev.parent, |
922 | "Firmware update available. Please contact support@peak-system.com\n"); |
923 | } |
924 | |
925 | return 0; |
926 | } |
927 | |
928 | /* |
929 | * probe function for new PCAN-USB usb interface |
930 | */ |
931 | static int pcan_usb_probe(struct usb_interface *intf) |
932 | { |
933 | struct usb_host_interface *if_desc; |
934 | int i; |
935 | |
936 | if_desc = intf->altsetting; |
937 | |
938 | /* check interface endpoint addresses */ |
939 | for (i = 0; i < if_desc->desc.bNumEndpoints; i++) { |
940 | struct usb_endpoint_descriptor *ep = &if_desc->endpoint[i].desc; |
941 | |
942 | switch (ep->bEndpointAddress) { |
943 | case PCAN_USB_EP_CMDOUT: |
944 | case PCAN_USB_EP_CMDIN: |
945 | case PCAN_USB_EP_MSGOUT: |
946 | case PCAN_USB_EP_MSGIN: |
947 | break; |
948 | default: |
949 | return -ENODEV; |
950 | } |
951 | } |
952 | |
953 | return 0; |
954 | } |
955 | |
956 | static int pcan_usb_set_phys_id(struct net_device *netdev, |
957 | enum ethtool_phys_id_state state) |
958 | { |
959 | struct peak_usb_device *dev = netdev_priv(dev: netdev); |
960 | int err = 0; |
961 | |
962 | switch (state) { |
963 | case ETHTOOL_ID_ACTIVE: |
964 | /* call ON/OFF twice a second */ |
965 | return 2; |
966 | |
967 | case ETHTOOL_ID_OFF: |
968 | err = pcan_usb_set_led(dev, onoff: 0); |
969 | break; |
970 | |
971 | case ETHTOOL_ID_ON: |
972 | fallthrough; |
973 | |
974 | case ETHTOOL_ID_INACTIVE: |
975 | /* restore LED default */ |
976 | err = pcan_usb_set_led(dev, onoff: 1); |
977 | break; |
978 | |
979 | default: |
980 | break; |
981 | } |
982 | |
983 | return err; |
984 | } |
985 | |
986 | /* This device only handles 8-bit CAN channel id. */ |
987 | static int pcan_usb_get_eeprom_len(struct net_device *netdev) |
988 | { |
989 | return sizeof(u8); |
990 | } |
991 | |
992 | static const struct ethtool_ops pcan_usb_ethtool_ops = { |
993 | .set_phys_id = pcan_usb_set_phys_id, |
994 | .get_ts_info = pcan_get_ts_info, |
995 | .get_eeprom_len = pcan_usb_get_eeprom_len, |
996 | .get_eeprom = peak_usb_get_eeprom, |
997 | .set_eeprom = peak_usb_set_eeprom, |
998 | }; |
999 | |
1000 | /* |
1001 | * describe the PCAN-USB adapter |
1002 | */ |
1003 | static const struct can_bittiming_const pcan_usb_const = { |
1004 | .name = "pcan_usb", |
1005 | .tseg1_min = 1, |
1006 | .tseg1_max = 16, |
1007 | .tseg2_min = 1, |
1008 | .tseg2_max = 8, |
1009 | .sjw_max = 4, |
1010 | .brp_min = 1, |
1011 | .brp_max = 64, |
1012 | .brp_inc = 1, |
1013 | }; |
1014 | |
1015 | const struct peak_usb_adapter pcan_usb = { |
1016 | .name = "PCAN-USB", |
1017 | .device_id = PCAN_USB_PRODUCT_ID, |
1018 | .ctrl_count = 1, |
1019 | .ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY | |
1020 | CAN_CTRLMODE_CC_LEN8_DLC, |
1021 | .clock = { |
1022 | .freq = PCAN_USB_CRYSTAL_HZ / 2, |
1023 | }, |
1024 | .bittiming_const = &pcan_usb_const, |
1025 | |
1026 | /* size of device private data */ |
1027 | .sizeof_dev_private = sizeof(struct pcan_usb), |
1028 | |
1029 | .ethtool_ops = &pcan_usb_ethtool_ops, |
1030 | |
1031 | /* timestamps usage */ |
1032 | .ts_used_bits = 16, |
1033 | .us_per_ts_scale = PCAN_USB_TS_US_PER_TICK, /* us=(ts*scale) */ |
1034 | .us_per_ts_shift = PCAN_USB_TS_DIV_SHIFTER, /* >> shift */ |
1035 | |
1036 | /* give here messages in/out endpoints */ |
1037 | .ep_msg_in = PCAN_USB_EP_MSGIN, |
1038 | .ep_msg_out = {PCAN_USB_EP_MSGOUT}, |
1039 | |
1040 | /* size of rx/tx usb buffers */ |
1041 | .rx_buffer_size = PCAN_USB_RX_BUFFER_SIZE, |
1042 | .tx_buffer_size = PCAN_USB_TX_BUFFER_SIZE, |
1043 | |
1044 | /* device callbacks */ |
1045 | .intf_probe = pcan_usb_probe, |
1046 | .dev_init = pcan_usb_init, |
1047 | .dev_set_bus = pcan_usb_write_mode, |
1048 | .dev_set_bittiming = pcan_usb_set_bittiming, |
1049 | .dev_get_can_channel_id = pcan_usb_get_can_channel_id, |
1050 | .dev_set_can_channel_id = pcan_usb_set_can_channel_id, |
1051 | .dev_decode_buf = pcan_usb_decode_buf, |
1052 | .dev_encode_msg = pcan_usb_encode_msg, |
1053 | .dev_start = pcan_usb_start, |
1054 | .dev_restart_async = pcan_usb_restart_async, |
1055 | .do_get_berr_counter = pcan_usb_get_berr_counter, |
1056 | }; |
1057 |
Definitions
- pcan_usb
- pcan_usb_msg_context
- pcan_usb_send_cmd
- pcan_usb_wait_rsp
- pcan_usb_set_sja1000
- pcan_usb_set_bus
- pcan_usb_set_silent
- pcan_usb_set_err_frame
- pcan_usb_set_ext_vcc
- pcan_usb_set_led
- pcan_usb_set_bittiming
- pcan_usb_write_mode
- pcan_usb_restart
- pcan_usb_restart_pending
- pcan_usb_restart_async
- pcan_usb_get_serial
- pcan_usb_get_can_channel_id
- pcan_usb_set_can_channel_id
- pcan_usb_update_ts
- pcan_usb_decode_ts
- pcan_usb_decode_error
- pcan_usb_handle_bus_evt
- pcan_usb_decode_status
- pcan_usb_decode_data
- pcan_usb_decode_msg
- pcan_usb_decode_buf
- pcan_usb_encode_msg
- pcan_usb_get_berr_counter
- pcan_usb_start
- pcan_usb_init
- pcan_usb_probe
- pcan_usb_set_phys_id
- pcan_usb_get_eeprom_len
- pcan_usb_ethtool_ops
- pcan_usb_const
Improve your Profiling and Debugging skills
Find out more