From patchwork Thu May 14 11:33:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "bhupesh.sharma@freescale.com" X-Patchwork-Id: 6404901 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 38BE39F374 for ; Thu, 14 May 2015 11:39:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0078B20453 for ; Thu, 14 May 2015 11:39:17 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC4FE202FE for ; Thu, 14 May 2015 11:39:15 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YsrR9-0008E2-4l; Thu, 14 May 2015 11:36:23 +0000 Received: from mail-bn1bon0146.outbound.protection.outlook.com ([157.56.111.146] helo=na01-bn1-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YsrPb-0006EY-0L for linux-arm-kernel@lists.infradead.org; Thu, 14 May 2015 11:34:49 +0000 Received: from CH1PR03CA007.namprd03.prod.outlook.com (10.255.156.152) by BLUPR03MB438.namprd03.prod.outlook.com (10.141.78.149) with Microsoft SMTP Server (TLS) id 15.1.166.19; Thu, 14 May 2015 11:34:24 +0000 Received: from BL2FFO11FD047.protection.gbl (10.255.156.132) by CH1PR03CA007.outlook.office365.com (10.255.156.152) with Microsoft SMTP Server (TLS) id 15.1.154.19 via Frontend Transport; Thu, 14 May 2015 11:34:24 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; lists.infradead.org; dkim=none (message not signed) header.d=none; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BL2FFO11FD047.mail.protection.outlook.com (10.173.161.209) with Microsoft SMTP Server (TLS) id 15.1.160.8 via Frontend Transport; Thu, 14 May 2015 11:34:23 +0000 Received: from b45370.ap.freescale.net (B45370-01.ap.freescale.net [10.232.40.212]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t4EBXct2006339; Thu, 14 May 2015 04:34:19 -0700 From: Bhupesh Sharma To: , , Subject: [PATCH v2 5/5] can: flexcan: Add support for non RX-FIFO mode Date: Thu, 14 May 2015 17:03:35 +0530 Message-ID: <1431603215-25546-6-git-send-email-bhupesh.sharma@freescale.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1431603215-25546-1-git-send-email-bhupesh.sharma@freescale.com> References: <1431603215-25546-1-git-send-email-bhupesh.sharma@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD047; 1:cdNb/BR54df9jtn0otSL19Q5EKWDek6N593xD7anIJBpJt/oXIvTJLyRt6O25NohY8HAMfRSZdTEr9CE8VUtMor2Xz0PetAn5QmVMPstVp+XHBJu/iqamtpC0OaK4V1fs/9wpdiP4r7J+0algmYgrBglAYsVNorXSKJ2gsvyMD2sB8E6xDB6jX58NKc7iddme5CuK7I7YH49YdRH7BwzVkqkbH+oZIIZBTikhbSm27ZuYwDCrN7MBXgWfsc2j+g77IrqHbqHKpO8EDs6oBXaykVOOEhdjbvnc8tu7IeCjSL0otGkrofEYUdv0Mh7CtchZEq3CBhf+aIxDbRg2aZBOA== X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(339900001)(199003)(189002)(189998001)(104016003)(19580395003)(5001960100002)(19580405001)(48376002)(50466002)(33646002)(77096005)(105606002)(50226001)(6806004)(2201001)(87936001)(2950100001)(106466001)(36756003)(76176999)(85426001)(46102003)(50986999)(92566002)(62966003)(77156002)(5001770100001)(86362001)(47776003)(229853001); DIR:OUT; SFP:1102; SCL:1; SRVR:BLUPR03MB438; H:az84smr01.freescale.net; FPR:; SPF:Fail; MLV:sfv; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB438; 2:rMKS2te/14MJaG7Z0QKt2rbv0Mx9NhyOPeEHqqFFirWwa/Cx9OzqCv+hbJ6Fwuhl; 2:qfRZ2E7atXgVbq0k8dRsZ44tV2TPxndh2y6Cv8nE0KdbSvVcIfazqW23b9kg2B3xcAn90zWqdKQFgAS6LudktukA6a1Sf+OV+PeBvCBw/Z6E7fDsv+opzYp3wvd0icvDYa+d4d9090PQw8Ze2dKgiALk1jl9nCRSXCx6RQ5ktu0/h3i96eEYgMqenFLmLq8YmlWRR/fExZYNlRQMxOlOqXGq1LjC1i4wH+OyiACEoi4=; 6:Agfo8cNCedpmiIFd3FXgX/cMAvmU3Fa3ibT/y6lwIJBwu1jz/Ttyp485EznbMXHEuk7Cqj5XYjp8zCDD0CySGRv+zUSd0TT1HQRfXHYwLifiQ8neVth2uMmYyvDEUDa3fi7U0W3uuwQcR/NDXQRHKRneGWvBFFGJv7zZI4oGknGiVD7dSfnSSa8P85gYDf2n/Qhi2cKdZ9ml62qIaxZizQ6oFY1h8vfZPyiSQQRbGM932+/QMwOOFHtJ2uyHkbcBvaeoMhaiR3tcoTO/D4uM83Zgf+0Y3j5Bm2x7Pcz/SniJr2gqYl8o/qmotRQwbVTV5lQRTyf2QhMDUQSCzEQYNw==; 3:sq6WIG3xLdOL+b7hAV3gfZvTVBvV7QYHjltpF4fmK0SPdVF8agKh+t+B56qCf0WzLzk3+US5GSvoFZ5RUsSPRz9YtcWAuDzGYNkP5jCqxoiITT6O7/PdPJNSoH3qfTtaCiGYXK5XKL7n9cxZD8NTaNTyo5T6q+F6TRXTr3RRyUqicb8EvGanDxiAvPaYBf9t9glP+uxkANqSdvsHDvFjcfR6dpxHhXsHG4h91Z3D+9jhvhidRZbFbelRsvVOSnfGAIJUD+iVJ1QLjgngNnHCQvGI5CX4qN5HXSiZSODAo2Q= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB438; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:BLUPR03MB438; BCL:0; PCL:0; RULEID:; SRVR:BLUPR03MB438; X-Forefront-PRVS: 0576145E86 X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB438; 9:xZQ+FBzuxssvv9nh5ngbVQRljSQEkLRV2n714bfy/ivNxkR9LAt+J9ch/wxaBRahk00IiiOgX89Mpx60/f5yFZ1/mw2x9HP/O7MCYGiC5/k2ifUya2LlMzExmY7Snc2wEdU2IJFEYAmwwFUN/+v+ZYKrlxI9bygsENaSSFGJCCk0othtSQOr5t3IO5022gM3rYI6YqAdNTH5GZWUbtJYGHtPyzQ/jGlcZcYXTPsVgKCYQLpB/+/Vc2avJkooW8vVifJTQRILWz4nF28kUeIdboQOpLWzlKvk/VCagSKZZ8b6qLEdsl1fgHS8WpjhpvGR5hREQbZAOAdEAzZqEP6dTAC8rXZvJdW4IW5EFqhQ/bFPmItjJmf0B+yrJQd7QgJMe41S2jPlA/weSNGZwZ8HWrdgGUBqGUOdCOxsWd2A7Y3MfMsU6XGfR55j9Ki8qLJY/P8txcP0NxM+qp4x2a2yCH+jab0ZYrXzxI96Wh686cofVf4Be9bqpIKjxffhk51Hs57z1/htQwqAA4AWpGt6tH5PyU7+QxHhD5OLDix9BA65foOapWf1PSbkpKru5NZmVd/gXzRQNHa4Nrc+0B5ehREf4KYTrPi9RljRtWO1QXNLE3snWtPiQJ9pMqtVJ3yTLRxFvfW3pIBEQC6EgFt+376qTnBb7nibUogjkB1dxdcYwqfpJ0jOC13urtXA4OKzAJkxRtqX1ZBvxRaukVi2Ux5QZLMn075EPmo1Gu58utit0n31aMb779g4MhbzChQ3AUKKw4XnmP8bkjCEOBAE3syzcacQfFdoWCdi1xirDmP3X880x7qWtN//POR8nXW9NWmdTFx/gQIJyU15a/9nT9HFEj6YYyqoIEL++pTaNOA= X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB438; 3:P02tq/FKiL187W7pTKrzy0SUbvzC+BIMg5tA/sx1IICRl63iLPx3z2bh377M0R6Sl0zeNIfhddI6SibWwEPZ2FdycEKpPJfVlW40n9iixKJiVmi2NyB5teA+nMHO5BxB5sqX6lvdZgkLnl5+vIItQw==; 10:42yBAT+AXnWaPmXjbfXmiR7ldFL50OvNi01yvYvdAMN07lCynsTpqYbvzdbKvbKyLebwofCgKSKw1yO8afVy131622eqdG9hdT4tQe2ZmxM=; 6:/whqQb/AjJhjQYGNhPIMfkXcC133REzv4o6RNrUcm7z+hHRmCsdpr9qfzNkfqx/d X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 May 2015 11:34:23.4888 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR03MB438 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150514_043447_421973_8135309C X-CRM114-Status: GOOD ( 18.35 ) X-Spam-Score: -0.0 (/) Cc: bhupesh.sharma@freescale.com, bhupesh.linux@gmail.com, linux-arm-kernel@lists.infradead.org, Sakar.Arora@freescale.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds support for non RX-FIFO (legacy) mode in the flexcan driver. On certain SoCs, the RX-FIFO support might be broken, as a result we need to fall-back on the legacy (non RX-FIFO) mode to receive CAN frames. Signed-off-by: Bhupesh Sharma Signed-off-by: Sakar Arora --- drivers/net/can/flexcan.c | 188 +++++++++++++++++++++++++++++++++------------ 1 file changed, 138 insertions(+), 50 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index b0222ae..3240472 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -156,6 +156,9 @@ #define FLEXCAN_IFLAG_DEFAULT \ (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \ FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) +#define FLEXCAN_IFLAG_DEFAULT_RX_MB_MODE \ + (FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) +#define FLEXCAN_IFLAG_RX_MB_RXMASK ((1 << FLEXCAN_TX_BUF_RESERVED) - 1) /* FLEXCAN message buffers */ #define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) @@ -198,6 +201,8 @@ #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ #define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */ +#define FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT \ + BIT(4) /* No RX FIFO mode support */ /* Structure of the message buffer */ struct flexcan_mb { @@ -252,6 +257,7 @@ struct flexcan_priv { void __iomem *base; u32 reg_esr; u32 reg_ctrl_default; + u32 rx_msg_buf; struct clk *clk_ipg; struct clk *clk_per; @@ -303,8 +309,7 @@ static const struct can_bittiming_const flexcan_bittiming_const = { .brp_inc = 1, }; -/* - * FlexCAN module is essentially modelled as a little-endian IP in most +/* FlexCAN module is essentially modelled as a little-endian IP in most * SoCs, i.e the registers as well as the message buffer areas are * implemented in a little-endian fashion. * @@ -646,12 +651,10 @@ 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 void flexcan_read_can_frame(const struct flexcan_priv *priv, + struct flexcan_mb __iomem *mb, + struct can_frame *cf) { - const struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->base; - struct flexcan_mb __iomem *mb = ®s->cantxfg[0]; u32 reg_ctrl, reg_id; reg_ctrl = priv->read(&mb->can_ctrl); @@ -667,14 +670,39 @@ static void flexcan_read_fifo(const struct net_device *dev, *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0])); *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1])); +} + +static void flexcan_read_fifo(const struct net_device *dev, + struct can_frame *cf) +{ + const struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->base; + struct flexcan_mb __iomem *mb = ®s->cantxfg[0]; + + flexcan_read_can_frame(priv, mb, cf); /* mark as read */ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); priv->read(®s->timer); } +static void flexcan_read_msg_buf(const struct net_device *dev, + struct can_frame *cf, u32 msg_buf) +{ + const struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_regs __iomem *regs = priv->base; + struct flexcan_mb __iomem *mb = ®s->cantxfg[msg_buf]; + + flexcan_read_can_frame(priv, mb, cf); + + /* mark as read */ + priv->write(BIT(msg_buf), ®s->iflag1); + priv->read(®s->timer); +} + static int flexcan_read_frame(struct net_device *dev) { + const struct flexcan_priv *priv = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; struct can_frame *cf; struct sk_buff *skb; @@ -685,7 +713,11 @@ static int flexcan_read_frame(struct net_device *dev) return 0; } - flexcan_read_fifo(dev, cf); + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) + flexcan_read_msg_buf(dev, cf, priv->rx_msg_buf); + else + flexcan_read_fifo(dev, cf); + netif_receive_skb(skb); stats->rx_packets++; @@ -699,9 +731,10 @@ static int flexcan_read_frame(struct net_device *dev) static int flexcan_poll(struct napi_struct *napi, int quota) { struct net_device *dev = napi->dev; - const struct flexcan_priv *priv = netdev_priv(dev); + struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->base; u32 reg_iflag1, reg_esr; + unsigned long iflag1; int work_done = 0; /* @@ -713,12 +746,25 @@ static int flexcan_poll(struct napi_struct *napi, int quota) /* handle state changes */ work_done += flexcan_poll_state(dev, reg_esr); - /* handle RX-FIFO */ reg_iflag1 = priv->read(®s->iflag1); - while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE && - work_done < quota) { - work_done += flexcan_read_frame(dev); - reg_iflag1 = priv->read(®s->iflag1); + + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) { + /* handle legacy RX mode */ + iflag1 = reg_iflag1 & FLEXCAN_IFLAG_RX_MB_RXMASK; + while ((reg_iflag1 & FLEXCAN_IFLAG_RX_MB_RXMASK) && + work_done < quota) { + priv->rx_msg_buf = find_first_bit(&iflag1, + (FLEXCAN_TX_BUF_ID - 1)); + work_done += flexcan_read_frame(dev); + reg_iflag1 = priv->read(®s->iflag1); + } + } else { + /* handle RX-FIFO */ + while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE && + work_done < quota) { + work_done += flexcan_read_frame(dev); + reg_iflag1 = priv->read(®s->iflag1); + } } /* report bus errors */ @@ -728,7 +774,13 @@ static int flexcan_poll(struct napi_struct *napi, int quota) if (work_done < quota) { napi_complete(napi); /* enable IRQs */ - priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); + if (priv->devtype_data->features & + FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) + priv->write(FLEXCAN_IFLAG_DEFAULT_RX_MB_MODE | + FLEXCAN_IFLAG_RX_MB_RXMASK, ®s->imask1); + else + priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); + priv->write(priv->reg_ctrl_default, ®s->ctrl); } @@ -755,26 +807,45 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) * - 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) || - 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; - priv->write(FLEXCAN_IFLAG_DEFAULT & - ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1); - priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, - ®s->ctrl); - napi_schedule(&priv->napi); - } + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) { + if ((reg_iflag1 & FLEXCAN_IFLAG_RX_MB_RXMASK) || + (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; + priv->write(FLEXCAN_IFLAG_DEFAULT_RX_MB_MODE & + ~FLEXCAN_IFLAG_RX_MB_RXMASK, ®s->imask1); + priv->write(priv->reg_ctrl_default & + ~FLEXCAN_CTRL_ERR_ALL, ®s->ctrl); + + napi_schedule(&priv->napi); + } + } else { + if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) || + (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; + priv->write(FLEXCAN_IFLAG_DEFAULT & + ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, + ®s->imask1); + priv->write(priv->reg_ctrl_default & + ~FLEXCAN_CTRL_ERR_ALL, ®s->ctrl); + napi_schedule(&priv->napi); + } - /* FIFO overflow */ - if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { - priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); - dev->stats.rx_over_errors++; - dev->stats.rx_errors++; + /* FIFO overflow */ + if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { + priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, + ®s->iflag1); + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; + } } /* transmission complete interrupt */ @@ -869,7 +940,12 @@ static int flexcan_chip_start(struct net_device *dev) */ reg_mcr = priv->read(®s->mcr); reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); - reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) + reg_mcr &= ~FLEXCAN_MCR_FEN; + else + reg_mcr |= FLEXCAN_MCR_FEN; + + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); @@ -966,8 +1042,13 @@ static int flexcan_chip_start(struct net_device *dev) priv->can.state = CAN_STATE_ERROR_ACTIVE; - /* enable FIFO interrupts */ - priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) + /* enable mb interrupts */ + priv->write(FLEXCAN_IFLAG_DEFAULT_RX_MB_MODE | + FLEXCAN_IFLAG_RX_MB_RXMASK, ®s->imask1); + else + /* enable FIFO interrupts */ + priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); /* print chip status */ netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, @@ -1125,22 +1206,29 @@ static int register_flexcandev(struct net_device *dev) if (err) goto out_chip_disable; - /* set freeze, halt and activate FIFO, restrict register access */ + /* set freeze, halt and activate FIFO/legacy mode, restrict + * register access + */ reg = priv->read(®s->mcr); - reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | - FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) + reg &= ~FLEXCAN_MCR_FEN; + else + reg |= FLEXCAN_MCR_FEN; + + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV; priv->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. - */ - reg = priv->read(®s->mcr); - if (!(reg & FLEXCAN_MCR_FEN)) { - netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); - err = -ENODEV; - goto out_chip_disable; + if (priv->devtype_data->features & FLEXCAN_HAS_ONLY_LEGACY_RX_SUPPORT) { + /* Legacy RX mode*/ + netdev_info(dev, "Legacy mode (non RX-FIFO) enabled\n"); + } else { + /* RX FIFO mode */ + reg = priv->read(®s->mcr); + if (!(reg & FLEXCAN_MCR_FEN)) { + netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); + err = -ENODEV; + goto out_chip_disable; + } } err = register_candev(dev);