Skip to content

Commit c1a6911

Browse files
Merge patch series "can: kvaser_usb: Update stats and state even if alloc_can_err_skb() fails"
This series improves the the kvaser_usb and the kvaser_pciefd driver. Update the error statistics, even if allocation of error skb fails and add support for CAN_CTRLMODE_BERR_REPORTING. Link: https://patch.msgid.link/[email protected] Signed-off-by: Marc Kleine-Budde <[email protected]>
2 parents 7e0c2f1 + 9d92fda commit c1a6911

File tree

4 files changed

+115
-140
lines changed

4 files changed

+115
-140
lines changed

drivers/net/can/kvaser_pciefd.c

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,8 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie)
999999
can->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
10001000
CAN_CTRLMODE_FD |
10011001
CAN_CTRLMODE_FD_NON_ISO |
1002-
CAN_CTRLMODE_CC_LEN8_DLC;
1002+
CAN_CTRLMODE_CC_LEN8_DLC |
1003+
CAN_CTRLMODE_BERR_REPORTING;
10031004

10041005
status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG);
10051006
if (!(status & KVASER_PCIEFD_KCAN_STAT_FD)) {
@@ -1234,11 +1235,15 @@ static int kvaser_pciefd_handle_data_packet(struct kvaser_pciefd *pcie,
12341235
}
12351236

12361237
static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
1238+
const struct can_berr_counter *bec,
12371239
struct can_frame *cf,
12381240
enum can_state new_state,
12391241
enum can_state tx_state,
12401242
enum can_state rx_state)
12411243
{
1244+
enum can_state old_state;
1245+
1246+
old_state = can->can.state;
12421247
can_change_state(can->can.dev, cf, tx_state, rx_state);
12431248

12441249
if (new_state == CAN_STATE_BUS_OFF) {
@@ -1254,6 +1259,18 @@ static void kvaser_pciefd_change_state(struct kvaser_pciefd_can *can,
12541259
can_bus_off(ndev);
12551260
}
12561261
}
1262+
if (old_state == CAN_STATE_BUS_OFF &&
1263+
new_state == CAN_STATE_ERROR_ACTIVE &&
1264+
can->can.restart_ms) {
1265+
can->can.can_stats.restarts++;
1266+
if (cf)
1267+
cf->can_id |= CAN_ERR_RESTARTED;
1268+
}
1269+
if (cf && new_state != CAN_STATE_BUS_OFF) {
1270+
cf->can_id |= CAN_ERR_CNT;
1271+
cf->data[6] = bec->txerr;
1272+
cf->data[7] = bec->rxerr;
1273+
}
12571274
}
12581275

12591276
static void kvaser_pciefd_packet_to_state(struct kvaser_pciefd_rx_packet *p,
@@ -1288,7 +1305,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
12881305
struct can_berr_counter bec;
12891306
enum can_state old_state, new_state, tx_state, rx_state;
12901307
struct net_device *ndev = can->can.dev;
1291-
struct sk_buff *skb;
1308+
struct sk_buff *skb = NULL;
12921309
struct can_frame *cf = NULL;
12931310

12941311
old_state = can->can.state;
@@ -1297,16 +1314,10 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
12971314
bec.rxerr = FIELD_GET(KVASER_PCIEFD_SPACK_RXERR_MASK, p->header[0]);
12981315

12991316
kvaser_pciefd_packet_to_state(p, &bec, &new_state, &tx_state, &rx_state);
1300-
skb = alloc_can_err_skb(ndev, &cf);
1317+
if (can->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
1318+
skb = alloc_can_err_skb(ndev, &cf);
13011319
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-
}
1320+
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
13101321
}
13111322

13121323
can->err_rep_cnt++;
@@ -1319,18 +1330,19 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
13191330
can->bec.txerr = bec.txerr;
13201331
can->bec.rxerr = bec.rxerr;
13211332

1322-
if (!skb) {
1323-
ndev->stats.rx_dropped++;
1324-
return -ENOMEM;
1333+
if (can->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
1334+
if (!skb) {
1335+
netdev_warn(ndev, "No memory left for err_skb\n");
1336+
ndev->stats.rx_dropped++;
1337+
return -ENOMEM;
1338+
}
1339+
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
1340+
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
1341+
cf->data[6] = bec.txerr;
1342+
cf->data[7] = bec.rxerr;
1343+
netif_rx(skb);
13251344
}
13261345

1327-
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
1328-
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
1329-
cf->data[6] = bec.txerr;
1330-
cf->data[7] = bec.rxerr;
1331-
1332-
netif_rx(skb);
1333-
13341346
return 0;
13351347
}
13361348

