can: add CAN_ERR_CNT flag to notify availability of error counter
Add a dedicated flag in uapi/linux/can/error.h to notify the userland that fields data[6] and data[7] of the CAN error frame were respectively populated with the tx and rx error counters. For all driver tree-wide, set up this flags whenever needed. Link: https://lore.kernel.org/all/20220719143550.3681-12-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
e70a3263a7
commit
3e5c291c79
25 changed files with 38 additions and 18 deletions
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
@ -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) ?
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -497,6 +497,7 @@ static void pch_can_error(struct net_device *ndev, u32 status)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -334,6 +334,7 @@ static void rcar_can_error(struct net_device *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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -426,6 +426,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -314,6 +314,7 @@ static void slc_bump_state(struct slcan *sl)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -680,6 +680,7 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -566,6 +566,7 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -918,6 +918,7 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
|
|||
priv->can.can_stats.restarts++;
|
||||
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec->txerr;
|
||||
cf->data[7] = bec->rxerr;
|
||||
}
|
||||
|
@ -1072,6 +1073,7 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
|
|||
|
||||
cf->can_id |= CAN_ERR_BUSERROR;
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
}
|
||||
|
|
|
@ -854,6 +854,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
|
|||
}
|
||||
|
||||
if (new_state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = es->txerr;
|
||||
cf->data[7] = es->rxerr;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -439,6 +439,7 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
|
|||
if (rx_errors)
|
||||
stats->rx_errors++;
|
||||
if (priv->can.state != CAN_STATE_BUS_OFF) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
|
|
@ -965,6 +965,7 @@ static void xcan_set_error_state(struct net_device *ndev,
|
|||
can_change_state(ndev, cf, tx_state, rx_state);
|
||||
|
||||
if (cf) {
|
||||
cf->can_id |= CAN_ERR_CNT;
|
||||
cf->data[6] = txerr;
|
||||
cf->data[7] = rxerr;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#define CAN_ERR_BUSOFF 0x00000040U /* bus off */
|
||||
#define CAN_ERR_BUSERROR 0x00000080U /* bus error (may flood!) */
|
||||
#define CAN_ERR_RESTARTED 0x00000100U /* controller restarted */
|
||||
#define CAN_ERR_CNT 0x00000200U /* TX error counter / data[6] */
|
||||
/* RX error counter / data[7] */
|
||||
|
||||
/* arbitration lost in bit ... / data[0] */
|
||||
#define CAN_ERR_LOSTARB_UNSPEC 0x00 /* unspecified */
|
||||
|
|
Loading…
Add table
Reference in a new issue