All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too
@ 2016-05-07 22:34 Marek Vasut
  2016-05-07 22:34 ` [PATCH 2/6] net: can: ifi: Update timing configuration code Marek Vasut
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can
  Cc: Marek Vasut, Marc Kleine-Budde, Mark Rutland, Oliver Hartkopp,
	Wolfgang Grandegger

Start the NAPI polling in case the bus warning interrupt happens,
since it is the poll function which checks and reports the warning.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index a1bd54f..1ad05f1 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -497,7 +497,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
 	struct ifi_canfd_priv *priv = netdev_priv(ndev);
 	struct net_device_stats *stats = &ndev->stats;
 	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
-				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER;
+				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
+				IFI_CANFD_INTERRUPT_ERROR_WARNING;
 	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
 				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
 	const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
@@ -513,7 +514,7 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
 	/* Clear all pending interrupts but ErrWarn */
 	writel(clr_irq_mask, priv->base + IFI_CANFD_INTERRUPT);
 
-	/* RX IRQ, start NAPI */
+	/* RX IRQ or bus warning, start NAPI */
 	if (isr & rx_irq_mask) {
 		ifi_canfd_irq_enable(ndev, 0);
 		napi_schedule(&priv->napi);
-- 
2.7.0


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

* [PATCH 2/6] net: can: ifi: Update timing configuration code
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
@ 2016-05-07 22:34 ` Marek Vasut
  2016-05-07 22:34 ` [PATCH 3/6] net: can: ifi: Unify timing constants Marek Vasut
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can
  Cc: Marek Vasut, Marc Kleine-Budde, Mark Rutland, Oliver Hartkopp,
	Wolfgang Grandegger

The updated documentation regarding the IFI CANFD core from April 2016
adds more details regarding the timing calculation. There is no longer
any distinction in the timing calculation between CANFD and CAN2.0, but
instead there are two timing modes -- 4_12_6_6 and 7_9_8_8 -- where the
numbers mean the width in bits of the SJW/Prescaler/TimeA/TimeB fields.
The code uses 7_9_8_8 mode, which allows more fine-grained control over
the timing.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 54 ++++++++++++++---------------------
 1 file changed, 21 insertions(+), 33 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 1ad05f1..b9efd6e 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -34,6 +34,7 @@
 #define IFI_CANFD_STCMD_LOOPBACK		BIT(18)
 #define IFI_CANFD_STCMD_DISABLE_CANFD		BIT(24)
 #define IFI_CANFD_STCMD_ENABLE_ISO		BIT(25)
+#define IFI_CANFD_STCMD_ENABLE_7_9_8_8_TIMING	BIT(26)
 #define IFI_CANFD_STCMD_NORMAL_MODE		((u32)BIT(31))
 
 #define IFI_CANFD_RXSTCMD			0x4
@@ -71,12 +72,12 @@
 #define IFI_CANFD_TIME_TIMEB_OFF		0
 #define IFI_CANFD_TIME_TIMEA_OFF		8
 #define IFI_CANFD_TIME_PRESCALE_OFF		16
-#define IFI_CANFD_TIME_SJW_OFF_ISO		25
-#define IFI_CANFD_TIME_SJW_OFF_BOSCH		28
-#define IFI_CANFD_TIME_SET_SJW_BOSCH		BIT(6)
-#define IFI_CANFD_TIME_SET_TIMEB_BOSCH		BIT(7)
-#define IFI_CANFD_TIME_SET_PRESC_BOSCH		BIT(14)
-#define IFI_CANFD_TIME_SET_TIMEA_BOSCH		BIT(15)
+#define IFI_CANFD_TIME_SJW_OFF_7_9_8_8		25
+#define IFI_CANFD_TIME_SJW_OFF_4_12_6_6		28
+#define IFI_CANFD_TIME_SET_SJW_4_12_6_6		BIT(6)
+#define IFI_CANFD_TIME_SET_TIMEB_4_12_6_6	BIT(7)
+#define IFI_CANFD_TIME_SET_PRESC_4_12_6_6	BIT(14)
+#define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6	BIT(15)
 
 #define IFI_CANFD_TDELAY			0x1c
 
@@ -534,24 +535,24 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
 static const struct can_bittiming_const ifi_canfd_bittiming_const = {
 	.name		= KBUILD_MODNAME,
 	.tseg1_min	= 1,	/* Time segment 1 = prop_seg + phase_seg1 */
-	.tseg1_max	= 64,
+	.tseg1_max	= 256,
 	.tseg2_min	= 2,	/* Time segment 2 = phase_seg2 */
-	.tseg2_max	= 64,
-	.sjw_max	= 16,
+	.tseg2_max	= 256,
+	.sjw_max	= 128,
 	.brp_min	= 2,
-	.brp_max	= 256,
+	.brp_max	= 512,
 	.brp_inc	= 1,
 };
 
 static const struct can_bittiming_const ifi_canfd_data_bittiming_const = {
 	.name		= KBUILD_MODNAME,
 	.tseg1_min	= 1,	/* Time segment 1 = prop_seg + phase_seg1 */
-	.tseg1_max	= 64,
+	.tseg1_max	= 256,
 	.tseg2_min	= 2,	/* Time segment 2 = phase_seg2 */
-	.tseg2_max	= 64,
-	.sjw_max	= 16,
+	.tseg2_max	= 256,
+	.sjw_max	= 128,
 	.brp_min	= 2,
-	.brp_max	= 256,
+	.brp_max	= 512,
 	.brp_inc	= 1,
 };
 
@@ -561,19 +562,6 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
 	const struct can_bittiming *bt = &priv->can.bittiming;
 	const struct can_bittiming *dbt = &priv->can.data_bittiming;
 	u16 brp, sjw, tseg1, tseg2;
-	u32 noniso_arg = 0;
-	u32 time_off;
-
-	if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) &&
-	    !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) {
-		time_off = IFI_CANFD_TIME_SJW_OFF_ISO;
-	} else {
-		noniso_arg = IFI_CANFD_TIME_SET_TIMEB_BOSCH |
-			     IFI_CANFD_TIME_SET_TIMEA_BOSCH |
-			     IFI_CANFD_TIME_SET_PRESC_BOSCH |
-			     IFI_CANFD_TIME_SET_SJW_BOSCH;
-		time_off = IFI_CANFD_TIME_SJW_OFF_BOSCH;
-	}
 
 	/* Configure bit timing */
 	brp = bt->brp - 2;
@@ -583,8 +571,7 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
 	writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) |
 	       (tseg1 << IFI_CANFD_TIME_TIMEA_OFF) |
 	       (brp << IFI_CANFD_TIME_PRESCALE_OFF) |
-	       (sjw << time_off) |
-	       noniso_arg,
+	       (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8),
 	       priv->base + IFI_CANFD_TIME);
 
 	/* Configure data bit timing */
@@ -595,8 +582,7 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev)
 	writel((tseg2 << IFI_CANFD_TIME_TIMEB_OFF) |
 	       (tseg1 << IFI_CANFD_TIME_TIMEA_OFF) |
 	       (brp << IFI_CANFD_TIME_PRESCALE_OFF) |
-	       (sjw << time_off) |
-	       noniso_arg,
+	       (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8),
 	       priv->base + IFI_CANFD_FTIME);
 }
 
@@ -641,7 +627,8 @@ static void ifi_canfd_start(struct net_device *ndev)
 
 	/* Reset the IP */
 	writel(IFI_CANFD_STCMD_HARDRESET, priv->base + IFI_CANFD_STCMD);
-	writel(0, priv->base + IFI_CANFD_STCMD);
+	writel(IFI_CANFD_STCMD_ENABLE_7_9_8_8_TIMING,
+	       priv->base + IFI_CANFD_STCMD);
 
 	ifi_canfd_set_bittiming(ndev);
 	ifi_canfd_set_filters(ndev);
@@ -660,7 +647,8 @@ static void ifi_canfd_start(struct net_device *ndev)
 	writel((u32)(~IFI_CANFD_INTERRUPT_SET_IRQ),
 	       priv->base + IFI_CANFD_INTERRUPT);
 
-	stcmd = IFI_CANFD_STCMD_ENABLE | IFI_CANFD_STCMD_NORMAL_MODE;
+	stcmd = IFI_CANFD_STCMD_ENABLE | IFI_CANFD_STCMD_NORMAL_MODE |
+		IFI_CANFD_STCMD_ENABLE_7_9_8_8_TIMING;
 
 	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
 		stcmd |= IFI_CANFD_STCMD_BUSMONITOR;
-- 
2.7.0


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

* [PATCH 3/6] net: can: ifi: Unify timing constants
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
  2016-05-07 22:34 ` [PATCH 2/6] net: can: ifi: Update timing configuration code Marek Vasut
