Skip to content

Commit ee66925

Browse files
committed
Fix for bug #73
- Implemented command-line option '-R' to allow for Bus error state recovery; particularly for Error Passive State issues. - Removed legacy debug asserts in netif_wake_queue() and netif_stop_queue(); these were only active for Debug builds. - Fixed a bug in command-line help option '-r'; it was still '-b' from prior changes.
1 parent 5ffddfa commit ee66925

File tree

7 files changed

+109
-12
lines changed

7 files changed

+109
-12
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,20 @@ Options:
148148
-r delay - Bus-off recovery delay timer duration (milliseconds).
149149
If set to 0ms, then the bus-off recovery is disabled!
150150
Default: 50ms
151+
-R count - Error state recovery error count value (trigger limit).
152+
Associated SJA1000 states:
153+
< 96 - CAN state error active
154+
< 128 - CAN state error warning
155+
< 256 - CAN state error passive (main reason for feature)
156+
>= 256 - CAN state error bus-off
157+
If enabled, CAN state stopped and sleeping will trigger the
158+
recovery also for any value.
159+
To prevent Error Passive State issues experienced with some
160+
hardware, recommended value to use is 128. This will reboot the
161+
chip if the chip gets overwhelmed with errors; if this
162+
behaviour is desired.
163+
If set to 0, then the error state recovery is disabled.
164+
Default: 0
151165
-x - Start the driver with extended MIDs enabled.
152166
Device suboptions take precedence over this option.
153167
-?/h - Print help menu and exit.

config/PROGRAM_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.3.4
1+
1.3.5

src/config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
*/
5151
int optr = 0;
5252
int optr_restart_ms = DEFAULT_RESTART_MS;
53+
int optR = 0;
54+
int optR_error_count = DEFAULT_ERROR_COUNT;
5355
int optv = 0;
5456
int optl = 0;
5557
int opti = 0;

src/include/config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define DEFAULT_NUM_RX_CHANNELS 1
3838
#define DEFAULT_NUM_TX_CHANNELS 1
3939
#define DEFAULT_RESTART_MS 50 // Default bus-off restart delay
40+
#define DEFAULT_ERROR_COUNT 0 // default error state recovery count
4041

4142

