Skip to content

Commit e048c5e

Browse files
Jimmy Assarssonmarckleinebudde
authored andcommitted
can: kvaser_pciefd: Update stats and state even if alloc_can_err_skb() fails
Ensure statistics, error counters, and CAN state are updated consistently, even when alloc_can_err_skb() fails during state changes or error message frame reception. Signed-off-by: Jimmy Assarsson <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 0dfa617 commit e048c5e

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

drivers/net/can/kvaser_pciefd.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,11 +1234,15 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
12341234
}
12351235

12361236
static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
1237+
const struct can_berr_counter *bec,
12371238
struct can_frame *cf,
12381239
enum can_state new_state,
12391240
enum can_state tx_state,
12401241
enum can_state rx_state)
12411242
{
1243+
enum can_state old_state;
1244+
1245+
old_state = can->can.state;
12421246
can_change_state(can->can.dev, cf, tx_state, rx_state);
12431247

12441248
if (new_state == CAN_STATE_BUS_OFF) {
@@ -1254,6 +1258,18 @@ static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
12541258
can_bus_off(ndev);
12551259
}
12561260
}
1261+
if (old_state == CAN_STATE_BUS_OFF &&
1262+
new_state == CAN_STATE_ERROR_ACTIVE &&
1263+
can->can.restart_ms) {
1264+
can->can.can_stats.restarts++;
1265+
if (cf)
1266+
cf->can_id |= CAN_ERR_RESTARTED;
1267+
}
1268+
if (cf && new_state != CAN_STATE_BUS_OFF) {
1269+
cf->can_id |= CAN_ERR_CNT;
1270+
cf->data[6] = bec->txerr;
1271+
cf->data[7] = bec->rxerr;
1272+
}
12571273
}
12581274

12591275
static void kvaser_pciefd_packet_to_state(struct kvaser_pciefd_rx_packet *p,
@@ -1299,14 +1315,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
12991315
kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, &rx_state);
13001316
skb = alloc_can_err_skb(ndev, &cf);
13011317
if (new_state != old_state) {
1302-
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
1303-
if (old_state == CAN_STATE_BUS_OFF &&
1304-
new_state == CAN_STATE_ERROR_ACTIVE &&
1305-
can->can.restart_ms) {
1306-
can->can.can_stats.restarts++;
1307-
if (skb)
1308-
cf->can_id |= CAN_ERR_RESTARTED;
1309-
}
1318+
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
13101319
}
13111320

13121321
can->err_rep_cnt++;
@@ -1359,6 +1368,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
13591368
{
13601369
struct can_berr_counter bec;
13611370
enum can_state old_state, new_state, tx_state, rx_state;
1371+
int ret = 0;
13621372

13631373
old_state = can->can.state;
13641374

@@ -1372,33 +1382,23 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
13721382
struct can_frame *cf;
13731383

13741384
skb = alloc_can_err_skb(ndev, &cf);
1375-
if (!skb) {
1385+
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
1386+
if (skb) {
1387+
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
1388+
netif_rx(skb);
1389+
} else {
13761390
ndev->stats.rx_dropped++;
1377-
return -ENOMEM;
1391+
netdev_warn(ndev, "No memory left for err_skb\n");
1392+
ret = -ENOMEM;
13781393
}
1379-
1380-
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
1381-
if (old_state == CAN_STATE_BUS_OFF &&
1382-
new_state == CAN_STATE_ERROR_ACTIVE &&
1383-
can->can.restart_ms) {
1384-
can->can.can_stats.restarts++;
1385-
cf->can_id |= CAN_ERR_RESTARTED;
1386-
}
1387-
1388-
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
1389-
1390-
cf->data[6] = bec.txerr;
1391-
cf->data[7] = bec.rxerr;
1392-
1393-
netif_rx(skb);
13941394
}
13951395
can->bec.txerr = bec.txerr;
13961396
can->bec.rxerr = bec.rxerr;
13971397
/* Check if we need to poll the error counters */
13981398
if (bec.txerr || bec.rxerr)
13991399
mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
14001400

1401-
return 0;
1401+
return ret;
14021402
}
14031403

14041404
static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,

0 commit comments

Comments
 (0)