All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/6] can: flexcan: implement error passive state quirk
@ 2017-09-13  9:36 ZHU Yi (ST-FIR/ENG1-Zhu)
  2017-09-13 12:46 ` Marc Kleine-Budde
  0 siblings, 1 reply; 3+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-09-13  9:36 UTC (permalink / raw)
  To: Wolfgang Grandegger, Marc Kleine-Budde, Andri Yngvason, linux-can
  Cc: hs, RUAN Tingquan (ST-FIR/ENG1-Zhu), Jonas Mark (ST-FIR/ENG1)

From d4e60c16aeb5f6108479cebb754539bcc3c2be5d Mon Sep 17 00:00:00 2001
From: Zhu Yi <yi.zhu5@cn.bosch.com>
Date: Thu, 31 Aug 2017 09:21:24 +0800
Subject: [PATCH 3/6] can: flexcan: implement error passive state quirk

Add FLEXCAN_QUIRK_BROKEN_PERR_STATE for better description
of the missing error passive interrupt quirk.

Error interrupt flooding may happen if the broken error state quirk
fix is enabled. For example, in case there is singled out node on
the bus and the node sends a frame, then error interrupt flooding
happens and will not stop because the node cannot go to bus off. The
flooding will stop after another node connected to the bus again.

If high bitrate configured on the low end system, then the flooding
may causes performance issue, hence, this patch mitigates this by:
1. disable error interrupt upon error passive state transition
2. re-enable error interrupt upon error warning state transition
3. disable/enable error interrupt upon error active state transition
   depends on FLEXCAN_QUIRK_BROKEN_WERR_STATE

In this way, the driver is still able to report correct state
transitions without additional latency. When there are bus problems,
flooding of error interrupts is limited to the number of frames
required to change state from error warning to error passive if the
core has [TR]WRN_INT connected (FLEXCAN_QUIRK_BROKEN_WERR_STATE is
not enabled), otherwise, the flooding is limited to the number of
frames required to change state from error active to error passive.

Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/flexcan.c | 79 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 70 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index e163c55..52b69fc 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -182,14 +182,14 @@
 /* FLEXCAN hardware feature flags
  *
  * Below is some version info we got:
- *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT Memory err RTR re-
- *                                Filter? connected?  detection  ception in MB
- *   MX25  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX28  FlexCAN2  03.00.04.00    yes       yes         no        no
- *   MX35  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX53  FlexCAN2  03.00.00.00    yes        no         no        no
- *   MX6s  FlexCAN3  10.00.12.00    yes       yes         no       yes
- *   VF610 FlexCAN3  ?               no       yes        yes       yes?
+ *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
+ *                                Filter? connected?  Passive detection  ception in MB
+ *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX28  FlexCAN2  03.00.04.00    yes       yes         ?       no        no
+ *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX53  FlexCAN2  03.00.00.00    yes        no        no?      no        no
+ *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
+ *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
@@ -198,6 +198,7 @@
 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS	BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
 #define FLEXCAN_QUIRK_DISABLE_MECR	BIT(4) /* Disable Memory error detection */
 #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP	BIT(5) /* Use timestamp based offloading */
+#define FLEXCAN_QUIRK_BROKEN_PERR_STATE	BIT(6) /* No interrupt for error passive */
 
 /* Structure of the message buffer */
 struct flexcan_mb {
@@ -335,6 +336,26 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
 }
 #endif
 
+static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
+{
+	struct flexcan_regs __iomem *regs = priv->regs;
+	u32 reg_ctrl;
+
+	reg_ctrl = flexcan_read(&regs->ctrl);
+	reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
+	flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
+static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
+{
+	struct flexcan_regs __iomem *regs = priv->regs;
+	u32 reg_ctrl;
+
+	reg_ctrl = flexcan_read(&regs->ctrl);
+	reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK;
+	flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
 {
 	if (!priv->reg_xceiver)
@@ -713,6 +734,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 	struct flexcan_regs __iomem *regs = priv->regs;
 	irqreturn_t handled = IRQ_NONE;
 	u32 reg_iflag1, reg_esr;
+	enum can_state last_state = priv->can.state;
 
 	reg_iflag1 = flexcan_read(&regs->iflag1);
 
@@ -767,7 +789,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 
 	/* state change interrupt or broken error state quirk fix is enabled */
 	if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
-	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE))
+	    (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE |
+	                                   FLEXCAN_QUIRK_BROKEN_PERR_STATE)))
 		flexcan_irq_state(dev, reg_esr);
 
 	/* bus error IRQ - handle if bus error reporting is activated */
@@ -775,6 +798,44 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 	    (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
 		flexcan_irq_bus_err(dev, reg_esr);
 
+	/* availability of error interrupt among state transitions in case
+	 * bus error reporting is de-activated and
+	 * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled:
+	 *  +--------------------------------------------------------------+
+	 *  | +----------------------------------------------+ [stopped /  |
+	 *  | |                                              |  sleeping] -+
+	 *  +-+-> active <-> warning <-> passive -> bus off -+
+	 *        ___________^^^^^^^^^^^^_______________________________
+	 *        disabled(1)  enabled             disabled
+	 *
+	 * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled
+	 */
+	if ((last_state != priv->can.state) &&
+	    (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) &&
+	   !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
+		switch (priv->can.state) {
+		case CAN_STATE_ERROR_ACTIVE:
+			if (priv->devtype_data->quirks &
+			    FLEXCAN_QUIRK_BROKEN_WERR_STATE)
+				flexcan_error_irq_enable(priv);
+			else
+				flexcan_error_irq_disable(priv);
+			break;
+
+		case CAN_STATE_ERROR_WARNING:
+			flexcan_error_irq_enable(priv);
+			break;
+
+		case CAN_STATE_ERROR_PASSIVE:
+		case CAN_STATE_BUS_OFF:
+			flexcan_error_irq_disable(priv);
+			break;
+
+		default:
+			break;
+		}
+	}
+
 	return handled;
 }
 
-- 
2.7.4




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 3/6] can: flexcan: implement error passive state quirk
  2017-09-13  9:36 [PATCH 3/6] can: flexcan: implement error passive state quirk ZHU Yi (ST-FIR/ENG1-Zhu)
@ 2017-09-13 12:46 ` Marc Kleine-Budde
  2017-09-14  8:26   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Kleine-Budde @ 2017-09-13 12:46 UTC (permalink / raw)
  To: ZHU Yi (ST-FIR/ENG1-Zhu), Wolfgang Grandegger, Andri Yngvason, linux-can
  Cc: hs, RUAN Tingquan (ST-FIR/ENG1-Zhu), Jonas Mark (ST-FIR/ENG1)


