From: Joakim Zhang <qiangqing.zhang@nxp.com>
To: "mkl@pengutronix.de" <mkl@pengutronix.de>,
"linux-can@vger.kernel.org" <linux-can@vger.kernel.org>
Cc: "wg@grandegger.com" <wg@grandegger.com>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
dl-linux-imx <linux-imx@nxp.com>,
Joakim Zhang <qiangqing.zhang@nxp.com>
Subject: [PATCH] can: flexcan: add TX support for variable payload size
Date: Wed, 12 Dec 2018 06:46:34 +0000 [thread overview]
Message-ID: <20181212064419.18613-1-qiangqing.zhang@nxp.com> (raw)
Now the FlexCAN driver always use last mailbox for TX, it will work well
when MB payload size is 8/16 bytes.
TX mailbox would change to 13 when MB payload size is 64 bytes to
support CANFD. So we may need to set iflag register to add support for
variable payload size.
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
drivers/net/can/flexcan.c | 42 +++++++++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 0f36eafe3ac1..13fd085fcf84 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -141,7 +141,9 @@
#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8
#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0
#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
-#define FLEXCAN_IFLAG_MB(x) BIT((x) & 0x1f)
+#define FLEXCAN_IFLAG1_MB_NUM 32
+#define FLEXCAN_IFLAG1_MB(x) BIT(x)
+#define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f)
#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
@@ -822,9 +824,15 @@ static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
struct flexcan_regs __iomem *regs = priv->regs;
u32 iflag1, iflag2;
- iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default &
- ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
- iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default;
+ if (priv->tx_mb_idx >= FLEXCAN_IFLAG1_MB_NUM) {
+ iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default &
+ ~FLEXCAN_IFLAG2_MB(priv->tx_mb_idx);
+ iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default;
+ } else {
+ iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default;
+ iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default &
+ ~FLEXCAN_IFLAG1_MB(priv->tx_mb_idx);
+ }
return (u64)iflag2 << 32 | iflag1;
}
@@ -836,7 +844,8 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->regs;
irqreturn_t handled = IRQ_NONE;
- u32 reg_iflag2, reg_esr;
+ u32 reg_tx_iflag, tx_iflag_idx, reg_esr;
+ void __iomem *reg_iflag;
enum can_state last_state = priv->can.state;
/* reception interrupt */
@@ -870,10 +879,18 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
}
}
- reg_iflag2 = priv->read(®s->iflag2);
+ if (priv->tx_mb_idx >= FLEXCAN_IFLAG1_MB_NUM) {
+ reg_tx_iflag = priv->read(®s->iflag2);
+ tx_iflag_idx = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx);
+ reg_iflag = ®s->iflag2;
+ } else {
+ reg_tx_iflag = priv->read(®s->iflag1);
+ tx_iflag_idx = FLEXCAN_IFLAG1_MB(priv->tx_mb_idx);
+ reg_iflag = ®s->iflag1;
+ }
/* transmission complete interrupt */
- if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) {
+ if (reg_tx_iflag & tx_iflag_idx) {
u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl);
handled = IRQ_HANDLED;
@@ -885,7 +902,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
/* after sending a RTR frame MB is in RX mode */
priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
&priv->tx_mb->can_ctrl);
- priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2);
+ priv->write(tx_iflag_idx, reg_iflag);
netif_wake_queue(dev);
}
@@ -1244,8 +1261,13 @@ static int flexcan_open(struct net_device *dev)
priv->tx_mb_idx = priv->mb_count - 1;
priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx);
- priv->reg_imask1_default = 0;
- priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
+ if (priv->tx_mb_idx >= FLEXCAN_IFLAG1_MB_NUM) {
+ priv->reg_imask1_default = 0;
+ priv->reg_imask2_default = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx);
+ } else {
+ priv->reg_imask1_default = FLEXCAN_IFLAG1_MB(priv->tx_mb_idx);
+ priv->reg_imask2_default = 0;
+ }
priv->offload.mailbox_read = flexcan_mailbox_read;
--
2.17.1
next reply other threads:[~2018-12-12 6:46 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-12 6:46 Joakim Zhang [this message]
2019-01-17 6:26 ` [PATCH] can: flexcan: add TX support for variable payload size Joakim Zhang
2019-02-14 9:57 ` Joakim Zhang
2019-02-27 14:03 ` Marc Kleine-Budde
2019-02-28 3:43 ` Joakim Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181212064419.18613-1-qiangqing.zhang@nxp.com \
--to=qiangqing.zhang@nxp.com \
--cc=linux-can@vger.kernel.org \
--cc=linux-imx@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mkl@pengutronix.de \
--cc=netdev@vger.kernel.org \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox