On 21.07.2023 05:23:02, Goud, Srinivas wrote: > >> + if (priv->ecc_enable) { > >> + u32 reg_ecc; > >> + > >> + reg_ecc = priv->read_reg(priv, XCAN_RXFIFO_ECC_OFFSET); > >> + if (isr & XCAN_IXR_E2BERX_MASK) { > >> + priv->ecc_2bit_rxfifo_cnt += > >> + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, > >reg_ecc); > >> + netdev_dbg(ndev, "%s: RX FIFO 2bit ECC error count > >%d\n", > >> + __func__, priv->ecc_2bit_rxfifo_cnt); > >> + } > >> + if (isr & XCAN_IXR_E1BERX_MASK) { > >> + priv->ecc_1bit_rxfifo_cnt += reg_ecc & > >> + XCAN_ECC_1BIT_CNT_MASK; > > > >Please use FIELD_GET here, too. > > > >> + netdev_dbg(ndev, "%s: RX FIFO 1bit ECC error count > >%d\n", > >> + __func__, priv->ecc_1bit_rxfifo_cnt); > >> + } > >> + > >> + reg_ecc = priv->read_reg(priv, XCAN_TXOLFIFO_ECC_OFFSET); > >> + if (isr & XCAN_IXR_E2BETXOL_MASK) { > >> + priv->ecc_2bit_txolfifo_cnt += > >> + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, > >reg_ecc); > >> + netdev_dbg(ndev, "%s: TXOL FIFO 2bit ECC error count > >%d\n", > >> + __func__, priv->ecc_2bit_txolfifo_cnt); > >> + } > >> + if (isr & XCAN_IXR_E1BETXOL_MASK) { > >> + priv->ecc_1bit_txolfifo_cnt += reg_ecc & > >> + XCAN_ECC_1BIT_CNT_MASK; > > > >same here > > > >> + netdev_dbg(ndev, "%s: TXOL FIFO 1bit ECC error count > >%d\n", > >> + __func__, priv->ecc_1bit_txolfifo_cnt); > >> + } > >> + > >> + reg_ecc = priv->read_reg(priv, XCAN_TXTLFIFO_ECC_OFFSET); > >> + if (isr & XCAN_IXR_E2BETXTL_MASK) { > >> + priv->ecc_2bit_txtlfifo_cnt += > >> + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, > >reg_ecc); > >> + netdev_dbg(ndev, "%s: TXTL FIFO 2bit ECC error count > >%d\n", > >> + __func__, priv->ecc_2bit_txtlfifo_cnt); > >> + } > >> + if (isr & XCAN_IXR_E1BETXTL_MASK) { > >> + priv->ecc_1bit_txtlfifo_cnt += reg_ecc & > >> + XCAN_ECC_1BIT_CNT_MASK; > > > >same here > > > >> + netdev_dbg(ndev, "%s: TXTL FIFO 1bit ECC error count > >%d\n", > >> + __func__, priv->ecc_1bit_txtlfifo_cnt); > >> + } > >> + > >> + /* Reset FIFO ECC counters */ > >> + priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, > >XCAN_ECC_CFG_REECRX_MASK | > >> + XCAN_ECC_CFG_REECTXOL_MASK | > >XCAN_ECC_CFG_REECTXTL_MASK); > > > >This is racy - you will lose events that occur between reading the register value > >and clearing the register. You can save the old value and add the difference > >between the new and the old value to the total counter. What happens when > >the counter overflows? The following pseudocode should handle the u16 > >counter rolling over to 0: > As per IP specifications when counter reaching maximum value of 0xFFFF will > stays there until reset. > > Not sure we can avoid this race condition completely, as we need to reset > the counters after reaching the 0xFFFF to avoid losing the events. > > To minimize the race condition, we can reset the counters after reaching > the events to 0xFFFF instead of resetting for every interrupt. > Can you please suggest if we can go this approach. Ok, the counter doesn't overflow. To keep the logic in the driver simple, I think it's best to read the value and reset the counter directly in the next line. Please add a comment like: "The counter reaches its maximum at 0xffff and does not overflow. Accept the small race window between reading and resetting." regards, Marc -- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung Nürnberg | Phone: +49-5121-206917-129 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
Attachment:
signature.asc
Description: PGP signature