4243
/*
@@ -47,6 +48,8 @@
4748

4849
extern int optr;
4950
extern int optr_restart_ms;
51+
extern int optR;
52+
extern int optR_error_count;
5053
extern int optv;
5154
extern int optl;
5255
extern int opti;

src/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,18 @@ int main (int argc, char* argv[]) {
121121
opterr = opt_bak_opterr;
122122
optopt = opt_bak_optopt;
123123

124-
while ((opt = getopt(argc, argv, "r:d:e:U:u:b:m:viqstlVCEwcx?h")) != -1) {
124+
while ((opt = getopt(argc, argv, "r:R:d:e:U:u:b:m:viqstlVCEwcx?h")) != -1) {
125125
switch (opt) {
126126
case 'r':
127127
optr++;
128128
optr_restart_ms = atoi(optarg);
129129
break;
130130

131+
case 'R':
132+
optR++;
133+
optR_error_count = atoi(optarg);
134+
break;
135+
131136
case 'd':
132137
{
133138
device_config_t* new_disable_device_config;

src/netif.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@
2020

2121
#include <pci/pci.h>
2222

23-
#include <linux/units.h>
24-
#include <linux/netdevice.h>
25-
#include <linux/can.h>
26-
#include <linux/can/error.h>
27-
#include <linux/can/skb.h>
23+
#include <drivers/net/can/sja1000/sja1000.h>
2824
#include <session.h>
2925

3026
#include "netif.h"
@@ -104,6 +100,9 @@ int netif_rx (struct sk_buff* skb) {
104100

105101
/* handle error message frame */
106102
if (msg->can_id & CAN_ERR_FLAG) {
103+
struct sja1000_priv *priv = netdev_priv(skb->dev);
104+
enum can_state state = priv->can.state;
105+
107106
if (msg->can_id & CAN_ERR_TX_TIMEOUT) {
108107
log_warn("netif_rx: %s: TX timeout (by netdevice driver)\n",
109108
skb->dev->name);
@@ -144,6 +143,70 @@ int netif_rx (struct sk_buff* skb) {
144143
skb->dev->name, msg->data[6], msg->data[7]);
145144
}
146145

146+
if (optR_error_count != 0) {
147+
bool restart_trigger = false;
148+
149+
switch (state) {
150+
case CAN_STATE_ERROR_ACTIVE: /* RX/TX error count < 96 */
151+
if (optR_error_count < 96) {
152+
restart_trigger = true;
153+
154+
log_trace("netif_rx: can_restart_now (Error Active)\n");
155+
156+
}
157+
break;
158+
case CAN_STATE_ERROR_WARNING: /* RX/TX error count < 128 */
159+
if (optR_error_count < 128) {
160+
restart_trigger = true;
161+
162+
log_trace("netif_rx: can_restart_now (Error Warning)\n");
163+
}
164+
break;
165+
case CAN_STATE_ERROR_PASSIVE: /* RX/TX error count < 256 */
166+
if (optR_error_count < 256) {
167+
restart_trigger = true;
168+
169+
log_trace("netif_rx: can_restart_now (Error Passive)\n");
170+
}
171+
break;
172+
case CAN_STATE_BUS_OFF: /* RX/TX error count >= 256 */
173+
if (optR_error_count >= 256) {
174+
restart_trigger = true;
175+
176+
log_trace("netif_rx: can_restart_now (Error Bus-Off)\n");
177+
}
178+
break;
179+
case CAN_STATE_STOPPED: /* Device is stopped */
180+
restart_trigger = true;
181+
log_trace("netif_rx: can_restart_now (State Stopped)\n");
182+
break;
183+
case CAN_STATE_SLEEPING: /* Device is sleeping */
184+
restart_trigger = true;
185+
log_trace("netif_rx: can_restart_now (State Sleeping)\n");
186+
break;
187+
default:
188+
break;
189+
}
190+
191+
if (restart_trigger) {
192+
struct can_priv *priv = netdev_priv(skb->dev);
193+
194+
// Save automatic restart
195+
int backup_restart_ms = priv->restart_ms;
196+
197+
priv->restart_ms = 0; // Force automatic restart off
198+
priv->state = CAN_STATE_BUS_OFF; // Force CAN-bus state Bus-off
199+
200+
int err = can_restart_now(skb->dev);
201+
if (err) {
202+
log_err("netif_rx: can_restart_now error (%d)\n", err);
203+
}
204+
205+
// Restore automatic restart
206+
priv->restart_ms = backup_restart_ms;
207+
}
208+
}
209+
147210
kfree_skb(skb);
148211

149212
return NET_RX_SUCCESS;
@@ -285,8 +348,6 @@ void netif_wake_queue (struct net_device* dev) {
285348

286349
device_session_t* ds = dev->device_session;
287350

288-
assert( ds->tx_thread != pthread_self() || shutdown_program );
289-
290351
queue_wake_up(&ds->tx_queue);
291352
}
292353

@@ -295,8 +356,6 @@ void netif_stop_queue (struct net_device* dev) {
295356

296357
device_session_t* ds = dev->device_session;
297358

298-
assert( ds->tx_thread == pthread_self() || shutdown_program );
299-
300359
queue_stop(&ds->tx_queue);
301360
}
302361

src/prints.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,25 @@ void print_help (char* program_name) {
211211
printf(" e.g. -e 13fe:00d7,0x11\n");
212212
printf(" By default MSI capability is enabled and MSI-X is disabled,\n");
213213
printf(" and requires enabling to be activated (EXPERIMENTAL).\n");
214-
printf(" \e[1m-b delay\e[m - Bus-off recovery delay timer length (milliseconds).\n");
214+
printf(" \e[1m-r delay\e[m - Bus-off recovery delay timer length (milliseconds).\n");
215215
printf(" If set to 0ms, then the bus-off recovery is disabled!\n");
216216
printf(" The netif transmission queue fault recovery is also set to this\n");
217217
printf(" delay value.\n");
218218
printf(" Default: %dms\n", DEFAULT_RESTART_MS);
219+
printf(" \e[1m-R count\e[m - Error state recovery error count value (trigger limit).\n");
220+
printf(" Associated SJA1000 states:\n");
221+
printf(" < 96 - CAN state error active\n");
222+
printf(" < 128 - CAN state error warning\n");
223+
printf(" < 256 - CAN state error passive (main reason for feature)\n");
224+
printf(" >= 256 - CAN state error bus-off\n");
225+
printf(" If enabled, CAN state stopped and sleeping will trigger the\n");
226+
printf(" recovery also for any value.\n");
227+
printf(" To prevent Error Passive State issues experienced with some\n");
228+
printf(" hardware, recommended value to use is 128. This will reboot the\n");
229+
printf(" chip if the chip gets overwhelmed with errors; if this\n");
230+
printf(" behaviour is desired.\n");
231+
printf(" If set to 0, then the error state recovery is disabled.\n");
232+
printf(" Default: %d\n", DEFAULT_ERROR_COUNT);
219233
printf(" \e[1m-?/h\e[m - Print help menu and exit.\n");
220234
printf("\n");
221235
printf("\e[1mNOTES\e[m\n");

0 commit comments

Comments
 (0)