Commit 8a517946 authored by Wolfgang Grandegger's avatar Wolfgang Grandegger Committed by Stephen Hemminger

iproute2: netlink support for bus-error reporting and counters

This patch uses the new features of the kernel's netlink CAN interface
making the bus-error reporting configurable and allowing to retrieve
the CAN TX and RX bus error counters via netlink interface. Here is the
output of my test session showing how to use them:

# ip link set can0 up type can bitrate 500000 berr-reporting on
# ip -d -s link show can0
2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10
    link/can
    can <BERR-REPORTING> state ERROR-PASSIVE (berr-counter tx 128 rx 0) restart-ms 0
                              CAN bus error counter values ^^^^^^^^^^^
    bitrate 500000 sample-point 0.875
    tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
    sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
    clock 8000000
    re-started bus-errors arbit-lost error-warn error-pass bus-off
    0          54101      0          1          1          0
    RX: bytes  packets  errors  dropped overrun mcast
    432808     54101    54101   0       0       0
    TX: bytes  packets  errors  dropped carrier collsns
    0          0        0       0       0       0

# ifconfig can0 down
# ip link set can0 up type can berr-reporting off
# candump -t d any,0:0,#FFFFFFFF
 (0.000000)  can0  20000004  [8] 00 08 00 00 00 00 60 00   ERRORFRAME
 (0.000474)  can0  20000004  [8] 00 20 00 00 00 00 80 00   ERRORFRAME
                                                   ^^ ^^
						    \  \___ rxerr
						     \_____ txerr

Furthermore, the missing support for one-shot mode has been added.
Signed-off-by: default avatarWolfgang Grandegger <wg@grandegger.com>
parent c90cda94
...@@ -30,6 +30,8 @@ static void usage(void) ...@@ -30,6 +30,8 @@ static void usage(void)
"\t[ loopback { on | off } ]\n" "\t[ loopback { on | off } ]\n"
"\t[ listen-only { on | off } ]\n" "\t[ listen-only { on | off } ]\n"
"\t[ triple-sampling { on | off } ]\n" "\t[ triple-sampling { on | off } ]\n"
"\t[ one-shot { on | off } ]\n"
"\t[ berr-reporting { on | off } ]\n"
"\n" "\n"
"\t[ restart-ms TIME-MS ]\n" "\t[ restart-ms TIME-MS ]\n"
"\t[ restart ]\n" "\t[ restart ]\n"
...@@ -84,6 +86,8 @@ static void print_ctrlmode(FILE *f, __u32 cm) ...@@ -84,6 +86,8 @@ static void print_ctrlmode(FILE *f, __u32 cm)
_PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK"); _PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK");
_PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY"); _PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY");
_PF(CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING"); _PF(CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING");
_PF(CAN_CTRLMODE_ONE_SHOT, "ONE-SHOT");
_PF(CAN_CTRLMODE_BERR_REPORTING, "BERR-REPORTING");
#undef _PF #undef _PF
if (cm) if (cm)
fprintf(f, "%x", cm); fprintf(f, "%x", cm);
...@@ -142,6 +146,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv, ...@@ -142,6 +146,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv,
NEXT_ARG(); NEXT_ARG();
set_ctrlmode("triple-sampling", *argv, &cm, set_ctrlmode("triple-sampling", *argv, &cm,
CAN_CTRLMODE_3_SAMPLES); CAN_CTRLMODE_3_SAMPLES);
} else if (matches(*argv, "one-shot") == 0) {
NEXT_ARG();
set_ctrlmode("one-shot", *argv, &cm,
CAN_CTRLMODE_ONE_SHOT);
} else if (matches(*argv, "berr-reporting") == 0) {
NEXT_ARG();
set_ctrlmode("berr-reporting", *argv, &cm,
CAN_CTRLMODE_BERR_REPORTING);
} else if (matches(*argv, "restart") == 0) { } else if (matches(*argv, "restart") == 0) {
__u32 val = 1; __u32 val = 1;
...@@ -200,6 +212,13 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) ...@@ -200,6 +212,13 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
can_state_names[*state] : "UNKNOWN"); can_state_names[*state] : "UNKNOWN");
} }
if (tb[IFLA_CAN_BERR_COUNTER]) {
struct can_berr_counter *bc =
RTA_DATA(tb[IFLA_CAN_BERR_COUNTER]);
fprintf(f, "(berr-counter tx %d rx %d) ", bc->txerr, bc->rxerr);
}
if (tb[IFLA_CAN_RESTART_MS]) { if (tb[IFLA_CAN_RESTART_MS]) {
__u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]); __u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment