Skip to content

Commit

Permalink
Merge branch 'can-error-set-of-fixes-and-improvement-on-txerr-and-rxe…
Browse files Browse the repository at this point in the history
…rr-reporting'

Vincent Mailhol says:

====================
can: error: set of fixes and improvement on txerr and rxerr reporting

This series is a collection of patches targeting the CAN error
counter. The series is split in three blocks (with small relation to
each other).

Several drivers uses the data[6] and data[7] fields (both of type u8)
of the CAN error frame to report those values. However, the maximum
size an u8 can hold is 255 and the error counter can exceed this value
if bus-off status occurs. As such, the first nine patches of this
series make sure that no drivers try to report txerr or rxerr through
the CAN error frame when bus-off status is reached.

can_frame::data[5..7] are defined as being "controller
specific". Controller specific behaviors are not something desirable
(portability issue...) The tenth patch of this series specifies how
can_frame::data[5..7] should be use and remove any "controller
specific" freedom. The eleventh patch adds a flag to notify though
can_frame::can_id that data[6..7] were populated (in order to be
consistent with other fields).

Finally, the twelfth and last patch add three macro values to specify
the different error counter threshold with so far was hard-coded as
magic numbers in the drivers.

N.B.:
  * patches 1 to 10 are for net (stable).
  * patches 11 and 12 are for net-next (but depends on patches 1 to 10).

** Changelog **

v1 -> v2: https://lore.kernel.org/all/20220712153157.83847-1-mailhol.vincent@wanadoo.fr
  * Fix typo in patch #10: data[7] of CAN error frames is for the RX
    error counter, not the TX one (this is litteraly a one byte
    change).
====================

As discussed take the whole series via can-next -> net-next.

Link: https://lore.kernel.org/all/20220719143550.3681-1-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
Marc Kleine-Budde committed Jul 20, 2022
2 parents d79ee9a + 3f9c262 commit 1dbd874
Show file tree
Hide file tree
Showing 25 changed files with 94 additions and 52 deletions.
6 changes: 3 additions & 3 deletions drivers/net/can/c_can/c_can_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -952,14 +952,14 @@ static int c_can_handle_state_change(struct net_device *dev,

switch (error_type) {
case C_CAN_NO_ERROR:
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
break;
case C_CAN_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
Expand All @@ -969,7 +969,7 @@ static int c_can_handle_state_change(struct net_device *dev,
break;
case C_CAN_ERROR_PASSIVE:
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
if (rx_err_passive)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
if (bec.txerr > 127)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/cc770/cc770.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ static int cc770_err(struct net_device *dev, u8 status)

/* Use extended functions of the CC770 */
if (priv->control_normal_mode & CTRL_EAF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = cc770_read_reg(priv, tx_error_counter);
cf->data[7] = cc770_read_reg(priv, rx_error_counter);
}
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/can/ctucanfd/ctucanfd_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
case CAN_STATE_ERROR_PASSIVE:
priv->can.can_stats.error_passive++;
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.rxerr > 127) ?
CAN_ERR_CRTL_RX_PASSIVE :
CAN_ERR_CRTL_TX_PASSIVE;
Expand All @@ -858,7 +858,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
case CAN_STATE_ERROR_WARNING:
priv->can.can_stats.error_warning++;
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] |= (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
Expand All @@ -867,6 +867,7 @@ static void ctucan_err_interrupt(struct net_device *ndev, u32 isr)
}
break;
case CAN_STATE_ERROR_ACTIVE:
cf->can_id |= CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/grcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ static void grcan_err(struct net_device *dev, u32 sources, u32 status)
/* There are no others at this point */
break;
}
cf.can_id |= CAN_ERR_CNT;
cf.data[6] = txerr;
cf.data[7] = rxerr;
priv->can.state = state;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/can/ifi_canfd/ifi_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
switch (new_state) {
case CAN_STATE_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
Expand All @@ -501,7 +501,7 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
break;
case CAN_STATE_ERROR_PASSIVE:
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
if (bec.txerr > 127)
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/can/janz-ican3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
/* bus error interrupt */
if (isrc == CEVTIND_BEI) {
mod->can.can_stats.bus_error++;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;

switch (ecc & ECC_MASK) {
case ECC_BIT:
Expand All @@ -1153,7 +1153,7 @@ static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)

if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING ||
state == CAN_STATE_ERROR_PASSIVE)) {
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
if (state == CAN_STATE_ERROR_WARNING) {
mod->can.can_stats.error_warning++;
cf->data[1] = (txerr > rxerr) ?
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/kvaser_pciefd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
shhwtstamps->hwtstamp =
ns_to_ktime(div_u64(p->timestamp * 1000,
can->kv_pcie->freq_to_ticks_div));
cf->can_id |= CAN_ERR_BUSERROR;
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_CNT;

cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/can/m_can/m_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ static int m_can_handle_state_change(struct net_device *dev,
switch (new_state) {
case CAN_STATE_ERROR_WARNING:
/* error warning state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (bec.txerr > bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
Expand All @@ -750,7 +750,7 @@ static int m_can_handle_state_change(struct net_device *dev,
break;
case CAN_STATE_ERROR_PASSIVE:
/* error passive state */
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
ecr = m_can_read(cdev, M_CAN_ECR);
if (ecr & ECR_RP)
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/can/pch_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@ static void pch_can_error(struct net_device *ndev, u32 status)
cf->can_id |= CAN_ERR_BUSOFF;
priv->can.can_stats.bus_off++;
can_bus_off(ndev);
} else {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = errc & PCH_TEC;
cf->data[7] = (errc & PCH_REC) >> 8;
}

errc = ioread32(&priv->regs->errc);
Expand Down Expand Up @@ -556,9 +560,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
break;
}

cf->data[6] = errc & PCH_TEC;
cf->data[7] = (errc & PCH_REC) >> 8;

priv->can.state = state;
netif_receive_skb(skb);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/can/peak_canfd/peak_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
priv->can.state = CAN_STATE_ERROR_PASSIVE;
priv->can.can_stats.error_passive++;
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE;
Expand All @@ -386,7 +386,7 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
priv->can.state = CAN_STATE_ERROR_WARNING;
priv->can.can_stats.error_warning++;
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = (priv->bec.txerr > priv->bec.rxerr) ?
CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
Expand Down Expand Up @@ -430,7 +430,7 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
return -ENOMEM;
}

cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;

cf->data[6] = priv->bec.txerr;
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/can/rcar/rcar_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,8 @@ static void rcar_can_error(struct net_device *ndev)
if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
txerr = readb(&priv->regs->tecr);
rxerr = readb(&priv->regs->recr);
if (skb) {
if (skb)
cf->can_id |= CAN_ERR_CRTL;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
}
if (eifr & RCAR_CAN_EIFR_BEIF) {
int rx_errors = 0, tx_errors = 0;
Expand Down Expand Up @@ -336,6 +333,10 @@ static void rcar_can_error(struct net_device *ndev)
can_bus_off(ndev);
if (skb)
cf->can_id |= CAN_ERR_BUSOFF;
} else if (skb) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (eifr & RCAR_CAN_EIFR_ORIF) {
netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/can/rcar/rcar_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
netdev_dbg(ndev, "Error warning interrupt\n");
priv->can.state = CAN_STATE_ERROR_WARNING;
priv->can.can_stats.error_warning++;
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING :
CAN_ERR_CRTL_RX_WARNING;
cf->data[6] = txerr;
Expand All @@ -1062,7 +1062,7 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
netdev_dbg(ndev, "Error passive interrupt\n");
priv->can.state = CAN_STATE_ERROR_PASSIVE;
priv->can.can_stats.error_passive++;
cf->can_id |= CAN_ERR_CRTL;
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE :
CAN_ERR_CRTL_RX_PASSIVE;
cf->data[6] = txerr;
Expand Down
8 changes: 5 additions & 3 deletions drivers/net/can/sja1000/sja1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
txerr = priv->read_reg(priv, SJA1000_TXERR);
rxerr = priv->read_reg(priv, SJA1000_RXERR);

cf->data[6] = txerr;
cf->data[7] = rxerr;

if (isrc & IRQ_DOI) {
/* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n");
Expand All @@ -428,6 +425,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
else
state = CAN_STATE_ERROR_ACTIVE;
}
if (state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (isrc & IRQ_BEI) {
/* bus error interrupt */
priv->can.can_stats.bus_error++;
Expand Down
13 changes: 6 additions & 7 deletions drivers/net/can/slcan/slcan-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,19 +306,18 @@ static void slc_bump_state(struct slcan *sl)
return;

skb = alloc_can_err_skb(dev, &cf);
if (skb) {
cf->data[6] = txerr;
cf->data[7] = rxerr;
} else {
cf = NULL;
}

tx_state = txerr >= rxerr ? state : 0;
rx_state = txerr <= rxerr ? state : 0;
can_change_state(dev, cf, tx_state, rx_state);

if (state == CAN_STATE_BUS_OFF)
if (state == CAN_STATE_BUS_OFF) {
can_bus_off(dev);
} else if (skb) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}

if (skb)
netif_rx(skb);
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/can/spi/hi311x.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,6 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)

txerr = hi3110_read(spi, HI3110_READ_TEC);
rxerr = hi3110_read(spi, HI3110_READ_REC);
cf->data[6] = txerr;
cf->data[7] = rxerr;
tx_state = txerr >= rxerr ? new_state : 0;
rx_state = txerr <= rxerr ? new_state : 0;
can_change_state(net, cf, tx_state, rx_state);
Expand All @@ -681,6 +679,10 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
hi3110_hw_sleep(spi);
break;
}
} else {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
}

Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,7 @@ static int mcp251xfd_handle_cerrif(struct mcp251xfd_priv *priv)
err = mcp251xfd_get_berr_counter(priv->ndev, &bec);
if (err)
return err;
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
}
Expand Down
10 changes: 5 additions & 5 deletions drivers/net/can/sun4i_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,6 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
rxerr = (errc >> 16) & 0xFF;
txerr = errc & 0xFF;

