]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
a2a021baf03af9f17b87e9a4e294baeebd335f72
[thirdparty/kernel/stable-queue.git] /
1 From d5a7b406c529e4595ce03dc8f6dcf7fa36f106fa Mon Sep 17 00:00:00 2001
2 From: Marc Kleine-Budde <mkl@pengutronix.de>
3 Date: Fri, 4 Oct 2013 10:52:36 +0200
4 Subject: can: flexcan: flexcan_chip_start: fix regression, mark one MB for TX and abort pending TX
5
6 From: Marc Kleine-Budde <mkl@pengutronix.de>
7
8 commit d5a7b406c529e4595ce03dc8f6dcf7fa36f106fa upstream.
9
10 In patch
11
12 0d1862e can: flexcan: fix flexcan_chip_start() on imx6
13
14 the loop in flexcan_chip_start() that iterates over all mailboxes after the
15 soft reset of the CAN core was removed. This loop put all mailboxes (even the
16 ones marked as reserved 1...7) into EMPTY/INACTIVE mode. On mailboxes 8...63,
17 this aborts any pending TX messages.
18
19 After a cold boot there is random garbage in the mailboxes, which leads to
20 spontaneous transmit of CAN frames during first activation. Further if the
21 interface was disabled with a pending message (usually due to an error
22 condition on the CAN bus), this message is retransmitted after enabling the
23 interface again.
24
25 This patch fixes the regression by:
26 1) Limiting the maximum number of used mailboxes to 8, 0...7 are used by the RX
27 FIFO, 8 is used by TX.
28 2) Marking the TX mailbox as EMPTY/INACTIVE, so that any pending TX of that
29 mailbox is aborted.
30
31 Cc: Lothar Waßmann <LW@KARO-electronics.de>
32 Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
33 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34
35 ---
36 drivers/net/can/flexcan.c | 10 ++++++++--
37 1 file changed, 8 insertions(+), 2 deletions(-)
38
39 --- a/drivers/net/can/flexcan.c
40 +++ b/drivers/net/can/flexcan.c
41 @@ -60,7 +60,7 @@
42 #define FLEXCAN_MCR_BCC BIT(16)
43 #define FLEXCAN_MCR_LPRIO_EN BIT(13)
44 #define FLEXCAN_MCR_AEN BIT(12)
45 -#define FLEXCAN_MCR_MAXMB(x) ((x) & 0xf)
46 +#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f)
47 #define FLEXCAN_MCR_IDAM_A (0 << 8)
48 #define FLEXCAN_MCR_IDAM_B (1 << 8)
49 #define FLEXCAN_MCR_IDAM_C (2 << 8)
50 @@ -701,9 +701,11 @@ static int flexcan_chip_start(struct net
51 *
52 */
53 reg_mcr = flexcan_read(&regs->mcr);
54 + reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
55 reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
56 FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
57 - FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS;
58 + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS |
59 + FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
60 netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
61 flexcan_write(reg_mcr, &regs->mcr);
62
63 @@ -744,6 +746,10 @@ static int flexcan_chip_start(struct net
64 &regs->cantxfg[i].can_ctrl);
65 }
66
67 + /* Abort any pending TX, mark Mailbox as INACTIVE */
68 + flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
69 + &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
70 +
71 /* acceptance mask/acceptance code (accept everything) */
72 flexcan_write(0x0, &regs->rxgmask);
73 flexcan_write(0x0, &regs->rx14mask);