mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
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 <extja@kvaser.com> Link: https://patch.msgid.link/20241230142645.128244-3-extja@kvaser.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
0dfa617c3f
commit
e048c5e55f
|
|
@ -1234,11 +1234,15 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
|
|||
}
|
||||
|
||||
static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
|
||||
const struct can_berr_counter *bec,
|
||||
struct can_frame *cf,
|
||||
enum can_state new_state,
|
||||
enum can_state tx_state,
|
||||
enum can_state rx_state)
|
||||
{
|
||||
enum can_state old_state;
|
||||
|
||||
old_state = can->can.state;
|
||||
can_change_state(can->can.dev, cf, tx_state, rx_state);
|
||||
|
||||
if (new_state == CAN_STATE_BUS_OFF) {
|
||||
|
|
@ -1254,6 +1258,18 @@ static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
|
|||
can_bus_off(ndev);
|
||||
}
|
||||
}
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
if (cf)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
if (cf && new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
|||
kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, &rx_state);
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (new_state != old_state) {
|
||||
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
if (skb)
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
|
||||
}
|
||||
|
||||
can->err_rep_cnt++;
|
||||
|
|
@ -1359,6 +1368,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
|||
{
|
||||
struct can_berr_counter bec;
|
||||
enum can_state old_state, new_state, tx_state, rx_state;
|
||||
int ret = 0;
|
||||
|
||||
old_state = can->can.state;
|
||||
|
||||
|
|
@ -1372,25 +1382,15 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
|||
struct can_frame *cf;
|
||||
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (!skb) {
|
||||
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
|
||||
if (skb) {
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
netif_rx(skb);
|
||||
} else {
|
||||
ndev->stats.rx_dropped++;
|
||||
return -ENOMEM;
|
||||
netdev_warn(ndev, "No memory left for err_skb\n");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
kvaser_pciefd_change_state(can, cf, new_state, tx_state, rx_state);
|
||||
if (old_state == CAN_STATE_BUS_OFF &&
|
||||
new_state == CAN_STATE_ERROR_ACTIVE &&
|
||||
can->can.restart_ms) {
|
||||
can->can.can_stats.restarts++;
|
||||
cf->can_id |= CAN_ERR_RESTARTED;
|
||||
}
|
||||
|
||||
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
|
||||
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
|
||||
netif_rx(skb);
|
||||
}
|
||||
can->bec.txerr = bec.txerr;
|
||||
can->bec.rxerr = bec.rxerr;
|
||||
|
|
@ -1398,7 +1398,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
|
|||
if (bec.txerr || bec.rxerr)
|
||||
mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user