|
|
@@ -62,7 +62,7 @@
|
|
|
#define FLEXCAN_MCR_BCC BIT(16)
|
|
|
#define FLEXCAN_MCR_LPRIO_EN BIT(13)
|
|
|
#define FLEXCAN_MCR_AEN BIT(12)
|
|
|
-#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f)
|
|
|
+#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f)
|
|
|
#define FLEXCAN_MCR_IDAM_A (0 << 8)
|
|
|
#define FLEXCAN_MCR_IDAM_B (1 << 8)
|
|
|
#define FLEXCAN_MCR_IDAM_C (2 << 8)
|
|
|
@@ -125,7 +125,9 @@
|
|
|
FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
|
|
|
|
|
|
/* FLEXCAN interrupt flag register (IFLAG) bits */
|
|
|
-#define FLEXCAN_TX_BUF_ID 8
|
|
|
+/* 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_IFLAG_RX_FIFO_OVERFLOW BIT(7)
|
|
|
#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
|
|
|
@@ -136,6 +138,17 @@
|
|
|
|
|
|
/* FLEXCAN message buffers */
|
|
|
#define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 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)
|
|
|
+#define FLEXCAN_MB_CODE_RX_OVERRRUN (0x6 << 24)
|
|
|
+#define FLEXCAN_MB_CODE_RX_RANSWER (0xa << 24)
|
|
|
+
|
|
|
+#define FLEXCAN_MB_CODE_TX_INACTIVE (0x8 << 24)
|
|
|
+#define FLEXCAN_MB_CODE_TX_ABORT (0x9 << 24)
|
|
|
+#define FLEXCAN_MB_CODE_TX_DATA (0xc << 24)
|
|
|
+#define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24)
|
|
|
+
|
|
|
#define FLEXCAN_MB_CNT_SRR BIT(22)
|
|
|
#define FLEXCAN_MB_CNT_IDE BIT(21)
|
|
|
#define FLEXCAN_MB_CNT_RTR BIT(20)
|
|
|
@@ -428,6 +441,14 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
|
|
|
flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
|
|
|
|
|
|
+ /* Errata ERR005829 step8:
|
|
|
+ * Write twice INACTIVE(0x8) code to first MB.
|
|
|
+ */
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
|
|
+ ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
|
|
+ ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
|
|
+
|
|
|
return NETDEV_TX_OK;
|
|
|
}
|
|
|
|
|
|
@@ -744,6 +765,9 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
|
|
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 mailbox is in RX mode */
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
|
|
+ ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
|
|
|
flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
|
|
|
netif_wake_queue(dev);
|
|
|
}
|
|
|
@@ -801,6 +825,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
|
|
struct flexcan_regs __iomem *regs = priv->base;
|
|
|
int err;
|
|
|
u32 reg_mcr, reg_ctrl;
|
|
|
+ int i;
|
|
|
|
|
|
/* enable module */
|
|
|
err = flexcan_chip_enable(priv);
|
|
|
@@ -867,8 +892,18 @@ 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);
|
|
|
|
|
|
- /* Abort any pending TX, mark Mailbox as INACTIVE */
|
|
|
- flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
|
|
|
+ /* clear and invalidate all mailboxes first */
|
|
|
+ for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->cantxfg); i++) {
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
|
|
+ ®s->cantxfg[i].can_ctrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Errata ERR005829: mark first TX mailbox as INACTIVE */
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
|
|
+ ®s->cantxfg[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
|
|
+
|
|
|
+ /* mark TX mailbox as INACTIVE */
|
|
|
+ flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
|
|
®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
|
|
|
|
|
|
/* acceptance mask/acceptance code (accept everything) */
|