[-- Attachment #1.1: Type: text/plain, Size: 5318 bytes --]

On 09/13/2017 11:36 AM, ZHU Yi (ST-FIR/ENG1-Zhu) wrote:
> From d4e60c16aeb5f6108479cebb754539bcc3c2be5d Mon Sep 17 00:00:00 2001
> From: Zhu Yi <yi.zhu5@cn.bosch.com>
> Date: Thu, 31 Aug 2017 09:21:24 +0800
> Subject: [PATCH 3/6] can: flexcan: implement error passive state quirk
> 
> Add FLEXCAN_QUIRK_BROKEN_PERR_STATE for better description
> of the missing error passive interrupt quirk.
> 
> Error interrupt flooding may happen if the broken error state quirk
> fix is enabled. For example, in case there is singled out node on
> the bus and the node sends a frame, then error interrupt flooding
> happens and will not stop because the node cannot go to bus off. The
> flooding will stop after another node connected to the bus again.
> 
> If high bitrate configured on the low end system, then the flooding
> may causes performance issue, hence, this patch mitigates this by:
> 1. disable error interrupt upon error passive state transition
> 2. re-enable error interrupt upon error warning state transition
> 3. disable/enable error interrupt upon error active state transition
>    depends on FLEXCAN_QUIRK_BROKEN_WERR_STATE
> 
> In this way, the driver is still able to report correct state
> transitions without additional latency. When there are bus problems,
> flooding of error interrupts is limited to the number of frames
> required to change state from error warning to error passive if the
> core has [TR]WRN_INT connected (FLEXCAN_QUIRK_BROKEN_WERR_STATE is
> not enabled), otherwise, the flooding is limited to the number of
> frames required to change state from error active to error passive.
> 
> Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
> Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
> Acked-by: Wolfgang Grandegger <wg@grandegger.com>
> ---
>  drivers/net/can/flexcan.c | 79 +++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 70 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index e163c55..52b69fc 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -182,14 +182,14 @@
>  /* FLEXCAN hardware feature flags
>   *
>   * Below is some version info we got:
> - *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT Memory err RTR re-
> - *                                Filter? connected?  detection  ception in MB
> - *   MX25  FlexCAN2  03.00.00.00     no        no         no        no
> - *   MX28  FlexCAN2  03.00.04.00    yes       yes         no        no
> - *   MX35  FlexCAN2  03.00.00.00     no        no         no        no
> - *   MX53  FlexCAN2  03.00.00.00    yes        no         no        no
> - *   MX6s  FlexCAN3  10.00.12.00    yes       yes         no       yes
> - *   VF610 FlexCAN3  ?               no       yes        yes       yes?
> + *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
> + *                                Filter? connected?  Passive detection  ception in MB
> + *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
> + *   MX28  FlexCAN2  03.00.04.00    yes       yes         ?       no        no
> + *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
> + *   MX53  FlexCAN2  03.00.00.00    yes        no        no?      no        no
> + *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
> + *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
                                                            ^^^

Is there new information on this table after the tests on the mx53 and mx28?

>   *
>   * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
>   */
> @@ -198,6 +198,7 @@
>  #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS	BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
>  #define FLEXCAN_QUIRK_DISABLE_MECR	BIT(4) /* Disable Memory error detection */
>  #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP	BIT(5) /* Use timestamp based offloading */
> +#define FLEXCAN_QUIRK_BROKEN_PERR_STATE	BIT(6) /* No interrupt for error passive */
>  
>  /* Structure of the message buffer */
>  struct flexcan_mb {
> @@ -335,6 +336,26 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
>  }
>  #endif
>  
> +static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
> +{
> +	struct flexcan_regs __iomem *regs = priv->regs;
> +	u32 reg_ctrl;
> +
> +	reg_ctrl = flexcan_read(&regs->ctrl);

Please make use of "priv->reg_ctrl_default", there should be no need to
read regs->ctrl during runtime.

> +	reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
> +	flexcan_write(reg_ctrl, &regs->ctrl);
> +}
> +
> +static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
> +{
> +	struct flexcan_regs __iomem *regs = priv->regs;
> +	u32 reg_ctrl;
> +
> +	reg_ctrl = flexcan_read(&regs->ctrl);
> +	reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK;

same here

> +	flexcan_write(reg_ctrl, &regs->ctrl);
> +}

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH 3/6] can: flexcan: implement error passive state quirk
  2017-09-13 12:46 ` Marc Kleine-Budde
@ 2017-09-14  8:26   ` ZHU Yi (ST-FIR/ENG1-Zhu)
  0 siblings, 0 replies; 3+ messages in thread
