* [PATCH v2 01/11] can: flexcan: calculate default value for imask1 during runtime
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 02/11] can: flexcan: make TX mailbox selectable " Marc Kleine-Budde
` (11 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
This patch converts the define FLEXCAN_IFLAG_DEFAULT into the runtime
calculated value priv->reg_imask1_default. This is a preparation patch to make
the TX mailbox selectable during runtime, too.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 41c0fc9f3b14..b377e1069bf8 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -149,9 +149,6 @@
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
-#define FLEXCAN_IFLAG_DEFAULT \
- (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
- FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))
/* FLEXCAN message buffers */
#define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24)
@@ -254,6 +251,7 @@ struct flexcan_priv {
struct flexcan_regs __iomem *regs;
u32 reg_esr;
u32 reg_ctrl_default;
+ u32 reg_imask1_default;
struct clk *clk_ipg;
struct clk *clk_per;
@@ -705,7 +703,7 @@ static int flexcan_poll(struct napi_struct *napi, int quota)
if (work_done < quota) {
napi_complete(napi);
/* enable IRQs */
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(priv->reg_imask1_default, ®s->imask1);
flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
}
@@ -739,7 +737,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
* save them for later use.
*/
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
- flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+ flexcan_write(priv->reg_imask1_default &
~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
®s->ctrl);
@@ -942,7 +940,7 @@ static int flexcan_chip_start(struct net_device *dev)
/* enable interrupts atomically */
disable_irq(dev->irq);
flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
+ flexcan_write(priv->reg_imask1_default, ®s->imask1);
enable_irq(dev->irq);
/* print chip status */
@@ -1227,6 +1225,10 @@ static int flexcan_probe(struct platform_device *pdev)
priv->devtype_data = devtype_data;
priv->reg_xceiver = reg_xceiver;
+ priv->reg_imask1_default = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
+ FLEXCAN_IFLAG_RX_FIFO_AVAILABLE |
+ FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID);
+
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
platform_set_drvdata(pdev, dev);
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 02/11] can: flexcan: make TX mailbox selectable during runtime
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 01/11] can: flexcan: calculate default value for imask1 during runtime Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 03/11] can: rx-fifo: Add support for simple irq offloading Marc Kleine-Budde
` (10 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
This patch makes the TX mailbox selectable duing runtime. This is a preparation
patch to use of the hardware FIFO selectable via runtime. As the TX mailbox
number is different in HW FIFO and normal mode.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 42 ++++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index b377e1069bf8..52065f2f92e0 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -143,9 +143,9 @@
/* FLEXCAN interrupt flag register (IFLAG) bits */
/* Errata ERR005829 step7: Reserve first valid MB */
-#define FLEXCAN_TX_BUF_RESERVED 8
-#define FLEXCAN_TX_BUF_ID 9
-#define FLEXCAN_IFLAG_BUF(x) BIT(x)
+#define FLEXCAN_TX_MB_RESERVED_HW_FIFO 8
+#define FLEXCAN_TX_MB_HW_FIFO 9
+#define FLEXCAN_IFLAG_MB(x) BIT(x)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
@@ -249,6 +249,9 @@ struct flexcan_priv {
struct napi_struct napi;
struct flexcan_regs __iomem *regs;
+ struct flexcan_mb __iomem *tx_mb;
+ struct flexcan_mb __iomem *tx_mb_reserved;
+ u8 tx_mb_idx;
u32 reg_esr;
u32 reg_ctrl_default;
u32 reg_imask1_default;
@@ -466,7 +469,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
const struct flexcan_priv *priv = netdev_priv(dev);
- struct flexcan_regs __iomem *regs = priv->regs;
struct can_frame *cf = (struct can_frame *)skb->data;
u32 can_id;
u32 data;
@@ -489,25 +491,25 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (cf->can_dlc > 0) {
data = be32_to_cpup((__be32 *)&cf->data[0]);
- flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]);
+ flexcan_write(data, &priv->tx_mb->data[0]);
}
if (cf->can_dlc > 3) {
data = be32_to_cpup((__be32 *)&cf->data[4]);
- flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]);
+ flexcan_write(data, &priv->tx_mb->data[1]);
}
can_put_echo_skb(skb, dev, 0);
- flexcan_write(can_id, ®s->mb[FLEXCAN_TX_BUF_ID].can_id);
- flexcan_write(ctrl, ®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
+ flexcan_write(can_id, &priv->tx_mb->can_id);
+ flexcan_write(ctrl, &priv->tx_mb->can_ctrl);
/* Errata ERR005829 step8:
* Write twice INACTIVE(0x8) code to first MB.
*/
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- ®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
+ &priv->tx_mb_reserved->can_ctrl);
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- ®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
+ &priv->tx_mb_reserved->can_ctrl);
return NETDEV_TX_OK;
}
@@ -752,15 +754,15 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
}
/* transmission complete interrupt */
- if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
+ if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
stats->tx_bytes += can_get_echo_skb(dev, 0);
stats->tx_packets++;
can_led_event(dev, CAN_LED_EVENT_TX);
/* after sending a RTR frame MB is in RX mode */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- ®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
- flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
+ &priv->tx_mb->can_ctrl);
+ flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1);
netif_wake_queue(dev);
}
@@ -844,7 +846,7 @@ static int flexcan_chip_start(struct net_device *dev)
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
- FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
+ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
flexcan_write(reg_mcr, ®s->mcr);
@@ -882,18 +884,18 @@ static int flexcan_chip_start(struct net_device *dev)
flexcan_write(reg_ctrl, ®s->ctrl);
/* clear and invalidate all mailboxes first */
- for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->mb); i++) {
+ for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
®s->mb[i].can_ctrl);
}
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- ®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
+ &priv->tx_mb_reserved->can_ctrl);
/* mark TX mailbox as INACTIVE */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
- ®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
+ &priv->tx_mb->can_ctrl);
/* acceptance mask/acceptance code (accept everything) */
flexcan_write(0x0, ®s->rxgmask);
@@ -1225,9 +1227,13 @@ static int flexcan_probe(struct platform_device *pdev)
priv->devtype_data = devtype_data;
priv->reg_xceiver = reg_xceiver;
+ priv->tx_mb_idx = FLEXCAN_TX_MB_HW_FIFO;
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_HW_FIFO];
+ priv->tx_mb = ®s->mb[priv->tx_mb_idx];
+
priv->reg_imask1_default = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
FLEXCAN_IFLAG_RX_FIFO_AVAILABLE |
- FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID);
+ FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 03/11] can: rx-fifo: Add support for simple irq offloading
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 01/11] can: flexcan: calculate default value for imask1 during runtime Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 02/11] can: flexcan: make TX mailbox selectable " Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 04/11] can: flexcan: make use of rx-fifo's irq_offload_simple Marc Kleine-Budde
` (9 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, David Jander, Marc Kleine-Budde
From: David Jander <david@protonic.nl>
Some CAN controllers have a usable FIFO already but can still benefit from
off-loading the CAN controller FIFO. The mailboxes of the FIFO are copied to a
ring buffer during the interrupt and then transmitted in a NAPI context.
Signed-off-by: David Jander <david@protonic.nl>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/Makefile | 3 +-
drivers/net/can/rx-fifo.c | 174 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/can/rx-fifo.h | 58 +++++++++++++++
3 files changed, 234 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/can/rx-fifo.c
create mode 100644 include/linux/can/rx-fifo.h
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 1f21cef1d458..4b279d3ae0ab 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o
obj-$(CONFIG_CAN_SLCAN) += slcan.o
obj-$(CONFIG_CAN_DEV) += can-dev.o
-can-dev-y := dev.o
+can-dev-y += dev.o
+can-dev-y += rx-fifo.o
can-dev-$(CONFIG_CAN_LEDS) += led.o
diff --git a/drivers/net/can/rx-fifo.c b/drivers/net/can/rx-fifo.c
new file mode 100644
index 000000000000..7896a1034588
--- /dev/null
+++ b/drivers/net/can/rx-fifo.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2014 David Jander, Protonic Holland
+ * Copyright (C) 2014, 2015 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/circ_buf.h>
+#include <linux/can/dev.h>
+#include <linux/can/rx-fifo.h>
+
+static int can_rx_fifo_napi_read_frame(struct can_rx_fifo *fifo, int index)
+{
+ struct net_device *dev = fifo->dev;
+ struct net_device_stats *stats = &dev->stats;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ skb = alloc_can_skb(dev, &cf);
+ if (unlikely(!skb)) {
+ stats->rx_dropped++;
+ return 0;
+ }
+
+ memcpy(cf, &fifo->ring[index], sizeof(*cf));
+ memset(&fifo->ring[index], 0x0, sizeof(*cf));
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_receive_skb(skb);
+
+ return 1;
+}
+
+static int can_rx_fifo_napi_poll(struct napi_struct *napi, int quota)
+{
+ struct can_rx_fifo *fifo = container_of(napi, struct can_rx_fifo, napi);
+ unsigned int tail;
+ int work_done = 0;
+
+ if (fifo->poll_pre_read && work_done < quota)
+ work_done += fifo->poll_pre_read(fifo);
+
+ /* handle mailboxes */
+ tail = fifo->ring_tail;
+ while ((CIRC_CNT(smp_load_acquire(&fifo->ring_head), tail, fifo->ring_size)) &&
+ (work_done < quota)) {
+ work_done += can_rx_fifo_napi_read_frame(fifo, tail);
+ tail++;
+ tail &= fifo->ring_size -1;
+ smp_store_release(&fifo->ring_tail, tail);
+ }
+
+ if (fifo->poll_post_read && work_done < quota)
+ work_done += fifo->poll_post_read(fifo);
+
+ if (work_done < quota) {
+ unsigned int head;
+
+ napi_complete(napi);
+
+ /* Check if there was another interrupt */
+ head = smp_load_acquire(&fifo->ring_head);
+ if (((CIRC_CNT(head, tail, fifo->ring_size)) || fifo->poll_errors) &&
+ napi_reschedule(&fifo->napi)) {
+ fifo->poll_errors = false;
+ }
+
+ if (fifo->poll_error_interrupts_enable)
+ fifo->poll_error_interrupts_enable(fifo);
+ }
+
+ can_led_event(fifo->dev, CAN_LED_EVENT_RX);
+
+ return work_done;
+}
+
+static unsigned int can_rx_fifo_offload_one(struct can_rx_fifo *fifo, unsigned int n)
+{
+ unsigned int head, tail;
+ unsigned int ret;
+
+ head = fifo->ring_head;
+ tail = ACCESS_ONCE(fifo->ring_tail);
+ if (CIRC_SPACE(head, tail, fifo->ring_size)) {
+ ret = fifo->mailbox_read(fifo, &fifo->ring[head], n);
+ if (ret) {
+ head++;
+ head &= fifo->ring_size - 1;
+ smp_store_release(&fifo->ring_head, head);
+ }
+ } else {
+ /* Circular buffer is fill, read to discard mailbox */
+ ret = fifo->mailbox_read(fifo, &fifo->overflow, n);
+ if (ret)
+ fifo->dev->stats.rx_dropped++;
+ }
+
+ return ret;
+}
+
+int can_rx_fifo_irq_offload_simple(struct can_rx_fifo *fifo)
+{
+ unsigned int received = 0;
+ unsigned int ret;
+
+ do {
+ ret = can_rx_fifo_offload_one(fifo, 0);
+ received += ret;
+ } while (ret);
+
+ if (received)
+ can_rx_fifo_schedule(fifo);
+
+ return received;
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_irq_offload_simple);
+
+static int can_rx_fifo_init_ring(struct net_device *dev,
+ struct can_rx_fifo *fifo, unsigned int weight)
+{
+ fifo->dev = dev;
+
+ /* Make ring-buffer a sensible size that is a power of 2 */
+ fifo->ring_size = 2 << fls(weight);
+ fifo->ring = kzalloc(sizeof(struct can_frame) * fifo->ring_size,
+ GFP_KERNEL);
+ if (!fifo->ring)
+ return -ENOMEM;
+
+ fifo->ring_head = fifo->ring_tail = 0;
+ netif_napi_add(dev, &fifo->napi, can_rx_fifo_napi_poll, weight);
+
+ return 0;
+}
+
+int can_rx_fifo_add_simple(struct net_device *dev, struct can_rx_fifo *fifo, unsigned int weight)
+{
+ if (!fifo->mailbox_read)
+ return -EINVAL;
+
+ return can_rx_fifo_init_ring(dev, fifo, weight);
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_add_simple);
+
+void can_rx_fifo_enable(struct can_rx_fifo *fifo)
+{
+ napi_enable(&fifo->napi);
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_enable);
+
+void can_rx_fifo_irq_error(struct can_rx_fifo *fifo)
+{
+ fifo->poll_errors = true;
+ can_rx_fifo_schedule(fifo);
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_irq_error);
+
+void can_rx_fifo_del(struct can_rx_fifo *fifo)
+{
+ netif_napi_del(&fifo->napi);
+ kfree(fifo->ring);
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_del);
diff --git a/include/linux/can/rx-fifo.h b/include/linux/can/rx-fifo.h
new file mode 100644
index 000000000000..fc157f23722c
--- /dev/null
+++ b/include/linux/can/rx-fifo.h
@@ -0,0 +1,58 @@
+/*
+ * linux/can/rx-fifo.h
+ *
+ * Copyright (c) 2014 David Jander, Protonic Holland
+ * Copyright (c) 2014, 2015 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAN_RX_FIFO_H
+#define _CAN_RX_FIFO_H
+
+#include <linux/netdevice.h>
+#include <linux/can.h>
+
+struct can_rx_fifo {
+ struct net_device *dev;
+
+ void (*poll_error_interrupts_enable)(struct can_rx_fifo *fifo);
+ unsigned int (*mailbox_read)(struct can_rx_fifo *fifo, struct can_frame *cf, unsigned int mb);
+ unsigned int (*poll_pre_read)(struct can_rx_fifo *fifo);
+ unsigned int (*poll_post_read)(struct can_rx_fifo *fifo);
+
+ unsigned int ring_size;
+ unsigned int ring_head;
+ unsigned int ring_tail;
+
+ struct can_frame *ring;
+ struct can_frame overflow;
+ struct napi_struct napi;
+
+ bool poll_errors;
+};
+
+int can_rx_fifo_add_simple(struct net_device *dev, struct can_rx_fifo *fifo, unsigned int weight);
+int can_rx_fifo_irq_offload_simple(struct can_rx_fifo *fifo);
+void can_rx_fifo_irq_error(struct can_rx_fifo *fifo);
+void can_rx_fifo_del(struct can_rx_fifo *fifo);
+void can_rx_fifo_enable(struct can_rx_fifo *fifo);
+
+static inline void can_rx_fifo_schedule(struct can_rx_fifo *fifo)
+{
+ napi_schedule(&fifo->napi);
+}
+
+static inline void can_rx_fifo_disable(struct can_rx_fifo *fifo)
+{
+ napi_disable(&fifo->napi);
+}
+
+#endif /* !_CAN_RX_FIFO_H */
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 04/11] can: flexcan: make use of rx-fifo's irq_offload_simple
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (2 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 03/11] can: rx-fifo: Add support for simple irq offloading Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 05/11] can: flexcan: add missing register definitions Marc Kleine-Budde
` (8 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
This patch converts the flexcan driver to make use of the rx-fifo
can_rx_fifo_irq_offload_simple() helper function. The idea is to read the CAN
frames already in the interrupt context, as the depth of the flexcan HW FIFO is
too shallow, resulting in too many missed frames. During a normal NAPI poll the
frames are the pushed into the upper layers.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 134 +++++++++++++++++++---------------------------
1 file changed, 56 insertions(+), 78 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 52065f2f92e0..bddd2ef904f0 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -24,6 +24,7 @@
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
+#include <linux/can/rx-fifo.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -246,13 +247,14 @@ struct flexcan_devtype_data {
struct flexcan_priv {
struct can_priv can;
- struct napi_struct napi;
+ struct can_rx_fifo fifo;
struct flexcan_regs __iomem *regs;
struct flexcan_mb __iomem *tx_mb;
struct flexcan_mb __iomem *tx_mb_reserved;
u8 tx_mb_idx;
u32 reg_esr;
+ u32 poll_esr; /* used in flexcan_poll_bus_err */
u32 reg_ctrl_default;
u32 reg_imask1_default;
@@ -514,6 +516,11 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
+static inline struct flexcan_priv *rx_fifo_to_priv(struct can_rx_fifo *fifo)
+{
+ return container_of(fifo, struct flexcan_priv, fifo);
+}
+
static void do_bus_err(struct net_device *dev,
struct can_frame *cf, u32 reg_esr)
{
@@ -562,16 +569,21 @@ static void do_bus_err(struct net_device *dev,
dev->stats.tx_errors++;
}
-static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr)
+static unsigned int flexcan_poll_bus_err(struct can_rx_fifo *fifo)
{
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
+ struct net_device *dev = fifo->dev;
struct sk_buff *skb;
struct can_frame *cf;
+ if (!flexcan_has_and_handle_berr(priv, priv->poll_esr))
+ return 0;
+
skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb))
return 0;
- do_bus_err(dev, cf, reg_esr);
+ do_bus_err(dev, cf, priv->poll_esr);
dev->stats.rx_packets++;
dev->stats.rx_bytes += cf->can_dlc;
@@ -580,14 +592,21 @@ static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr)
return 1;
}
-static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
+static unsigned int flexcan_poll_state(struct can_rx_fifo *fifo)
{
- struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
+ struct net_device *dev = fifo->dev;
+ struct flexcan_regs __iomem *regs = priv->regs;
struct sk_buff *skb;
struct can_frame *cf;
enum can_state new_state = 0, rx_state = 0, tx_state = 0;
int flt;
struct can_berr_counter bec;
+ u32 reg_esr;
+
+ /* esr bits are clear-on-read, so save them for flexcan_poll_bus_err() */
+ priv->poll_esr = priv->reg_esr | flexcan_read(®s->esr);
+ reg_esr = priv->poll_esr;
flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
@@ -624,13 +643,17 @@ static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
return 1;
}
-static void flexcan_read_fifo(const struct net_device *dev,
- struct can_frame *cf)
+static unsigned int flexcan_mailbox_read(struct can_rx_fifo *fifo,
+ struct can_frame *cf, unsigned int n)
{
- const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
struct flexcan_regs __iomem *regs = priv->regs;
- struct flexcan_mb __iomem *mb = ®s->mb[0];
- u32 reg_ctrl, reg_id;
+ struct flexcan_mb __iomem *mb = ®s->mb[n];
+ u32 reg_ctrl, reg_id, reg_iflag1;
+
+ reg_iflag1 = flexcan_read(®s->iflag1);
+ if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
+ return 0;
reg_ctrl = flexcan_read(&mb->can_ctrl);
reg_id = flexcan_read(&mb->can_id);
@@ -649,67 +672,16 @@ static void flexcan_read_fifo(const struct net_device *dev,
/* mark as read */
flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
flexcan_read(®s->timer);
-}
-
-static int flexcan_read_frame(struct net_device *dev)
-{
- struct net_device_stats *stats = &dev->stats;
- struct can_frame *cf;
- struct sk_buff *skb;
-
- skb = alloc_can_skb(dev, &cf);
- if (unlikely(!skb)) {
- stats->rx_dropped++;
- return 0;
- }
-
- flexcan_read_fifo(dev, cf);
-
- stats->rx_packets++;
- stats->rx_bytes += cf->can_dlc;
- netif_receive_skb(skb);
-
- can_led_event(dev, CAN_LED_EVENT_RX);
return 1;
}
-static int flexcan_poll(struct napi_struct *napi, int quota)
+static void flexcan_poll_error_interrupts_enable(struct can_rx_fifo *fifo)
{
- struct net_device *dev = napi->dev;
- const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
struct flexcan_regs __iomem *regs = priv->regs;
- u32 reg_iflag1, reg_esr;
- int work_done = 0;
-
- /* The error bits are cleared on read,
- * use saved value from irq handler.
- */
- reg_esr = flexcan_read(®s->esr) | priv->reg_esr;
- /* handle state changes */
- work_done += flexcan_poll_state(dev, reg_esr);
-
- /* handle RX-FIFO */
- reg_iflag1 = flexcan_read(®s->iflag1);
- while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
- work_done < quota) {
- work_done += flexcan_read_frame(dev);
- reg_iflag1 = flexcan_read(®s->iflag1);
- }
-
- /* report bus errors */
- if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota)
- work_done += flexcan_poll_bus_err(dev, reg_esr);
-
- if (work_done < quota) {
- napi_complete(napi);
- /* enable IRQs */
- flexcan_write(priv->reg_imask1_default, ®s->imask1);
- flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
- }
-
- return work_done;
+ flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
}
static irqreturn_t flexcan_irq(int irq, void *dev_id)
@@ -727,25 +699,22 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
if (reg_esr & FLEXCAN_ESR_ALL_INT)
flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr);
- /* schedule NAPI in case of:
- * - rx IRQ
- * - state change IRQ
- * - bus error IRQ and bus error reporting is activated
- */
- if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) ||
- (reg_esr & FLEXCAN_ESR_ERR_STATE) ||
+ /* bus error IRQ and bus error reporting is activated */
+ if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
flexcan_has_and_handle_berr(priv, reg_esr)) {
/* The error bits are cleared on read,
* save them for later use.
*/
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
- flexcan_write(priv->reg_imask1_default &
- ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
®s->ctrl);
- napi_schedule(&priv->napi);
+ can_rx_fifo_irq_error(&priv->fifo);
}
+ /* reception interrupt */
+ if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)
+ can_rx_fifo_irq_offload_simple(&priv->fifo);
+
/* FIFO overflow */
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
@@ -1008,7 +977,7 @@ static int flexcan_open(struct net_device *dev)
can_led_event(dev, CAN_LED_EVENT_OPEN);
- napi_enable(&priv->napi);
+ can_rx_fifo_enable(&priv->fifo);
netif_start_queue(dev);
return 0;
@@ -1030,7 +999,7 @@ static int flexcan_close(struct net_device *dev)
struct flexcan_priv *priv = netdev_priv(dev);
netif_stop_queue(dev);
- napi_disable(&priv->napi);
+ can_rx_fifo_disable(&priv->fifo);
flexcan_chip_stop(dev);
free_irq(dev->irq, dev);
@@ -1235,7 +1204,15 @@ static int flexcan_probe(struct platform_device *pdev)
FLEXCAN_IFLAG_RX_FIFO_AVAILABLE |
FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
- netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
+ priv->fifo.poll_pre_read = flexcan_poll_state;
+ priv->fifo.poll_post_read = flexcan_poll_bus_err;
+ priv->fifo.poll_error_interrupts_enable =
+ flexcan_poll_error_interrupts_enable;
+ priv->fifo.mailbox_read = flexcan_mailbox_read;
+
+ err = can_rx_fifo_add_simple(dev, &priv->fifo, FLEXCAN_NAPI_WEIGHT);
+ if (err)
+ goto failed_fifo;
platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -1253,6 +1230,7 @@ static int flexcan_probe(struct platform_device *pdev)
return 0;
+ failed_fifo:
failed_register:
free_candev(dev);
return err;
@@ -1264,7 +1242,7 @@ static int flexcan_remove(struct platform_device *pdev)
struct flexcan_priv *priv = netdev_priv(dev);
unregister_flexcandev(dev);
- netif_napi_del(&priv->napi);
+ can_rx_fifo_del(&priv->fifo);
free_candev(dev);
return 0;
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 05/11] can: flexcan: add missing register definitions
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (3 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 04/11] can: flexcan: make use of rx-fifo's irq_offload_simple Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 06/11] can: flexcan: activate individual RX masking and initialize reg_rximr Marc Kleine-Budde
` (7 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
This patch adds some missing register definitions, which are needed in an
upcoming patch.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index bddd2ef904f0..ef4693b970f4 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -56,7 +56,7 @@
#define FLEXCAN_MCR_WAK_SRC BIT(19)
#define FLEXCAN_MCR_DOZE BIT(18)
#define FLEXCAN_MCR_SRX_DIS BIT(17)
-#define FLEXCAN_MCR_BCC BIT(16)
+#define FLEXCAN_MCR_IRMQ BIT(16)
#define FLEXCAN_MCR_LPRIO_EN BIT(13)
#define FLEXCAN_MCR_AEN BIT(12)
#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f)
@@ -211,7 +211,10 @@ struct flexcan_regs {
u32 imask1; /* 0x28 */
u32 iflag2; /* 0x2c */
u32 iflag1; /* 0x30 */
- u32 ctrl2; /* 0x34 */
+ union { /* 0x34 */
+ u32 gfwr_mx28; /* MX28, MX53 */
+ u32 ctrl2; /* MX6, VF610 */
+ };
u32 esr2; /* 0x38 */
u32 imeur; /* 0x3c */
u32 lrfr; /* 0x40 */
@@ -230,7 +233,11 @@ struct flexcan_regs {
* size conf'ed via ctrl2::RFFN
* (mx6, vf610)
*/
- u32 _reserved4[408];
+ u32 _reserved4[256]; /* 0x480 */
+ u32 rximr[64]; /* 0x880 */
+ u32 _reserved5[24]; /* 0x980 */
+ u32 gfwr_mx6; /* 0x9e0 - MX6 */
+ u32 _reserved6[63]; /* 0x9e4 */
u32 mecr; /* 0xae0 */
u32 erriar; /* 0xae4 */
u32 erridpr; /* 0xae8 */
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 06/11] can: flexcan: activate individual RX masking and initialize reg_rximr
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (4 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 05/11] can: flexcan: add missing register definitions Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 07/11] can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS Marc Kleine-Budde
` (6 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
Modern flexcan IP cores support two RX modes. One is using the 6 fames deep
hardware FIFO, the other is using up to 64 mailboxes (in non FIFO mode). For
now only the HW FIFO mode is activated.
In order to make use of the RX mailboxes the individual RX masking feature has
to be activated, otherwise matching mailboxes are overwritten during the
reception process. This however switches on the individual RX masking, which
uses reg_rximr registers for masking.
This patch activates the individual RX masking feature unconditionally and
initializes the mask registers (reg_rximr) with 0x0 == "don't care", which
switches off any filtering.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index ef4693b970f4..f4c2bc4935a2 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -815,6 +815,7 @@ static int flexcan_chip_start(struct net_device *dev)
* only supervisor access
* enable warning int
* disable local echo
+ * enable individual RX masking
* choose format C
* set max mailbox number
*/
@@ -822,7 +823,8 @@ static int flexcan_chip_start(struct net_device *dev)
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
- FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+ FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C |
+ FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
flexcan_write(reg_mcr, ®s->mcr);
@@ -881,6 +883,10 @@ static int flexcan_chip_start(struct net_device *dev)
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
flexcan_write(0x0, ®s->rxfgmask);
+ /* clear acceptance filters */
+ for (i = 0; i < ARRAY_SIZE(regs->mb); i++)
+ flexcan_write(0, ®s->rximr[i]);
+
/* On Vybrid, disable memory error detection interrupts
* and freeze mode.
* This also works around errata e5295 which generates
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 07/11] can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (5 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 06/11] can: flexcan: activate individual RX masking and initialize reg_rximr Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 08/11] can: flexcan: reg_imask2_default Marc Kleine-Budde
` (5 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
In order to receive RTR frames in the non HW FIFO mode the RSS and EACEN bits
of the reg_ctrl2 have to be activated. As this has no side effect in the FIFO
mode, we do this unconditionally on cores with the reg_ctrl2.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index f4c2bc4935a2..b1135012ced3 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -187,7 +187,8 @@
*/
#define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */
#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */
-#define FLEXCAN_QUIRK_DISABLE_MECR BIT(3) /* Disble Memory error detection */
+#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
+#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disble Memory error detection */
/* Structure of the message buffer */
struct flexcan_mb {
@@ -279,11 +280,12 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = {
static struct flexcan_devtype_data fsl_imx28_devtype_data;
static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
- .quirks = FLEXCAN_QUIRK_DISABLE_RXFG,
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS,
};
static struct flexcan_devtype_data fsl_vf610_devtype_data = {
- .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
+ FLEXCAN_QUIRK_DISABLE_MECR,
};
static const struct can_bittiming_const flexcan_bittiming_const = {
@@ -861,6 +863,12 @@ static int flexcan_chip_start(struct net_device *dev)
netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
flexcan_write(reg_ctrl, ®s->ctrl);
+ if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
+ reg_ctrl2 = flexcan_read(®s->ctrl2);
+ reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
+ flexcan_write(reg_ctrl2, ®s->ctrl2);
+ }
+
/* clear and invalidate all mailboxes first */
for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) {
flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 08/11] can: flexcan: reg_imask2_default
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (6 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 07/11] can: flexcan: add quirk FLEXCAN_QUIRK_ENABLE_EACEN_RRS Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 09/11] can: rx-fifo: introduce software rx-fifo implementation Marc Kleine-Budde
` (4 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index b1135012ced3..1b3a784607c9 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -265,6 +265,7 @@ struct flexcan_priv {
u32 poll_esr; /* used in flexcan_poll_bus_err */
u32 reg_ctrl_default;
u32 reg_imask1_default;
+ u32 reg_imask2_default;
struct clk *clk_ipg;
struct clk *clk_per;
@@ -933,6 +934,7 @@ static int flexcan_chip_start(struct net_device *dev)
disable_irq(dev->irq);
flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
flexcan_write(priv->reg_imask1_default, ®s->imask1);
+ flexcan_write(priv->reg_imask2_default, ®s->imask2);
enable_irq(dev->irq);
/* print chip status */
@@ -962,6 +964,7 @@ static void flexcan_chip_stop(struct net_device *dev)
flexcan_chip_disable(priv);
/* Disable all interrupts */
+ flexcan_write(0, ®s->imask2);
flexcan_write(0, ®s->imask1);
flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
®s->ctrl);
@@ -1224,6 +1227,7 @@ static int flexcan_probe(struct platform_device *pdev)
priv->reg_imask1_default = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
FLEXCAN_IFLAG_RX_FIFO_AVAILABLE |
FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+ priv->reg_imask2_default = 0;
priv->fifo.poll_pre_read = flexcan_poll_state;
priv->fifo.poll_post_read = flexcan_poll_bus_err;
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 09/11] can: rx-fifo: introduce software rx-fifo implementation
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (7 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 08/11] can: flexcan: reg_imask2_default Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 10/11] can: flexcan: add support for rx-fifo based software FIFO implementation Marc Kleine-Budde
` (3 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde, David Jander
This patch adds a software rx-fifo implementation for CAN controllers which
offer only a number of mailboxes, where the incoming message is stored int othe
first free one. Both controllers which start with the lowest or highest free
mailbox are supported.
The mailboxes are copied to a ring buffer during the interrupt and then
transmitted in a NAPI context.
Signed-off-by: David Jander <david@protonic.nl>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/rx-fifo.c | 178 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/can/rx-fifo.h | 14 ++++
2 files changed, 192 insertions(+)
diff --git a/drivers/net/can/rx-fifo.c b/drivers/net/can/rx-fifo.c
index 7896a1034588..53c01d3cd157 100644
--- a/drivers/net/can/rx-fifo.c
+++ b/drivers/net/can/rx-fifo.c
@@ -19,6 +19,50 @@
#include <linux/can/dev.h>
#include <linux/can/rx-fifo.h>
+static bool can_rx_fifo_ge(struct can_rx_fifo *fifo, unsigned int a, unsigned int b)
+{
+ if (fifo->inc)
+ return a >= b;
+ else
+ return a <= b;
+}
+
+static bool can_rx_fifo_le(struct can_rx_fifo *fifo, unsigned int a, unsigned int b)
+{
+ if (fifo->inc)
+ return a <= b;
+ else
+ return a >= b;
+}
+
+static unsigned int can_rx_fifo_inc(struct can_rx_fifo *fifo, unsigned int *val)
+{
+ if (fifo->inc)
+ return (*val)++;
+ else
+ return (*val)--;
+}
+
+static u64 can_rx_fifo_mask_low(struct can_rx_fifo *fifo)
+{
+ if (fifo->inc)
+ return ~0LLU >> (64 + fifo->low_first - fifo->high_first)
+ << fifo->low_first;
+ else
+ return ~0LLU >> (64 - fifo->low_first + fifo->high_first)
+ << (fifo->high_first + 1);
+}
+
+static u64 can_rx_fifo_mask_high(struct can_rx_fifo *fifo)
+{
+ if (fifo->inc)
+ return ~0LLU >> (64 + fifo->high_first - fifo->high_last - 1)
+ << fifo->high_first;
+ else
+ return ~0LLU >> (64 - fifo->high_first + fifo->high_last - 1)
+ << fifo->high_last;
+}
+
static int can_rx_fifo_napi_read_frame(struct can_rx_fifo *fifo, int index)
{
struct net_device *dev = fifo->dev;
@@ -109,6 +153,68 @@ static unsigned int can_rx_fifo_offload_one(struct can_rx_fifo *fifo, unsigned i
return ret;
}
+int can_rx_fifo_irq_offload(struct can_rx_fifo *fifo)
+{
+ unsigned int i;
+ unsigned int ret;
+ unsigned int received = 0;
+
+ if (fifo->scan_high_first) {
+ fifo->scan_high_first = false;
+ for (i = fifo->high_first;
+ can_rx_fifo_le(fifo, i, fifo->high_last);
+ can_rx_fifo_inc(fifo, &i)) {
+ received += can_rx_fifo_offload_one(fifo, i);
+ fifo->active |= BIT_ULL(i);
+ fifo->mailbox_enable(fifo, i);
+ }
+ }
+
+ /* Copy and disable FULL MBs */
+ for (i = fifo->low_first;
+ can_rx_fifo_le(fifo, i, fifo->high_last);
+ can_rx_fifo_inc(fifo, &i)) {
+ if (!(fifo->active & BIT_ULL(i)))
+ continue;
+
+ ret = can_rx_fifo_offload_one(fifo, i);
+ if (!ret)
+ break;
+
+ received += ret;
+ fifo->active &= ~BIT_ULL(i);
+ }
+
+ if (can_rx_fifo_ge(fifo, i, fifo->high_first) && fifo->scan_high_first)
+ netdev_warn(fifo->dev, "%s: RX order cannot be guaranteed. (count=%d)\n",
+ __func__, i);
+
+ /* No EMPTY MB in first half? */
+ if (can_rx_fifo_ge(fifo, i, fifo->high_first)) {
+ /* Re-enable all disabled MBs */
+ fifo->active = fifo->mask_low | fifo->mask_high;
+ fifo->mailbox_enable_mask(fifo, fifo->active);
+
+ /* Next time we need to check the second half first */
+ fifo->scan_high_first = true;
+ }
+
+ if (WARN(!received, "%s: No messages found, RX-FIFO out of sync?\n",
+ __func__)) {
+ /* This should only happen if the CAN conroller was
+ * reset, but can_rx_fifo_reset() was not
+ * called. WARN() the user and try to recover. This
+ * may fail and the system may hang though.
+ */
+ can_rx_fifo_reset(fifo);
+ } else {
+ can_rx_fifo_schedule(fifo);
+ }
+
+ return received;
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_irq_offload);
+
int can_rx_fifo_irq_offload_simple(struct can_rx_fifo *fifo)
{
unsigned int received = 0;
@@ -139,11 +245,72 @@ static int can_rx_fifo_init_ring(struct net_device *dev,
return -ENOMEM;
fifo->ring_head = fifo->ring_tail = 0;
+ can_rx_fifo_reset(fifo);
netif_napi_add(dev, &fifo->napi, can_rx_fifo_napi_poll, weight);
return 0;
}
+static void rx_fifo_enable_mask_default(struct can_rx_fifo *fifo, u64 mask)
+{
+ unsigned int i;
+
+ for (i = fifo->low_first;
+ can_rx_fifo_le(fifo, i, fifo->high_last);
+ can_rx_fifo_inc(fifo, &i)) {
+ if (mask & BIT_ULL(i))
+ fifo->mailbox_enable(fifo, i);
+ }
+}
+
+static void rx_fifo_enable_default(struct can_rx_fifo *fifo, unsigned int mb)
+{
+ fifo->mailbox_enable_mask(fifo, BIT_ULL(mb));
+}
+
+int can_rx_fifo_add(struct net_device *dev, struct can_rx_fifo *fifo)
+{
+ unsigned int weight;
+ int ret;
+
+ if ((fifo->low_first < fifo->high_first) &&
+ (fifo->high_first < fifo->high_last)) {
+ fifo->inc = true;
+ weight = fifo->high_last - fifo->low_first;
+ } else if ((fifo->low_first > fifo->high_first) &&
+ (fifo->high_first > fifo->high_last)) {
+ fifo->inc = false;
+ weight = fifo->low_first - fifo->high_last;
+ } else {
+ return -EINVAL;
+ }
+
+ if ((!fifo->mailbox_enable_mask && !fifo->mailbox_enable) ||
+ !fifo->mailbox_read)
+ return -EINVAL;
+
+ if (!fifo->mailbox_enable_mask)
+ fifo->mailbox_enable_mask = rx_fifo_enable_mask_default;
+ if (!fifo->mailbox_enable)
+ fifo->mailbox_enable = rx_fifo_enable_default;
+
+ /* init variables */
+ fifo->mask_low = can_rx_fifo_mask_low(fifo);
+ fifo->mask_high = can_rx_fifo_mask_high(fifo);
+
+ ret = can_rx_fifo_init_ring(dev, fifo, weight);
+ if (ret)
+ return ret;
+
+ netdev_dbg(dev, "%s: low_first=%d, high_first=%d, high_last=%d\n", __func__,
+ fifo->low_first, fifo->high_first, fifo->high_last);
+ netdev_dbg(dev, "%s: mask_low=0x%016llx mask_high=0x%016llx\n", __func__,
+ fifo->mask_low, fifo->mask_high);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_add);
+
int can_rx_fifo_add_simple(struct net_device *dev, struct can_rx_fifo *fifo, unsigned int weight)
{
if (!fifo->mailbox_read)
@@ -155,6 +322,9 @@ EXPORT_SYMBOL_GPL(can_rx_fifo_add_simple);
void can_rx_fifo_enable(struct can_rx_fifo *fifo)
{
+ can_rx_fifo_reset(fifo);
+ if (fifo->mailbox_enable_mask)
+ fifo->mailbox_enable_mask(fifo, fifo->active);
napi_enable(&fifo->napi);
}
EXPORT_SYMBOL_GPL(can_rx_fifo_enable);
@@ -172,3 +342,11 @@ void can_rx_fifo_del(struct can_rx_fifo *fifo)
kfree(fifo->ring);
}
EXPORT_SYMBOL_GPL(can_rx_fifo_del);
+
+void can_rx_fifo_reset(struct can_rx_fifo *fifo)
+{
+ fifo->scan_high_first = false;
+ fifo->poll_errors = false;
+ fifo->active = fifo->mask_low | fifo->mask_high;
+}
+EXPORT_SYMBOL_GPL(can_rx_fifo_reset);
diff --git a/include/linux/can/rx-fifo.h b/include/linux/can/rx-fifo.h
index fc157f23722c..cd1614118b33 100644
--- a/include/linux/can/rx-fifo.h
+++ b/include/linux/can/rx-fifo.h
@@ -23,25 +23,39 @@
struct can_rx_fifo {
struct net_device *dev;
+ void (*mailbox_enable_mask)(struct can_rx_fifo *fifo, u64 mask);
+ void (*mailbox_enable)(struct can_rx_fifo *fifo, unsigned int mb);
void (*poll_error_interrupts_enable)(struct can_rx_fifo *fifo);
unsigned int (*mailbox_read)(struct can_rx_fifo *fifo, struct can_frame *cf, unsigned int mb);
unsigned int (*poll_pre_read)(struct can_rx_fifo *fifo);
unsigned int (*poll_post_read)(struct can_rx_fifo *fifo);
+ u64 mask_low;
+ u64 mask_high;
+ u64 active;
+
unsigned int ring_size;
unsigned int ring_head;
unsigned int ring_tail;
+ unsigned int low_first;
+ unsigned int high_first;
+ unsigned int high_last;
struct can_frame *ring;
struct can_frame overflow;
struct napi_struct napi;
+ bool inc;
+ bool scan_high_first;
bool poll_errors;
};
+int can_rx_fifo_add(struct net_device *dev, struct can_rx_fifo *fifo);
int can_rx_fifo_add_simple(struct net_device *dev, struct can_rx_fifo *fifo, unsigned int weight);
+int can_rx_fifo_irq_offload(struct can_rx_fifo *fifo);
int can_rx_fifo_irq_offload_simple(struct can_rx_fifo *fifo);
void can_rx_fifo_irq_error(struct can_rx_fifo *fifo);
+void can_rx_fifo_reset(struct can_rx_fifo *fifo);
void can_rx_fifo_del(struct can_rx_fifo *fifo);
void can_rx_fifo_enable(struct can_rx_fifo *fifo);
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 10/11] can: flexcan: add support for rx-fifo based software FIFO implementation
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (8 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 09/11] can: rx-fifo: introduce software rx-fifo implementation Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
2015-12-10 12:33 ` [PATCH v2 11/11] can: flexcan: switch imx6 and vf610 to software based fifo Marc Kleine-Budde
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 184 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 157 insertions(+), 27 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1b3a784607c9..1482d10917a5 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -3,7 +3,8 @@
*
* Copyright (c) 2005-2006 Varma Electronics Oy
* Copyright (c) 2009 Sascha Hauer, Pengutronix
- * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix
+ * Copyright (c) 2010-2015 Marc Kleine-Budde, Pengutronix
+ * Copyright (c) 2014 David Jander, Protonic Holland
*
* Based on code originally by Andrey Volkov <avolkov@varma-el.com>
*
@@ -59,6 +60,7 @@
#define FLEXCAN_MCR_IRMQ BIT(16)
#define FLEXCAN_MCR_LPRIO_EN BIT(13)
#define FLEXCAN_MCR_AEN BIT(12)
+/* MCR_MAXMB: maximum used MBs is MAXMB + 1 */
#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f)
#define FLEXCAN_MCR_IDAM_A (0x0 << 8)
#define FLEXCAN_MCR_IDAM_B (0x1 << 8)
@@ -146,12 +148,19 @@
/* Errata ERR005829 step7: Reserve first valid MB */
#define FLEXCAN_TX_MB_RESERVED_HW_FIFO 8
#define FLEXCAN_TX_MB_HW_FIFO 9
+#define FLEXCAN_TX_MB_RESERVED_SW_FIFO 0
+#define FLEXCAN_TX_MB_SW_FIFO 1
+#define FLEXCAN_RX_MB_LOW_FIRST (FLEXCAN_TX_MB_SW_FIFO + 1)
+#define FLEXCAN_RX_MB_HIGH_FIRST 32
+#define FLEXCAN_RX_MB_HIGH_LAST 63
#define FLEXCAN_IFLAG_MB(x) BIT(x)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
/* FLEXCAN message buffers */
+#define FLEXCAN_MB_CODE_MASK (0xf << 24)
+#define FLEXCAN_MB_CODE_RX_BUSY_BIT (0x1 << 24)
#define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24)
#define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24)
#define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24)
@@ -189,6 +198,7 @@
#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */
#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disble Memory error detection */
+#define FLEXCAN_QUIRK_USE_SW_FIFO BIT(5) /* Use SW-FIFO */
/* Structure of the message buffer */
struct flexcan_mb {
@@ -653,6 +663,49 @@ static unsigned int flexcan_poll_state(struct can_rx_fifo *fifo)
return 1;
}
+static void do_mailbox_enable(struct flexcan_mb __iomem *mb)
+{
+ u32 reg_ctrl;
+ u32 code;
+
+ do {
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
+
+ code = reg_ctrl & FLEXCAN_MB_CODE_MASK;
+ if (code == FLEXCAN_MB_CODE_RX_INACTIVE) {
+ flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY, &mb->can_ctrl);
+ }
+}
+
+static void flexcan_mailbox_enable(struct can_rx_fifo *fifo, unsigned int n)
+{
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
+ struct flexcan_regs __iomem *regs = priv->regs;
+
+ do_mailbox_enable(®s->mb[n]);
+
+ /* unlock mailbox */
+ flexcan_read(®s->timer);
+}
+
+static void flexcan_mailbox_enable_mask(struct can_rx_fifo *fifo, u64 mask)
+{
+ struct flexcan_priv *priv = rx_fifo_to_priv(fifo);
+ struct flexcan_regs __iomem *regs = priv->regs;
+ unsigned int i;
+
+ for (i = priv->fifo.low_first; i <= priv->fifo.high_last; i++) {
+ if (!(mask & BIT_ULL(i)))
+ continue;
+
+ do_mailbox_enable(®s->mb[i]);
+ }
+
+ /* unlock mailbox */
+ flexcan_read(®s->timer);
+}
+
static unsigned int flexcan_mailbox_read(struct can_rx_fifo *fifo,
struct can_frame *cf, unsigned int n)
{
@@ -661,11 +714,32 @@ static unsigned int flexcan_mailbox_read(struct can_rx_fifo *fifo,
struct flexcan_mb __iomem *mb = ®s->mb[n];
u32 reg_ctrl, reg_id, reg_iflag1;
- reg_iflag1 = flexcan_read(®s->iflag1);
- if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
- return 0;
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ u32 code;
+
+ do {
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT);
+
+ /* is this MB empty? */
+ code = reg_ctrl & FLEXCAN_MB_CODE_MASK;
+ if ((code != FLEXCAN_MB_CODE_RX_FULL) &&
+ (code != FLEXCAN_MB_CODE_RX_OVERRUN))
+ return 0;
+
+ if (code == FLEXCAN_MB_CODE_RX_OVERRUN) {
+ /* This MB was overrun, we lost data */
+ fifo->dev->stats.rx_over_errors++;
+ fifo->dev->stats.rx_errors++;
+ }
+ } else {
+ reg_iflag1 = flexcan_read(®s->iflag1);
+ if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE))
+ return 0;
+
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ }
- reg_ctrl = flexcan_read(&mb->can_ctrl);
reg_id = flexcan_read(&mb->can_id);
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
@@ -680,8 +754,18 @@ static unsigned int flexcan_mailbox_read(struct can_rx_fifo *fifo,
*(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
/* mark as read */
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
- flexcan_read(®s->timer);
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ /* Clear IRQ and lock MB */
+ if (n < 32)
+ flexcan_write(BIT(n), ®s->iflag1);
+ else
+ flexcan_write(BIT(n - 32), ®s->iflag2);
+
+ flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE, &mb->can_ctrl);
+ } else {
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ flexcan_read(®s->timer);
+ }
return 1;
}
@@ -722,14 +806,24 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
}
/* reception interrupt */
- if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)
- can_rx_fifo_irq_offload_simple(&priv->fifo);
-
- /* FIFO overflow */
- if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
- dev->stats.rx_over_errors++;
- dev->stats.rx_errors++;
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ u32 reg_iflag2;
+
+ reg_iflag2 = flexcan_read(®s->iflag2);
+ if (reg_iflag1 & (priv->reg_imask1_default &
+ ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) ||
+ reg_iflag2 & priv->reg_imask2_default)
+ can_rx_fifo_irq_offload(&priv->fifo);
+ } else {
+ if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)
+ can_rx_fifo_irq_offload_simple(&priv->fifo);
+
+ /* FIFO overflow */
+ if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
+ }
}
/* transmission complete interrupt */
@@ -824,10 +918,17 @@ static int flexcan_chip_start(struct net_device *dev)
*/
reg_mcr = flexcan_read(®s->mcr);
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
- reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
- FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
- FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C |
- FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+ reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV |
+ FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ |
+ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ reg_mcr &= ~FLEXCAN_MCR_FEN;
+ reg_mcr |= FLEXCAN_MCR_MAXMB(priv->fifo.high_last);
+ } else {
+ reg_mcr |= FLEXCAN_MCR_FEN |
+ FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
+ }
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
flexcan_write(reg_mcr, ®s->mcr);
@@ -876,6 +977,12 @@ static int flexcan_chip_start(struct net_device *dev)
®s->mb[i].can_ctrl);
}
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ for (i = priv->fifo.low_first; i <= priv->fifo.high_last; i++)
+ flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY,
+ ®s->mb[i].can_ctrl);
+ }
+
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb_reserved->can_ctrl);
@@ -1097,8 +1204,9 @@ static int register_flexcandev(struct net_device *dev)
flexcan_write(reg, ®s->mcr);
/* Currently we only support newer versions of this core
- * featuring a RX FIFO. Older cores found on some Coldfire
- * derivates are not yet supported.
+ * featuring a RX hardware FIFO (although this driver doesn't
+ * make use of it on some cores). Older cores, found on some
+ * Coldfire derivates are not tested.
*/
reg = flexcan_read(®s->mcr);
if (!(reg & FLEXCAN_MCR_FEN)) {
@@ -1220,13 +1328,16 @@ static int flexcan_probe(struct platform_device *pdev)
priv->devtype_data = devtype_data;
priv->reg_xceiver = reg_xceiver;
- priv->tx_mb_idx = FLEXCAN_TX_MB_HW_FIFO;
- priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_HW_FIFO];
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ priv->tx_mb_idx = FLEXCAN_TX_MB_SW_FIFO;
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_SW_FIFO];
+ } else {
+ priv->tx_mb_idx = FLEXCAN_TX_MB_HW_FIFO;
+ priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_HW_FIFO];
+ }
priv->tx_mb = ®s->mb[priv->tx_mb_idx];
- priv->reg_imask1_default = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
- FLEXCAN_IFLAG_RX_FIFO_AVAILABLE |
- FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+ priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
priv->reg_imask2_default = 0;
priv->fifo.poll_pre_read = flexcan_poll_state;
@@ -1235,7 +1346,26 @@ static int flexcan_probe(struct platform_device *pdev)
flexcan_poll_error_interrupts_enable;
priv->fifo.mailbox_read = flexcan_mailbox_read;
- err = can_rx_fifo_add_simple(dev, &priv->fifo, FLEXCAN_NAPI_WEIGHT);
+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SW_FIFO) {
+ u64 imask;
+
+ priv->fifo.low_first = FLEXCAN_RX_MB_LOW_FIRST;
+ priv->fifo.high_first = FLEXCAN_RX_MB_HIGH_FIRST;
+ priv->fifo.high_last = FLEXCAN_RX_MB_HIGH_LAST;
+ priv->fifo.mailbox_enable_mask = flexcan_mailbox_enable_mask;
+ priv->fifo.mailbox_enable = flexcan_mailbox_enable;
+
+ imask = ~0LLU >> (64 + priv->fifo.low_first - priv->fifo.high_last - 1)
+ << priv->fifo.low_first;
+ priv->reg_imask1_default |= imask;
+ priv->reg_imask2_default |= imask >> 32;
+
+ err = can_rx_fifo_add(dev, &priv->fifo);
+ } else {
+ priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW |
+ FLEXCAN_IFLAG_RX_FIFO_AVAILABLE;
+ err = can_rx_fifo_add_simple(dev, &priv->fifo, FLEXCAN_NAPI_WEIGHT);
+ }
if (err)
goto failed_fifo;
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 11/11] can: flexcan: switch imx6 and vf610 to software based fifo
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (9 preceding siblings ...)
2015-12-10 12:33 ` [PATCH v2 10/11] can: flexcan: add support for rx-fifo based software FIFO implementation Marc Kleine-Budde
@ 2015-12-10 12:33 ` Marc Kleine-Budde
[not found] ` <CAOpc7mGK9WEnbowHJONbP-szW7mVQbU46uUPXF8V09omqWLQMA@mail.gmail.com>
2016-01-18 11:14 ` Holger Schurig
12 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 12:33 UTC (permalink / raw)
To: linux-can; +Cc: kernel, bhupesh.sharma, Marc Kleine-Budde
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/flexcan.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1482d10917a5..116b8aee9712 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -291,12 +291,13 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = {
static struct flexcan_devtype_data fsl_imx28_devtype_data;
static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
- .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS,
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
+ FLEXCAN_QUIRK_USE_SW_FIFO,
};
static struct flexcan_devtype_data fsl_vf610_devtype_data = {
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
- FLEXCAN_QUIRK_DISABLE_MECR,
+ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_SW_FIFO,
};
static const struct can_bittiming_const flexcan_bittiming_const = {
--
2.6.2
^ permalink raw reply related [flat|nested] 18+ messages in thread[parent not found: <CAOpc7mGK9WEnbowHJONbP-szW7mVQbU46uUPXF8V09omqWLQMA@mail.gmail.com>]
* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
[not found] ` <CAOpc7mGK9WEnbowHJONbP-szW7mVQbU46uUPXF8V09omqWLQMA@mail.gmail.com>
@ 2015-12-10 14:04 ` Marc Kleine-Budde
0 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2015-12-10 14:04 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-can, Sascha Hauer, bhupesh.sharma
[-- Attachment #1: Type: text/plain, Size: 689 bytes --]
On 12/10/2015 02:52 PM, Holger Schurig wrote:
> Why did you invent your own rx-fifo.c/.h and didn't reuse the kernel's
> fifo, kfifo ?
Good question. We actually make use of the kernel circular buffer
(linux/circ_buf.h). However, it seems we need a more powerful data
structure anyways, e.g. list sorted by timestamp (with some magic taking
care of the limited width of the timestamp register).
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] 18+ messages in thread
* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
2015-12-10 12:33 [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading Marc Kleine-Budde
` (11 preceding siblings ...)
[not found] ` <CAOpc7mGK9WEnbowHJONbP-szW7mVQbU46uUPXF8V09omqWLQMA@mail.gmail.com>
@ 2016-01-18 11:14 ` Holger Schurig
2016-01-18 22:04 ` Marc Kleine-Budde
12 siblings, 1 reply; 18+ messages in thread
From: Holger Schurig @ 2016-01-18 11:14 UTC (permalink / raw)
To: Marc Kleine-Budde; +Cc: linux-can, kernel, bhupesh.sharma
Marc Kleine-Budde <mkl@pengutronix.de> writes:
> Testing and feedback welcome.
And here it is, albeit a bit late:
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at /home/schurig/d/mkarm/linux-4.4/drivers/net/can/rx-fifo.c:203 can_rx_fifo_irq_offload+0x214/0x264()
can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
Modules linked in: bnep btusb btrtl btbcm btintel bluetooth smsc95xx usbnet mii imx_sdma flexcan dlog(O)
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.4.0 #1
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[<c0012694>] (dump_backtrace) from [<c001288c>] (show_stack+0x18/0x1c)
r6:c04def61 r5:00000009 r4:00000000 r3:00200000
[<c0012874>] (show_stack) from [<c01b87a4>] (dump_stack+0x88/0xd4)
[<c01b871c>] (dump_stack) from [<c001ecd8>] (warn_slowpath_common+0x90/0xbc)
r4:c0559dd8 r3:c0558000
[<c001ec48>] (warn_slowpath_common) from [<c001ed3c>] (warn_slowpath_fmt+0x38/0x40)
r8:00000000 r7:00040008 r6:00000010 r5:00000000 r4:ee952570
[<c001ed08>] (warn_slowpath_fmt) from [<c02913a8>] (can_rx_fifo_irq_offload+0x214/0x264)
r3:c041894e r2:c04def9b
[<c0291194>] (can_rx_fifo_irq_offload) from [<bf008da4>] (flexcan_irq+0xcc/0x188 [flexcan])
r8:00000000 r7:00040008 r6:00000010 r5:f0b30000 r4:ee952000 r3:fffffffc
[<bf008cd8>] (flexcan_irq [flexcan]) from [<c0058b50>] (handle_irq_event_percpu+0x38/0x12c)
fec 2188000.ethernet eth0: MDIO read timeout
r8:0000001a r7:00000000 r6:ef1316c0 r5:00000000 r4:ee25f800 r3:bf008cd8
[<c0058b18>] (handle_irq_event_percpu) from [<c0058c84>] (handle_irq_event+0x40/0x64)
r10:00000000 r9:ef7dc6c0 r8:ef008000 r7:0000001a r6:ef131720 r5:ef131720
r4:ef1316c0
[<c0058c44>] (handle_irq_event) from [<c005bff4>] (handle_fasteoi_irq+0xb0/0x12c)
r6:ef131720 r5:c055def0 r4:ef1316c0 r3:00000000
[<c005bf44>] (handle_fasteoi_irq) from [<c0058288>] (generic_handle_irq+0x20/0x30)
r6:c0553080 r5:00000000 r4:00000000 r3:c005bf44
[<c0058268>] (generic_handle_irq) from [<c0058590>] (__handle_domain_irq+0x94/0xbc)
[<c00584fc>] (__handle_domain_irq) from [<c00093fc>] (gic_handle_irq+0x4c/0x78)
r8:c05478c0 r7:f4001100 r6:c0559f18 r5:c055a744 r4:f4000100 r3:c0559f18
[<c00093b0>] (gic_handle_irq) from [<c0013354>] (__irq_svc+0x54/0x90)
Exception stack(0xc0559f18 to 0xc0559f60)
9f00: 00000000 002d4f24
9f20: ef7aa2d4 c001a420 c0558000 c055a4d8 c0559f88 c055a4d8 c05478c0 ef7dc6c0
9f40: 00000000 c0559f74 c0559f78 c0559f68 c000faa8 c000faac 60070013 ffffffff
r7:c0559f4c r6:ffffffff r5:60070013 r4:c000faac
[<c000fa78>] (arch_cpu_idle) from [<c0050c68>] (default_idle_call+0x30/0x34)
[<c0050c38>] (default_idle_call) from [<c0050d80>] (cpu_startup_entry+0x114/0x17c)
[<c0050c6c>] (cpu_startup_entry) from [<c03e3d3c>] (rest_init+0x7c/0x94)
r7:c055a400 r3:c0558000
[<c03e3cc0>] (rest_init) from [<c0524c4c>] (start_kernel+0x304/0x35c)
r4:00000000 r3:c0558000
[<c0524948>] (start_kernel) from [<10008078>] (0x10008078)
---[ end trace 9a14375964ae8903 ]---
------------[ cut here ]------------
Kernel is 4.4 with ...
flexcan/flexcan-calculate-default-value-for-imask1-during-runtime.patch
flexcan/flexcan-make-TX-mailbox-selectable-during-runtime.patch
flexcan/rx-fifo-Add-support-for-simple-irq-offloading.patch
flexcan/flexcan-make-use-of-rx-fifos-irq_offload_simple.patch
flexcan/flexcan-add-missing-register-definitions.patch
flexcan/flexcan-activate-individual-RX-masking-and-initialize-reg_rximr.patch
flexcan/flexcan-add-quirk-FLEXCAN_QUIRK_ENABLE_EACEN_RRS.patch
flexcan/flexcan-reg_imask2_default.patch
flexcan/rx-fifo-introduce-software-rx-fifo-implementation.patch
flexcan/flexcan-add-support-for-rx-fifo-based-software-FIFO-implementation.patch
flexcan/flexcan-switch-imx6-and-vf610-to-software-based-fifo.patch
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
2016-01-18 11:14 ` Holger Schurig
@ 2016-01-18 22:04 ` Marc Kleine-Budde
2016-01-19 0:26 ` Tom Evans
0 siblings, 1 reply; 18+ messages in thread
From: Marc Kleine-Budde @ 2016-01-18 22:04 UTC (permalink / raw)
To: Holger Schurig; +Cc: linux-can, kernel, bhupesh.sharma
[-- Attachment #1: Type: text/plain, Size: 1987 bytes --]
On 01/18/2016 12:14 PM, Holger Schurig wrote:
> Marc Kleine-Budde <mkl@pengutronix.de> writes:
>
>> Testing and feedback welcome.
>
> And here it is, albeit a bit late:
>
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 0 at /home/schurig/d/mkarm/linux-4.4/drivers/net/can/rx-fifo.c:203 can_rx_fifo_irq_offload+0x214/0x264()
> can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
> Modules linked in: bnep btusb btrtl btbcm btintel bluetooth smsc95xx usbnet mii imx_sdma flexcan dlog(O)
> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.4.0 #1
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Thanks for testing, this driver triggers what we think a hardware bug,
resulting in packages are not beeing filled into the correct order into
the hardware. There are some people at fsl/nxp looking into this issue
at the hardware level.
> flexcan/flexcan-calculate-default-value-for-imask1-during-runtime.patch
> flexcan/flexcan-make-TX-mailbox-selectable-during-runtime.patch
> flexcan/rx-fifo-Add-support-for-simple-irq-offloading.patch
> flexcan/flexcan-make-use-of-rx-fifos-irq_offload_simple.patch
> flexcan/flexcan-add-missing-register-definitions.patch
> flexcan/flexcan-activate-individual-RX-masking-and-initialize-reg_rximr.patch
> flexcan/flexcan-add-quirk-FLEXCAN_QUIRK_ENABLE_EACEN_RRS.patch
> flexcan/flexcan-reg_imask2_default.patch
> flexcan/rx-fifo-introduce-software-rx-fifo-implementation.patch
> flexcan/flexcan-add-support-for-rx-fifo-based-software-FIFO-implementation.patch
> flexcan/flexcan-switch-imx6-and-vf610-to-software-based-fifo.patch
You can omit the last patch and it should work.
regards,
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] 18+ messages in thread
* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
2016-01-18 22:04 ` Marc Kleine-Budde
@ 2016-01-19 0:26 ` Tom Evans
2016-02-22 15:16 ` Mirza Krak
0 siblings, 1 reply; 18+ messages in thread
From: Tom Evans @ 2016-01-19 0:26 UTC (permalink / raw)
To: Marc Kleine-Budde, Holger Schurig; +Cc: linux-can, kernel, bhupesh.sharma
On 19/01/16 09:04, Marc Kleine-Budde wrote:
> On 01/18/2016 12:14 PM, Holger Schurig wrote:
>> Marc Kleine-Budde <mkl@pengutronix.de> writes:
>>
>>> Testing and feedback welcome.
>>
>> And here it is, albeit a bit late:
>>
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 0 at /home/schurig/d/mkarm/linux-4.4/drivers/net/can/rx-fifo.c:203 can_rx_fifo_irq_offload+0x214/0x264()
>> can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
>> Modules linked in: bnep btusb btrtl btbcm btintel bluetooth smsc95xx usbnet mii imx_sdma flexcan dlog(O)
>> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.4.0 #1
>> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
>
> Thanks for testing, this driver triggers what we think a hardware bug,
> resulting in packages are not beeing filled into the correct order into
> the hardware. There are some people at fsl/nxp looking into this issue
> at the hardware level.
Very unlikely, but I'd like to check that this isn't a similar driver bug to
the one Freescale had in the 2.6.35 FlexCAN driver in the FIFO handling code.
The one line description of the problem is that the driver cleared the FIFO
interrupt and THEN read the FIFO, which is the opposite of what the manual
says to do.
The above and the following link should be enough information to check to see
if there's an obvious problem like this, otherwise could someone please email
me the source of the driver or a link to same so I can check?
https://community.freescale.com/thread/381075
Tom
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
2016-01-19 0:26 ` Tom Evans
@ 2016-02-22 15:16 ` Mirza Krak
2016-02-22 15:19 ` Marc Kleine-Budde
0 siblings, 1 reply; 18+ messages in thread
From: Mirza Krak @ 2016-02-22 15:16 UTC (permalink / raw)
To: tom_usenet
Cc: Marc Kleine-Budde, Holger Schurig, linux-can@vger.kernel.org,
kernel, bhupesh.sharma
2016-01-19 1:26 GMT+01:00 Tom Evans <tom_usenet@optusnet.com.au>:
> On 19/01/16 09:04, Marc Kleine-Budde wrote:
>>
>> On 01/18/2016 12:14 PM, Holger Schurig wrote:
>>>
>>> Marc Kleine-Budde <mkl@pengutronix.de> writes:
>>>
>>>> Testing and feedback welcome.
>>>
>>>
>>> And here it is, albeit a bit late:
>>>
>>> ------------[ cut here ]------------
>>> WARNING: CPU: 0 PID: 0 at
>>> /home/schurig/d/mkarm/linux-4.4/drivers/net/can/rx-fifo.c:203
>>> can_rx_fifo_irq_offload+0x214/0x264()
>>> can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
>>> Modules linked in: bnep btusb btrtl btbcm btintel bluetooth smsc95xx
>>> usbnet mii imx_sdma flexcan dlog(O)
>>> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 4.4.0 #1
>>> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Applied this patch series to my 4.1.5 kernel and for what it is worth
I get the same error on VF610 after approximately 500 k frames.
[ 118.751463] WARNING: CPU: 0 PID: 0 at drivers/net/can/rx-fifo.c:205
can_rx_fifo_irq_offload+0x2dc/0x30c() [ 118.761065]
can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
[ 118.768137] Modules
linked in: mx4_pic(O) mcp251x [last unloaded: mx4_pic]
[ 118.775108] CPU: 0 PID: 0
Comm: swapper Tainted: G O
4.1.15-00058-gd84a5e156db7-dirty #1 [ 118.784355]
Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree)
--
Med Vänliga Hälsningar / Best Regards
*******************************************************************
Mirza Krak
Host Mobility AB
mirza.krak@hostmobility.com
Anders Personsgatan 12, 416 64 Göteborg
Sweden
http://www.hostmobility.com
Direct: +46 31 31 32 704
Phone: +46 31 31 32 700
Fax: +46 31 80 67 51
Mobile: +46 730 28 06 22
*******************************************************************
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 00/11] RFC: cleanup flexcan driver, introduce and make use of IRQ offloading
2016-02-22 15:16 ` Mirza Krak
@ 2016-02-22 15:19 ` Marc Kleine-Budde
0 siblings, 0 replies; 18+ messages in thread
From: Marc Kleine-Budde @ 2016-02-22 15:19 UTC (permalink / raw)
To: Mirza Krak, tom_usenet
Cc: Holger Schurig, linux-can@vger.kernel.org, kernel, bhupesh.sharma
[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]
On 02/22/2016 04:16 PM, Mirza Krak wrote:
> Applied this patch series to my 4.1.5 kernel and for what it is worth
> I get the same error on VF610 after approximately 500 k frames.
>
> [ 118.751463] WARNING: CPU: 0 PID: 0 at drivers/net/can/rx-fifo.c:205
> can_rx_fifo_irq_offload+0x2dc/0x30c() [ 118.761065]
> can_rx_fifo_irq_offload: No messages found, RX-FIFO out of sync?
> [ 118.768137] Modules
> linked in: mx4_pic(O) mcp251x [last unloaded: mx4_pic]
> [ 118.775108] CPU: 0 PID: 0
> Comm: swapper Tainted: G O
> 4.1.15-00058-gd84a5e156db7-dirty #1 [ 118.784355]
> Hardware name: Freescale Vybrid VF5xx/VF6xx (Device Tree)
Thanks for the feedback. The fsl/nxp people are working on this. They
gave me a hint I'll verify and test today,
regards,
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] 18+ messages in thread