@ 2016-05-07 22:34 ` Marek Vasut
  2016-05-07 22:34 ` [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly Marek Vasut
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can
  Cc: Marek Vasut, Marc Kleine-Budde, Mark Rutland, Oliver Hartkopp,
	Wolfgang Grandegger

There is no distinction between bittiming constants for the slow and
fast part of the CANFD operation on this controller, so just use one
single bittiming constant set.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index b9efd6e..30dc3b6 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -544,18 +544,6 @@ static const struct can_bittiming_const ifi_canfd_bittiming_const = {
 	.brp_inc	= 1,
 };
 
-static const struct can_bittiming_const ifi_canfd_data_bittiming_const = {
-	.name		= KBUILD_MODNAME,
-	.tseg1_min	= 1,	/* Time segment 1 = prop_seg + phase_seg1 */
-	.tseg1_max	= 256,
-	.tseg2_min	= 2,	/* Time segment 2 = phase_seg2 */
-	.tseg2_max	= 256,
-	.sjw_max	= 128,
-	.brp_min	= 2,
-	.brp_max	= 512,
-	.brp_inc	= 1,
-};
-
 static void ifi_canfd_set_bittiming(struct net_device *ndev)
 {
 	struct ifi_canfd_priv *priv = netdev_priv(ndev);
@@ -866,7 +854,7 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
 	priv->can.clock.freq = readl(addr + IFI_CANFD_CANCLOCK);
 
 	priv->can.bittiming_const	= &ifi_canfd_bittiming_const;
-	priv->can.data_bittiming_const	= &ifi_canfd_data_bittiming_const;
+	priv->can.data_bittiming_const	= &ifi_canfd_bittiming_const;
 	priv->can.do_set_mode		= ifi_canfd_set_mode;
 	priv->can.do_get_berr_counter	= ifi_canfd_get_berr_counter;
 
-- 
2.7.0


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

* [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
  2016-05-07 22:34 ` [PATCH 2/6] net: can: ifi: Update timing configuration code Marek Vasut
  2016-05-07 22:34 ` [PATCH 3/6] net: can: ifi: Unify timing constants Marek Vasut
@ 2016-05-07 22:34 ` Marek Vasut
  2016-05-08 18:26   ` Oliver Hartkopp
  2016-05-07 22:34 ` [PATCH 5/6] net: can: ifi: Increment TX counters only on real transmission Marek Vasut
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can
  Cc: Marek Vasut, Marc Kleine-Budde, Mark Rutland, Oliver Hartkopp,
	Wolfgang Grandegger

The CAN_CTRLMODE_FD flag is set for both ISO and BOSCH CANFD mode,
while the CAN_CTRLMODE_FD_NON_ISO is additional flag which is only
set for CANFD-BOSCH mode. Fix the handling of the flags to reflect
this.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 30dc3b6..5bd95dd 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -644,10 +644,11 @@ static void ifi_canfd_start(struct net_device *ndev)
 	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
 		stcmd |= IFI_CANFD_STCMD_LOOPBACK;
 
-	if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
+	if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) &&
+	    !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO))
 		stcmd |= IFI_CANFD_STCMD_ENABLE_ISO;
 
-	if (!(priv->can.ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO)))
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD))
 		stcmd |= IFI_CANFD_STCMD_DISABLE_CANFD;
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
-- 
2.7.0


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

* [PATCH 5/6] net: can: ifi: Increment TX counters only on real transmission
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
                   ` (2 preceding siblings ...)
  2016-05-07 22:34 ` [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly Marek Vasut
@ 2016-05-07 22:34 ` Marek Vasut
  2016-05-07 22:34 ` [PATCH 6/6] net: can: ifi: Add more detailed error reporting Marek Vasut
  2016-05-08 18:59 ` [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marc Kleine-Budde
  5 siblings, 0 replies; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can
  Cc: Marek Vasut, Marc Kleine-Budde, Mark Rutland, Oliver Hartkopp,
	Wolfgang Grandegger

Only increment the TX counters in the irq handler if a CAN message
was sent. The current code incremented the counters also if the TX
FIFO empty interrupt happened, which is incorrect.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 5bd95dd..ba6cd43 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -522,13 +522,15 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
 	}
 
 	/* TX IRQ */
-	if (isr & tx_irq_mask) {
+	if (isr & IFI_CANFD_INTERRUPT_TXFIFO_REMOVE) {
 		stats->tx_bytes += can_get_echo_skb(ndev, 0);
 		stats->tx_packets++;
 		can_led_event(ndev, CAN_LED_EVENT_TX);
-		netif_wake_queue(ndev);
 	}
 
+	if (isr & tx_irq_mask)
+		netif_wake_queue(ndev);
+
 	return IRQ_HANDLED;
 }
 
-- 
2.7.0


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

* [PATCH 6/6] net: can: ifi: Add more detailed error reporting
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
                   ` (3 preceding siblings ...)
  2016-05-07 22:34 ` [PATCH 5/6] net: can: ifi: Increment TX counters only on real transmission Marek Vasut
@ 2016-05-07 22:34 ` Marek Vasut
  2016-05-08 18:58   ` Marc Kleine-Budde
  2016-05-08 18:59 ` [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marc Kleine-Budde
  5 siblings, 1 reply; 11+ messages in thread
From: Marek Vasut @ 2016-05-07 22:34 UTC (permalink / raw)
  To: linux-can; +Cc: Marek Vasut

The updated specification for the IFI CANFD core contains description
of more detailed error reporting capability of the core. Implement
support for this detailed error reporting.

Signed-off-by: Marek Vasut <marex@denx.de>
---
 drivers/net/can/ifi_canfd/ifi_canfd.c | 109 ++++++++++++++++++++++++++++++++--
 1 file changed, 105 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index ba6cd43..495879f 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -52,7 +52,8 @@
 #define IFI_CANFD_TXSTCMD_OVERFLOW		BIT(13)
 
 #define IFI_CANFD_INTERRUPT			0xc
-#define IFI_CANFD_INTERRUPT_ERROR_WARNING	((u32)BIT(1))
+#define IFI_CANFD_INTERRUPT_ERROR_WARNING	BIT(1)
+#define IFI_CANFD_INTERRUPT_ERROR_COUNTER	BIT(10)
 #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY	BIT(16)
 #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE	BIT(22)
 #define IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY	BIT(24)
@@ -103,7 +104,26 @@
 
 #define IFI_CANFD_RES1				0x40
 
-#define IFI_CANFD_RES2				0x44
+#define IFI_CANFD_ERROR_CTR			0x44
+#define IFI_CANFD_ERROR_CTR_UNLOCK_MAGIC	0x21302899
+#define IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST	BIT(0)
+#define IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST	BIT(1)
+#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST	BIT(2)
+#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST	BIT(3)
+#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST	BIT(4)
+#define IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST	BIT(5)
+#define IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST	BIT(6)
+#define IFI_CANFD_ERROR_CTR_OVERLOAD_ALL	BIT(8)
+#define IFI_CANFD_ERROR_CTR_ACK_ERROR_ALL	BIT(9)
+#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_ALL	BIT(10)
+#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_ALL	BIT(11)
+#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_ALL	BIT(12)
+#define IFI_CANFD_ERROR_CTR_CRC_ERROR_ALL	BIT(13)
+#define IFI_CANFD_ERROR_CTR_FORM_ERROR_ALL	BIT(14)
+#define IFI_CANFD_ERROR_CTR_BITPOSITION_OFFSET	16
+#define IFI_CANFD_ERROR_CTR_BITPOSITION_MASK	0xff
+#define IFI_CANFD_ERROR_CTR_ER_RESET		BIT(30)
+#define IFI_CANFD_ERROR_CTR_ER_ENABLE		((u32)BIT(31))
 
 #define IFI_CANFD_PAR				0x48
 
@@ -197,6 +217,8 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
 	if (enable) {
 		enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
 			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
+		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+			enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
 	}
 
 	writel(IFI_CANFD_IRQMASK_SET_ERR |
@@ -335,6 +357,68 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
 	return 1;
 }
 
+static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
+{
+	struct ifi_canfd_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
+			    IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
+			    IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
+			    IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST |
+			    IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST |
+			    IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST |
+			    IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST;
+
+	if (!(errctr & errmask))	/* No error happened. */
+		return 0;
+
+	priv->can.can_stats.bus_error++;
+	stats->rx_errors++;
+
+	/* Propagate the error condition to the CAN stack. */
+	skb = alloc_can_err_skb(ndev, &cf);
+	if (unlikely(!skb))
+		return 0;
+
+	/* Read the error counter register and check for new errors. */
+	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
+		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
+		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
+		cf->data[2] |= CAN_ERR_PROT_BIT0;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
+		cf->data[2] |= CAN_ERR_PROT_BIT1;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+
+	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+
+	/* Reset the error counter, ack the IRQ and re-enable the counter. */
+	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
+	writel(IFI_CANFD_INTERRUPT_ERROR_COUNTER,
+	       priv->base + IFI_CANFD_INTERRUPT);
+	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
+
+	stats->rx_packets++;
+	stats->rx_bytes += cf->can_dlc;
+	netif_receive_skb(skb);
+
+	return 1;
+}
+
 static int ifi_canfd_get_berr_counter(const struct net_device *ndev,
 				      struct can_berr_counter *bec)
 {
@@ -470,6 +554,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
 
 	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
 	u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
+	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
 
 	/* Handle bus state changes */
 	if ((stcmd & stcmd_state_mask) ||
@@ -480,6 +565,10 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
 	if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
 		work_done += ifi_canfd_handle_lost_msg(ndev);
 
+	/* Handle lec errors on the bus */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+		work_done += ifi_canfd_handle_lec_err(ndev, errctr);
+
 	/* Handle normal messages on RX */
 	if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
 		work_done += ifi_canfd_do_rx_poll(ndev, quota - work_done);
@@ -499,7 +588,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
 	struct net_device_stats *stats = &ndev->stats;
 	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
 				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
-				IFI_CANFD_INTERRUPT_ERROR_WARNING;
+				IFI_CANFD_INTERRUPT_ERROR_WARNING |
+				IFI_CANFD_INTERRUPT_ERROR_COUNTER;
 	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
 				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
 	const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
@@ -657,6 +747,12 @@ static void ifi_canfd_start(struct net_device *ndev)
 
 	ifi_canfd_irq_enable(ndev, 1);
 
+	/* Unlock, reset and enable the error counter. */
+	writel(IFI_CANFD_ERROR_CTR_UNLOCK_MAGIC,
+	       priv->base + IFI_CANFD_ERROR_CTR);
+	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
+	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
+
 	/* Enable controller */
 	writel(stcmd, priv->base + IFI_CANFD_STCMD);
 }
@@ -665,6 +761,10 @@ static void ifi_canfd_stop(struct net_device *ndev)
 {
 	struct ifi_canfd_priv *priv = netdev_priv(ndev);
 
+	/* Reset and disable the error counter. */
+	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
+	writel(0, priv->base + IFI_CANFD_ERROR_CTR);
+
 	/* Reset the IP */
 	writel(IFI_CANFD_STCMD_HARDRESET, priv->base + IFI_CANFD_STCMD);
 
@@ -868,7 +968,8 @@ static int ifi_canfd_plat_probe(struct platform_device *pdev)
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
 				       CAN_CTRLMODE_LISTENONLY |
 				       CAN_CTRLMODE_FD |
-				       CAN_CTRLMODE_FD_NON_ISO;
+				       CAN_CTRLMODE_FD_NON_ISO |
+				       CAN_CTRLMODE_BERR_REPORTING;
 
 	platform_set_drvdata(pdev, ndev);
 	SET_NETDEV_DEV(ndev, dev);
-- 
2.7.0


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

* Re: [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly
  2016-05-07 22:34 ` [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly Marek Vasut
@ 2016-05-08 18:26   ` Oliver Hartkopp
  2016-05-08 18:55     ` Marc Kleine-Budde
  0 siblings, 1 reply; 11+ messages in thread
From: Oliver Hartkopp @ 2016-05-08 18:26 UTC (permalink / raw)
  To: Marek Vasut, linux-can
  Cc: Marc Kleine-Budde, Mark Rutland, Wolfgang Grandegger



On 05/08/2016 12:34 AM, Marek Vasut wrote:
> The CAN_CTRLMODE_FD flag is set for both ISO and BOSCH CANFD mode,
> while the CAN_CTRLMODE_FD_NON_ISO is additional flag which is only
> set for CANFD-BOSCH mode. Fix the handling of the flags to reflect
> this.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Oliver Hartkopp <socketcan@hartkopp.net>

Makes sense :-)

Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>


> Cc: Wolfgang Grandegger <wg@grandegger.com>
> ---
>   drivers/net/can/ifi_canfd/ifi_canfd.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index 30dc3b6..5bd95dd 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -644,10 +644,11 @@ static void ifi_canfd_start(struct net_device *ndev)
>   	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
>   		stcmd |= IFI_CANFD_STCMD_LOOPBACK;
>
> -	if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
> +	if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) &&
> +	    !(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO))
>   		stcmd |= IFI_CANFD_STCMD_ENABLE_ISO;
>
> -	if (!(priv->can.ctrlmode & (CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO)))
> +	if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD))
>   		stcmd |= IFI_CANFD_STCMD_DISABLE_CANFD;
>
>   	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>

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

