Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2541548imu; Thu, 29 Nov 2018 06:37:44 -0800 (PST) X-Google-Smtp-Source: AFSGD/U8k5YPS9/529aft6xvia/u+rmE0rkg2P5cft90ZeqBn5ulq3FaoztG3IezPabEp2PvrGSq X-Received: by 2002:a63:a91a:: with SMTP id u26mr1414291pge.349.1543502264896; Thu, 29 Nov 2018 06:37:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543502264; cv=none; d=google.com; s=arc-20160816; b=njXy+DCUJ0LCDbSV1zC3Nlu9huHZjTRufCp73vKnDkXmu+377AGw3NXK5QnMmFZdxx dj7F3W3F6Tayr/6AfX/EdEwSqxjJRZaVTO88dF2xM+wxM83wgaIiJ3KrMlePh2u7X6UV 2YYLkfTZbahVMu3zZrcyutbGBLUXar4Tk2nvkslWBVDIxQYi8x0/Xcx0AWp2mnfu5+Gy sVyLcPM2VAM5hILdBGx8LYYewp3IVIiL5hHUvWkoMJ6l6VcPEx8zP4j7r0lcSNQOt8tQ ApbVzEQAGRQl2dns8AHUISR/0jiFZQs0LEFKCUilTDXE4aEmRPpJJEsyIep1UWtkZ4If RZNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=I0CdIM7c13Klbs+7F+B0OeNZDqSLpoHw6r1VYkp+Ask=; b=rNEVBJGf0Dzk/IGaFZhqO62EeTNNd8ApL2bBFhftSX8Q61mKUeXWeqqUNrUzR17laT zdVehxbSQltiFOgaKFpEJDP816qaLGIIXOPRve6N3neSD2wY1dvVwVBHbcNa7XNbajeW YLV6TN42wgniHX5sMgAi/VMrwXTBmrfZ1K3aVnCUOMSSeGWnkXoN3xi6nSceEvEruRYe 2gH9ay8nfSiTr6N0p61/rDC7ErGmZ4Fu4E/UsyvujVEGRZPu8hNYWLuO9c7IipHc61Ur ZEIk3b2rxK0SV1zrx42zeReymHNZei+FY3jhLvi5pPtteJ5ziIF8ZGGox/Wo3xFmjbXy h++g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=0TGRopl1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j61si2255467plb.232.2018.11.29.06.37.29; Thu, 29 Nov 2018 06:37:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=0TGRopl1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389283AbeK3Bh2 (ORCPT + 99 others); Thu, 29 Nov 2018 20:37:28 -0500 Received: from mail.kernel.org ([198.145.29.99]:40390 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732374AbeK3Bh1 (ORCPT ); Thu, 29 Nov 2018 20:37:27 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0BE65213A2; Thu, 29 Nov 2018 14:31:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1543501913; bh=7P5G6jWQ/LMhDsCD/UQAmfqcOV6mCEA0MKl9hY2ARxI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0TGRopl1cq9/FGNztrSiXlTuFsQwnLf/GwBQnuqlNrq2uxtmRxIQtybirT8soRkaK n3Ttsy9SVyPT9z0SfEa0qlE4YDfgMpUY7dv+XJoxG6mwmY68u+k79HDlcKX3SZ5bEA snruS900tFiG+on5yxvJbgv37LlI/zlTT/ZPuf10= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Alexander Stein , Marc Kleine-Budde Subject: [PATCH 4.19 059/110] can: flexcan: Always use last mailbox for TX Date: Thu, 29 Nov 2018 15:12:30 +0100 Message-Id: <20181129135923.648208772@linuxfoundation.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129135921.231283053@linuxfoundation.org> References: <20181129135921.231283053@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alexander Stein commit cbffaf7aa09edbaea2bc7dc440c945297095e2fd upstream. Essentially this patch moves the TX mailbox to position 63, regardless of timestamp based offloading or RX FIFO. So mainly the iflag register usage regarding TX has changed. The rest is consolidating RX FIFO and timestamp offloading as they now use both the same TX mailbox. The reason is a very annoying behavior regarding sending RTR frames when _not_ using RX FIFO: If a TX mailbox sent a RTR frame it becomes a RX mailbox. For that reason flexcan_irq disables the TX mailbox again. But if during the time the RTR was sent and the TX mailbox is disabled a new CAN frames is received, it is lost without notice. The reason is that so-called "Move-in" process starts from the lowest mailbox which happen to be a TX mailbox set to EMPTY. Steps to reproduce (I used an imx7d): 1. generate regular bursts of messages 2. send a RTR from flexcan with higher priority than burst messages every 1ms, e.g. cangen -I 0x100 -L 0 -g 1 -R can0 3. notice a lost message without notification after some seconds When running an iperf in parallel this problem is occurring even more frequently. Using filters is not possible as at least one single CAN-ID is allowed. Handling the TX MB during RX is also not possible as there is no race-free disable of RX MB. There is still a slight window when the described problem can occur. But for that all RX MB must be in use which is essentially next to an overrun. Still there will be no indication if it ever occurs. Signed-off-by: Alexander Stein Cc: linux-stable Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/flexcan.c | 67 ++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 34 deletions(-) --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -135,13 +135,12 @@ /* FLEXCAN interrupt flag register (IFLAG) bits */ /* Errata ERR005829 step7: Reserve first valid MB */ -#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 -#define FLEXCAN_TX_MB_OFF_FIFO 9 +#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 -#define FLEXCAN_TX_MB_OFF_TIMESTAMP 1 -#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1) -#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63 -#define FLEXCAN_IFLAG_MB(x) BIT(x) +#define FLEXCAN_TX_MB 63 +#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) +#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1) +#define FLEXCAN_IFLAG_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) @@ -745,9 +744,9 @@ static inline u64 flexcan_read_reg_iflag struct flexcan_regs __iomem *regs = priv->regs; u32 iflag1, iflag2; - iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default; - iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default & + 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; return (u64)iflag2 << 32 | iflag1; } @@ -759,11 +758,9 @@ static irqreturn_t flexcan_irq(int irq, struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->regs; irqreturn_t handled = IRQ_NONE; - u32 reg_iflag1, reg_esr; + u32 reg_iflag2, reg_esr; enum can_state last_state = priv->can.state; - reg_iflag1 = priv->read(®s->iflag1); - /* reception interrupt */ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { u64 reg_iflag; @@ -777,6 +774,9 @@ static irqreturn_t flexcan_irq(int irq, break; } } else { + u32 reg_iflag1; + + reg_iflag1 = priv->read(®s->iflag1); if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { handled = IRQ_HANDLED; can_rx_offload_irq_offload_fifo(&priv->offload); @@ -792,8 +792,10 @@ static irqreturn_t flexcan_irq(int irq, } } + reg_iflag2 = priv->read(®s->iflag2); + /* transmission complete interrupt */ - if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { + if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl); handled = IRQ_HANDLED; @@ -805,7 +807,7 @@ static irqreturn_t flexcan_irq(int irq, /* 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->iflag1); + priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2); netif_wake_queue(dev); } @@ -947,15 +949,13 @@ static int flexcan_chip_start(struct net reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | - FLEXCAN_MCR_IDAM_C; + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) reg_mcr &= ~FLEXCAN_MCR_FEN; - reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last); - } else { - reg_mcr |= FLEXCAN_MCR_FEN | - FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); - } + else + reg_mcr |= FLEXCAN_MCR_FEN; + netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); priv->write(reg_mcr, ®s->mcr); @@ -998,16 +998,17 @@ static int flexcan_chip_start(struct net priv->write(reg_ctrl2, ®s->ctrl2); } - /* clear and invalidate all mailboxes first */ - for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) { - priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, - ®s->mb[i].can_ctrl); - } - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { - for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) + for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { priv->write(FLEXCAN_MB_CODE_RX_EMPTY, ®s->mb[i].can_ctrl); + } + } else { + /* clear and invalidate unused mailboxes first */ + for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i <= ARRAY_SIZE(regs->mb); i++) { + priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, + ®s->mb[i].can_ctrl); + } } /* Errata ERR005829: mark first TX mailbox as INACTIVE */ @@ -1371,17 +1372,15 @@ static int flexcan_probe(struct platform priv->devtype_data = devtype_data; priv->reg_xceiver = reg_xceiver; - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { - priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP; + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; - } else { - priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO; + else priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; - } + priv->tx_mb_idx = FLEXCAN_TX_MB; priv->tx_mb = ®s->mb[priv->tx_mb_idx]; - priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); - priv->reg_imask2_default = 0; + priv->reg_imask1_default = 0; + priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); priv->offload.mailbox_read = flexcan_mailbox_read;