diff options
author | Ahmed S. Darwish <ahmed.darwish@valeo.com> | 2015-01-26 00:33:10 -0500 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-01-28 07:39:37 -0500 |
commit | f5d4abea3ce0747ba2b5061dbc99c6f3149c4ba4 (patch) | |
tree | 60fc4dc1a3907e4c779d9a73f37f787e838a33f4 /drivers/net/can/usb | |
parent | 96d7f10634e66b27e23854c774fbcc0a2a654e82 (diff) |
can: kvaser_usb: Add support for the USBcan-II family
CAN to USB interfaces sold by the Swedish manufacturer Kvaser are
divided into two major families: 'Leaf', and 'USBcanII'. From an
Operating System perspective, the firmware of both families behave
in a not too drastically different fashion.
This patch adds support for the USBcanII family of devices to the
current Kvaser Leaf-only driver.
CAN frames sending, receiving, and error handling paths has been
tested using the dual-channel "Kvaser USBcan II HS/LS" dongle. It
should also work nicely with other products in the same category.
List of new devices supported by this driver update:
- Kvaser USBcan II HS/HS
- Kvaser USBcan II HS/LS
- Kvaser USBcan Rugged ("USBcan Rev B")
- Kvaser Memorator HS/HS
- Kvaser Memorator HS/LS
- Scania VCI2 (if you have the Kvaser logo on top)
Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com>
Acked-by: Andri Yngvason <andri.yngvason@marel.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/usb')
-rw-r--r-- | drivers/net/can/usb/Kconfig | 8 | ||||
-rw-r--r-- | drivers/net/can/usb/kvaser_usb.c | 590 |
2 files changed, 474 insertions, 124 deletions
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index a77db919363c..f6f55004fe2b 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig | |||
@@ -25,7 +25,7 @@ config CAN_KVASER_USB | |||
25 | tristate "Kvaser CAN/USB interface" | 25 | tristate "Kvaser CAN/USB interface" |
26 | ---help--- | 26 | ---help--- |
27 | This driver adds support for Kvaser CAN/USB devices like Kvaser | 27 | This driver adds support for Kvaser CAN/USB devices like Kvaser |
28 | Leaf Light. | 28 | Leaf Light and Kvaser USBcan II. |
29 | 29 | ||
30 | The driver provides support for the following devices: | 30 | The driver provides support for the following devices: |
31 | - Kvaser Leaf Light | 31 | - Kvaser Leaf Light |
@@ -46,6 +46,12 @@ config CAN_KVASER_USB | |||
46 | - Kvaser USBcan R | 46 | - Kvaser USBcan R |
47 | - Kvaser Leaf Light v2 | 47 | - Kvaser Leaf Light v2 |
48 | - Kvaser Mini PCI Express HS | 48 | - Kvaser Mini PCI Express HS |
49 | - Kvaser USBcan II HS/HS | ||
50 | - Kvaser USBcan II HS/LS | ||
51 | - Kvaser USBcan Rugged ("USBcan Rev B") | ||
52 | - Kvaser Memorator HS/HS | ||
53 | - Kvaser Memorator HS/LS | ||
54 | - Scania VCI2 (if you have the Kvaser logo on top) | ||
49 | 55 | ||
50 | If unsure, say N. | 56 | If unsure, say N. |
51 | 57 | ||
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index ddc29549aded..17d28d7dd412 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
@@ -6,10 +6,12 @@ | |||
6 | * Parts of this driver are based on the following: | 6 | * Parts of this driver are based on the following: |
7 | * - Kvaser linux leaf driver (version 4.78) | 7 | * - Kvaser linux leaf driver (version 4.78) |
8 | * - CAN driver for esd CAN-USB/2 | 8 | * - CAN driver for esd CAN-USB/2 |
9 | * - Kvaser linux usbcanII driver (version 5.3) | ||
9 | * | 10 | * |
10 | * Copyright (C) 2002-2006 KVASER AB, Sweden. All rights reserved. | 11 | * Copyright (C) 2002-2006 KVASER AB, Sweden. All rights reserved. |
11 | * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh | 12 | * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh |
12 | * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be> | 13 | * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be> |
14 | * Copyright (C) 2015 Valeo A.S. | ||
13 | */ | 15 | */ |
14 | 16 | ||
15 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
@@ -30,8 +32,9 @@ | |||
30 | #define RX_BUFFER_SIZE 3072 | 32 | #define RX_BUFFER_SIZE 3072 |
31 | #define CAN_USB_CLOCK 8000000 | 33 | #define CAN_USB_CLOCK 8000000 |
32 | #define MAX_NET_DEVICES 3 | 34 | #define MAX_NET_DEVICES 3 |
35 | #define MAX_USBCAN_NET_DEVICES 2 | ||
33 | 36 | ||
34 | /* Kvaser USB devices */ | 37 | /* Kvaser Leaf USB devices */ |
35 | #define KVASER_VENDOR_ID 0x0bfd | 38 | #define KVASER_VENDOR_ID 0x0bfd |
36 | #define USB_LEAF_DEVEL_PRODUCT_ID 10 | 39 | #define USB_LEAF_DEVEL_PRODUCT_ID 10 |
37 | #define USB_LEAF_LITE_PRODUCT_ID 11 | 40 | #define USB_LEAF_LITE_PRODUCT_ID 11 |
@@ -56,6 +59,24 @@ | |||
56 | #define USB_LEAF_LITE_V2_PRODUCT_ID 288 | 59 | #define USB_LEAF_LITE_V2_PRODUCT_ID 288 |
57 | #define USB_MINI_PCIE_HS_PRODUCT_ID 289 | 60 | #define USB_MINI_PCIE_HS_PRODUCT_ID 289 |
58 | 61 | ||
62 | static inline bool kvaser_is_leaf(const struct usb_device_id *id) | ||
63 | { | ||
64 | return id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID && | ||
65 | id->idProduct <= USB_MINI_PCIE_HS_PRODUCT_ID; | ||
66 | } | ||
67 | |||
68 | /* Kvaser USBCan-II devices */ | ||
69 | #define USB_USBCAN_REVB_PRODUCT_ID 2 | ||
70 | #define USB_VCI2_PRODUCT_ID 3 | ||
71 | #define USB_USBCAN2_PRODUCT_ID 4 | ||
72 | #define USB_MEMORATOR_PRODUCT_ID 5 | ||
73 | |||
74 | static inline bool kvaser_is_usbcan(const struct usb_device_id *id) | ||
75 | { | ||
76 | return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID && | ||
77 | id->idProduct <= USB_MEMORATOR_PRODUCT_ID; | ||
78 | } | ||
79 | |||
59 | /* USB devices features */ | 80 | /* USB devices features */ |
60 | #define KVASER_HAS_SILENT_MODE BIT(0) | 81 | #define KVASER_HAS_SILENT_MODE BIT(0) |
61 | #define KVASER_HAS_TXRX_ERRORS BIT(1) | 82 | #define KVASER_HAS_TXRX_ERRORS BIT(1) |
@@ -73,7 +94,7 @@ | |||
73 | #define MSG_FLAG_TX_ACK BIT(6) | 94 | #define MSG_FLAG_TX_ACK BIT(6) |
74 | #define MSG_FLAG_TX_REQUEST BIT(7) | 95 | #define MSG_FLAG_TX_REQUEST BIT(7) |
75 | 96 | ||
76 | /* Can states */ | 97 | /* Can states (M16C CxSTRH register) */ |
77 | #define M16C_STATE_BUS_RESET BIT(0) | 98 | #define M16C_STATE_BUS_RESET BIT(0) |
78 | #define M16C_STATE_BUS_ERROR BIT(4) | 99 | #define M16C_STATE_BUS_ERROR BIT(4) |
79 | #define M16C_STATE_BUS_PASSIVE BIT(5) | 100 | #define M16C_STATE_BUS_PASSIVE BIT(5) |
@@ -98,7 +119,11 @@ | |||
98 | #define CMD_START_CHIP_REPLY 27 | 119 | #define CMD_START_CHIP_REPLY 27 |
99 | #define CMD_STOP_CHIP 28 | 120 | #define CMD_STOP_CHIP 28 |
100 | #define CMD_STOP_CHIP_REPLY 29 | 121 | #define CMD_STOP_CHIP_REPLY 29 |
101 | #define CMD_GET_CARD_INFO2 32 | 122 | |
123 | #define CMD_LEAF_GET_CARD_INFO2 32 | ||
124 | #define CMD_USBCAN_RESET_CLOCK 32 | ||
125 | #define CMD_USBCAN_CLOCK_OVERFLOW_EVENT 33 | ||
126 | |||
102 | #define CMD_GET_CARD_INFO 34 | 127 | #define CMD_GET_CARD_INFO 34 |
103 | #define CMD_GET_CARD_INFO_REPLY 35 | 128 | #define CMD_GET_CARD_INFO_REPLY 35 |
104 | #define CMD_GET_SOFTWARE_INFO 38 | 129 | #define CMD_GET_SOFTWARE_INFO 38 |
@@ -108,8 +133,9 @@ | |||
108 | #define CMD_RESET_ERROR_COUNTER 49 | 133 | #define CMD_RESET_ERROR_COUNTER 49 |
109 | #define CMD_TX_ACKNOWLEDGE 50 | 134 | #define CMD_TX_ACKNOWLEDGE 50 |
110 | #define CMD_CAN_ERROR_EVENT 51 | 135 | #define CMD_CAN_ERROR_EVENT 51 |
111 | #define CMD_USB_THROTTLE 77 | 136 | |
112 | #define CMD_LOG_MESSAGE 106 | 137 | #define CMD_LEAF_USB_THROTTLE 77 |
138 | #define CMD_LEAF_LOG_MESSAGE 106 | ||
113 | 139 | ||
114 | /* error factors */ | 140 | /* error factors */ |
115 | #define M16C_EF_ACKE BIT(0) | 141 | #define M16C_EF_ACKE BIT(0) |
@@ -121,6 +147,14 @@ | |||
121 | #define M16C_EF_RCVE BIT(6) | 147 | #define M16C_EF_RCVE BIT(6) |
122 | #define M16C_EF_TRE BIT(7) | 148 | #define M16C_EF_TRE BIT(7) |
123 | 149 | ||
150 | /* Only Leaf-based devices can report M16C error factors, | ||
151 | * thus define our own error status flags for USBCANII | ||
152 | */ | ||
153 | #define USBCAN_ERROR_STATE_NONE 0 | ||
154 | #define USBCAN_ERROR_STATE_TX_ERROR BIT(0) | ||
155 | #define USBCAN_ERROR_STATE_RX_ERROR BIT(1) | ||
156 | #define USBCAN_ERROR_STATE_BUSERROR BIT(2) | ||
157 | |||
124 | /* bittiming parameters */ | 158 | /* bittiming parameters */ |
125 | #define KVASER_USB_TSEG1_MIN 1 | 159 | #define KVASER_USB_TSEG1_MIN 1 |
126 | #define KVASER_USB_TSEG1_MAX 16 | 160 | #define KVASER_USB_TSEG1_MAX 16 |
@@ -137,9 +171,18 @@ | |||
137 | #define KVASER_CTRL_MODE_SELFRECEPTION 3 | 171 | #define KVASER_CTRL_MODE_SELFRECEPTION 3 |
138 | #define KVASER_CTRL_MODE_OFF 4 | 172 | #define KVASER_CTRL_MODE_OFF 4 |
139 | 173 | ||
140 | /* log message */ | 174 | /* Extended CAN identifier flag */ |
141 | #define KVASER_EXTENDED_FRAME BIT(31) | 175 | #define KVASER_EXTENDED_FRAME BIT(31) |
142 | 176 | ||
177 | /* Kvaser USB CAN dongles are divided into two major families: | ||
178 | * - Leaf: Based on Renesas M32C, running firmware labeled as 'filo' | ||
179 | * - UsbcanII: Based on Renesas M16C, running firmware labeled as 'helios' | ||
180 | */ | ||
181 | enum kvaser_usb_family { | ||
182 | KVASER_LEAF, | ||
183 | KVASER_USBCAN, | ||
184 | }; | ||
185 | |||
143 | struct kvaser_msg_simple { | 186 | struct kvaser_msg_simple { |
144 | u8 tid; | 187 | u8 tid; |
145 | u8 channel; | 188 | u8 channel; |
@@ -148,30 +191,55 @@ struct kvaser_msg_simple { | |||
148 | struct kvaser_msg_cardinfo { | 191 | struct kvaser_msg_cardinfo { |
149 | u8 tid; | 192 | u8 tid; |
150 | u8 nchannels; | 193 | u8 nchannels; |
151 | __le32 serial_number; | 194 | union { |
152 | __le32 padding; | 195 | struct { |
196 | __le32 serial_number; | ||
197 | __le32 padding; | ||
198 | } __packed leaf0; | ||
199 | struct { | ||
200 | __le32 serial_number_low; | ||
201 | __le32 serial_number_high; | ||
202 | } __packed usbcan0; | ||
203 | } __packed; | ||
153 | __le32 clock_resolution; | 204 | __le32 clock_resolution; |
154 | __le32 mfgdate; | 205 | __le32 mfgdate; |
155 | u8 ean[8]; | 206 | u8 ean[8]; |
156 | u8 hw_revision; | 207 | u8 hw_revision; |
157 | u8 usb_hs_mode; | 208 | union { |
158 | __le16 padding2; | 209 | struct { |
210 | u8 usb_hs_mode; | ||
211 | } __packed leaf1; | ||
212 | struct { | ||
213 | u8 padding; | ||
214 | } __packed usbcan1; | ||
215 | } __packed; | ||
216 | __le16 padding; | ||
159 | } __packed; | 217 | } __packed; |
160 | 218 | ||
161 | struct kvaser_msg_cardinfo2 { | 219 | struct kvaser_msg_cardinfo2 { |
162 | u8 tid; | 220 | u8 tid; |
163 | u8 channel; | 221 | u8 reserved; |
164 | u8 pcb_id[24]; | 222 | u8 pcb_id[24]; |
165 | __le32 oem_unlock_code; | 223 | __le32 oem_unlock_code; |
166 | } __packed; | 224 | } __packed; |
167 | 225 | ||
168 | struct kvaser_msg_softinfo { | 226 | struct leaf_msg_softinfo { |
169 | u8 tid; | 227 | u8 tid; |
170 | u8 channel; | 228 | u8 padding0; |
171 | __le32 sw_options; | 229 | __le32 sw_options; |
172 | __le32 fw_version; | 230 | __le32 fw_version; |
173 | __le16 max_outstanding_tx; | 231 | __le16 max_outstanding_tx; |
174 | __le16 padding[9]; | 232 | __le16 padding1[9]; |
233 | } __packed; | ||
234 | |||
235 | struct usbcan_msg_softinfo { | ||
236 | u8 tid; | ||
237 | u8 fw_name[5]; | ||
238 | __le16 max_outstanding_tx; | ||
239 | u8 padding[6]; | ||
240 | __le32 fw_version; | ||
241 | __le16 checksum; | ||
242 | __le16 sw_options; | ||
175 | } __packed; | 243 | } __packed; |
176 | 244 | ||
177 | struct kvaser_msg_busparams { | 245 | struct kvaser_msg_busparams { |
@@ -188,36 +256,86 @@ struct kvaser_msg_tx_can { | |||
188 | u8 channel; | 256 | u8 channel; |
189 | u8 tid; | 257 | u8 tid; |
190 | u8 msg[14]; | 258 | u8 msg[14]; |
191 | u8 padding; | 259 | union { |
192 | u8 flags; | 260 | struct { |
261 | u8 padding; | ||
262 | u8 flags; | ||
263 | } __packed leaf; | ||
264 | struct { | ||
265 | u8 flags; | ||
266 | u8 padding; | ||
267 | } __packed usbcan; | ||
268 | } __packed; | ||
269 | } __packed; | ||
270 | |||
271 | struct kvaser_msg_rx_can_header { | ||
272 | u8 channel; | ||
273 | u8 flag; | ||
193 | } __packed; | 274 | } __packed; |
194 | 275 | ||
195 | struct kvaser_msg_rx_can { | 276 | struct leaf_msg_rx_can { |
196 | u8 channel; | 277 | u8 channel; |
197 | u8 flag; | 278 | u8 flag; |
279 | |||
198 | __le16 time[3]; | 280 | __le16 time[3]; |
199 | u8 msg[14]; | 281 | u8 msg[14]; |
200 | } __packed; | 282 | } __packed; |
201 | 283 | ||
202 | struct kvaser_msg_chip_state_event { | 284 | struct usbcan_msg_rx_can { |
285 | u8 channel; | ||
286 | u8 flag; | ||
287 | |||
288 | u8 msg[14]; | ||
289 | __le16 time; | ||
290 | } __packed; | ||
291 | |||
292 | struct leaf_msg_chip_state_event { | ||
203 | u8 tid; | 293 | u8 tid; |
204 | u8 channel; | 294 | u8 channel; |
295 | |||
205 | __le16 time[3]; | 296 | __le16 time[3]; |
206 | u8 tx_errors_count; | 297 | u8 tx_errors_count; |
207 | u8 rx_errors_count; | 298 | u8 rx_errors_count; |
299 | |||
300 | u8 status; | ||
301 | u8 padding[3]; | ||
302 | } __packed; | ||
303 | |||
304 | struct usbcan_msg_chip_state_event { | ||
305 | u8 tid; | ||
306 | u8 channel; | ||
307 | |||
308 | u8 tx_errors_count; | ||
309 | u8 rx_errors_count; | ||
310 | __le16 time; | ||
311 | |||
208 | u8 status; | 312 | u8 status; |
209 | u8 padding[3]; | 313 | u8 padding[3]; |
210 | } __packed; | 314 | } __packed; |
211 | 315 | ||
212 | struct kvaser_msg_tx_acknowledge { | 316 | struct kvaser_msg_tx_acknowledge_header { |
213 | u8 channel; | 317 | u8 channel; |
214 | u8 tid; | 318 | u8 tid; |
319 | } __packed; | ||
320 | |||
321 | struct leaf_msg_tx_acknowledge { | ||
322 | u8 channel; | ||
323 | u8 tid; | ||
324 | |||
215 | __le16 time[3]; | 325 | __le16 time[3]; |
216 | u8 flags; | 326 | u8 flags; |
217 | u8 time_offset; | 327 | u8 time_offset; |
218 | } __packed; | 328 | } __packed; |
219 | 329 | ||
220 | struct kvaser_msg_error_event { | 330 | struct usbcan_msg_tx_acknowledge { |
331 | u8 channel; | ||
332 | u8 tid; | ||
333 | |||
334 | __le16 time; | ||
335 | __le16 padding; | ||
336 | } __packed; | ||
337 | |||
338 | struct leaf_msg_error_event { | ||
221 | u8 tid; | 339 | u8 tid; |
222 | u8 flags; | 340 | u8 flags; |
223 | __le16 time[3]; | 341 | __le16 time[3]; |
@@ -229,6 +347,18 @@ struct kvaser_msg_error_event { | |||
229 | u8 error_factor; | 347 | u8 error_factor; |
230 | } __packed; | 348 | } __packed; |
231 | 349 | ||
350 | struct usbcan_msg_error_event { | ||
351 | u8 tid; | ||
352 | u8 padding; | ||
353 | u8 tx_errors_count_ch0; | ||
354 | u8 rx_errors_count_ch0; | ||
355 | u8 tx_errors_count_ch1; | ||
356 | u8 rx_errors_count_ch1; | ||
357 | u8 status_ch0; | ||
358 | u8 status_ch1; | ||
359 | __le16 time; | ||
360 | } __packed; | ||
361 | |||
232 | struct kvaser_msg_ctrl_mode { | 362 | struct kvaser_msg_ctrl_mode { |
233 | u8 tid; | 363 | u8 tid; |
234 | u8 channel; | 364 | u8 channel; |
@@ -243,7 +373,7 @@ struct kvaser_msg_flush_queue { | |||
243 | u8 padding[3]; | 373 | u8 padding[3]; |
244 | } __packed; | 374 | } __packed; |
245 | 375 | ||
246 | struct kvaser_msg_log_message { | 376 | struct leaf_msg_log_message { |
247 | u8 channel; | 377 | u8 channel; |
248 | u8 flags; | 378 | u8 flags; |
249 | __le16 time[3]; | 379 | __le16 time[3]; |
@@ -260,21 +390,55 @@ struct kvaser_msg { | |||
260 | struct kvaser_msg_simple simple; | 390 | struct kvaser_msg_simple simple; |
261 | struct kvaser_msg_cardinfo cardinfo; | 391 | struct kvaser_msg_cardinfo cardinfo; |
262 | struct kvaser_msg_cardinfo2 cardinfo2; | 392 | struct kvaser_msg_cardinfo2 cardinfo2; |
263 | struct kvaser_msg_softinfo softinfo; | ||
264 | struct kvaser_msg_busparams busparams; | 393 | struct kvaser_msg_busparams busparams; |
394 | |||
395 | struct kvaser_msg_rx_can_header rx_can_header; | ||
396 | struct kvaser_msg_tx_acknowledge_header tx_acknowledge_header; | ||
397 | |||
398 | union { | ||
399 | struct leaf_msg_softinfo softinfo; | ||
400 | struct leaf_msg_rx_can rx_can; | ||
401 | struct leaf_msg_chip_state_event chip_state_event; | ||
402 | struct leaf_msg_tx_acknowledge tx_acknowledge; | ||
403 | struct leaf_msg_error_event error_event; | ||
404 | struct leaf_msg_log_message log_message; | ||
405 | } __packed leaf; | ||
406 | |||
407 | union { | ||
408 | struct usbcan_msg_softinfo softinfo; | ||
409 | struct usbcan_msg_rx_can rx_can; | ||
410 | struct usbcan_msg_chip_state_event chip_state_event; | ||
411 | struct usbcan_msg_tx_acknowledge tx_acknowledge; | ||
412 | struct usbcan_msg_error_event error_event; | ||
413 | } __packed usbcan; | ||
414 | |||
265 | struct kvaser_msg_tx_can tx_can; | 415 | struct kvaser_msg_tx_can tx_can; |
266 | struct kvaser_msg_rx_can rx_can; | ||
267 | struct kvaser_msg_chip_state_event chip_state_event; | ||
268 | struct kvaser_msg_tx_acknowledge tx_acknowledge; | ||
269 | struct kvaser_msg_error_event error_event; | ||
270 | struct kvaser_msg_ctrl_mode ctrl_mode; | 416 | struct kvaser_msg_ctrl_mode ctrl_mode; |
271 | struct kvaser_msg_flush_queue flush_queue; | 417 | struct kvaser_msg_flush_queue flush_queue; |
272 | struct kvaser_msg_log_message log_message; | ||
273 | } u; | 418 | } u; |
274 | } __packed; | 419 | } __packed; |
275 | 420 | ||
421 | /* Summary of a kvaser error event, for a unified Leaf/Usbcan error | ||
422 | * handling. Some discrepancies between the two families exist: | ||
423 | * | ||
424 | * - USBCAN firmware does not report M16C "error factors" | ||
425 | * - USBCAN controllers has difficulties reporting if the raised error | ||
426 | * event is for ch0 or ch1. They leave such arbitration to the OS | ||
427 | * driver by letting it compare error counters with previous values | ||
428 | * and decide the error event's channel. Thus for USBCAN, the channel | ||
429 | * field is only advisory. | ||
430 | */ | ||
276 | struct kvaser_usb_error_summary { | 431 | struct kvaser_usb_error_summary { |
277 | u8 channel, status, txerr, rxerr, error_factor; | 432 | u8 channel, status, txerr, rxerr; |
433 | union { | ||
434 | struct { | ||
435 | u8 error_factor; | ||
436 | } leaf; | ||
437 | struct { | ||
438 | u8 other_ch_status; | ||
439 | u8 error_state; | ||
440 | } usbcan; | ||
441 | }; | ||
278 | }; | 442 | }; |
279 | 443 | ||
280 | struct kvaser_usb_tx_urb_context { | 444 | struct kvaser_usb_tx_urb_context { |
@@ -292,6 +456,7 @@ struct kvaser_usb { | |||
292 | 456 | ||
293 | u32 fw_version; | 457 | u32 fw_version; |
294 | unsigned int nchannels; | 458 | unsigned int nchannels; |
459 | enum kvaser_usb_family family; | ||
295 | 460 | ||
296 | bool rxinitdone; | 461 | bool rxinitdone; |
297 | void *rxbuf[MAX_RX_URBS]; | 462 | void *rxbuf[MAX_RX_URBS]; |
@@ -315,6 +480,7 @@ struct kvaser_usb_net_priv { | |||
315 | }; | 480 | }; |
316 | 481 | ||
317 | static const struct usb_device_id kvaser_usb_table[] = { | 482 | static const struct usb_device_id kvaser_usb_table[] = { |
483 | /* Leaf family IDs */ | ||
318 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) }, | 484 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) }, |
319 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) }, | 485 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) }, |
320 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), | 486 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), |
@@ -364,6 +530,17 @@ static const struct usb_device_id kvaser_usb_table[] = { | |||
364 | .driver_info = KVASER_HAS_TXRX_ERRORS }, | 530 | .driver_info = KVASER_HAS_TXRX_ERRORS }, |
365 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) }, | 531 | { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) }, |
366 | { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, | 532 | { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, |
533 | |||
534 | /* USBCANII family IDs */ | ||
535 | { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), | ||
536 | .driver_info = KVASER_HAS_TXRX_ERRORS }, | ||
537 | { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID), | ||
538 | .driver_info = KVASER_HAS_TXRX_ERRORS }, | ||
539 | { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID), | ||
540 | .driver_info = KVASER_HAS_TXRX_ERRORS }, | ||
541 | { USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID), | ||
542 | .driver_info = KVASER_HAS_TXRX_ERRORS }, | ||
543 | |||
367 | { } | 544 | { } |
368 | }; | 545 | }; |
369 | MODULE_DEVICE_TABLE(usb, kvaser_usb_table); | 546 | MODULE_DEVICE_TABLE(usb, kvaser_usb_table); |
@@ -467,7 +644,14 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev) | |||
467 | if (err) | 644 | if (err) |
468 | return err; | 645 | return err; |
469 | 646 | ||
470 | dev->fw_version = le32_to_cpu(msg.u.softinfo.fw_version); | 647 | switch (dev->family) { |
648 | case KVASER_LEAF: | ||
649 | dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); | ||
650 | break; | ||
651 | case KVASER_USBCAN: | ||
652 | dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); | ||
653 | break; | ||
654 | } | ||
471 | 655 | ||
472 | return 0; | 656 | return 0; |
473 | } | 657 | } |
@@ -486,7 +670,9 @@ static int kvaser_usb_get_card_info(struct kvaser_usb *dev) | |||
486 | return err; | 670 | return err; |
487 | 671 | ||
488 | dev->nchannels = msg.u.cardinfo.nchannels; | 672 | dev->nchannels = msg.u.cardinfo.nchannels; |
489 | if (dev->nchannels > MAX_NET_DEVICES) | 673 | if ((dev->nchannels > MAX_NET_DEVICES) || |
674 | (dev->family == KVASER_USBCAN && | ||
675 | dev->nchannels > MAX_USBCAN_NET_DEVICES)) | ||
490 | return -EINVAL; | 676 | return -EINVAL; |
491 | 677 | ||
492 | return 0; | 678 | return 0; |
@@ -500,8 +686,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, | |||
500 | struct kvaser_usb_net_priv *priv; | 686 | struct kvaser_usb_net_priv *priv; |
501 | struct sk_buff *skb; | 687 | struct sk_buff *skb; |
502 | struct can_frame *cf; | 688 | struct can_frame *cf; |
503 | u8 channel = msg->u.tx_acknowledge.channel; | 689 | u8 channel, tid; |
504 | u8 tid = msg->u.tx_acknowledge.tid; | 690 | |
691 | channel = msg->u.tx_acknowledge_header.channel; | ||
692 | tid = msg->u.tx_acknowledge_header.tid; | ||
505 | 693 | ||
506 | if (channel >= dev->nchannels) { | 694 | if (channel >= dev->nchannels) { |
507 | dev_err(dev->udev->dev.parent, | 695 | dev_err(dev->udev->dev.parent, |
@@ -623,12 +811,12 @@ static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *pri | |||
623 | const struct kvaser_usb_error_summary *es, | 811 | const struct kvaser_usb_error_summary *es, |
624 | struct can_frame *cf) | 812 | struct can_frame *cf) |
625 | { | 813 | { |
626 | struct net_device_stats *stats; | 814 | struct kvaser_usb *dev = priv->dev; |
815 | struct net_device_stats *stats = &priv->netdev->stats; | ||
627 | enum can_state cur_state, new_state, tx_state, rx_state; | 816 | enum can_state cur_state, new_state, tx_state, rx_state; |
628 | 817 | ||
629 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status); | 818 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status); |
630 | 819 | ||
631 | stats = &priv->netdev->stats; | ||
632 | new_state = cur_state = priv->can.state; | 820 | new_state = cur_state = priv->can.state; |
633 | 821 | ||
634 | if (es->status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) | 822 | if (es->status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) |
@@ -662,9 +850,22 @@ static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *pri | |||
662 | priv->can.can_stats.restarts++; | 850 | priv->can.can_stats.restarts++; |
663 | } | 851 | } |
664 | 852 | ||
665 | if (es->error_factor) { | 853 | switch (dev->family) { |
666 | priv->can.can_stats.bus_error++; | 854 | case KVASER_LEAF: |
667 | stats->rx_errors++; | 855 | if (es->leaf.error_factor) { |
856 | priv->can.can_stats.bus_error++; | ||
857 | stats->rx_errors++; | ||
858 | } | ||
859 | break; | ||
860 | case KVASER_USBCAN: | ||
861 | if (es->usbcan.error_state & USBCAN_ERROR_STATE_TX_ERROR) | ||
862 | stats->tx_errors++; | ||
863 | if (es->usbcan.error_state & USBCAN_ERROR_STATE_RX_ERROR) | ||
864 | stats->rx_errors++; | ||
865 | if (es->usbcan.error_state & USBCAN_ERROR_STATE_BUSERROR) { | ||
866 | priv->can.can_stats.bus_error++; | ||
867 | } | ||
868 | break; | ||
668 | } | 869 | } |
669 | 870 | ||
670 | priv->bec.txerr = es->txerr; | 871 | priv->bec.txerr = es->txerr; |
@@ -672,50 +873,21 @@ static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *pri | |||
672 | } | 873 | } |
673 | 874 | ||
674 | static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | 875 | static void kvaser_usb_rx_error(const struct kvaser_usb *dev, |
675 | const struct kvaser_msg *msg) | 876 | const struct kvaser_usb_error_summary *es) |
676 | { | 877 | { |
677 | struct can_frame *cf, tmp_cf = { .can_id = CAN_ERR_FLAG, .can_dlc = CAN_ERR_DLC }; | 878 | struct can_frame *cf, tmp_cf = { .can_id = CAN_ERR_FLAG, .can_dlc = CAN_ERR_DLC }; |
678 | struct sk_buff *skb; | 879 | struct sk_buff *skb; |
679 | struct net_device_stats *stats; | 880 | struct net_device_stats *stats; |
680 | struct kvaser_usb_net_priv *priv; | 881 | struct kvaser_usb_net_priv *priv; |
681 | struct kvaser_usb_error_summary es = { }; | ||
682 | enum can_state old_state, new_state; | 882 | enum can_state old_state, new_state; |
683 | 883 | ||
684 | switch (msg->id) { | 884 | if (es->channel >= dev->nchannels) { |
685 | case CMD_CAN_ERROR_EVENT: | ||
686 | es.channel = msg->u.error_event.channel; | ||
687 | es.status = msg->u.error_event.status; | ||
688 | es.txerr = msg->u.error_event.tx_errors_count; | ||
689 | es.rxerr = msg->u.error_event.rx_errors_count; | ||
690 | es.error_factor = msg->u.error_event.error_factor; | ||
691 | break; | ||
692 | case CMD_LOG_MESSAGE: | ||
693 | es.channel = msg->u.log_message.channel; | ||
694 | es.status = msg->u.log_message.data[0]; | ||
695 | es.txerr = msg->u.log_message.data[2]; | ||
696 | es.rxerr = msg->u.log_message.data[3]; | ||
697 | es.error_factor = msg->u.log_message.data[1]; | ||
698 | break; | ||
699 | case CMD_CHIP_STATE_EVENT: | ||
700 | es.channel = msg->u.chip_state_event.channel; | ||
701 | es.status = msg->u.chip_state_event.status; | ||
702 | es.txerr = msg->u.chip_state_event.tx_errors_count; | ||
703 | es.rxerr = msg->u.chip_state_event.rx_errors_count; | ||
704 | es.error_factor = 0; | ||
705 | break; | ||
706 | default: | ||
707 | dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n", | ||
708 | msg->id); | ||
709 | return; | ||
710 | } | ||
711 | |||
712 | if (es.channel >= dev->nchannels) { | ||
713 | dev_err(dev->udev->dev.parent, | 885 | dev_err(dev->udev->dev.parent, |
714 | "Invalid channel number (%d)\n", es.channel); | 886 | "Invalid channel number (%d)\n", es->channel); |
715 | return; | 887 | return; |
716 | } | 888 | } |
717 | 889 | ||
718 | priv = dev->nets[es.channel]; | 890 | priv = dev->nets[es->channel]; |
719 | stats = &priv->netdev->stats; | 891 | stats = &priv->netdev->stats; |
720 | 892 | ||
721 | /* Update all of the can interface's state and error counters before | 893 | /* Update all of the can interface's state and error counters before |
@@ -729,7 +901,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
729 | * frame ID and data to userspace. Remove stack allocation afterwards. | 901 | * frame ID and data to userspace. Remove stack allocation afterwards. |
730 | */ | 902 | */ |
731 | old_state = priv->can.state; | 903 | old_state = priv->can.state; |
732 | kvaser_usb_rx_error_update_can_state(priv, &es, &tmp_cf); | 904 | kvaser_usb_rx_error_update_can_state(priv, es, &tmp_cf); |
733 | new_state = priv->can.state; | 905 | new_state = priv->can.state; |
734 | 906 | ||
735 | skb = alloc_can_err_skb(priv->netdev, &cf); | 907 | skb = alloc_can_err_skb(priv->netdev, &cf); |
@@ -740,7 +912,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
740 | memcpy(cf, &tmp_cf, sizeof(*cf)); | 912 | memcpy(cf, &tmp_cf, sizeof(*cf)); |
741 | 913 | ||
742 | if (new_state != old_state) { | 914 | if (new_state != old_state) { |
743 | if (es.status & | 915 | if (es->status & |
744 | (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { | 916 | (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { |
745 | if (!priv->can.restart_ms) | 917 | if (!priv->can.restart_ms) |
746 | kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP); | 918 | kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP); |
@@ -755,34 +927,161 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
755 | } | 927 | } |
756 | } | 928 | } |
757 | 929 | ||
758 | if (es.error_factor) { | 930 | switch (dev->family) { |
759 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; | 931 | case KVASER_LEAF: |
760 | 932 | if (es->leaf.error_factor) { | |
761 | if (es.error_factor & M16C_EF_ACKE) | 933 | cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; |
762 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK); | 934 | |
763 | if (es.error_factor & M16C_EF_CRCE) | 935 | if (es->leaf.error_factor & M16C_EF_ACKE) |
764 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | 936 | cf->data[3] |= (CAN_ERR_PROT_LOC_ACK); |
765 | CAN_ERR_PROT_LOC_CRC_DEL); | 937 | if (es->leaf.error_factor & M16C_EF_CRCE) |
766 | if (es.error_factor & M16C_EF_FORME) | 938 | cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | |
767 | cf->data[2] |= CAN_ERR_PROT_FORM; | 939 | CAN_ERR_PROT_LOC_CRC_DEL); |
768 | if (es.error_factor & M16C_EF_STFE) | 940 | if (es->leaf.error_factor & M16C_EF_FORME) |
769 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 941 | cf->data[2] |= CAN_ERR_PROT_FORM; |
770 | if (es.error_factor & M16C_EF_BITE0) | 942 | if (es->leaf.error_factor & M16C_EF_STFE) |
771 | cf->data[2] |= CAN_ERR_PROT_BIT0; | 943 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
772 | if (es.error_factor & M16C_EF_BITE1) | 944 | if (es->leaf.error_factor & M16C_EF_BITE0) |
773 | cf->data[2] |= CAN_ERR_PROT_BIT1; | 945 | cf->data[2] |= CAN_ERR_PROT_BIT0; |
774 | if (es.error_factor & M16C_EF_TRE) | 946 | if (es->leaf.error_factor & M16C_EF_BITE1) |
775 | cf->data[2] |= CAN_ERR_PROT_TX; | 947 | cf->data[2] |= CAN_ERR_PROT_BIT1; |
948 | if (es->leaf.error_factor & M16C_EF_TRE) | ||
949 | cf->data[2] |= CAN_ERR_PROT_TX; | ||
950 | } | ||
951 | break; | ||
952 | case KVASER_USBCAN: | ||
953 | if (es->usbcan.error_state & USBCAN_ERROR_STATE_BUSERROR) { | ||
954 | cf->can_id |= CAN_ERR_BUSERROR; | ||
955 | } | ||
956 | break; | ||
776 | } | 957 | } |
777 | 958 | ||
778 | cf->data[6] = es.txerr; | 959 | cf->data[6] = es->txerr; |
779 | cf->data[7] = es.rxerr; | 960 | cf->data[7] = es->rxerr; |
780 | 961 | ||
781 | stats->rx_packets++; | 962 | stats->rx_packets++; |
782 | stats->rx_bytes += cf->can_dlc; | 963 | stats->rx_bytes += cf->can_dlc; |
783 | netif_rx(skb); | 964 | netif_rx(skb); |
784 | } | 965 | } |
785 | 966 | ||
967 | /* For USBCAN, report error to userspace iff the channels's errors counter | ||
968 | * has changed, or we're the only channel seeing a bus error state. | ||
969 | */ | ||
970 | static void kvaser_usbcan_conditionally_rx_error(const struct kvaser_usb *dev, | ||
971 | struct kvaser_usb_error_summary *es) | ||
972 | { | ||
973 | struct kvaser_usb_net_priv *priv; | ||
974 | int channel; | ||
975 | bool report_error; | ||
976 | |||
977 | channel = es->channel; | ||
978 | if (channel >= dev->nchannels) { | ||
979 | dev_err(dev->udev->dev.parent, | ||
980 | "Invalid channel number (%d)\n", channel); | ||
981 | return; | ||
982 | } | ||
983 | |||
984 | priv = dev->nets[channel]; | ||
985 | report_error = false; | ||
986 | |||
987 | if (es->txerr != priv->bec.txerr) { | ||
988 | es->usbcan.error_state |= USBCAN_ERROR_STATE_TX_ERROR; | ||
989 | report_error = true; | ||
990 | } | ||
991 | if (es->rxerr != priv->bec.rxerr) { | ||
992 | es->usbcan.error_state |= USBCAN_ERROR_STATE_RX_ERROR; | ||
993 | report_error = true; | ||
994 | } | ||
995 | if ((es->status & M16C_STATE_BUS_ERROR) && | ||
996 | !(es->usbcan.other_ch_status & M16C_STATE_BUS_ERROR)) { | ||
997 | es->usbcan.error_state |= USBCAN_ERROR_STATE_BUSERROR; | ||
998 | report_error = true; | ||
999 | } | ||
1000 | |||
1001 | if (report_error) | ||
1002 | kvaser_usb_rx_error(dev, es); | ||
1003 | } | ||
1004 | |||
1005 | static void kvaser_usbcan_rx_error(const struct kvaser_usb *dev, | ||
1006 | const struct kvaser_msg *msg) | ||
1007 | { | ||
1008 | struct kvaser_usb_error_summary es = { }; | ||
1009 | |||
1010 | switch (msg->id) { | ||
1011 | /* Sometimes errors are sent as unsolicited chip state events */ | ||
1012 | case CMD_CHIP_STATE_EVENT: | ||
1013 | es.channel = msg->u.usbcan.chip_state_event.channel; | ||
1014 | es.status = msg->u.usbcan.chip_state_event.status; | ||
1015 | es.txerr = msg->u.usbcan.chip_state_event.tx_errors_count; | ||
1016 | es.rxerr = msg->u.usbcan.chip_state_event.rx_errors_count; | ||
1017 | kvaser_usbcan_conditionally_rx_error(dev, &es); | ||
1018 | break; | ||
1019 | |||
1020 | case CMD_CAN_ERROR_EVENT: | ||
1021 | es.channel = 0; | ||
1022 | es.status = msg->u.usbcan.error_event.status_ch0; | ||
1023 | es.txerr = msg->u.usbcan.error_event.tx_errors_count_ch0; | ||
1024 | es.rxerr = msg->u.usbcan.error_event.rx_errors_count_ch0; | ||
1025 | es.usbcan.other_ch_status = | ||
1026 | msg->u.usbcan.error_event.status_ch1; | ||
1027 | kvaser_usbcan_conditionally_rx_error(dev, &es); | ||
1028 | |||
1029 | /* The USBCAN firmware supports up to 2 channels. | ||
1030 | * Now that ch0 was checked, check if ch1 has any errors. | ||
1031 | */ | ||
1032 | if (dev->nchannels == MAX_USBCAN_NET_DEVICES) { | ||
1033 | es.channel = 1; | ||
1034 | es.status = msg->u.usbcan.error_event.status_ch1; | ||
1035 | es.txerr = msg->u.usbcan.error_event.tx_errors_count_ch1; | ||
1036 | es.rxerr = msg->u.usbcan.error_event.rx_errors_count_ch1; | ||
1037 | es.usbcan.other_ch_status = | ||
1038 | msg->u.usbcan.error_event.status_ch0; | ||
1039 | kvaser_usbcan_conditionally_rx_error(dev, &es); | ||
1040 | } | ||
1041 | break; | ||
1042 | |||
1043 | default: | ||
1044 | dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n", | ||
1045 | msg->id); | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | static void kvaser_leaf_rx_error(const struct kvaser_usb *dev, | ||
1050 | const struct kvaser_msg *msg) | ||
1051 | { | ||
1052 | struct kvaser_usb_error_summary es = { }; | ||
1053 | |||
1054 | switch (msg->id) { | ||
1055 | case CMD_CAN_ERROR_EVENT: | ||
1056 | es.channel = msg->u.leaf.error_event.channel; | ||
1057 | es.status = msg->u.leaf.error_event.status; | ||
1058 | es.txerr = msg->u.leaf.error_event.tx_errors_count; | ||
1059 | es.rxerr = msg->u.leaf.error_event.rx_errors_count; | ||
1060 | es.leaf.error_factor = msg->u.leaf.error_event.error_factor; | ||
1061 | break; | ||
1062 | case CMD_LEAF_LOG_MESSAGE: | ||
1063 | es.channel = msg->u.leaf.log_message.channel; | ||
1064 | es.status = msg->u.leaf.log_message.data[0]; | ||
1065 | es.txerr = msg->u.leaf.log_message.data[2]; | ||
1066 | es.rxerr = msg->u.leaf.log_message.data[3]; | ||
1067 | es.leaf.error_factor = msg->u.leaf.log_message.data[1]; | ||
1068 | break; | ||
1069 | case CMD_CHIP_STATE_EVENT: | ||
1070 | es.channel = msg->u.leaf.chip_state_event.channel; | ||
1071 | es.status = msg->u.leaf.chip_state_event.status; | ||
1072 | es.txerr = msg->u.leaf.chip_state_event.tx_errors_count; | ||
1073 | es.rxerr = msg->u.leaf.chip_state_event.rx_errors_count; | ||
1074 | es.leaf.error_factor = 0; | ||
1075 | break; | ||
1076 | default: | ||
1077 | dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n", | ||
1078 | msg->id); | ||
1079 | return; | ||
1080 | } | ||
1081 | |||
1082 | kvaser_usb_rx_error(dev, &es); | ||
1083 | } | ||
1084 | |||
786 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | 1085 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, |
787 | const struct kvaser_msg *msg) | 1086 | const struct kvaser_msg *msg) |
788 | { | 1087 | { |
@@ -790,16 +1089,16 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | |||
790 | struct sk_buff *skb; | 1089 | struct sk_buff *skb; |
791 | struct net_device_stats *stats = &priv->netdev->stats; | 1090 | struct net_device_stats *stats = &priv->netdev->stats; |
792 | 1091 | ||
793 | if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | | 1092 | if (msg->u.rx_can_header.flag & (MSG_FLAG_ERROR_FRAME | |
794 | MSG_FLAG_NERR)) { | 1093 | MSG_FLAG_NERR)) { |
795 | netdev_err(priv->netdev, "Unknow error (flags: 0x%02x)\n", | 1094 | netdev_err(priv->netdev, "Unknow error (flags: 0x%02x)\n", |
796 | msg->u.rx_can.flag); | 1095 | msg->u.rx_can_header.flag); |
797 | 1096 | ||
798 | stats->rx_errors++; | 1097 | stats->rx_errors++; |
799 | return; | 1098 | return; |
800 | } | 1099 | } |
801 | 1100 | ||
802 | if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) { | 1101 | if (msg->u.rx_can_header.flag & MSG_FLAG_OVERRUN) { |
803 | stats->rx_over_errors++; | 1102 | stats->rx_over_errors++; |
804 | stats->rx_errors++; | 1103 | stats->rx_errors++; |
805 | 1104 | ||
@@ -825,7 +1124,8 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, | |||
825 | struct can_frame *cf; | 1124 | struct can_frame *cf; |
826 | struct sk_buff *skb; | 1125 | struct sk_buff *skb; |
827 | struct net_device_stats *stats; | 1126 | struct net_device_stats *stats; |
828 | u8 channel = msg->u.rx_can.channel; | 1127 | u8 channel = msg->u.rx_can_header.channel; |
1128 | const u8 *rx_msg = NULL; /* GCC */ | ||
829 | 1129 | ||
830 | if (channel >= dev->nchannels) { | 1130 | if (channel >= dev->nchannels) { |
831 | dev_err(dev->udev->dev.parent, | 1131 | dev_err(dev->udev->dev.parent, |
@@ -836,60 +1136,68 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, | |||
836 | priv = dev->nets[channel]; | 1136 | priv = dev->nets[channel]; |
837 | stats = &priv->netdev->stats; | 1137 | stats = &priv->netdev->stats; |
838 | 1138 | ||
839 | if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) && | 1139 | if ((msg->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) && |
840 | (msg->id == CMD_LOG_MESSAGE)) { | 1140 | (dev->family == KVASER_LEAF && msg->id == CMD_LEAF_LOG_MESSAGE)) { |
841 | kvaser_usb_rx_error(dev, msg); | 1141 | kvaser_leaf_rx_error(dev, msg); |
842 | return; | 1142 | return; |
843 | } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME | | 1143 | } else if (msg->u.rx_can_header.flag & (MSG_FLAG_ERROR_FRAME | |
844 | MSG_FLAG_NERR | | 1144 | MSG_FLAG_NERR | |
845 | MSG_FLAG_OVERRUN)) { | 1145 | MSG_FLAG_OVERRUN)) { |
846 | kvaser_usb_rx_can_err(priv, msg); | 1146 | kvaser_usb_rx_can_err(priv, msg); |
847 | return; | 1147 | return; |
848 | } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) { | 1148 | } else if (msg->u.rx_can_header.flag & ~MSG_FLAG_REMOTE_FRAME) { |
849 | netdev_warn(priv->netdev, | 1149 | netdev_warn(priv->netdev, |
850 | "Unhandled frame (flags: 0x%02x)", | 1150 | "Unhandled frame (flags: 0x%02x)", |
851 | msg->u.rx_can.flag); | 1151 | msg->u.rx_can_header.flag); |
852 | return; | 1152 | return; |
853 | } | 1153 | } |
854 | 1154 | ||
1155 | switch (dev->family) { | ||
1156 | case KVASER_LEAF: | ||
1157 | rx_msg = msg->u.leaf.rx_can.msg; | ||
1158 | break; | ||
1159 | case KVASER_USBCAN: | ||
1160 | rx_msg = msg->u.usbcan.rx_can.msg; | ||
1161 | break; | ||
1162 | } | ||
1163 | |||
855 | skb = alloc_can_skb(priv->netdev, &cf); | 1164 | skb = alloc_can_skb(priv->netdev, &cf); |
856 | if (!skb) { | 1165 | if (!skb) { |
857 | stats->tx_dropped++; | 1166 | stats->tx_dropped++; |
858 | return; | 1167 | return; |
859 | } | 1168 | } |
860 | 1169 | ||
861 | if (msg->id == CMD_LOG_MESSAGE) { | 1170 | if (dev->family == KVASER_LEAF && msg->id == CMD_LEAF_LOG_MESSAGE) { |
862 | cf->can_id = le32_to_cpu(msg->u.log_message.id); | 1171 | cf->can_id = le32_to_cpu(msg->u.leaf.log_message.id); |
863 | if (cf->can_id & KVASER_EXTENDED_FRAME) | 1172 | if (cf->can_id & KVASER_EXTENDED_FRAME) |
864 | cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; | 1173 | cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; |
865 | else | 1174 | else |
866 | cf->can_id &= CAN_SFF_MASK; | 1175 | cf->can_id &= CAN_SFF_MASK; |
867 | 1176 | ||
868 | cf->can_dlc = get_can_dlc(msg->u.log_message.dlc); | 1177 | cf->can_dlc = get_can_dlc(msg->u.leaf.log_message.dlc); |
869 | 1178 | ||
870 | if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME) | 1179 | if (msg->u.leaf.log_message.flags & MSG_FLAG_REMOTE_FRAME) |
871 | cf->can_id |= CAN_RTR_FLAG; | 1180 | cf->can_id |= CAN_RTR_FLAG; |
872 | else | 1181 | else |
873 | memcpy(cf->data, &msg->u.log_message.data, | 1182 | memcpy(cf->data, &msg->u.leaf.log_message.data, |
874 | cf->can_dlc); | 1183 | cf->can_dlc); |
875 | } else { | 1184 | } else { |
876 | cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) | | 1185 | cf->can_id = ((rx_msg[0] & 0x1f) << 6) | (rx_msg[1] & 0x3f); |
877 | (msg->u.rx_can.msg[1] & 0x3f); | ||
878 | 1186 | ||
879 | if (msg->id == CMD_RX_EXT_MESSAGE) { | 1187 | if (msg->id == CMD_RX_EXT_MESSAGE) { |
880 | cf->can_id <<= 18; | 1188 | cf->can_id <<= 18; |
881 | cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) | | 1189 | cf->can_id |= ((rx_msg[2] & 0x0f) << 14) | |
882 | ((msg->u.rx_can.msg[3] & 0xff) << 6) | | 1190 | ((rx_msg[3] & 0xff) << 6) | |
883 | (msg->u.rx_can.msg[4] & 0x3f); | 1191 | (rx_msg[4] & 0x3f); |
884 | cf->can_id |= CAN_EFF_FLAG; | 1192 | cf->can_id |= CAN_EFF_FLAG; |
885 | } | 1193 | } |
886 | 1194 | ||
887 | cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]); | 1195 | cf->can_dlc = get_can_dlc(rx_msg[5]); |
888 | 1196 | ||
889 | if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME) | 1197 | if (msg->u.rx_can_header.flag & MSG_FLAG_REMOTE_FRAME) |
890 | cf->can_id |= CAN_RTR_FLAG; | 1198 | cf->can_id |= CAN_RTR_FLAG; |
891 | else | 1199 | else |
892 | memcpy(cf->data, &msg->u.rx_can.msg[6], | 1200 | memcpy(cf->data, &rx_msg[6], |
893 | cf->can_dlc); | 1201 | cf->can_dlc); |
894 | } | 1202 | } |
895 | 1203 | ||
@@ -952,21 +1260,35 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev, | |||
952 | 1260 | ||
953 | case CMD_RX_STD_MESSAGE: | 1261 | case CMD_RX_STD_MESSAGE: |
954 | case CMD_RX_EXT_MESSAGE: | 1262 | case CMD_RX_EXT_MESSAGE: |
955 | case CMD_LOG_MESSAGE: | 1263 | kvaser_usb_rx_can_msg(dev, msg); |
1264 | break; | ||
1265 | |||
1266 | case CMD_LEAF_LOG_MESSAGE: | ||
1267 | if (dev->family != KVASER_LEAF) | ||
1268 | goto warn; | ||
956 | kvaser_usb_rx_can_msg(dev, msg); | 1269 | kvaser_usb_rx_can_msg(dev, msg); |
957 | break; | 1270 | break; |
958 | 1271 | ||
959 | case CMD_CHIP_STATE_EVENT: | 1272 | case CMD_CHIP_STATE_EVENT: |
960 | case CMD_CAN_ERROR_EVENT: | 1273 | case CMD_CAN_ERROR_EVENT: |
961 | kvaser_usb_rx_error(dev, msg); | 1274 | if (dev->family == KVASER_LEAF) |
1275 | kvaser_leaf_rx_error(dev, msg); | ||
1276 | else | ||
1277 | kvaser_usbcan_rx_error(dev, msg); | ||
962 | break; | 1278 | break; |
963 | 1279 | ||
964 | case CMD_TX_ACKNOWLEDGE: | 1280 | case CMD_TX_ACKNOWLEDGE: |
965 | kvaser_usb_tx_acknowledge(dev, msg); | 1281 | kvaser_usb_tx_acknowledge(dev, msg); |
966 | break; | 1282 | break; |
967 | 1283 | ||
1284 | /* Ignored messages */ | ||
1285 | case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: | ||
1286 | if (dev->family != KVASER_USBCAN) | ||
1287 | goto warn; | ||
1288 | break; | ||
1289 | |||
968 | default: | 1290 | default: |
969 | dev_warn(dev->udev->dev.parent, | 1291 | warn: dev_warn(dev->udev->dev.parent, |
970 | "Unhandled message (%d)\n", msg->id); | 1292 | "Unhandled message (%d)\n", msg->id); |
971 | break; | 1293 | break; |
972 | } | 1294 | } |
@@ -1186,7 +1508,7 @@ static void kvaser_usb_unlink_all_urbs(struct kvaser_usb *dev) | |||
1186 | dev->rxbuf[i], | 1508 | dev->rxbuf[i], |
1187 | dev->rxbuf_dma[i]); | 1509 | dev->rxbuf_dma[i]); |
1188 | 1510 | ||
1189 | for (i = 0; i < MAX_NET_DEVICES; i++) { | 1511 | for (i = 0; i < dev->nchannels; i++) { |
1190 | struct kvaser_usb_net_priv *priv = dev->nets[i]; | 1512 | struct kvaser_usb_net_priv *priv = dev->nets[i]; |
1191 | 1513 | ||
1192 | if (priv) | 1514 | if (priv) |
@@ -1294,6 +1616,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1294 | struct kvaser_msg *msg; | 1616 | struct kvaser_msg *msg; |
1295 | int i, err; | 1617 | int i, err; |
1296 | int ret = NETDEV_TX_OK; | 1618 | int ret = NETDEV_TX_OK; |
1619 | u8 *msg_tx_can_flags = NULL; /* GCC */ | ||
1297 | 1620 | ||
1298 | if (can_dropped_invalid_skb(netdev, skb)) | 1621 | if (can_dropped_invalid_skb(netdev, skb)) |
1299 | return NETDEV_TX_OK; | 1622 | return NETDEV_TX_OK; |
@@ -1315,9 +1638,19 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1315 | 1638 | ||
1316 | msg = buf; | 1639 | msg = buf; |
1317 | msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can); | 1640 | msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can); |
1318 | msg->u.tx_can.flags = 0; | ||
1319 | msg->u.tx_can.channel = priv->channel; | 1641 | msg->u.tx_can.channel = priv->channel; |
1320 | 1642 | ||
1643 | switch (dev->family) { | ||
1644 | case KVASER_LEAF: | ||
1645 | msg_tx_can_flags = &msg->u.tx_can.leaf.flags; | ||
1646 | break; | ||
1647 | case KVASER_USBCAN: | ||
1648 | msg_tx_can_flags = &msg->u.tx_can.usbcan.flags; | ||
1649 | break; | ||
1650 | } | ||
1651 | |||
1652 | *msg_tx_can_flags = 0; | ||
1653 | |||
1321 | if (cf->can_id & CAN_EFF_FLAG) { | 1654 | if (cf->can_id & CAN_EFF_FLAG) { |
1322 | msg->id = CMD_TX_EXT_MESSAGE; | 1655 | msg->id = CMD_TX_EXT_MESSAGE; |
1323 | msg->u.tx_can.msg[0] = (cf->can_id >> 24) & 0x1f; | 1656 | msg->u.tx_can.msg[0] = (cf->can_id >> 24) & 0x1f; |
@@ -1335,7 +1668,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1335 | memcpy(&msg->u.tx_can.msg[6], cf->data, cf->can_dlc); | 1668 | memcpy(&msg->u.tx_can.msg[6], cf->data, cf->can_dlc); |
1336 | 1669 | ||
1337 | if (cf->can_id & CAN_RTR_FLAG) | 1670 | if (cf->can_id & CAN_RTR_FLAG) |
1338 | msg->u.tx_can.flags |= MSG_FLAG_REMOTE_FRAME; | 1671 | *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME; |
1339 | 1672 | ||
1340 | for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { | 1673 | for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) { |
1341 | if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { | 1674 | if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) { |
@@ -1604,6 +1937,17 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
1604 | if (!dev) | 1937 | if (!dev) |
1605 | return -ENOMEM; | 1938 | return -ENOMEM; |
1606 | 1939 | ||
1940 | if (kvaser_is_leaf(id)) { | ||
1941 | dev->family = KVASER_LEAF; | ||
1942 | } else if (kvaser_is_usbcan(id)) { | ||
1943 | dev->family = KVASER_USBCAN; | ||
1944 | } else { | ||
1945 | dev_err(&intf->dev, | ||
1946 | "Product ID (%d) does not belong to any known Kvaser USB family", | ||
1947 | id->idProduct); | ||
1948 | return -ENODEV; | ||
1949 | } | ||
1950 | |||
1607 | err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out); | 1951 | err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out); |
1608 | if (err) { | 1952 | if (err) { |
1609 | dev_err(&intf->dev, "Cannot get usb endpoint(s)"); | 1953 | dev_err(&intf->dev, "Cannot get usb endpoint(s)"); |