* Re: [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly
  2016-05-08 18:26   ` Oliver Hartkopp
@ 2016-05-08 18:55     ` Marc Kleine-Budde
  0 siblings, 0 replies; 11+ messages in thread
From: Marc Kleine-Budde @ 2016-05-08 18:55 UTC (permalink / raw)
  To: Oliver Hartkopp, Marek Vasut, linux-can; +Cc: Mark Rutland, Wolfgang Grandegger


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

On 05/08/2016 08:26 PM, Oliver Hartkopp wrote:
> 
> 
> On 05/08/2016 12:34 AM, Marek Vasut wrote:
>> The CAN_CTRLMODE_FD flag is set for both ISO and BOSCH CANFD mode,
>> while the CAN_CTRLMODE_FD_NON_ISO is additional flag which is only
>> set for CANFD-BOSCH mode. Fix the handling of the flags to reflect
>> this.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Oliver Hartkopp <socketcan@hartkopp.net>
> 
> Makes sense :-)
> 
> Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>

Added to the patch.

Thanks,
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: 455 bytes --]

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

* Re: [PATCH 6/6] net: can: ifi: Add more detailed error reporting
  2016-05-07 22:34 ` [PATCH 6/6] net: can: ifi: Add more detailed error reporting Marek Vasut
@ 2016-05-08 18:58   ` Marc Kleine-Budde
  2016-05-08 19:25     ` Marek Vasut
  0 siblings, 1 reply; 11+ messages in thread
From: Marc Kleine-Budde @ 2016-05-08 18:58 UTC (permalink / raw)
  To: Marek Vasut, linux-can


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

On 05/08/2016 12:34 AM, Marek Vasut wrote:
> The updated specification for the IFI CANFD core contains description
> of more detailed error reporting capability of the core. Implement
> support for this detailed error reporting.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
>  drivers/net/can/ifi_canfd/ifi_canfd.c | 109 ++++++++++++++++++++++++++++++++--
>  1 file changed, 105 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index ba6cd43..495879f 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -52,7 +52,8 @@
>  #define IFI_CANFD_TXSTCMD_OVERFLOW		BIT(13)
>  
>  #define IFI_CANFD_INTERRUPT			0xc
> -#define IFI_CANFD_INTERRUPT_ERROR_WARNING	((u32)BIT(1))
> +#define IFI_CANFD_INTERRUPT_ERROR_WARNING	BIT(1)
> +#define IFI_CANFD_INTERRUPT_ERROR_COUNTER	BIT(10)
>  #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY	BIT(16)
>  #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE	BIT(22)
>  #define IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY	BIT(24)
> @@ -103,7 +104,26 @@
>  
>  #define IFI_CANFD_RES1				0x40
>  
> -#define IFI_CANFD_RES2				0x44
> +#define IFI_CANFD_ERROR_CTR			0x44
> +#define IFI_CANFD_ERROR_CTR_UNLOCK_MAGIC	0x21302899
> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST	BIT(0)
> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST	BIT(1)
> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST	BIT(2)
> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST	BIT(3)
> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST	BIT(4)
> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST	BIT(5)
> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST	BIT(6)
> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_ALL	BIT(8)
> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_ALL	BIT(9)
> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_ALL	BIT(10)
> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_ALL	BIT(11)
> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_ALL	BIT(12)
> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_ALL	BIT(13)
> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_ALL	BIT(14)
> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_OFFSET	16
> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_MASK	0xff
> +#define IFI_CANFD_ERROR_CTR_ER_RESET		BIT(30)
> +#define IFI_CANFD_ERROR_CTR_ER_ENABLE		((u32)BIT(31))
>  
>  #define IFI_CANFD_PAR				0x48
>  
> @@ -197,6 +217,8 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
>  	if (enable) {
>  		enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
>  			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
> +		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
> +			enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>  	}
>  
>  	writel(IFI_CANFD_IRQMASK_SET_ERR |
> @@ -335,6 +357,68 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
>  	return 1;
>  }
>  
> +static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
> +{
> +	struct ifi_canfd_priv *priv = netdev_priv(ndev);
> +	struct net_device_stats *stats = &ndev->stats;
> +	struct can_frame *cf;
> +	struct sk_buff *skb;
> +	const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
> +			    IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST |
> +			    IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST;
> +
> +	if (!(errctr & errmask))	/* No error happened. */
> +		return 0;
> +
> +	priv->can.can_stats.bus_error++;
> +	stats->rx_errors++;
> +
> +	/* Propagate the error condition to the CAN stack. */
> +	skb = alloc_can_err_skb(ndev, &cf);
> +	if (unlikely(!skb))
> +		return 0;
> +
> +	/* Read the error counter register and check for new errors. */
> +	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
> +		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_BIT0;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_BIT1;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_STUFF;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
> +		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
> +
> +	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
> +		cf->data[2] |= CAN_ERR_PROT_FORM;
> +
> +	/* Reset the error counter, ack the IRQ and re-enable the counter. */
> +	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
> +	writel(IFI_CANFD_INTERRUPT_ERROR_COUNTER,
> +	       priv->base + IFI_CANFD_INTERRUPT);
> +	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
> +
> +	stats->rx_packets++;
> +	stats->rx_bytes += cf->can_dlc;
> +	netif_receive_skb(skb);
> +
> +	return 1;
> +}
> +
>  static int ifi_canfd_get_berr_counter(const struct net_device *ndev,
>  				      struct can_berr_counter *bec)
>  {
> @@ -470,6 +554,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>  
>  	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
>  	u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
> +	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
>  
>  	/* Handle bus state changes */
>  	if ((stcmd & stcmd_state_mask) ||
> @@ -480,6 +565,10 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>  	if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
>  		work_done += ifi_canfd_handle_lost_msg(ndev);
>  
> +	/* Handle lec errors on the bus */
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
> +		work_done += ifi_canfd_handle_lec_err(ndev, errctr);
> +
>  	/* Handle normal messages on RX */
>  	if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
>  		work_done += ifi_canfd_do_rx_poll(ndev, quota - work_done);
> @@ -499,7 +588,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>  	struct net_device_stats *stats = &ndev->stats;
>  	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
>  				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
> -				IFI_CANFD_INTERRUPT_ERROR_WARNING;
> +				IFI_CANFD_INTERRUPT_ERROR_WARNING |
> +				IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>  	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>  				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
>  	const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |

I'll fold this hunk to get rid of another of this warnings :(


>   CC [M]  drivers/net/can/ifi_canfd/ifi_canfd.o
> drivers/net/can/ifi_canfd/ifi_canfd.c: In function ‘ifi_canfd_isr’:
> drivers/net/can/ifi_canfd/ifi_canfd.c:595:27: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>   const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
>                            ^

> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
> index 495879f30906..2d1d22eec750 100644
> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
> @@ -592,8 +592,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>                                 IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>         const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>                                 IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
> -       const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
> -                                  IFI_CANFD_INTERRUPT_ERROR_WARNING);
> +       const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ |
> +                                        IFI_CANFD_INTERRUPT_ERROR_WARNING));
>         u32 isr;
>  
>         isr = readl(priv->base + IFI_CANFD_INTERRUPT);

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: 455 bytes --]

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

* Re: [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too
  2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
                   ` (4 preceding siblings ...)
  2016-05-07 22:34 ` [PATCH 6/6] net: can: ifi: Add more detailed error reporting Marek Vasut
@ 2016-05-08 18:59 ` Marc Kleine-Budde
  5 siblings, 0 replies; 11+ messages in thread