if (skb) {
cf->data[6] = txerr;
cf->data[7] = rxerr;
}

if (isrc & SUN4I_INT_DATA_OR) {
/* data overrun interrupt */
netdev_dbg(dev, "data overrun interrupt\n");
Expand Down Expand Up @@ -570,6 +565,11 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
else
state = CAN_STATE_ERROR_ACTIVE;
}
if (skb && state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = txerr;
cf->data[7] = rxerr;
}
if (isrc & SUN4I_INT_BUS_ERR) {
/* bus error interrupt */
netdev_dbg(dev, "bus error interrupt\n");
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/ti_hecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ static void ti_hecc_change_state(struct net_device *ndev,
can_change_state(priv->ndev, cf, tx_state, rx_state);

if (max(tx_state, rx_state) != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = hecc_read(priv, HECC_CANTEC);
cf->data[7] = hecc_read(priv, HECC_CANREC);
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/can/usb/esd_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
priv->can.can_stats.bus_error++;
stats->rx_errors++;

cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR |
CAN_ERR_CNT;

switch (ecc & SJA1000_ECC_MASK) {
case SJA1000_ECC_BIT:
Expand Down
14 changes: 10 additions & 4 deletions drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,8 +917,11 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
new_state < CAN_STATE_BUS_OFF)
priv->can.can_stats.restarts++;

cf->data[6] = bec->txerr;
cf->data[7] = bec->rxerr;
if (new_state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec->txerr;
cf->data[7] = bec->rxerr;
}

netif_rx(skb);
}
Expand Down Expand Up @@ -1069,8 +1072,11 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
shhwtstamps->hwtstamp = hwtstamp;

cf->can_id |= CAN_ERR_BUSERROR;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
if (new_state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
}

netif_rx(skb);

Expand Down
7 changes: 5 additions & 2 deletions drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -853,8 +853,11 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
break;
}

cf->data[6] = es->txerr;
cf->data[7] = es->rxerr;
if (new_state != CAN_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_CNT;
cf->data[6] = es->txerr;
cf->data[7] = es->rxerr;
}

netif_rx(skb);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/net/can/usb/peak_usb/pcan_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
/* Supply TX/RX error counters in case of
* controller error.
*/
cf->can_id = CAN_ERR_CNT;
cf->data[6] = mc->pdev->bec.txerr;
cf->data[7] = mc->pdev->bec.rxerr;
}
Expand Down
Loading

0 comments on commit 1dbd874

Please sign in to comment.