hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/can/usb/peak_usb/pcan_usb.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * CAN driver for PEAK System PCAN-USB adapter
34 * Derived from the PCAN project file driver/src/pcan_usb.c
....@@ -6,15 +7,6 @@
67 * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
78 *
89 * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
9
- *
10
- * This program is free software; you can redistribute it and/or modify it
11
- * under the terms of the GNU General Public License as published
12
- * by the Free Software Foundation; version 2 of the License.
13
- *
14
- * This program is distributed in the hope that it will be useful, but
15
- * WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
- * General Public License for more details.
1810 */
1911 #include <linux/netdevice.h>
2012 #include <linux/usb.h>
....@@ -41,6 +33,23 @@
4133 #define PCAN_USB_CMD_ARGS_LEN 14
4234 #define PCAN_USB_CMD_LEN (PCAN_USB_CMD_ARGS + \
4335 PCAN_USB_CMD_ARGS_LEN)
36
+
37
+/* PCAN-USB commands */
38
+#define PCAN_USB_CMD_BITRATE 1
39
+#define PCAN_USB_CMD_SET_BUS 3
40
+#define PCAN_USB_CMD_DEVID 4
41
+#define PCAN_USB_CMD_SN 6
42
+#define PCAN_USB_CMD_REGISTER 9
43
+#define PCAN_USB_CMD_EXT_VCC 10
44
+#define PCAN_USB_CMD_ERR_FR 11
45
+
46
+/* PCAN_USB_CMD_SET_BUS number arg */
47
+#define PCAN_USB_BUS_XCVER 2
48
+#define PCAN_USB_BUS_SILENT_MODE 3
49
+
50
+/* PCAN_USB_CMD_xxx functions */
51
+#define PCAN_USB_GET 1
52
+#define PCAN_USB_SET 2
4453
4554 /* PCAN-USB command timeout (ms.) */
4655 #define PCAN_USB_COMMAND_TIMEOUT 1000
....@@ -74,6 +83,10 @@
7483 #define PCAN_USB_ERROR_QOVR 0x40
7584 #define PCAN_USB_ERROR_TXQFULL 0x80
7685
86
+#define PCAN_USB_ERROR_BUS (PCAN_USB_ERROR_BUS_LIGHT | \
87
+ PCAN_USB_ERROR_BUS_HEAVY | \
88
+ PCAN_USB_ERROR_BUS_OFF)
89
+
7790 /* SJA1000 modes */
7891 #define SJA1000_MODE_NORMAL 0x00
7992 #define SJA1000_MODE_INIT 0x01
....@@ -93,11 +106,26 @@
93106 #define PCAN_USB_REC_TS 4
94107 #define PCAN_USB_REC_BUSEVT 5
95108
109
+/* CAN bus events notifications selection mask */
110
+#define PCAN_USB_ERR_RXERR 0x02 /* ask for rxerr counter */
111
+#define PCAN_USB_ERR_TXERR 0x04 /* ask for txerr counter */
112
+
113
+/* This mask generates an usb packet each time the state of the bus changes.
114
+ * In other words, its interest is to know which side among rx and tx is
115
+ * responsible of the change of the bus state.
116
+ */
117
+#define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR)
118
+
119
+/* identify bus event packets with rx/tx error counters */
120
+#define PCAN_USB_ERR_CNT_DEC 0x00 /* counters are decreasing */
121
+#define PCAN_USB_ERR_CNT_INC 0x80 /* counters are increasing */
122
+
96123 /* private to PCAN-USB adapter */
97124 struct pcan_usb {
98125 struct peak_usb_device dev;
99126 struct peak_time_ref time_ref;
100127 struct timer_list restart_timer;
128
+ struct can_berr_counter bec;
101129 };
102130
103131 /* incoming message context for decoding */
....@@ -180,7 +208,8 @@
180208 [1] = mode,
181209 };
182210
183
- return pcan_usb_send_cmd(dev, 9, 2, args);
211
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_REGISTER, PCAN_USB_SET,
212
+ args);
184213 }
185214
186215 static int pcan_usb_set_bus(struct peak_usb_device *dev, u8 onoff)
....@@ -189,7 +218,8 @@
189218 [0] = !!onoff,
190219 };
191220
192
- return pcan_usb_send_cmd(dev, 3, 2, args);
221
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_SET_BUS, PCAN_USB_BUS_XCVER,
222
+ args);
193223 }
194224
195225 static int pcan_usb_set_silent(struct peak_usb_device *dev, u8 onoff)
....@@ -198,7 +228,18 @@
198228 [0] = !!onoff,
199229 };
200230
201
- return pcan_usb_send_cmd(dev, 3, 3, args);
231
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_SET_BUS,
232
+ PCAN_USB_BUS_SILENT_MODE, args);
233
+}
234
+
235
+/* send the cmd to be notified from bus errors */
236
+static int pcan_usb_set_err_frame(struct peak_usb_device *dev, u8 err_mask)
237
+{
238
+ u8 args[PCAN_USB_CMD_ARGS_LEN] = {
239
+ [0] = err_mask,
240
+ };
241
+
242
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_ERR_FR, PCAN_USB_SET, args);
202243 }
203244
204245 static int pcan_usb_set_ext_vcc(struct peak_usb_device *dev, u8 onoff)
....@@ -207,7 +248,7 @@
207248 [0] = !!onoff,
208249 };
209250
210
- return pcan_usb_send_cmd(dev, 10, 2, args);
251
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_EXT_VCC, PCAN_USB_SET, args);
211252 }
212253
213254 /*
....@@ -231,7 +272,7 @@
231272 args[0] = btr1;
232273 args[1] = btr0;
233274
234
- return pcan_usb_send_cmd(dev, 1, 2, args);
275
+ return pcan_usb_send_cmd(dev, PCAN_USB_CMD_BITRATE, PCAN_USB_SET, args);
235276 }
236277
237278 /*
....@@ -315,7 +356,7 @@
315356 u8 args[PCAN_USB_CMD_ARGS_LEN];
316357 int err;
317358
318
- err = pcan_usb_wait_rsp(dev, 6, 1, args);
359
+ err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_SN, PCAN_USB_GET, args);
319360 if (err) {
320361 netdev_err(dev->netdev, "getting serial failure: %d\n", err);
321362 } else if (serial_number) {
....@@ -336,7 +377,7 @@
336377 u8 args[PCAN_USB_CMD_ARGS_LEN];
337378 int err;
338379
339
- err = pcan_usb_wait_rsp(dev, 4, 1, args);
380
+ err = pcan_usb_wait_rsp(dev, PCAN_USB_CMD_DEVID, PCAN_USB_GET, args);
340381 if (err)
341382 netdev_err(dev->netdev, "getting device id failure: %d\n", err);
342383 else if (device_id)
....@@ -423,7 +464,7 @@
423464 new_state = CAN_STATE_ERROR_WARNING;
424465 break;
425466 }
426
- /* else: fall through */
467
+ fallthrough;
427468
428469 case CAN_STATE_ERROR_WARNING:
429470 if (n & PCAN_USB_ERROR_BUS_HEAVY) {
....@@ -434,7 +475,7 @@
434475 new_state = CAN_STATE_BUS_OFF;
435476 break;
436477 }
437
- if (n & (PCAN_USB_ERROR_RXQOVR | PCAN_USB_ERROR_QOVR)) {
478
+ if (n & ~PCAN_USB_ERROR_BUS) {
438479 /*
439480 * trick to bypass next comparison and process other
440481 * errors
....@@ -458,7 +499,7 @@
458499 new_state = CAN_STATE_ERROR_WARNING;
459500 break;
460501 }
461
- if (n & (PCAN_USB_ERROR_RXQOVR | PCAN_USB_ERROR_QOVR)) {
502
+ if (n & ~PCAN_USB_ERROR_BUS) {
462503 /*
463504 * trick to bypass next comparison and process other
464505 * errors
....@@ -497,29 +538,50 @@
497538
498539 case CAN_STATE_ERROR_PASSIVE:
499540 cf->can_id |= CAN_ERR_CRTL;
500
- cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE |
501
- CAN_ERR_CRTL_RX_PASSIVE;
541
+ cf->data[1] = (mc->pdev->bec.txerr > mc->pdev->bec.rxerr) ?
542
+ CAN_ERR_CRTL_TX_PASSIVE :
543
+ CAN_ERR_CRTL_RX_PASSIVE;
544
+ cf->data[6] = mc->pdev->bec.txerr;
545
+ cf->data[7] = mc->pdev->bec.rxerr;
546
+
502547 mc->pdev->dev.can.can_stats.error_passive++;
503548 break;
504549
505550 case CAN_STATE_ERROR_WARNING:
506551 cf->can_id |= CAN_ERR_CRTL;
507
- cf->data[1] |= CAN_ERR_CRTL_TX_WARNING |
508
- CAN_ERR_CRTL_RX_WARNING;
552
+ cf->data[1] = (mc->pdev->bec.txerr > mc->pdev->bec.rxerr) ?
553
+ CAN_ERR_CRTL_TX_WARNING :
554
+ CAN_ERR_CRTL_RX_WARNING;
555
+ cf->data[6] = mc->pdev->bec.txerr;
556
+ cf->data[7] = mc->pdev->bec.rxerr;
557
+
509558 mc->pdev->dev.can.can_stats.error_warning++;
510559 break;
511560
512561 case CAN_STATE_ERROR_ACTIVE:
513562 cf->can_id |= CAN_ERR_CRTL;
514563 cf->data[1] = CAN_ERR_CRTL_ACTIVE;
564
+
565
+ /* sync local copies of rxerr/txerr counters */
566
+ mc->pdev->bec.txerr = 0;
567
+ mc->pdev->bec.rxerr = 0;
515568 break;
516569
517570 default:
518571 /* CAN_STATE_MAX (trick to handle other errors) */
519
- cf->can_id |= CAN_ERR_CRTL;
520
- cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
521
- mc->netdev->stats.rx_over_errors++;
522
- mc->netdev->stats.rx_errors++;
572
+ if (n & PCAN_USB_ERROR_TXQFULL)
573
+ netdev_dbg(mc->netdev, "device Tx queue full)\n");
574
+
575
+ if (n & PCAN_USB_ERROR_RXQOVR) {
576
+ netdev_dbg(mc->netdev, "data overrun interrupt\n");
577
+ cf->can_id |= CAN_ERR_CRTL;
578
+ cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
579
+ mc->netdev->stats.rx_over_errors++;
580
+ mc->netdev->stats.rx_errors++;
581
+ }
582
+
583
+ cf->data[6] = mc->pdev->bec.txerr;
584
+ cf->data[7] = mc->pdev->bec.rxerr;
523585
524586 new_state = mc->pdev->dev.can.state;
525587 break;
....@@ -537,6 +599,31 @@
537599 mc->netdev->stats.rx_packets++;
538600 mc->netdev->stats.rx_bytes += cf->can_dlc;
539601 netif_rx(skb);
602
+
603
+ return 0;
604
+}
605
+
606
+/* decode bus event usb packet: first byte contains rxerr while 2nd one contains
607
+ * txerr.
608
+ */
609
+static int pcan_usb_handle_bus_evt(struct pcan_usb_msg_context *mc, u8 ir)
610
+{
611
+ struct pcan_usb *pdev = mc->pdev;
612
+
613
+ /* acccording to the content of the packet */
614
+ switch (ir) {
615
+ case PCAN_USB_ERR_CNT_DEC:
616
+ case PCAN_USB_ERR_CNT_INC:
617
+
618
+ /* save rx/tx error counters from in the device context */
619
+ pdev->bec.rxerr = mc->ptr[1];
620
+ pdev->bec.txerr = mc->ptr[2];
621
+ break;
622
+
623
+ default:
624
+ /* reserved */
625
+ break;
626
+ }
540627
541628 return 0;
542629 }
....@@ -595,9 +682,10 @@
595682 break;
596683
597684 case PCAN_USB_REC_BUSEVT:
598
- /* error frame/bus event */
599
- if (n & PCAN_USB_ERROR_TXQFULL)
600
- netdev_dbg(mc->netdev, "device Tx queue full)\n");
685
+ /* bus event notifications (get rxerr/txerr) */
686
+ err = pcan_usb_handle_bus_evt(mc, n);
687
+ if (err)
688
+ return err;
601689 break;
602690 default:
603691 netdev_err(mc->netdev, "unexpected function %u\n", f);
....@@ -781,20 +869,44 @@
781869 return 0;
782870 }
783871
872
+/* socket callback used to copy berr counters values received through USB */
873
+static int pcan_usb_get_berr_counter(const struct net_device *netdev,
874
+ struct can_berr_counter *bec)
875
+{
876
+ struct peak_usb_device *dev = netdev_priv(netdev);
877
+ struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev);
878
+
879
+ *bec = pdev->bec;
880
+
881
+ /* must return 0 */
882
+ return 0;
883
+}
884
+
784885 /*
785886 * start interface
786887 */
787888 static int pcan_usb_start(struct peak_usb_device *dev)
788889 {
789890 struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev);
891
+ int err;
790892
791893 /* number of bits used in timestamps read from adapter struct */
792894 peak_usb_init_time_ref(&pdev->time_ref, &pcan_usb);
793895
896
+ pdev->bec.rxerr = 0;
897
+ pdev->bec.txerr = 0;
898
+
899
+ /* be notified on error counter changes (if requested by user) */
900
+ if (dev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
901
+ err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK);
902
+ if (err)
903
+ netdev_warn(dev->netdev,
904
+ "Asking for BERR reporting error %u\n",
905
+ err);
906
+ }
907
+
794908 /* if revision greater than 3, can put silent mode on/off */
795909 if (dev->device_rev > 3) {
796
- int err;
797
-
798910 err = pcan_usb_set_silent(dev,
799911 dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY);
800912 if (err)
....@@ -881,7 +993,8 @@
881993 .name = "PCAN-USB",
882994 .device_id = PCAN_USB_PRODUCT_ID,
883995 .ctrl_count = 1,
884
- .ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
996
+ .ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY |
997
+ CAN_CTRLMODE_BERR_REPORTING,
885998 .clock = {
886999 .freq = PCAN_USB_CRYSTAL_HZ / 2 ,
8871000 },
....@@ -914,4 +1027,5 @@
9141027 .dev_encode_msg = pcan_usb_encode_msg,
9151028 .dev_start = pcan_usb_start,
9161029 .dev_restart_async = pcan_usb_restart_async,
1030
+ .do_get_berr_counter = pcan_usb_get_berr_counter,
9171031 };