From: Marc Kleine-Budde @ 2016-05-08 18:59 UTC (permalink / raw)
  To: Marek Vasut, linux-can; +Cc: Mark Rutland, Oliver Hartkopp, Wolfgang Grandegger


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

On 05/08/2016 12:34 AM, Marek Vasut wrote:
> Start the NAPI polling in case the bus warning interrupt happens,
> since it is the poll function which checks and reports the warning.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Oliver Hartkopp <socketcan@hartkopp.net>
> Cc: Wolfgang Grandegger <wg@grandegger.com>

Added all 6 to net-next/master.

thanks,
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: 455 bytes --]

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

* Re: [PATCH 6/6] net: can: ifi: Add more detailed error reporting
  2016-05-08 18:58   ` Marc Kleine-Budde
@ 2016-05-08 19:25     ` Marek Vasut
  0 siblings, 0 replies; 11+ messages in thread
From: Marek Vasut @ 2016-05-08 19:25 UTC (permalink / raw)
  To: Marc Kleine-Budde, linux-can

On 05/08/2016 08:58 PM, Marc Kleine-Budde wrote:
> On 05/08/2016 12:34 AM, Marek Vasut wrote:
>> The updated specification for the IFI CANFD core contains description
>> of more detailed error reporting capability of the core. Implement
>> support for this detailed error reporting.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> ---
>>  drivers/net/can/ifi_canfd/ifi_canfd.c | 109 ++++++++++++++++++++++++++++++++--
>>  1 file changed, 105 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
>> index ba6cd43..495879f 100644
>> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
>> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
>> @@ -52,7 +52,8 @@
>>  #define IFI_CANFD_TXSTCMD_OVERFLOW		BIT(13)
>>  
>>  #define IFI_CANFD_INTERRUPT			0xc
>> -#define IFI_CANFD_INTERRUPT_ERROR_WARNING	((u32)BIT(1))
>> +#define IFI_CANFD_INTERRUPT_ERROR_WARNING	BIT(1)
>> +#define IFI_CANFD_INTERRUPT_ERROR_COUNTER	BIT(10)
>>  #define IFI_CANFD_INTERRUPT_TXFIFO_EMPTY	BIT(16)
>>  #define IFI_CANFD_INTERRUPT_TXFIFO_REMOVE	BIT(22)
>>  #define IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY	BIT(24)
>> @@ -103,7 +104,26 @@
>>  
>>  #define IFI_CANFD_RES1				0x40
>>  
>> -#define IFI_CANFD_RES2				0x44
>> +#define IFI_CANFD_ERROR_CTR			0x44
>> +#define IFI_CANFD_ERROR_CTR_UNLOCK_MAGIC	0x21302899
>> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST	BIT(0)
>> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST	BIT(1)
>> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST	BIT(2)
>> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST	BIT(3)
>> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST	BIT(4)
>> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST	BIT(5)
>> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST	BIT(6)
>> +#define IFI_CANFD_ERROR_CTR_OVERLOAD_ALL	BIT(8)
>> +#define IFI_CANFD_ERROR_CTR_ACK_ERROR_ALL	BIT(9)
>> +#define IFI_CANFD_ERROR_CTR_BIT0_ERROR_ALL	BIT(10)
>> +#define IFI_CANFD_ERROR_CTR_BIT1_ERROR_ALL	BIT(11)
>> +#define IFI_CANFD_ERROR_CTR_STUFF_ERROR_ALL	BIT(12)
>> +#define IFI_CANFD_ERROR_CTR_CRC_ERROR_ALL	BIT(13)
>> +#define IFI_CANFD_ERROR_CTR_FORM_ERROR_ALL	BIT(14)
>> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_OFFSET	16
>> +#define IFI_CANFD_ERROR_CTR_BITPOSITION_MASK	0xff
>> +#define IFI_CANFD_ERROR_CTR_ER_RESET		BIT(30)
>> +#define IFI_CANFD_ERROR_CTR_ER_ENABLE		((u32)BIT(31))
>>  
>>  #define IFI_CANFD_PAR				0x48
>>  
>> @@ -197,6 +217,8 @@ static void ifi_canfd_irq_enable(struct net_device *ndev, bool enable)
>>  	if (enable) {
>>  		enirq = IFI_CANFD_IRQMASK_TXFIFO_EMPTY |
>>  			IFI_CANFD_IRQMASK_RXFIFO_NEMPTY;
>> +		if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
>> +			enirq |= IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>>  	}
>>  
>>  	writel(IFI_CANFD_IRQMASK_SET_ERR |
>> @@ -335,6 +357,68 @@ static int ifi_canfd_handle_lost_msg(struct net_device *ndev)
>>  	return 1;
>>  }
>>  
>> +static int ifi_canfd_handle_lec_err(struct net_device *ndev, const u32 errctr)
>> +{
>> +	struct ifi_canfd_priv *priv = netdev_priv(ndev);
>> +	struct net_device_stats *stats = &ndev->stats;
>> +	struct can_frame *cf;
>> +	struct sk_buff *skb;
>> +	const u32 errmask = IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST |
>> +			    IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST;
>> +
>> +	if (!(errctr & errmask))	/* No error happened. */
>> +		return 0;
>> +
>> +	priv->can.can_stats.bus_error++;
>> +	stats->rx_errors++;
>> +
>> +	/* Propagate the error condition to the CAN stack. */
>> +	skb = alloc_can_err_skb(ndev, &cf);
>> +	if (unlikely(!skb))
>> +		return 0;
>> +
>> +	/* Read the error counter register and check for new errors. */
>> +	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
>> +		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
>> +		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
>> +		cf->data[2] |= CAN_ERR_PROT_BIT0;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
>> +		cf->data[2] |= CAN_ERR_PROT_BIT1;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
>> +		cf->data[2] |= CAN_ERR_PROT_STUFF;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
>> +		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
>> +
>> +	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
>> +		cf->data[2] |= CAN_ERR_PROT_FORM;
>> +
>> +	/* Reset the error counter, ack the IRQ and re-enable the counter. */
>> +	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
>> +	writel(IFI_CANFD_INTERRUPT_ERROR_COUNTER,
>> +	       priv->base + IFI_CANFD_INTERRUPT);
>> +	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
>> +
>> +	stats->rx_packets++;
>> +	stats->rx_bytes += cf->can_dlc;
>> +	netif_receive_skb(skb);
>> +
>> +	return 1;
>> +}
>> +
>>  static int ifi_canfd_get_berr_counter(const struct net_device *ndev,
>>  				      struct can_berr_counter *bec)
>>  {
>> @@ -470,6 +554,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>>  
>>  	u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
>>  	u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
>> +	u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
>>  
>>  	/* Handle bus state changes */
>>  	if ((stcmd & stcmd_state_mask) ||
>> @@ -480,6 +565,10 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
>>  	if (rxstcmd & IFI_CANFD_RXSTCMD_OVERFLOW)
>>  		work_done += ifi_canfd_handle_lost_msg(ndev);
>>  
>> +	/* Handle lec errors on the bus */
>> +	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
>> +		work_done += ifi_canfd_handle_lec_err(ndev, errctr);
>> +
>>  	/* Handle normal messages on RX */
>>  	if (!(rxstcmd & IFI_CANFD_RXSTCMD_EMPTY))
>>  		work_done += ifi_canfd_do_rx_poll(ndev, quota - work_done);
>> @@ -499,7 +588,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>>  	struct net_device_stats *stats = &ndev->stats;
>>  	const u32 rx_irq_mask = IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY |
>>  				IFI_CANFD_INTERRUPT_RXFIFO_NEMPTY_PER |
>> -				IFI_CANFD_INTERRUPT_ERROR_WARNING;
>> +				IFI_CANFD_INTERRUPT_ERROR_WARNING |
>> +				IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>>  	const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>>  				IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
>>  	const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
> 
> I'll fold this hunk to get rid of another of this warnings :(
> 
> 
>>   CC [M]  drivers/net/can/ifi_canfd/ifi_canfd.o
>> drivers/net/can/ifi_canfd/ifi_canfd.c: In function ‘ifi_canfd_isr’:
>> drivers/net/can/ifi_canfd/ifi_canfd.c:595:27: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>>   const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
>>                            ^

Thanks for spotting and fixing this!

>> diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
>> index 495879f30906..2d1d22eec750 100644
>> --- a/drivers/net/can/ifi_canfd/ifi_canfd.c
>> +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
>> @@ -592,8 +592,8 @@ static irqreturn_t ifi_canfd_isr(int irq, void *dev_id)
>>                                 IFI_CANFD_INTERRUPT_ERROR_COUNTER;
>>         const u32 tx_irq_mask = IFI_CANFD_INTERRUPT_TXFIFO_EMPTY |
>>                                 IFI_CANFD_INTERRUPT_TXFIFO_REMOVE;
>> -       const u32 clr_irq_mask = ~(IFI_CANFD_INTERRUPT_SET_IRQ |
>> -                                  IFI_CANFD_INTERRUPT_ERROR_WARNING);
>> +       const u32 clr_irq_mask = ~((u32)(IFI_CANFD_INTERRUPT_SET_IRQ |
>> +                                        IFI_CANFD_INTERRUPT_ERROR_WARNING));
>>         u32 isr;
>>  
>>         isr = readl(priv->base + IFI_CANFD_INTERRUPT);
> 
> Marc
> 


-- 
Best regards,
Marek Vasut

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

end of thread, other threads:[~2016-05-08 19:25 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-07 22:34 [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marek Vasut
2016-05-07 22:34 ` [PATCH 2/6] net: can: ifi: Update timing configuration code Marek Vasut
2016-05-07 22:34 ` [PATCH 3/6] net: can: ifi: Unify timing constants Marek Vasut
2016-05-07 22:34 ` [PATCH 4/6] net: can: ifi: Treat CAN_CTRLMODE_FD_NON_ISO correctly Marek Vasut
2016-05-08 18:26   ` Oliver Hartkopp
2016-05-08 18:55     ` Marc Kleine-Budde
2016-05-07 22:34 ` [PATCH 5/6] net: can: ifi: Increment TX counters only on real transmission Marek Vasut
2016-05-07 22:34 ` [PATCH 6/6] net: can: ifi: Add more detailed error reporting Marek Vasut
2016-05-08 18:58   ` Marc Kleine-Budde
2016-05-08 19:25     ` Marek Vasut
2016-05-08 18:59 ` [PATCH 1/6] net: can: ifi: Start NAPI poll on bus warning too Marc Kleine-Budde

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.