@@ -1359,6 +1371,7 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
13591371
{
13601372
struct can_berr_counter bec;
13611373
enum can_state old_state, new_state, tx_state, rx_state;
1374+
int ret = 0;
13621375

13631376
old_state = can->can.state;
13641377

@@ -1372,33 +1385,23 @@ static int kvaser_pciefd_handle_status_resp(struct kvaser_pciefd_can *can,
13721385
struct can_frame *cf;
13731386

13741387
skb = alloc_can_err_skb(ndev, &cf);
1375-
if (!skb) {
1388+
kvaser_pciefd_change_state(can, &bec, cf, new_state, tx_state, rx_state);
1389+
if (skb) {
1390+
kvaser_pciefd_set_skb_timestamp(can->kv_pcie, skb, p->timestamp);
1391+
netif_rx(skb);
1392+
} else {
13761393
ndev->stats.rx_dropped++;
1377-
return -ENOMEM;
1394+
netdev_warn(ndev, "No memory left for err_skb\n");
1395+
ret = -ENOMEM;
13781396
}
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);
13941397
}
13951398
can->bec.txerr = bec.txerr;
13961399
can->bec.rxerr = bec.rxerr;
13971400
/* Check if we need to poll the error counters */
13981401
if (bec.txerr || bec.rxerr)
13991402
mod_timer(&can->bec_poll_timer, KVASER_PCIEFD_BEC_POLL_FREQ);
14001403

1401-
return 0;
1404+
return ret;
14021405
}
14031406

14041407
static int kvaser_pciefd_handle_status_packet(struct kvaser_pciefd *pcie,

drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,8 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
818818
init_completion(&priv->stop_comp);
819819
init_completion(&priv->flush_comp);
820820
init_completion(&priv->get_busparams_comp);
821-
priv->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC;
821+
priv->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC |
822+
CAN_CTRLMODE_BERR_REPORTING;
822823

823824
priv->dev = dev;
824825
priv->netdev = netdev;

drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c

Lines changed: 56 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,42 @@ kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
926926
}
927927
}
928928

929+
static void kvaser_usb_hydra_change_state(struct kvaser_usb_net_priv *priv,
930+
const struct can_berr_counter *bec,
931+
struct can_frame *cf,
932+
enum can_state new_state)
933+
{
934+
struct net_device *netdev = priv->netdev;
935+
enum can_state old_state = priv->can.state;
936+
enum can_state tx_state, rx_state;
937+
938+
tx_state = (bec->txerr >= bec->rxerr) ?
939+
new_state : CAN_STATE_ERROR_ACTIVE;
940+
rx_state = (bec->txerr <= bec->rxerr) ?
941+
new_state : CAN_STATE_ERROR_ACTIVE;
942+
can_change_state(netdev, cf, tx_state, rx_state);
943+
944+
if (new_state == CAN_STATE_BUS_OFF && old_state < CAN_STATE_BUS_OFF) {
945+
if (priv->can.restart_ms == 0)
946+
kvaser_usb_hydra_send_simple_cmd_async(priv, CMD_STOP_CHIP_REQ);
947+
948+
can_bus_off(netdev);
949+
}
950+
951+
if (priv->can.restart_ms &&
952+
old_state >= CAN_STATE_BUS_OFF &&
953+
new_state < CAN_STATE_BUS_OFF) {
954+
priv->can.can_stats.restarts++;
955+
if (cf)
956+
cf->can_id |= CAN_ERR_RESTARTED;
957+
}
958+
if (cf && new_state != CAN_STATE_BUS_OFF) {
959+
cf->can_id |= CAN_ERR_CNT;
960+
cf->data[6] = bec->txerr;
961+
cf->data[7] = bec->rxerr;
962+
}
963+
}
964+
929965
static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
930966
u8 bus_status,
931967
const struct can_berr_counter *bec)
@@ -951,41 +987,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
951987
return;
952988

