aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2013-04-12 06:49:36 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:47:23 -0400
commite1c0677e2a04c7f88e64b55afeb42b687d376627 (patch)
treef36c84fb9beaa99e7a6959b4631d4fff880d1bdf
parent94f609967b18344dd664e69e9ee28d517b428429 (diff)
ENGR00258885 flexcan: fix errata ERR005829 that MB may fail to be sent
This is an issue from IC errata ERR005829 which is described as follows: ---------------------------------------------------------- FlexCAN does not transmit a message that is enabled to be transmitted in a specific moment during the arbitration process. The following conditions are necessary to have the issue. - Only one MB is configured to be transmitted - The write which enables the MB to be transmitted (write on Control status word) happens during a specific clock during the arbitration process. After this arbitration process occurs, the bus goes to Idle state and no new message is received on bus. For example: 1) MB13 is deactivated on RxIntermission (write 0x0 on CODE field from Control Status word) - First write on CODE 2) Reconfigure the ID and data fields 3) Enable the MB13 to be transmitted on BusIdle (write 0xC on Code field) - Second write on code 4) CAN bus keeps in Idle state 5) No write on Control status from any MB happens. During the second write on code (step 3), the write must happen one clock before the current MB13 is to be scanned by arbitration process. In this case, it does not detect the new code (0xC) and no new arbitration is scheduled. The suggested workaround which is implemented in this patch is: The workaround consists of executing two extra steps: 6. Reserve the first valid mailbox as an inactive mailbox (CODE=0b1000). If RX FIFO is disabled, this mailbox must be MB0. Otherwise, the first valid mailbox can be found by using table "RX FIFO filters" on FlexCAN3 chapter. 7. Write twice INACTIVE code (0b1000) into the first valid mailbox. Note: The first mailbox cannot be used for reception or transmission process. ------------------------------------------------------------- Note: Although the currently flexcan driver does not have the step 1 to run, it's also possible to meet this issue in theory because we can not predict when the arbitration is scheduled. With a modified can-utils/canfdttest tool simulating Pingpong test, we were able to reproduce this issue after running a about one day. After applying this patch, we ran six days and did not see the issue happen again on two mx6q sabrelite boards. Note: with a few minors change for new kernel and change errata id from ERR005641 to ERR005829 which is the open one in freescale website. Signed-off-by: Dong Aisheng <b29396@freescale.com> (cherry picked from commit 872eb1691afb83a2760052c615ed410a7cfe71e0)
-rw-r--r--drivers/net/can/flexcan.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index e99e4d04ee43..a89765b81df5 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -130,7 +130,8 @@
130 FLEXCAN_ESR_WAK_INT) 130 FLEXCAN_ESR_WAK_INT)
131 131
132/* FLEXCAN interrupt flag register (IFLAG) bits */ 132/* FLEXCAN interrupt flag register (IFLAG) bits */
133#define FLEXCAN_TX_BUF_ID 8 133#define FLEXCAN_RESERVED_BUF_ID 8
134#define FLEXCAN_TX_BUF_ID 13
134#define FLEXCAN_IFLAG_BUF(x) BIT(x) 135#define FLEXCAN_IFLAG_BUF(x) BIT(x)
135#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) 136#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
136#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) 137#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
@@ -165,6 +166,7 @@
165 */ 166 */
166#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ 167#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
167#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ 168#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
169#define FLEXCAN_HAS_ERR005829 BIT(3) /* have errata ERR005829 */
168 170
169/* Structure of the message buffer */ 171/* Structure of the message buffer */
170struct flexcan_mb { 172struct flexcan_mb {
@@ -225,7 +227,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = {
225}; 227};
226static struct flexcan_devtype_data fsl_imx28_devtype_data; 228static struct flexcan_devtype_data fsl_imx28_devtype_data;
227static struct flexcan_devtype_data fsl_imx6q_devtype_data = { 229static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
228 .features = FLEXCAN_HAS_V10_FEATURES, 230 .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_ERR005829,
229}; 231};
230 232
231static const struct can_bittiming_const flexcan_bittiming_const = { 233static const struct can_bittiming_const flexcan_bittiming_const = {
@@ -379,6 +381,11 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
379 flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id); 381 flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
380 flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); 382 flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
381 383
384 if (priv->devtype_data->features & FLEXCAN_HAS_ERR005829) {
385 writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
386 writel(0x0, &regs->cantxfg[FLEXCAN_RESERVED_BUF_ID].can_ctrl);
387 }
388
382 return NETDEV_TX_OK; 389 return NETDEV_TX_OK;
383} 390}
384 391