* [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.