953989
skb = alloc_can_err_skb(netdev, &cf);
954-
if (skb) {
955-
enum can_state tx_state, rx_state;
956-
957-
tx_state = (bec->txerr >= bec->rxerr) ?
958-
new_state : CAN_STATE_ERROR_ACTIVE;
959-
rx_state = (bec->txerr <= bec->rxerr) ?
960-
new_state : CAN_STATE_ERROR_ACTIVE;
961-
can_change_state(netdev, cf, tx_state, rx_state);
962-
}
963-
964-
if (new_state == CAN_STATE_BUS_OFF && old_state < CAN_STATE_BUS_OFF) {
965-
if (!priv->can.restart_ms)
966-
kvaser_usb_hydra_send_simple_cmd_async
967-
(priv, CMD_STOP_CHIP_REQ);
968-
969-
can_bus_off(netdev);
970-
}
971-
972-
if (!skb) {
990+
kvaser_usb_hydra_change_state(priv, bec, cf, new_state);
991+
if (skb)
992+
netif_rx(skb);
993+
else
973994
netdev_warn(netdev, "No memory left for err_skb\n");
974-
return;
975-
}
976-
977-
if (priv->can.restart_ms &&
978-
old_state >= CAN_STATE_BUS_OFF &&
979-
new_state < CAN_STATE_BUS_OFF)
980-
priv->can.can_stats.restarts++;
981-
982-
if (new_state != CAN_STATE_BUS_OFF) {
983-
cf->can_id |= CAN_ERR_CNT;
984-
cf->data[6] = bec->txerr;
985-
cf->data[7] = bec->rxerr;
986-
}
987-
988-
netif_rx(skb);
989995
}
990996

991997
static void kvaser_usb_hydra_state_event(const struct kvaser_usb *dev,
@@ -1078,9 +1084,8 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
10781084
{
10791085
struct net_device *netdev = priv->netdev;
10801086
struct net_device_stats *stats = &netdev->stats;
1081-
struct can_frame *cf;
1082-
struct sk_buff *skb;
1083-
struct skb_shared_hwtstamps *shhwtstamps;
1087+
struct can_frame *cf = NULL;
1088+
struct sk_buff *skb = NULL;
10841089
struct can_berr_counter bec;
10851090
enum can_state new_state, old_state;
10861091
u8 bus_status;
@@ -1096,52 +1101,26 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
10961101
kvaser_usb_hydra_bus_status_to_can_state(priv, bus_status, &bec,
10971102
&new_state);
10981103

1099-
skb = alloc_can_err_skb(netdev, &cf);
1104+
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
1105+
skb = alloc_can_err_skb(netdev, &cf);
1106+
if (new_state != old_state)
1107+
kvaser_usb_hydra_change_state(priv, &bec, cf, new_state);
11001108

1101-
if (new_state != old_state) {
1109+
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
11021110
if (skb) {
1103-
enum can_state tx_state, rx_state;
1104-
1105-
tx_state = (bec.txerr >= bec.rxerr) ?
1106-
new_state : CAN_STATE_ERROR_ACTIVE;
1107-
rx_state = (bec.txerr <= bec.rxerr) ?
1108-
new_state : CAN_STATE_ERROR_ACTIVE;
1109-
1110-
can_change_state(netdev, cf, tx_state, rx_state);
1111-
1112-
if (priv->can.restart_ms &&
1113-
old_state >= CAN_STATE_BUS_OFF &&
1114-
new_state < CAN_STATE_BUS_OFF)
1115-
cf->can_id |= CAN_ERR_RESTARTED;
1116-
}
1117-
1118-
if (new_state == CAN_STATE_BUS_OFF) {
1119-
if (!priv->can.restart_ms)
1120-
kvaser_usb_hydra_send_simple_cmd_async
1121-
(priv, CMD_STOP_CHIP_REQ);
1111+
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
11221112

1123-
can_bus_off(netdev);
1113+
shhwtstamps->hwtstamp = hwtstamp;
1114+
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;
1115+
cf->data[6] = bec.txerr;
1116+
cf->data[7] = bec.rxerr;
1117+
netif_rx(skb);
1118+
} else {
1119+
stats->rx_dropped++;
1120+
netdev_warn(netdev, "No memory left for err_skb\n");
11241121
}
11251122
}
11261123

1127-
if (!skb) {
1128-
stats->rx_dropped++;
1129-
netdev_warn(netdev, "No memory left for err_skb\n");
1130-
return;
1131-
}
1132-
1133-
shhwtstamps = skb_hwtstamps(skb);
1134-
shhwtstamps->hwtstamp = hwtstamp;
1135-
1136-
cf->can_id |= CAN_ERR_BUSERROR;
1137-
if (new_state != CAN_STATE_BUS_OFF) {
1138-
cf->can_id |= CAN_ERR_CNT;
1139-
cf->data[6] = bec.txerr;
1140-
cf->data[7] = bec.rxerr;
1141-
}
1142-
1143-
netif_rx(skb);
1144-
11451124
priv->bec.txerr = bec.txerr;
11461125
priv->bec.rxerr = bec.rxerr;
11471126
}

0 commit comments

Comments
 (0)