Skip to content

Commit 6ad1727

Browse files
Merge patch series "can: esd_usb: Some more preparation for supporting esd CAN-USB/3"
Frank Jungclaus <[email protected]> says: Another small batch of patches to be seen as preparation for adding support of the newly available esd CAN-USB/3 to esd_usb.c. Due to some unresolved questions adding support for CAN_CTRLMODE_BERR_REPORTING has been postponed to one of the future patches. v2 -> v3: * More specific subjects * Try to use imperative instead of past tense v1 -> v2: https://lore.kernel.org/all/[email protected] * [Patch v2 1/3]: No changes. * [Patch v2 2/3]: Make use of can_change_state() and relocate testing alloc_can_err_skb() for NULL to the end of esd_usb_rx_event(), to have things like can_bus_off(), can_change_state() working even in out of memory conditions. * [Patch v2 3/3]: No changes. I will 'declare esd_usb_msg as an union instead of a struct' in a separate follow-up patch. v1: https://lore.kernel.org/all/[email protected] https://lore.kernel.org/all/[email protected] Link: https://lore.kernel.org/all/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
2 parents 470ac62 + 07c3f92 commit 6ad1727

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

drivers/net/can/usb/esd_usb.c

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,15 @@ struct rx_msg {
127127
u8 dlc;
128128
__le32 ts;
129129
__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+
};
131139
};
132140

133141
struct tx_msg {
@@ -229,51 +237,52 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
229237
u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK;
230238

231239
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;
236244

237245
netdev_dbg(priv->netdev,
238246
"CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
239247
msg->msg.rx.dlc, state, ecc, rxerr, txerr);
240248

241249
skb = alloc_can_err_skb(priv->netdev, &cf);
242-
if (skb == NULL) {
243-
stats->rx_dropped++;
244-
return;
245-
}
246250

247251
if (state != priv->old_state) {
252+
enum can_state tx_state, rx_state;
253+
enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
254+
248255
priv->old_state = state;
249256

250257
switch (state & ESD_BUSSTATE_MASK) {
251258
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;
255260
can_bus_off(priv->netdev);
256261
break;
257262
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;
260264
break;
261265
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;
264267
break;
265268
default:
266-
priv->can.state = CAN_STATE_ERROR_ACTIVE;
269+
new_state = CAN_STATE_ERROR_ACTIVE;
267270
txerr = 0;
268271
rxerr = 0;
269272
break;
270273
}
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) {
272282
priv->can.can_stats.bus_error++;
273283
stats->rx_errors++;
274284

275-
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR |
276-
CAN_ERR_CNT;
285+
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
277286

278287
switch (ecc & SJA1000_ECC_MASK) {
279288
case SJA1000_ECC_BIT:
@@ -286,28 +295,29 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
286295
cf->data[2] |= CAN_ERR_PROT_STUFF;
287296
break;
288297
default:
289-
cf->data[3] = ecc & SJA1000_ECC_SEG;
290298
break;
291299
}
292300

293301
/* Error occurred during transmission? */
294302
if (!(ecc & SJA1000_ECC_DIR))
295303
cf->data[2] |= CAN_ERR_PROT_TX;
296304

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;
305307
}
306308

307309
priv->bec.txerr = txerr;
308310
priv->bec.rxerr = rxerr;
309311

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+
}
311321
}
312322
}
313323

0 commit comments

Comments
 (0)