From: ZHU Yi (ST-FIR/ENG1-Zhu) @ 2017-09-14  8:26 UTC (permalink / raw)
  To: Marc Kleine-Budde, Wolfgang Grandegger, Andri Yngvason, linux-can
  Cc: hs, RUAN Tingquan (ST-FIR/ENG1-Zhu), Jonas Mark (ST-FIR/ENG1)

Hello Marc,

>From: Marc Kleine-Budde [mailto:mkl@pengutronix.de]
>Sent: Wednesday, September 13, 2017 8:47 PM
>> [...]
>> + *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
>> + *                                Filter? connected?  Passive detection  ception in MB
>> + *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
>> + *   MX28  FlexCAN2  03.00.04.00    yes       yes         ?       no        no
>> + *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
>> + *   MX53  FlexCAN2  03.00.00.00    yes        no        no?      no        no
>> + *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
>> + *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
>                                                            ^^^
>
>Is there new information on this table after the tests on the mx53 and mx28?
Sorry, I overlooked this. I'll fix this in the updated patches. :)

>
>> [...]
>>
>> +static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
>> +{
>> +	struct flexcan_regs __iomem *regs = priv->regs;
>> +	u32 reg_ctrl;
>> +
>> +	reg_ctrl = flexcan_read(&regs->ctrl);
>
>Please make use of "priv->reg_ctrl_default", there should be no need to
>read regs->ctrl during runtime.
That's a good catch. Test with i.MX6 works fine after the change,
so we can optimize further here.

>
>> +	reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
>> +	flexcan_write(reg_ctrl, &regs->ctrl);
>> +}
>> +
>> +static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
>> +{
>> +	struct flexcan_regs __iomem *regs = priv->regs;
>> +	u32 reg_ctrl;
>> +
>> +	reg_ctrl = flexcan_read(&regs->ctrl);
>> +	reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK;
>
>same here
Yes, thanks!

Best regards
Yi

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-09-14  8:26 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-13  9:36 [PATCH 3/6] can: flexcan: implement error passive state quirk ZHU Yi (ST-FIR/ENG1-Zhu)
2017-09-13 12:46 ` Marc Kleine-Budde
2017-09-14  8:26   ` ZHU Yi (ST-FIR/ENG1-Zhu)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.