@@ -127,7 +127,15 @@ struct rx_msg {
127
127
u8 dlc ;
128
128
__le32 ts ;
129
129
__le32 id ; /* upper 3 bits contain flags */
130
- u8 data [8 ];
130
+ union {
131
+ u8 data [8 ];
132
+ struct {
133
+ u8 status ; /* CAN Controller Status */
134
+ u8 ecc ; /* Error Capture Register */
135
+ u8 rec ; /* RX Error Counter */
136
+ u8 tec ; /* TX Error Counter */
137
+ } ev_can_err_ext ; /* For ESD_EV_CAN_ERROR_EXT */
138
+ };
131
139
};
132
140
133
141
struct tx_msg {
@@ -229,51 +237,52 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
229
237
u32 id = le32_to_cpu (msg -> msg .rx .id ) & ESD_IDMASK ;
230
238
231
239
if (id == ESD_EV_CAN_ERROR_EXT ) {
232
- u8 state = msg -> msg .rx .data [ 0 ] ;
233
- u8 ecc = msg -> msg .rx .data [ 1 ] ;
234
- u8 rxerr = msg -> msg .rx .data [ 2 ] ;
235
- u8 txerr = msg -> msg .rx .data [ 3 ] ;
240
+ u8 state = msg -> msg .rx .ev_can_err_ext . status ;
241
+ u8 ecc = msg -> msg .rx .ev_can_err_ext . ecc ;
242
+ u8 rxerr = msg -> msg .rx .ev_can_err_ext . rec ;
243
+ u8 txerr = msg -> msg .rx .ev_can_err_ext . tec ;
236
244
237
245
netdev_dbg (priv -> netdev ,
238
246
"CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n" ,
239
247
msg -> msg .rx .dlc , state , ecc , rxerr , txerr );
240
248
241
249
skb = alloc_can_err_skb (priv -> netdev , & cf );
242
- if (skb == NULL ) {
243
- stats -> rx_dropped ++ ;
244
- return ;
245
- }
246
250
247
251
if (state != priv -> old_state ) {
252
+ enum can_state tx_state , rx_state ;
253
+ enum can_state new_state = CAN_STATE_ERROR_ACTIVE ;
254
+
248
255
priv -> old_state = state ;
249
256
250
257
switch (state & ESD_BUSSTATE_MASK ) {
251
258
case ESD_BUSSTATE_BUSOFF :
252
- priv -> can .state = CAN_STATE_BUS_OFF ;
253
- cf -> can_id |= CAN_ERR_BUSOFF ;
254
- priv -> can .can_stats .bus_off ++ ;
259
+ new_state = CAN_STATE_BUS_OFF ;
255
260
can_bus_off (priv -> netdev );
256
261
break ;
257
262
case ESD_BUSSTATE_WARN :
258
- priv -> can .state = CAN_STATE_ERROR_WARNING ;
259
- priv -> can .can_stats .error_warning ++ ;
263
+ new_state = CAN_STATE_ERROR_WARNING ;
260
264
break ;
261
265
case ESD_BUSSTATE_ERRPASSIVE :
262
- priv -> can .state = CAN_STATE_ERROR_PASSIVE ;
263
- priv -> can .can_stats .error_passive ++ ;
266
+ new_state = CAN_STATE_ERROR_PASSIVE ;
264
267
break ;
265
268
default :
266
- priv -> can . state = CAN_STATE_ERROR_ACTIVE ;
269
+ new_state = CAN_STATE_ERROR_ACTIVE ;
267
270
txerr = 0 ;
268
271
rxerr = 0 ;
269
272
break ;
270
273
}
271
- } else {
274
+
275
+ if (new_state != priv -> can .state ) {
276
+ tx_state = (txerr >= rxerr ) ? new_state : 0 ;
277
+ rx_state = (txerr <= rxerr ) ? new_state : 0 ;
278
+ can_change_state (priv -> netdev , cf ,
279
+ tx_state , rx_state );
280
+ }
281
+ } else if (skb ) {
272
282
priv -> can .can_stats .bus_error ++ ;
273
283
stats -> rx_errors ++ ;
274
284
275
- cf -> can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR |
276
- CAN_ERR_CNT ;
285
+ cf -> can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR ;
277
286
278
287
switch (ecc & SJA1000_ECC_MASK ) {
279
288
case SJA1000_ECC_BIT :
@@ -286,28 +295,29 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
286
295
cf -> data [2 ] |= CAN_ERR_PROT_STUFF ;
287
296
break ;
288
297
default :
289
- cf -> data [3 ] = ecc & SJA1000_ECC_SEG ;
290
298
break ;
291
299
}
292
300
293
301
/* Error occurred during transmission? */
294
302
if (!(ecc & SJA1000_ECC_DIR ))
295
303
cf -> data [2 ] |= CAN_ERR_PROT_TX ;
296
304
297
- if (priv -> can .state == CAN_STATE_ERROR_WARNING ||
298
- priv -> can .state == CAN_STATE_ERROR_PASSIVE ) {
299
- cf -> data [1 ] = (txerr > rxerr ) ?
300
- CAN_ERR_CRTL_TX_PASSIVE :
301
- CAN_ERR_CRTL_RX_PASSIVE ;
302
- }
303
- cf -> data [6 ] = txerr ;
304
- cf -> data [7 ] = rxerr ;
305
+ /* Bit stream position in CAN frame as the error was detected */
306
+ cf -> data [3 ] = ecc & SJA1000_ECC_SEG ;
305
307
}
306
308
307
309
priv -> bec .txerr = txerr ;
308
310
priv -> bec .rxerr = rxerr ;
309
311
310
- netif_rx (skb );
312
+ if (skb ) {
313
+ cf -> can_id |= CAN_ERR_CNT ;
314
+ cf -> data [6 ] = txerr ;
315
+ cf -> data [7 ] = rxerr ;
316
+
317
+ netif_rx (skb );
318
+ } else {
319
+ stats -> rx_dropped ++ ;
320
+ }
311
321
}
312
322
}
313
323
0 commit comments