From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DF79EB64DD for ; Tue, 18 Jul 2023 07:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231807AbjGRH5s (ORCPT ); Tue, 18 Jul 2023 03:57:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231667AbjGRH5m (ORCPT ); Tue, 18 Jul 2023 03:57:42 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 442D61988 for ; Tue, 18 Jul 2023 00:57:15 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-317009c0f9aso1987866f8f.0 for ; Tue, 18 Jul 2023 00:57:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667033; x=1690271833; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ow0KD5sZWSRWo56RZ6bdbR/6fl1YYZAbnlt0NuXgAUU=; b=Dr6uZBsWOW5xzIal3C1gWSsSF3hXGn/01ZqnqhiOT3glIWr69J+wehas+wZdf79Q8z R4MxreQ4C4Ij+Lnxe+en7E46th/3IOLl1wlRD/UN0m015lsVdEf6u1ApyXkIp8Af8jIL rNqP+Bg5osfj+iATiTjgfurqIIKaUqdSEC/WCCdonQbcIKF5pLv4AN1U4+CHZdZzyHc9 7g7vUfcK3sgMy9v3uBRJs6rQF4Yk6x2rrLRVEkzP45nGm6cW30/S4XWZiKX7ha5haxLU pzBoBaiMuCq9Qkbx4K5ZQ3as5lcIQ6VT/VmvFrQO/HyV78ZXt/uDEdnaFCTf68Fjr/io RgBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667033; x=1690271833; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ow0KD5sZWSRWo56RZ6bdbR/6fl1YYZAbnlt0NuXgAUU=; b=HvmIrxl6kusvvLybH+PGNq4FqCIDGU4xMSaJfoU7fFh7SYCkg8WICoYdrVKpjVDzs+ XXaviTsE6+h4Z9p7o99akZWhuwHIFOQ9DbF9HzkJaiEzQ4WCI72vg3uZaScZVTnw5+6O GHIpRslid0hZ8qigGBuC/JkrVKeompjmU5ueGx2ySou/VlfJQ10QIrjRkF5+vLQnFDuq bAYtGyrasQC0sA1DtWajI/vwCufCTfdycyRAZA7b5+oDULs5AVC4gyxVJOEywoQjZDGz CNvwN98g78kWARVGOSPlqEby7lQLks6HLPQPea2QQhSlyuTP07gmBQw6/EpDobzxePw+ 5JmA== X-Gm-Message-State: ABy/qLZ9I2wHmZK6q6S38HgZNsMyxeARwltuEWP15NX2dyRvTP9kIBfe TPT6B2dXIVGKzF8MaF8Z1SWoSw== X-Google-Smtp-Source: APBJJlHVRaLHn0F1JdvwnkTQ/4mauOP2cP6/gHVr4fsugjvmxbBaR+XqGfCGrSkteg8mg7c8XcKvTw== X-Received: by 2002:a5d:670e:0:b0:314:12c:4322 with SMTP id o14-20020a5d670e000000b00314012c4322mr12924963wru.4.1689667033188; Tue, 18 Jul 2023 00:57:13 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:12 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 01/12] can: m_can: Write transmit header and data in one transaction Date: Tue, 18 Jul 2023 09:56:57 +0200 Message-Id: <20230718075708.958094-2-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Combine header and data before writing to the transmit fifo to reduce the overhead for peripheral chips. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index c5af92bcc9c9..478e0670f0d1 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -317,6 +317,12 @@ struct id_and_dlc { u32 dlc; }; =20 +struct m_can_fifo_element { + u32 id; + u32 dlc; + u8 data[CANFD_MAX_DLEN]; +}; + static inline u32 m_can_read(struct m_can_classdev *cdev, enum m_can_reg r= eg) { return cdev->ops->read_reg(cdev, reg); @@ -1622,9 +1628,10 @@ static int m_can_next_echo_skb_occupied(struct net_d= evice *dev, int putidx) static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) { struct canfd_frame *cf =3D (struct canfd_frame *)cdev->tx_skb->data; + u8 len_padded =3D DIV_ROUND_UP(cf->len, 4); + struct m_can_fifo_element fifo_element; struct net_device *dev =3D cdev->net; struct sk_buff *skb =3D cdev->tx_skb; - struct id_and_dlc fifo_header; u32 cccr, fdflags; u32 txfqs; int err; @@ -1635,27 +1642,27 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cl= assdev *cdev) /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ if (cf->can_id & CAN_EFF_FLAG) { - fifo_header.id =3D cf->can_id & CAN_EFF_MASK; - fifo_header.id |=3D TX_BUF_XTD; + fifo_element.id =3D cf->can_id & CAN_EFF_MASK; + fifo_element.id |=3D TX_BUF_XTD; } else { - fifo_header.id =3D ((cf->can_id & CAN_SFF_MASK) << 18); + fifo_element.id =3D ((cf->can_id & CAN_SFF_MASK) << 18); } =20 if (cf->can_id & CAN_RTR_FLAG) - fifo_header.id |=3D TX_BUF_RTR; + fifo_element.id |=3D TX_BUF_RTR; =20 if (cdev->version =3D=3D 30) { netif_stop_queue(dev); =20 - fifo_header.dlc =3D can_fd_len2dlc(cf->len) << 16; + fifo_element.dlc =3D can_fd_len2dlc(cf->len) << 16; =20 /* Write the frame ID, DLC, and payload to the FIFO element. */ - err =3D m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, &fifo_header, 2); + err =3D m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, &fifo_element, 2); if (err) goto out_fail; =20 err =3D m_can_fifo_write(cdev, 0, M_CAN_FIFO_DATA, - cf->data, DIV_ROUND_UP(cf->len, 4)); + cf->data, len_padded); if (err) goto out_fail; =20 @@ -1717,15 +1724,15 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cl= assdev *cdev) fdflags |=3D TX_BUF_BRS; } =20 - fifo_header.dlc =3D FIELD_PREP(TX_BUF_MM_MASK, putidx) | + fifo_element.dlc =3D FIELD_PREP(TX_BUF_MM_MASK, putidx) | FIELD_PREP(TX_BUF_DLC_MASK, can_fd_len2dlc(cf->len)) | fdflags | TX_BUF_EFC; - err =3D m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, &fifo_header, 2); - if (err) - goto out_fail; =20 - err =3D m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, - cf->data, DIV_ROUND_UP(cf->len, 4)); + memcpy_and_pad(fifo_element.data, CANFD_MAX_DLEN, &cf->data, + cf->len, 0); + + err =3D m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, + &fifo_element, 2 + len_padded); if (err) goto out_fail; =20 --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E63CC001DC for ; Tue, 18 Jul 2023 07:58:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231835AbjGRH5x (ORCPT ); Tue, 18 Jul 2023 03:57:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230447AbjGRH5n (ORCPT ); Tue, 18 Jul 2023 03:57:43 -0400 Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69914198C for ; Tue, 18 Jul 2023 00:57:16 -0700 (PDT) Received: by mail-lj1-x231.google.com with SMTP id 38308e7fff4ca-2b6f0508f54so80522081fa.3 for ; Tue, 18 Jul 2023 00:57:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667034; x=1690271834; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A+IAHaKiSJpEhojt50oheCT5NYSZEmbWbjYZr+oWDZU=; b=tuzmz2M1KjgLzrFx+29v3jKlzDjX4seJGwcbCnoiErGJSramNmn6cmFzOggAjZD0EA EOyn/iIzNFW1HmSZeLI5tb7KuhrxqY61F9t0oms4zr4kYbQCaB1sdxtGvQF+4cE463qa O/EexOPi4BIjF9GEOwHuTbTNrTtCS0mqb8CVP8pm6O/ABJJ+bBFDHwdQlsyaNKQCoen5 iaFowxfaELx+sKlWL5ECotiAin05bd4hATnYeCqi6F6XD9OYrOlibD8K9av9KWqY0Tya bUrx+9QBZTevXxCrN4hPp26w36Lbxi2sMkeiGIENrIuWY2cJXfojGl0vR4kX65RzZ6Jc yRqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667034; x=1690271834; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=A+IAHaKiSJpEhojt50oheCT5NYSZEmbWbjYZr+oWDZU=; b=CHk1IJYFDKitdkKk0ndRo8w1sXzd5ORr5jcger+vUNFaeWw5a9UR9NNQLBE5mrja9j OAZoj0JxkTfuFqbUSK6r1zNfLxlFQAEtJBlIk8jLaYGiuWHmoI84LhcgKDoC8fpJ3CkU Y9EduJF5zlZ90tUb7hgA6X9wi75kOKKmJvOSZrui+6wOt8oh2I6T9hifveKwggtnSsDc 9S/Lq/1iUMGzDyD928RKR5aXwPgwm4WRwqyk72A5RWZFHnUPYTwtjA8XSTYnwF7bIn7T 4okL1g+Bll9XoiiS2MnJPNRYPxG1OA0Wm14Gw2Iy74gj2646nMGBMsOm7vgeMgyJar75 EUmg== X-Gm-Message-State: ABy/qLZQXa/I2zgCKrMc4nPe9Jy47SekFkO8eatc0sGzKOOaI2RV8in2 cvfL5YYwpzpYv8VSkjLnETHFSw== X-Google-Smtp-Source: APBJJlEF5Jy0s4TOzLn2mz+GN31bENfStef44JnOPJ8OlUdWzc7h9po9ZLuLwxDQDfXOEkv1JuvGcQ== X-Received: by 2002:a2e:b70a:0:b0:2b6:eb5a:6504 with SMTP id j10-20020a2eb70a000000b002b6eb5a6504mr10786531ljo.18.1689667034110; Tue, 18 Jul 2023 00:57:14 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:13 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 02/12] can: m_can: Implement receive coalescing Date: Tue, 18 Jul 2023 09:56:58 +0200 Message-Id: <20230718075708.958094-3-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" m_can offers the possibility to set an interrupt on reaching a watermark level in the receive FIFO. This can be used to implement coalescing. Unfortunately there is no hardware timeout available to trigger an interrupt if only a few messages were received within a given time. To solve this I am using a hrtimer to wake up the irq thread after x microseconds. The timer is always started if receive coalescing is enabled and new received frames were available during an interrupt. The timer is stopped if during a interrupt handling no new data was available. If the timer is started the new item interrupt is disabled and the watermark interrupt takes over. If the timer is not started again, the new item interrupt is enabled again, notifying the handler about every new item received. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 70 ++++++++++++++++++++++++++++++++--- drivers/net/can/m_can/m_can.h | 7 ++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 478e0670f0d1..dd0fa58660d7 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -419,6 +419,22 @@ static void m_can_config_endisable(struct m_can_classd= ev *cdev, bool enable) } } =20 +static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interr= upts) +{ + if (cdev->active_interrupts =3D=3D interrupts) + return; + cdev->ops->write_reg(cdev, M_CAN_IE, interrupts); + cdev->active_interrupts =3D interrupts; +} + +static void m_can_coalescing_disable(struct m_can_classdev *cdev) +{ + u32 new_interrupts =3D cdev->active_interrupts | IR_RF0N; + + hrtimer_cancel(&cdev->irq_timer); + m_can_interrupt_enable(cdev, new_interrupts); +} + static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev) { /* Only interrupt line 0 is used in this driver */ @@ -427,6 +443,7 @@ static inline void m_can_enable_all_interrupts(struct m= _can_classdev *cdev) =20 static inline void m_can_disable_all_interrupts(struct m_can_classdev *cde= v) { + m_can_coalescing_disable(cdev); m_can_write(cdev, M_CAN_ILE, 0x0); } =20 @@ -1076,15 +1093,39 @@ static int m_can_echo_tx_event(struct net_device *d= ev) return err; } =20 +static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir) +{ + u32 new_interrupts =3D cdev->active_interrupts; + bool enable_timer =3D false; + + if (cdev->rx_coalesce_usecs_irq > 0 && (ir & (IR_RF0N | IR_RF0W))) { + enable_timer =3D true; + new_interrupts &=3D ~IR_RF0N; + } else if (!hrtimer_active(&cdev->irq_timer)) { + new_interrupts |=3D IR_RF0N; + } + + m_can_interrupt_enable(cdev, new_interrupts); + if (enable_timer) { + hrtimer_start(&cdev->irq_timer, + ns_to_ktime(cdev->rx_coalesce_usecs_irq * NSEC_PER_USEC), + HRTIMER_MODE_REL); + } +} + static irqreturn_t m_can_isr(int irq, void *dev_id) { struct net_device *dev =3D (struct net_device *)dev_id; struct m_can_classdev *cdev =3D netdev_priv(dev); u32 ir; =20 - if (pm_runtime_suspended(cdev->dev)) + if (pm_runtime_suspended(cdev->dev)) { + m_can_coalescing_disable(cdev); return IRQ_NONE; + } + ir =3D m_can_read(cdev, M_CAN_IR); + m_can_coalescing_update(cdev, ir); if (!ir) return IRQ_NONE; =20 @@ -1099,13 +1140,17 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) * - state change IRQ * - bus error IRQ and bus error reporting */ - if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { + if (ir & (IR_RF0N | IR_RF0W | IR_ERR_ALL_30X)) { cdev->irqstatus =3D ir; if (!cdev->is_peripheral) { m_can_disable_all_interrupts(cdev); napi_schedule(&cdev->napi); - } else if (m_can_rx_peripheral(dev, ir) < 0) { - goto out_fail; + } else { + int pkts; + + pkts =3D m_can_rx_peripheral(dev, ir); + if (pkts < 0) + goto out_fail; } } =20 @@ -1141,6 +1186,15 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) return IRQ_HANDLED; } =20 +static enum hrtimer_restart m_can_irq_timer(struct hrtimer *timer) +{ + struct m_can_classdev *cdev =3D container_of(timer, struct m_can_classdev= , irq_timer); + + irq_wake_thread(cdev->net->irq, cdev->net); + + return HRTIMER_NORESTART; +} + static const struct can_bittiming_const m_can_bittiming_const_30X =3D { .name =3D KBUILD_MODNAME, .tseg1_min =3D 2, /* Time segment 1 =3D prop_seg + phase_seg1 */ @@ -1281,7 +1335,7 @@ static int m_can_chip_config(struct net_device *dev) /* Disable unused interrupts */ interrupts &=3D ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TEFW | IR_TFE | IR_TCF | IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | - IR_RF0F | IR_RF0W); + IR_RF0F); =20 m_can_config_endisable(cdev, true); =20 @@ -1325,6 +1379,7 @@ static int m_can_chip_config(struct net_device *dev) =20 /* rx fifo configuration, blocking mode, fifo size 1 */ m_can_write(cdev, M_CAN_RXF0C, + FIELD_PREP(RXFC_FWM_MASK, cdev->rx_max_coalesced_frames_irq) | FIELD_PREP(RXFC_FS_MASK, cdev->mcfg[MRAM_RXF0].num) | cdev->mcfg[MRAM_RXF0].off); =20 @@ -1383,7 +1438,7 @@ static int m_can_chip_config(struct net_device *dev) else interrupts &=3D ~(IR_ERR_LEC_31X); } - m_can_write(cdev, M_CAN_IE, interrupts); + m_can_interrupt_enable(cdev, interrupts); =20 /* route all interrupts to INT0 */ m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); @@ -2047,6 +2102,9 @@ int m_can_class_register(struct m_can_classdev *cdev) =20 of_can_transceiver(cdev->net); =20 + hrtimer_init(&cdev->irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + cdev->irq_timer.function =3D m_can_irq_timer; + dev_info(cdev->dev, "%s device registered (irq=3D%d, version=3D%d)\n", KBUILD_MODNAME, cdev->net->irq, cdev->version); =20 diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index a839dc71dc9b..c59099d3f5b9 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -84,6 +84,8 @@ struct m_can_classdev { struct sk_buff *tx_skb; struct phy *transceiver; =20 + struct hrtimer irq_timer; + struct m_can_ops *ops; =20 int version; @@ -92,6 +94,11 @@ struct m_can_classdev { int pm_clock_support; int is_peripheral; =20 + // Cached M_CAN_IE register content + u32 active_interrupts; + u32 rx_max_coalesced_frames_irq; + u32 rx_coalesce_usecs_irq; + struct mram_cfg mcfg[MRAM_CFG_NUM]; }; =20 --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9DFE3EB64DA for ; Tue, 18 Jul 2023 07:58:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231849AbjGRH6N (ORCPT ); Tue, 18 Jul 2023 03:58:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230215AbjGRH5q (ORCPT ); Tue, 18 Jul 2023 03:57:46 -0400 Received: from mail-lf1-x129.google.com (mail-lf1-x129.google.com [IPv6:2a00:1450:4864:20::129]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 422CE1994 for ; Tue, 18 Jul 2023 00:57:17 -0700 (PDT) Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-4fb7589b187so8642446e87.1 for ; Tue, 18 Jul 2023 00:57:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667035; x=1690271835; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9Tf6HciWVoiOL4HjsCBCdDTuGHzKLKbtMGWBfyFkwm4=; b=B6B1d9nsdxH97FVeAMZ0iXNULQ3Cyk1izYY1xuNo7KRxtsv6DIxnx+vpeJb6ytSeJk 5acAJmhf0SXU+kVdQxfAGaN3LhnN+lNcT7tK+L8QuV1QR6Yvkykju6FMHlB5j5GNf+7R F2te+qzAHMK7mxql1tZ+QrpGyT/RKCYUjE0/9sLmAQVGDbcrXXsJW9kCTipPumb/tAtp g//T6rHcVTeGtK/piQLCDY6f+fxZwCB3/v1wqofXHsPoho6E5Kdnd08E2l4JBYTvjeJr 3jav3OBYKQ87LtXr8+Gsph9oktB2c6l+Djn+il9Bcl4FWQ2LSxwoN8+FrRhtYGAMvv8F 2JyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667035; x=1690271835; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9Tf6HciWVoiOL4HjsCBCdDTuGHzKLKbtMGWBfyFkwm4=; b=bHzkXObYZyHc8d7E709cmxsUFQOqHhTrMn4Q8s6aCC+/4AsXAsrQpaq2uwXIIZIBlH 7jjEWHcGByJDNJ3faJ7z2maZBia7VpLCFonFH9XcVwh5kG1XCbEsTF5C7DTwfmg/uCUJ yjqpkphXtUd4AOduR7wMtLw/jVUFY32DSf88rc1o6zN9wFbm7hQMnkTONcxHEFHQPQhh bYqKSVNrukwvwx9fibyDDUlk46OlvwSeOucbis0aO1lYl8DBnYsQiCtLxPav01E/M99I HQiHd26gKawW0o8oiCsS/xl7hT9MD37+7/4oBsALXgMLHJIS+bi9TERNmWQrx/0NxIBX JluA== X-Gm-Message-State: ABy/qLaPJe8zZ5xLUiMEFbW4ShewX34+SI6PrKGFlKV/puK3QcwwZIzG eC0PG1XpJlMmR1/mjdrsmWwg4w== X-Google-Smtp-Source: APBJJlGFNI8NrFHG48Ir6X3Cd0hWAQTegSl6CqMzx3Or5E+HsrcYr47lIIt/9Fgjrsca/gJwLH3w2w== X-Received: by 2002:a19:2d56:0:b0:4f8:5c90:f8a4 with SMTP id t22-20020a192d56000000b004f85c90f8a4mr9266824lft.33.1689667035070; Tue, 18 Jul 2023 00:57:15 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:14 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 03/12] can: m_can: Implement transmit coalescing Date: Tue, 18 Jul 2023 09:56:59 +0200 Message-Id: <20230718075708.958094-4-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Extend the coalescing implementation for transmits. In normal mode the chip raises an interrupt for every finished transmit. This implementation switches to coalescing mode as soon as an interrupt handled a transmit. For coalescing the watermark level interrupt is used to interrupt exactly after x frames were sent. It switches back into normal mode once there was an interrupt with no finished transmit and the timer being inactive. The timer is shared with receive coalescing. The time for receive and transmit coalescing timers have to be the same for that to work. The benefit is to have only a single running timer. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 33 ++++++++++++++++++++------------- drivers/net/can/m_can/m_can.h | 3 +++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index dd0fa58660d7..e979aeb2ef13 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -255,6 +255,7 @@ enum m_can_reg { #define TXESC_TBDS_64B 0x7 =20 /* Tx Event FIFO Configuration (TXEFC) */ +#define TXEFC_EFWM_MASK GENMASK(29, 24) #define TXEFC_EFS_MASK GENMASK(21, 16) =20 /* Tx Event FIFO Status (TXEFS) */ @@ -429,7 +430,7 @@ static void m_can_interrupt_enable(struct m_can_classde= v *cdev, u32 interrupts) =20 static void m_can_coalescing_disable(struct m_can_classdev *cdev) { - u32 new_interrupts =3D cdev->active_interrupts | IR_RF0N; + u32 new_interrupts =3D cdev->active_interrupts | IR_RF0N | IR_TEFN; =20 hrtimer_cancel(&cdev->irq_timer); m_can_interrupt_enable(cdev, new_interrupts); @@ -1096,21 +1097,26 @@ static int m_can_echo_tx_event(struct net_device *d= ev) static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir) { u32 new_interrupts =3D cdev->active_interrupts; - bool enable_timer =3D false; + bool enable_rx_timer =3D false; + bool enable_tx_timer =3D false; =20 if (cdev->rx_coalesce_usecs_irq > 0 && (ir & (IR_RF0N | IR_RF0W))) { - enable_timer =3D true; + enable_rx_timer =3D true; new_interrupts &=3D ~IR_RF0N; - } else if (!hrtimer_active(&cdev->irq_timer)) { - new_interrupts |=3D IR_RF0N; } + if (cdev->tx_coalesce_usecs_irq > 0 && (ir & (IR_TEFN | IR_TEFW))) { + enable_tx_timer =3D true; + new_interrupts &=3D ~IR_TEFN; + } + if (!enable_rx_timer && !hrtimer_active(&cdev->irq_timer)) + new_interrupts |=3D IR_RF0N; + if (!enable_tx_timer && !hrtimer_active(&cdev->irq_timer)) + new_interrupts |=3D IR_TEFN; =20 m_can_interrupt_enable(cdev, new_interrupts); - if (enable_timer) { - hrtimer_start(&cdev->irq_timer, - ns_to_ktime(cdev->rx_coalesce_usecs_irq * NSEC_PER_USEC), + if (enable_rx_timer | enable_tx_timer) + hrtimer_start(&cdev->irq_timer, cdev->irq_timer_wait, HRTIMER_MODE_REL); - } } =20 static irqreturn_t m_can_isr(int irq, void *dev_id) @@ -1165,7 +1171,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) netif_wake_queue(dev); } } else { - if (ir & IR_TEFN) { + if (ir & (IR_TEFN | IR_TEFW)) { /* New TX FIFO Element arrived */ if (m_can_echo_tx_event(dev) !=3D 0) goto out_fail; @@ -1333,9 +1339,8 @@ static int m_can_chip_config(struct net_device *dev) } =20 /* Disable unused interrupts */ - interrupts &=3D ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TEFW | IR_TFE | - IR_TCF | IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | - IR_RF0F); + interrupts &=3D ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TFE | IR_TCF | + IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | IR_RF0F); =20 m_can_config_endisable(cdev, true); =20 @@ -1372,6 +1377,8 @@ static int m_can_chip_config(struct net_device *dev) } else { /* Full TX Event FIFO is used */ m_can_write(cdev, M_CAN_TXEFC, + FIELD_PREP(TXEFC_EFWM_MASK, + cdev->tx_max_coalesced_frames_irq) | FIELD_PREP(TXEFC_EFS_MASK, cdev->mcfg[MRAM_TXE].num) | cdev->mcfg[MRAM_TXE].off); diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index c59099d3f5b9..d0c21eddb6ec 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -85,6 +85,7 @@ struct m_can_classdev { struct phy *transceiver; =20 struct hrtimer irq_timer; + ktime_t irq_timer_wait; =20 struct m_can_ops *ops; =20 @@ -98,6 +99,8 @@ struct m_can_classdev { u32 active_interrupts; u32 rx_max_coalesced_frames_irq; u32 rx_coalesce_usecs_irq; + u32 tx_max_coalesced_frames_irq; + u32 tx_coalesce_usecs_irq; =20 struct mram_cfg mcfg[MRAM_CFG_NUM]; }; --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FC33EB64DA for ; Tue, 18 Jul 2023 07:58:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231868AbjGRH6R (ORCPT ); Tue, 18 Jul 2023 03:58:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60130 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231133AbjGRH5r (ORCPT ); Tue, 18 Jul 2023 03:57:47 -0400 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB7EC1707 for ; Tue, 18 Jul 2023 00:57:17 -0700 (PDT) Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-3143798f542so5635724f8f.2 for ; Tue, 18 Jul 2023 00:57:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667036; x=1690271836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aw3452bl3IVkLYCgTU07wlcs12OEKKnmFHT15uujsjI=; b=jb+AE0lg/ruaMMzxDMgfRqakGL8VLjLeo6Uqd5vQpe/fo4aghhp8yAogRi3gZN5Di+ VjqGOimJnzwWl7hPJiaE2MWJSUKmZPAMM47DS926vvpjih1ch3h8fvIeY/1E6e/PGzvt uoH5TenqWMg+mW0R4LuG0uYfi8sLgrUiQh0hH0BpNNRzAhafkDEVQqunY2X9Qe/ZTnwj 2Z/FyIAW/GZQSwLCNsuqAka2sIo9oVdFgR0URDWc8Y9BpQJz5JrJBzX0lW+QgDREUE/h ZSr+17C19j3SaRz6O3h2BvRvNcF5ppmXfBm9DV54NcuVex9xh2qhpsMglB6RzpZPw8Se 4yvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667036; x=1690271836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aw3452bl3IVkLYCgTU07wlcs12OEKKnmFHT15uujsjI=; b=U6Lpq1y9HOhaJ9tpLH0tbRh1FHX438tcNqvIFo4GE08hegksHMEQjEXa5oPKBjzOiZ 4vIDm3vG0tduoTWT9h+UTM45UKuA8XYqshmZ7vk25wDoleb81nFNKZmkHyf0essiOfTq ILsCkT5issQk1+ACZlY6sDmMN/TgkZBZQ9sVifXfApOWYyb/S7Aad3K4hKpjzkPBVAGl BCWVq09mL6wcb9IzXVM7sfPOsHxR524Xw8MyovvZh7Md1HhG3J+WyFok+v5nx5y66BRW VKIPH2mrvE1GqBiiZJYLkc05UKqYlYuWYYUIujZcBnO5z825o1PqAJejq5EinmM3+A8k YPyA== X-Gm-Message-State: ABy/qLbUY2qV6RlgopiN+ZDPRmbkQBXhjfpEkv2lnNKVz4SYmI84Sn+t 9GeKTdXWLd6gVFpDLE9iBBv8JA== X-Google-Smtp-Source: APBJJlG4gvJkuWZOqhO+jvg2v72AC2MPY7n1+BA4EirjRCEXV+BN3SdjTHxmOiThZLSH6zO/kwgnIA== X-Received: by 2002:a5d:6841:0:b0:314:1ebc:6e19 with SMTP id o1-20020a5d6841000000b003141ebc6e19mr12196935wrw.64.1689667036031; Tue, 18 Jul 2023 00:57:16 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:15 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 04/12] can: m_can: Add rx coalescing ethtool support Date: Tue, 18 Jul 2023 09:57:00 +0200 Message-Id: <20230718075708.958094-5-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add the possibility to set coalescing parameters with ethtool. rx-frames-irq and rx-usecs-irq can only be set and unset together as the implemented mechanism would not work otherwise. rx-frames-irq can't be greater than the RX FIFO size. Also all values can only be changed if the chip is not active. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index e979aeb2ef13..c19fc10a7645 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1943,8 +1943,54 @@ static const struct net_device_ops m_can_netdev_ops = =3D { .ndo_change_mtu =3D can_change_mtu, }; =20 +static int m_can_get_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec, + struct kernel_ethtool_coalesce *kec, + struct netlink_ext_ack *ext_ack) +{ + struct m_can_classdev *cdev =3D netdev_priv(dev); + + ec->rx_max_coalesced_frames_irq =3D cdev->rx_max_coalesced_frames_irq; + ec->rx_coalesce_usecs_irq =3D cdev->rx_coalesce_usecs_irq; + + return 0; +} + +static int m_can_set_coalesce(struct net_device *dev, + struct ethtool_coalesce *ec, + struct kernel_ethtool_coalesce *kec, + struct netlink_ext_ack *ext_ack) +{ + struct m_can_classdev *cdev =3D netdev_priv(dev); + + if (cdev->can.state !=3D CAN_STATE_STOPPED) { + netdev_err(dev, "Device is in use, please shut it down first\n"); + return -EBUSY; + } + + if (ec->rx_max_coalesced_frames_irq > cdev->mcfg[MRAM_RXF0].num) { + netdev_err(dev, "rx-frames-irq %u greater than the RX FIFO %u\n", + ec->rx_max_coalesced_frames_irq, + cdev->mcfg[MRAM_RXF0].num); + return -EINVAL; + } + if ((ec->rx_max_coalesced_frames_irq =3D=3D 0) !=3D (ec->rx_coalesce_usec= s_irq =3D=3D 0)) { + netdev_err(dev, "rx-frames-irq and rx-usecs-irq can only be set together= \n"); + return -EINVAL; + } + + cdev->rx_max_coalesced_frames_irq =3D ec->rx_max_coalesced_frames_irq; + cdev->rx_coalesce_usecs_irq =3D ec->rx_coalesce_usecs_irq; + + return 0; +} + static const struct ethtool_ops m_can_ethtool_ops =3D { + .supported_coalesce_params =3D ETHTOOL_COALESCE_RX_USECS_IRQ | + ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ, .get_ts_info =3D ethtool_op_get_ts_info, + .get_coalesce =3D m_can_get_coalesce, + .set_coalesce =3D m_can_set_coalesce, }; =20 static int register_m_can_dev(struct net_device *dev) --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ABACCEB64DA for ; Tue, 18 Jul 2023 07:58:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231830AbjGRH6c (ORCPT ); Tue, 18 Jul 2023 03:58:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60236 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231521AbjGRH5t (ORCPT ); Tue, 18 Jul 2023 03:57:49 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4EE1199A for ; Tue, 18 Jul 2023 00:57:18 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-316feb137a7so2078480f8f.1 for ; Tue, 18 Jul 2023 00:57:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667037; x=1690271837; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uatwJm2PlUSbozsbYna8OyygyVe3MwDeYyEPTgg8b48=; b=Arq8X2JsqAujk8hjNYLnTe/epbrHDgvZo3ZiX/ZkWCgJaBdc0rNjhlXmGkYHB9nWnV tPZ3CMz6qu/Qv9kBos6lqtfj9mwz4F3q5AFYfWIZeDxdZ9rB1u4O1DOFkieZwwK2k6QF cqMZZDEBqLTNRtyfCNqFyzrRJKLi1/xcp+Ac25+Tx94TO9PKR1A8NAI+0okXEmD+/Km1 znZhUAgqe4qKLoESplgBuXwj7UicD2KVfJpkX/IiCAVKlwYxk/O9xGdosRMwEwAZSXiD Wo2TZamcViwYJty/cb8qbrRr86X3US5nToacvG9fW3XxLI7NBq/rZbqac07W0AZ9/1+Z CifQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667037; x=1690271837; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uatwJm2PlUSbozsbYna8OyygyVe3MwDeYyEPTgg8b48=; b=bAidpkwEM5irxYKlRhMyW7uCqFU7nE627urrr72i+jQ3kN8+H3G3MGvZq1wDE70pgD F41egb2Ohc3+qq5uhtuafyZCmq16Gysj0Z7exPk26j/8SbfzcBIk5bJgoce6pDAqwPZB VQ56FEQII+W5URzkxoQmg0N0r8Hqfz9XOYRbu/BWmsMYFPKRHOg0MRI1xZJXdBnq1wss +TLjAR7a1/JJT/GYJbp6p8e6sGNvuJUoSJIQYB0Kr/EiRRScejvP6OiqTHpDHvMNPQna jJTeehRGmjQGueK4h27fqU44/tHqUcOs3+qOrM+OOqmthy85CgHhrNHucOk2K20+RuRJ Ae8w== X-Gm-Message-State: ABy/qLYRN+I19YUFYp0AdcfwEZA98uga8GCUlS8OmNjP/gM11iu6hX0P 82H3lKwg+KNGWHCTOy0zaWrIZA== X-Google-Smtp-Source: APBJJlFld5Dg1NigahHEH9yi70FfP7nkOB9K1hNSFdVmhncd3gHkZhJFq7w00hxQQ4KUe/h3gmbAkg== X-Received: by 2002:a5d:6850:0:b0:314:53a4:2d3f with SMTP id o16-20020a5d6850000000b0031453a42d3fmr12703298wrw.63.1689667036932; Tue, 18 Jul 2023 00:57:16 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:16 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 05/12] can: m_can: Add tx coalescing ethtool support Date: Tue, 18 Jul 2023 09:57:01 +0200 Message-Id: <20230718075708.958094-6-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add TX support to get/set functions for ethtool coalescing. tx-frames-irq and tx-usecs-irq can only be set/unset together. tx-frames-irq needs to be less than TXE and TXB. As rx and tx share the same timer, rx-usecs-irq and tx-usecs-irq can be enabled/disabled individually but they need to have the same value if enabled. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index c19fc10a7645..6af5fa8c7eb3 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1952,6 +1952,8 @@ static int m_can_get_coalesce(struct net_device *dev, =20 ec->rx_max_coalesced_frames_irq =3D cdev->rx_max_coalesced_frames_irq; ec->rx_coalesce_usecs_irq =3D cdev->rx_coalesce_usecs_irq; + ec->tx_max_coalesced_frames_irq =3D cdev->tx_max_coalesced_frames_irq; + ec->tx_coalesce_usecs_irq =3D cdev->tx_coalesce_usecs_irq; =20 return 0; } @@ -1978,16 +1980,50 @@ static int m_can_set_coalesce(struct net_device *de= v, netdev_err(dev, "rx-frames-irq and rx-usecs-irq can only be set together= \n"); return -EINVAL; } + if (ec->tx_max_coalesced_frames_irq > cdev->mcfg[MRAM_TXE].num) { + netdev_err(dev, "tx-frames-irq %u greater than the TX event FIFO %u\n", + ec->tx_max_coalesced_frames_irq, + cdev->mcfg[MRAM_TXE].num); + return -EINVAL; + } + if (ec->tx_max_coalesced_frames_irq > cdev->mcfg[MRAM_TXB].num) { + netdev_err(dev, "tx-frames-irq %u greater than the TX FIFO %u\n", + ec->tx_max_coalesced_frames_irq, + cdev->mcfg[MRAM_TXB].num); + return -EINVAL; + } + if ((ec->tx_max_coalesced_frames_irq =3D=3D 0) !=3D (ec->tx_coalesce_usec= s_irq =3D=3D 0)) { + netdev_err(dev, "tx-frames-irq and tx-usecs-irq can only be set together= \n"); + return -EINVAL; + } + if (ec->rx_coalesce_usecs_irq !=3D 0 && ec->tx_coalesce_usecs_irq !=3D 0 = && + ec->rx_coalesce_usecs_irq !=3D ec->tx_coalesce_usecs_irq) { + netdev_err(dev, "rx-usecs-irq %u needs to be equal to tx-usecs-irq %u if= both are enabled\n", + ec->rx_coalesce_usecs_irq, + ec->tx_coalesce_usecs_irq); + return -EINVAL; + } =20 cdev->rx_max_coalesced_frames_irq =3D ec->rx_max_coalesced_frames_irq; cdev->rx_coalesce_usecs_irq =3D ec->rx_coalesce_usecs_irq; + cdev->tx_max_coalesced_frames_irq =3D ec->tx_max_coalesced_frames_irq; + cdev->tx_coalesce_usecs_irq =3D ec->tx_coalesce_usecs_irq; + + if (cdev->rx_coalesce_usecs_irq) + cdev->irq_timer_wait =3D + ns_to_ktime(cdev->rx_coalesce_usecs_irq * NSEC_PER_USEC); + else + cdev->irq_timer_wait =3D + ns_to_ktime(cdev->tx_coalesce_usecs_irq * NSEC_PER_USEC); =20 return 0; } =20 static const struct ethtool_ops m_can_ethtool_ops =3D { .supported_coalesce_params =3D ETHTOOL_COALESCE_RX_USECS_IRQ | - ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ, + ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ | + ETHTOOL_COALESCE_TX_USECS_IRQ | + ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, .get_ts_info =3D ethtool_op_get_ts_info, .get_coalesce =3D m_can_get_coalesce, .set_coalesce =3D m_can_set_coalesce, --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA560EB64DA for ; Tue, 18 Jul 2023 07:58:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229603AbjGRH6W (ORCPT ); Tue, 18 Jul 2023 03:58:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231667AbjGRH5t (ORCPT ); Tue, 18 Jul 2023 03:57:49 -0400 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B50E719A4 for ; Tue, 18 Jul 2023 00:57:19 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-316eabffaa6so4658527f8f.2 for ; Tue, 18 Jul 2023 00:57:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667038; x=1690271838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9327qe/b1po3J/jl0WXk20AqdOJMkfPU+3V2iMfGkew=; b=OdkXVFjbgx2kyWt3mov4p/Sa0veTtmXN1u7IWvsYSoyzwWb3o0Gh8T980BAO661SR8 3SpYwrL5p4u8xWvbE8crJEN9DFJcpDhG++pLKoswWp+RxwNtQSMnm/mFp/hmdbunhmkF 11YpAPt90bWWllDvTMGkFio6PvkxSsIjxGyZCMi1TIUpMywcIMBa1lowMzQHqMeMN3ks 2jrdmOJOw7jkuLlbdcuAqufg8g07QVkLLMGlFV5tozTDRA9ytZyZ/symrBb/vE+tVPUh Tjvv7gs1M4MHhcX2HqrBc14AZyLspvu3OFkIXyl9zy3r6bXqESdv0dvzHElnfEINvKqz UBpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667038; x=1690271838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9327qe/b1po3J/jl0WXk20AqdOJMkfPU+3V2iMfGkew=; b=O6154tyhGjx1jKJF5MpcWsCDVlULW8aPVIGYmYzza0rXPuEjxwhEz5ip5YhM4Ov9yn XClfbyNPElwMuVXKafHIsjFFiqvxIOWQc7dpTKU41F0moHu8E9QhPDiqEWY9ZSWF3Yo4 a/BelEEE4bZrLFgzqhmLpYuk8icTwiF2B72KRvPKqj8jYPAAOG2KgS3SrW9LVfiDB+xK hkg+F9NnfrfYY62WPcWUMlBMLxem2iMYIwaVTPHbkmNVkDPR2MYVxfJgd86t2X/9x/FU swp/GoJsngycAfFo5Nv26RabtQzGI6rqzWxxr8TzwmH8LF1+PnJa1DZenQm9jFGKCXKP SNAQ== X-Gm-Message-State: ABy/qLaqXTFcKAm5yvJiKGRwm0LhMq7iVX76i22K2mbpQLmHM8n+X11Z 2iqmMuoKEScz3SS0eNhKWS/PMA== X-Google-Smtp-Source: APBJJlHvPJsY7pGN2f/7pb0GBQLzzmt/nUI1Z8SrruT/sgroH/I5suRgGkS3Yp47fM3Rrq4KfvOySw== X-Received: by 2002:a05:6000:87:b0:314:449e:8536 with SMTP id m7-20020a056000008700b00314449e8536mr11483857wrx.10.1689667037833; Tue, 18 Jul 2023 00:57:17 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:17 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 06/12] can: m_can: Use u32 for putidx Date: Tue, 18 Jul 2023 09:57:02 +0200 Message-Id: <20230718075708.958094-7-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" putidx is not an integer normally, it is an unsigned field used in hardware registers. Use a u32 for it. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 6af5fa8c7eb3..6a815812ae38 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -467,7 +467,7 @@ static void m_can_clean(struct net_device *net) struct m_can_classdev *cdev =3D netdev_priv(net); =20 if (cdev->tx_skb) { - int putidx =3D 0; + u32 putidx =3D 0; =20 net->stats.tx_errors++; if (cdev->version > 30) @@ -1673,12 +1673,12 @@ static int m_can_close(struct net_device *dev) return 0; } =20 -static int m_can_next_echo_skb_occupied(struct net_device *dev, int putidx) +static int m_can_next_echo_skb_occupied(struct net_device *dev, u32 putidx) { struct m_can_classdev *cdev =3D netdev_priv(dev); /*get wrap around for loopback skb index */ unsigned int wrap =3D cdev->can.echo_skb_max; - int next_idx; + u32 next_idx; =20 /* calculate next index */ next_idx =3D (++putidx >=3D wrap ? 0 : putidx); @@ -1697,7 +1697,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev) u32 cccr, fdflags; u32 txfqs; int err; - int putidx; + u32 putidx; =20 cdev->tx_skb =3D NULL; =20 --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7F7CEB64DC for ; Tue, 18 Jul 2023 07:58:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231322AbjGRH63 (ORCPT ); Tue, 18 Jul 2023 03:58:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231831AbjGRH5x (ORCPT ); Tue, 18 Jul 2023 03:57:53 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB5D919AF for ; Tue, 18 Jul 2023 00:57:20 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-3fbc1218262so54353135e9.3 for ; Tue, 18 Jul 2023 00:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667038; x=1690271838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=79dyPF1dW9iLj8dVCiBHfNzjd/8aXcogMMHx2+UBEFs=; b=xI6AhBHEiKGjBrjg6uWp3lc7OX1cZK2+z2t0JWTkBKNpr6bKX0j8ybY94cE9Qvxtd2 NeJ9Bou7u/EX3ApYjhheLQn6Nim97a2CqSr5wOxZJd6Jpqe54YdoIrmy/4+qG9q/i3K9 7536+NwJnzHh5vTL8NTvvTxOk3yr7fVXDBoH++y4BjKksGKPhOJ4DcXmF7cfVfygfDes 15La8AuakdxulH21iIyXu5JiY5sm0L4PMjTubKC7bshxxxlh9YYvA1usk84rXhf1UHMS /uJtZiO5SzOblMAmPH7S6znzQLQnmylotQrgVefghFmp0HwTbwOB8345p2ovKMdDgTri RsPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667038; x=1690271838; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=79dyPF1dW9iLj8dVCiBHfNzjd/8aXcogMMHx2+UBEFs=; b=SscxJkChtY0SdoArQY0SYVAYyVxgdsMl2WCJ7X+EqK+g1tYLzyV8AdoG70VjS5sJRG v2yOWLdYXbUx5lx35x74rnK/w0QgxijyHV8TjcOTszjsaqQ4VETif+S/fS8bUNhWBrE5 +RYNkKtis//N/APvYPvvRkk6eIzQEvG1J1poitaM9yYQKgphhOKRJwmxpDBNdylobr6F K5ALEDnChfym3qaIUnAIfv+Tt7/6hSM1QuwmDo0FWzEj2GmjXJ78zut0Or1oU0Ebxg3S YSyT9Yh7qCzFkHTLwbXVKj19EU6u5qqGL4UJ5gHOH2oemTXTGUmKne4rnW3vvm87kqIK s8TQ== X-Gm-Message-State: ABy/qLZoywjWIglUDzVqmVo83MqOGrmWIlqFSzbEl1CyH4qcs752RweT NhuisaTnvEsPs9DuyuKZChp6VQ== X-Google-Smtp-Source: APBJJlHvNdgDo+D/5tJJf1TEpiShOTGIC7973pb53PfUXVIwE5WGe7lLeWNeuBWUXfC16Qkyg+IP6g== X-Received: by 2002:a7b:ce19:0:b0:3fc:4ee:12b4 with SMTP id m25-20020a7bce19000000b003fc04ee12b4mr1177310wmc.32.1689667038811; Tue, 18 Jul 2023 00:57:18 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:18 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 07/12] can: m_can: Cache tx putidx Date: Tue, 18 Jul 2023 09:57:03 +0200 Message-Id: <20230718075708.958094-8-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" m_can_tx_handler is the only place where data is written to the tx fifo. We can calculate the putidx in the driver code here to avoid the dependency on the txfqs register. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 8 +++++++- drivers/net/can/m_can/m_can.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 6a815812ae38..45e8afb1b795 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1482,6 +1482,10 @@ static int m_can_start(struct net_device *dev) =20 m_can_enable_all_interrupts(cdev); =20 + if (cdev->version > 30) + cdev->tx_fifo_putidx =3D FIELD_GET(TXFQS_TFQPI_MASK, + m_can_read(cdev, M_CAN_TXFQS)); + return 0; } =20 @@ -1771,7 +1775,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev) } =20 /* get put index for frame */ - putidx =3D FIELD_GET(TXFQS_TFQPI_MASK, txfqs); + putidx =3D cdev->tx_fifo_putidx; =20 /* Construct DLC Field, with CAN-FD configuration. * Use the put index of the fifo as the message marker, @@ -1805,6 +1809,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev) =20 /* Enable TX FIFO element to start transfer */ m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); + cdev->tx_fifo_putidx =3D (++cdev->tx_fifo_putidx >=3D cdev->can.echo_skb= _max ? + 0 : cdev->tx_fifo_putidx); =20 /* stop network queue if fifo full */ if (m_can_tx_fifo_full(cdev) || diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index d0c21eddb6ec..548ae908ac4e 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -102,6 +102,9 @@ struct m_can_classdev { u32 tx_max_coalesced_frames_irq; u32 tx_coalesce_usecs_irq; =20 + // Store this internally to avoid fetch delays on peripheral chips + int tx_fifo_putidx; + struct mram_cfg mcfg[MRAM_CFG_NUM]; }; =20 --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8BCEBEB64DA for ; Tue, 18 Jul 2023 07:58:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231169AbjGRH6g (ORCPT ); Tue, 18 Jul 2023 03:58:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231839AbjGRH5y (ORCPT ); Tue, 18 Jul 2023 03:57:54 -0400 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98CDA19B6 for ; Tue, 18 Jul 2023 00:57:21 -0700 (PDT) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-3fbc77e76abso49246175e9.1 for ; Tue, 18 Jul 2023 00:57:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667039; x=1690271839; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=48czNncddDn85hCm9Dic+NwS2CosoFz1usOAYX9qu5Y=; b=yNhT86LhYt+7HJqWZvG+gnce9M8HBLuoF+vF4JKLEe374JSHaWRED9Gfo5jHa4l0XI jHLuVZdm65yYxKk0VQk45MHH0qT51VOWV/I0RGeXop1T8rQPPkXHCFOPHaGwig6ByudU hrRuTOHMdeGqJQrezrJyd+HNIhDQYvw5gcTfm+lRdTe3ta2pbJiw+jX7FmKwT8LrBuP5 fqGea4mhEfolfuyXyPKkr4xOZglPAXis0qj1sbu4AgbYMJXjPUy8tyshrJeETCZ5hNcy P2Onf4RinFHHhCD0nZ0SBWx1G2GRhKf9w0DQMZJw/42dFm6pN+NmFzqB7hfx3hCL11Ng 9zuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667039; x=1690271839; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=48czNncddDn85hCm9Dic+NwS2CosoFz1usOAYX9qu5Y=; b=FEdbw31OxylZybz2xbfY6tIiDkkNn39b3of/Nq8USAm3370Gc7nxM82A/F8UaF5Rma weHqWKNuKA6dAaAJu0h4ixM05gJvt2O1zo6eD5EwxUrkoTN1OdS6cf0ngQjJwXAolC8U XoFsNyGJ8n+Wc4VUfjUyKPLrWGQ6Qmak70AMXTXeHaejQUvINoRxLOUqITczaT2DYqmR tO52uLn7A14AFd5vRY3S+X7pPpxLXHOq3kAiZsoQNk7ups6HkcLSZtRn0W2g1nXgLDay FpSBYkdaB5wzeDFEkidMZTIF1YwBqJOMCp3dRVUg5v9kw8wVmwJQqxkoye7dtBu0k7A2 c/cQ== X-Gm-Message-State: ABy/qLZPOIgFWHedXheGyB9bRw1hV55QXKF+NaHHtJxsF7iv9YCoxUBo FFmv76h4T4xp5qhJLRxOVXZG5Q== X-Google-Smtp-Source: APBJJlFpQEGqMC+c8lkLbcx+6Qe627jKMzU4jXDnlrq4vvOPFafdg5SusB/oVKgotE2qGHBDEibq4g== X-Received: by 2002:adf:f309:0:b0:316:efb9:ffa with SMTP id i9-20020adff309000000b00316efb90ffamr8565619wro.35.1689667039686; Tue, 18 Jul 2023 00:57:19 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:19 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 08/12] can: m_can: Use the workqueue as queue Date: Tue, 18 Jul 2023 09:57:04 +0200 Message-Id: <20230718075708.958094-9-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The current implementation uses the workqueue for peripheral chips to submit work. Only a single work item is queued and used at any time. To be able to keep more than one transmit in flight at a time, prepare the workqueue to support multiple transmits at the same time. Each work item now has a separate storage for a skb and a pointer to cdev. This assures that each workitem can be processed individually. The workqueue is replaced by an ordered workqueue which makes sure that only a single worker processes the items queued on the workqueue. Also items are ordered by the order they were enqueued. This removes most of the concurrency the workqueue normally offers. It is not necessary for this driver. The cleanup functions have to be adopted a bit to handle this new mechanism. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 109 ++++++++++++++++++++-------------- drivers/net/can/m_can/m_can.h | 14 ++++- 2 files changed, 75 insertions(+), 48 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 45e8afb1b795..9e4dcdfda59d 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -466,17 +466,16 @@ static void m_can_clean(struct net_device *net) { struct m_can_classdev *cdev =3D netdev_priv(net); =20 - if (cdev->tx_skb) { - u32 putidx =3D 0; + for (int i =3D 0; i !=3D cdev->tx_fifo_size; ++i) { + if (!cdev->tx_ops[i].skb) + continue; =20 net->stats.tx_errors++; - if (cdev->version > 30) - putidx =3D FIELD_GET(TXFQS_TFQPI_MASK, - m_can_read(cdev, M_CAN_TXFQS)); - - can_free_echo_skb(cdev->net, putidx, NULL); - cdev->tx_skb =3D NULL; + cdev->tx_ops[i].skb =3D NULL; } + + for (int i =3D 0; i !=3D cdev->can.echo_skb_max; ++i) + can_free_echo_skb(cdev->net, i, NULL); } =20 /* For peripherals, pass skb to rx-offload, which will push skb from @@ -1663,8 +1662,9 @@ static int m_can_close(struct net_device *dev) m_can_clk_stop(cdev); free_irq(dev->irq, dev); =20 + m_can_clean(dev); + if (cdev->is_peripheral) { - cdev->tx_skb =3D NULL; destroy_workqueue(cdev->tx_wq); cdev->tx_wq =3D NULL; can_rx_offload_disable(&cdev->offload); @@ -1691,20 +1691,18 @@ static int m_can_next_echo_skb_occupied(struct net_= device *dev, u32 putidx) return !!cdev->can.echo_skb[next_idx]; } =20 -static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) +static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, + struct sk_buff *skb) { - struct canfd_frame *cf =3D (struct canfd_frame *)cdev->tx_skb->data; + struct canfd_frame *cf =3D (struct canfd_frame *)skb->data; u8 len_padded =3D DIV_ROUND_UP(cf->len, 4); struct m_can_fifo_element fifo_element; struct net_device *dev =3D cdev->net; - struct sk_buff *skb =3D cdev->tx_skb; u32 cccr, fdflags; u32 txfqs; int err; u32 putidx; =20 - cdev->tx_skb =3D NULL; - /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ if (cf->can_id & CAN_EFF_FLAG) { @@ -1828,10 +1826,36 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cl= assdev *cdev) =20 static void m_can_tx_work_queue(struct work_struct *ws) { - struct m_can_classdev *cdev =3D container_of(ws, struct m_can_classdev, - tx_work); + struct m_can_tx_op *op =3D container_of(ws, struct m_can_tx_op, work); + struct m_can_classdev *cdev =3D op->cdev; + struct sk_buff *skb =3D op->skb; =20 - m_can_tx_handler(cdev); + op->skb =3D NULL; + m_can_tx_handler(cdev, skb); +} + +static void m_can_tx_queue_skb(struct m_can_classdev *cdev, struct sk_buff= *skb) +{ + cdev->tx_ops[cdev->next_tx_op].skb =3D skb; + queue_work(cdev->tx_wq, &cdev->tx_ops[cdev->next_tx_op].work); + + ++cdev->next_tx_op; + if (cdev->next_tx_op >=3D cdev->tx_fifo_size) + cdev->next_tx_op =3D 0; +} + +static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev, + struct sk_buff *skb) +{ + if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF) { + m_can_clean(cdev->net); + return NETDEV_TX_OK; + } + + netif_stop_queue(cdev->net); + m_can_tx_queue_skb(cdev, skb); + + return NETDEV_TX_OK; } =20 static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, @@ -1842,30 +1866,10 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff = *skb, if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; =20 - if (cdev->is_peripheral) { - if (cdev->tx_skb) { - netdev_err(dev, "hard_xmit called while tx busy\n"); - return NETDEV_TX_BUSY; - } - - if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF) { - m_can_clean(dev); - } else { - /* Need to stop the queue to avoid numerous requests - * from being sent. Suggested improvement is to create - * a queueing mechanism that will queue the skbs and - * process them in order. - */ - cdev->tx_skb =3D skb; - netif_stop_queue(cdev->net); - queue_work(cdev->tx_wq, &cdev->tx_work); - } - } else { - cdev->tx_skb =3D skb; - return m_can_tx_handler(cdev); - } - - return NETDEV_TX_OK; + if (cdev->is_peripheral) + return m_can_start_peripheral_xmit(cdev, skb); + else + return m_can_tx_handler(cdev, skb); } =20 static int m_can_open(struct net_device *dev) @@ -1893,15 +1897,17 @@ static int m_can_open(struct net_device *dev) =20 /* register interrupt handler */ if (cdev->is_peripheral) { - cdev->tx_skb =3D NULL; - cdev->tx_wq =3D alloc_workqueue("mcan_wq", - WQ_FREEZABLE | WQ_MEM_RECLAIM, 0); + cdev->tx_wq =3D alloc_ordered_workqueue("mcan_wq", + WQ_FREEZABLE | WQ_MEM_RECLAIM); if (!cdev->tx_wq) { err =3D -ENOMEM; goto out_wq_fail; } =20 - INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); + for (int i =3D 0; i !=3D cdev->tx_fifo_size; ++i) { + cdev->tx_ops[i].cdev =3D cdev; + INIT_WORK(&cdev->tx_ops[i].work, m_can_tx_work_queue); + } =20 err =3D request_threaded_irq(dev->irq, NULL, m_can_isr, IRQF_ONESHOT, @@ -2171,6 +2177,19 @@ int m_can_class_register(struct m_can_classdev *cdev) { int ret; =20 + cdev->tx_fifo_size =3D max(1, min(cdev->mcfg[MRAM_TXB].num, + cdev->mcfg[MRAM_TXE].num)); + if (cdev->is_peripheral) { + cdev->tx_ops =3D + devm_kzalloc(cdev->dev, + cdev->tx_fifo_size * sizeof(*cdev->tx_ops), + GFP_KERNEL); + if (!cdev->tx_ops) { + dev_err(cdev->dev, "Failed to allocate tx_ops for workqueue\n"); + return -ENOMEM; + } + } + if (cdev->pm_clock_support) { ret =3D m_can_clk_start(cdev); if (ret) diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index 548ae908ac4e..38b154fea04b 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -70,6 +70,12 @@ struct m_can_ops { int (*init)(struct m_can_classdev *cdev); }; =20 +struct m_can_tx_op { + struct m_can_classdev *cdev; + struct work_struct work; + struct sk_buff *skb; +}; + struct m_can_classdev { struct can_priv can; struct can_rx_offload offload; @@ -80,8 +86,6 @@ struct m_can_classdev { struct clk *cclk; =20 struct workqueue_struct *tx_wq; - struct work_struct tx_work; - struct sk_buff *tx_skb; struct phy *transceiver; =20 struct hrtimer irq_timer; @@ -103,7 +107,11 @@ struct m_can_classdev { u32 tx_coalesce_usecs_irq; =20 // Store this internally to avoid fetch delays on peripheral chips - int tx_fifo_putidx; + u32 tx_fifo_putidx; + + struct m_can_tx_op *tx_ops; + int tx_fifo_size; + int next_tx_op; =20 struct mram_cfg mcfg[MRAM_CFG_NUM]; }; --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3AECEB64DC for ; Tue, 18 Jul 2023 07:58:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231844AbjGRH6n (ORCPT ); Tue, 18 Jul 2023 03:58:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231865AbjGRH57 (ORCPT ); Tue, 18 Jul 2023 03:57:59 -0400 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FE90B3 for ; Tue, 18 Jul 2023 00:57:27 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-3142a9ffa89so5768547f8f.0 for ; Tue, 18 Jul 2023 00:57:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667040; x=1690271840; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5+cITQq+6DhgLZfrsuBe9J13n5cMEltSZ/UNHGZoGzo=; b=BoDZfUmE160ezuAbTAHahGEJhxwVXfpUk9zLbGxE47G2ktEKPRs+9YUiRc1BO00/KY dlfRAAe7KHNOl7PeFz4DavN0r3Y21SUvYuysC9vyPA4DnYQoq/s8axcMET80zD//v9nw BLqOISz1egdPc6EjbLwfqfF0vD7Q9tXyMb/rWUoIWN+qXlCS7xFAgdic5F3fpu0imAJE /qs+AzXRm5gzVI1GkX2S9RWyzpiR2QqG/HFE01jIU5Bb8PnTZFLTcoV74DziYjg+je3Z cUvye2ubgagCD4pv7gUWF2+udOo0F6LZA1t86/2CFO7ppbrkkVukNqvQE7uEjnnhwX4E yFKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667040; x=1690271840; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5+cITQq+6DhgLZfrsuBe9J13n5cMEltSZ/UNHGZoGzo=; b=FzdrTeFmJJnf1f7sLOqrdunP3JD2uJFKu3Ivu2bUqCgAcFMCvhDDSKPnE+JFcjR+Gw y113CaRfVkaIHtPrX0CDpXBDrqjIW5LvYRWc/Qe1rJmiKGGzGhYAiKrVD6xGrHHjq165 +JbCJ7YYBBi71SYO9J1eZFt7/XT/I99QiHyXkDn1RMID8OMgQEUnI+QCpYAm7k4CWAI9 EkpJvfNeZbV7vp0PN9LVLCMFOjT+Ru+3/SN/RMMsxFDXgFBT0HJuF+/1rTtnLawgo6u3 RFnmmgTkn81lWDk5Om4+WgSuM6hui1wpSRVb8GHqASN1V6O06sXfgYrhiobpI423edCI 4wVA== X-Gm-Message-State: ABy/qLbCaWOeM2RPrKfMyckj7i4Xjf5433PcNiQtTw6b9C1FpnOqltwH qBcqiesRixWwEm+D0gYhMRFixg== X-Google-Smtp-Source: APBJJlEBQLJo6hWnVBuAtt+NO1wgrjcb2PcpF/vGv9+txyy9uDdLk1m5jZej0xNasx/04PduMpwSGg== X-Received: by 2002:a05:6000:18d:b0:314:4ba7:b024 with SMTP id p13-20020a056000018d00b003144ba7b024mr13883694wrx.9.1689667040622; Tue, 18 Jul 2023 00:57:20 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:20 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 09/12] can: m_can: Introduce a tx_fifo_in_flight counter Date: Tue, 18 Jul 2023 09:57:05 +0200 Message-Id: <20230718075708.958094-10-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Keep track of the number of transmits in flight. This patch prepares the driver to control the network interface queue based on this counter. By itself this counter be implemented with an atomic, but as we need to do other things in the critical sections later I am using a spinlock instead. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 41 ++++++++++++++++++++++++++++++++++- drivers/net/can/m_can/m_can.h | 4 ++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 9e4dcdfda59d..98ca5d13916b 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -465,6 +465,7 @@ static u32 m_can_get_timestamp(struct m_can_classdev *c= dev) static void m_can_clean(struct net_device *net) { struct m_can_classdev *cdev =3D netdev_priv(net); + unsigned long irqflags; =20 for (int i =3D 0; i !=3D cdev->tx_fifo_size; ++i) { if (!cdev->tx_ops[i].skb) @@ -476,6 +477,10 @@ static void m_can_clean(struct net_device *net) =20 for (int i =3D 0; i !=3D cdev->can.echo_skb_max; ++i) can_free_echo_skb(cdev->net, i, NULL); + + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); + cdev->tx_fifo_in_flight =3D 0; + spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); } =20 /* For peripherals, pass skb to rx-offload, which will push skb from @@ -1046,6 +1051,24 @@ static void m_can_tx_update_stats(struct m_can_class= dev *cdev, stats->tx_packets++; } =20 +static void m_can_finish_tx(struct m_can_classdev *cdev, int transmitted) +{ + unsigned long irqflags; + + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); + cdev->tx_fifo_in_flight -=3D transmitted; + spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); +} + +static void m_can_start_tx(struct m_can_classdev *cdev) +{ + unsigned long irqflags; + + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); + ++cdev->tx_fifo_in_flight; + spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); +} + static int m_can_echo_tx_event(struct net_device *dev) { u32 txe_count =3D 0; @@ -1055,6 +1078,7 @@ static int m_can_echo_tx_event(struct net_device *dev) int i =3D 0; int err =3D 0; unsigned int msg_mark; + int processed =3D 0; =20 struct m_can_classdev *cdev =3D netdev_priv(dev); =20 @@ -1084,12 +1108,15 @@ static int m_can_echo_tx_event(struct net_device *d= ev) =20 /* update stats */ m_can_tx_update_stats(cdev, msg_mark, timestamp); + ++processed; } =20 if (ack_fgi !=3D -1) m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, ack_fgi)); =20 + m_can_finish_tx(cdev, processed); + return err; } =20 @@ -1168,6 +1195,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) timestamp =3D m_can_get_timestamp(cdev); m_can_tx_update_stats(cdev, 0, timestamp); netif_wake_queue(dev); + m_can_finish_tx(cdev, 1); } } else { if (ir & (IR_TEFN | IR_TEFW)) { @@ -1853,11 +1881,22 @@ static netdev_tx_t m_can_start_peripheral_xmit(stru= ct m_can_classdev *cdev, } =20 netif_stop_queue(cdev->net); + + m_can_start_tx(cdev); + m_can_tx_queue_skb(cdev, skb); =20 return NETDEV_TX_OK; } =20 +static netdev_tx_t m_can_start_fast_xmit(struct m_can_classdev *cdev, + struct sk_buff *skb) +{ + m_can_start_tx(cdev); + + return m_can_tx_handler(cdev, skb); +} + static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -1869,7 +1908,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *s= kb, if (cdev->is_peripheral) return m_can_start_peripheral_xmit(cdev, skb); else - return m_can_tx_handler(cdev, skb); + return m_can_start_fast_xmit(cdev, skb); } =20 static int m_can_open(struct net_device *dev) diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index 38b154fea04b..5c182aece15c 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -109,6 +109,10 @@ struct m_can_classdev { // Store this internally to avoid fetch delays on peripheral chips u32 tx_fifo_putidx; =20 + /* Protects shared state between start_xmit and m_can_isr */ + spinlock_t tx_handling_spinlock; + int tx_fifo_in_flight; + struct m_can_tx_op *tx_ops; int tx_fifo_size; int next_tx_op; --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC0F9EB64DA for ; Tue, 18 Jul 2023 07:58:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231924AbjGRH6s (ORCPT ); Tue, 18 Jul 2023 03:58:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231889AbjGRH6B (ORCPT ); Tue, 18 Jul 2023 03:58:01 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4FCA1701 for ; Tue, 18 Jul 2023 00:57:32 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-3fbd33a57b6so55536715e9.2 for ; Tue, 18 Jul 2023 00:57:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667041; x=1690271841; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=G/jeif0KRibRoKz+Xd7uH8q/Tb9kQunrwyHwyW7418o=; b=A5mcO8oaDLNeFF7/gAVY1+TS0k3/yqOD779NvsXE9AWq4MSN5Kp8GUAbWJ+cJnddra yXoPkaBf7hFYfRUAR6s9a7gUAplobzxtejn8EsUeG5sIha0iHjuapH7WFQjTn446b/xv swFuLotgL02GHlx5FHiksydbx61vboG6yQVwua40Fh+PV/vKoJBbjitCllgrj3C0aWwe fw1pKGy84SaWK4+VT+8IBJQXaP0coGhvOApdIqghQYmTOnS3nNwaJ/l2q3lihVkGLQ7V yTCCG9l645l0PG/p+KQJX7uY312m7J2ylTuebl0AgGiMMHE/yeoB6SU/Cvabw08uSRt3 GGvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667041; x=1690271841; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G/jeif0KRibRoKz+Xd7uH8q/Tb9kQunrwyHwyW7418o=; b=i2WstLb4hHe60cfUPHbbVwacowmlzHxpmx8H2MX1zhXrrX1ahCUJOlVKiC1iwJ1kNH mE7GbAg54Dnghm7ntUOsuoGML4191Vvuw77N2E5ZNYok9QqLVKigTIIrGfmJubDLJWvk 1Nw2ImBAEjYbHB9BkAjRHw1C0hvI25dvkTf1f9rixc4Vgkl0iSFqTTZDcQMFpDmulrpB OZRJ1YWPbVKFBYQ+ln6Nw7HFZ79+rxgWC4cOgO8sbJEtBNstOxmhrOx3sJKoJa5OX6Ri cgI/6k3QfY+596dA4X81zPlIz6P5Fp8pYVPhdaT89grRUfgqXrCq6OxT0OoOOxzOf63W oPCQ== X-Gm-Message-State: ABy/qLYwjC1DE6UvHlAezVcXZfp1SOfE/EtF8A1N4VKGihTO2WMvmvro 6ikhrCtiIF+knW5HC2R4mpUQZw== X-Google-Smtp-Source: APBJJlEpifpA7eGkH9vtxIFgoIO0hjuRDeAAMvFhBG52OedOizgaL9x4aRjFrFKKZfiqnILWiSGTAw== X-Received: by 2002:adf:fd4a:0:b0:30f:c012:b529 with SMTP id h10-20020adffd4a000000b0030fc012b529mr14374996wrs.56.1689667041634; Tue, 18 Jul 2023 00:57:21 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:21 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 10/12] can: m_can: Use tx_fifo_in_flight for netif_queue control Date: Tue, 18 Jul 2023 09:57:06 +0200 Message-Id: <20230718075708.958094-11-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The network queue is currently always stopped in start_xmit and continued in the interrupt handler. This is not possible anymore if we want to keep multiple transmits in flight in parallel. Use the previously introduced tx_fifo_in_flight counter to control the network queue instead. This has the benefit of not needing to ask the hardware about fifo status. This patch stops the network queue in start_xmit if the number of transmits in flight reaches the size of the fifo and wakes up the queue from the interrupt handler once the transmits in flight drops below the fifo size. This means any skbs over the limit will be rejected immediately in start_xmit (it shouldn't be possible at all to reach that state anyways). The maximum number of transmits in flight is the size of the fifo. Signed-off-by: Markus Schneider-Pargmann Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 85 +++++++++++------------------------ 1 file changed, 26 insertions(+), 59 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 98ca5d13916b..c01f60317e31 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -376,16 +376,6 @@ m_can_txe_fifo_read(struct m_can_classdev *cdev, u32 f= gi, u32 offset, u32 *val) return cdev->ops->read_fifo(cdev, addr_offset, val, 1); } =20 -static inline bool _m_can_tx_fifo_full(u32 txfqs) -{ - return !!(txfqs & TXFQS_TFQF); -} - -static inline bool m_can_tx_fifo_full(struct m_can_classdev *cdev) -{ - return _m_can_tx_fifo_full(m_can_read(cdev, M_CAN_TXFQS)); -} - static void m_can_config_endisable(struct m_can_classdev *cdev, bool enabl= e) { u32 cccr =3D m_can_read(cdev, M_CAN_CCCR); @@ -1056,17 +1046,31 @@ static void m_can_finish_tx(struct m_can_classdev *= cdev, int transmitted) unsigned long irqflags; =20 spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); + if (cdev->tx_fifo_in_flight >=3D cdev->tx_fifo_size && transmitted > 0) + netif_wake_queue(cdev->net); cdev->tx_fifo_in_flight -=3D transmitted; spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); } =20 -static void m_can_start_tx(struct m_can_classdev *cdev) +static netdev_tx_t m_can_start_tx(struct m_can_classdev *cdev) { unsigned long irqflags; + int tx_fifo_in_flight; =20 spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); - ++cdev->tx_fifo_in_flight; + tx_fifo_in_flight =3D cdev->tx_fifo_in_flight + 1; + if (tx_fifo_in_flight >=3D cdev->tx_fifo_size) { + netif_stop_queue(cdev->net); + if (tx_fifo_in_flight > cdev->tx_fifo_size) { + netdev_err_once(cdev->net, "hard_xmit called while TX FIFO full\n"); + spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); + return NETDEV_TX_BUSY; + } + } + cdev->tx_fifo_in_flight =3D tx_fifo_in_flight; spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); + + return NETDEV_TX_OK; } =20 static int m_can_echo_tx_event(struct net_device *dev) @@ -1194,7 +1198,6 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) if (cdev->is_peripheral) timestamp =3D m_can_get_timestamp(cdev); m_can_tx_update_stats(cdev, 0, timestamp); - netif_wake_queue(dev); m_can_finish_tx(cdev, 1); } } else { @@ -1202,10 +1205,6 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) /* New TX FIFO Element arrived */ if (m_can_echo_tx_event(dev) !=3D 0) goto out_fail; - - if (netif_queue_stopped(dev) && - !m_can_tx_fifo_full(cdev)) - netif_wake_queue(dev); } } =20 @@ -1705,20 +1704,6 @@ static int m_can_close(struct net_device *dev) return 0; } =20 -static int m_can_next_echo_skb_occupied(struct net_device *dev, u32 putidx) -{ - struct m_can_classdev *cdev =3D netdev_priv(dev); - /*get wrap around for loopback skb index */ - unsigned int wrap =3D cdev->can.echo_skb_max; - u32 next_idx; - - /* calculate next index */ - next_idx =3D (++putidx >=3D wrap ? 0 : putidx); - - /* check if occupied */ - return !!cdev->can.echo_skb[next_idx]; -} - static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, struct sk_buff *skb) { @@ -1727,7 +1712,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev, struct m_can_fifo_element fifo_element; struct net_device *dev =3D cdev->net; u32 cccr, fdflags; - u32 txfqs; int err; u32 putidx; =20 @@ -1782,24 +1766,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cla= ssdev *cdev, } else { /* Transmit routine for version >=3D v3.1.x */ =20 - txfqs =3D m_can_read(cdev, M_CAN_TXFQS); - - /* Check if FIFO full */ - if (_m_can_tx_fifo_full(txfqs)) { - /* This shouldn't happen */ - netif_stop_queue(dev); - netdev_warn(dev, - "TX queue active although FIFO is full."); - - if (cdev->is_peripheral) { - kfree_skb(skb); - dev->stats.tx_dropped++; - return NETDEV_TX_OK; - } else { - return NETDEV_TX_BUSY; - } - } - /* get put index for frame */ putidx =3D cdev->tx_fifo_putidx; =20 @@ -1837,11 +1803,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cla= ssdev *cdev, m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); cdev->tx_fifo_putidx =3D (++cdev->tx_fifo_putidx >=3D cdev->can.echo_skb= _max ? 0 : cdev->tx_fifo_putidx); - - /* stop network queue if fifo full */ - if (m_can_tx_fifo_full(cdev) || - m_can_next_echo_skb_occupied(dev, putidx)) - netif_stop_queue(dev); } =20 return NETDEV_TX_OK; @@ -1875,14 +1836,16 @@ static void m_can_tx_queue_skb(struct m_can_classde= v *cdev, struct sk_buff *skb) static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev, struct sk_buff *skb) { + netdev_tx_t err; + if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF) { m_can_clean(cdev->net); return NETDEV_TX_OK; } =20 - netif_stop_queue(cdev->net); - - m_can_start_tx(cdev); + err =3D m_can_start_tx(cdev); + if (err !=3D NETDEV_TX_OK) + return err; =20 m_can_tx_queue_skb(cdev, skb); =20 @@ -1892,7 +1855,11 @@ static netdev_tx_t m_can_start_peripheral_xmit(struc= t m_can_classdev *cdev, static netdev_tx_t m_can_start_fast_xmit(struct m_can_classdev *cdev, struct sk_buff *skb) { - m_can_start_tx(cdev); + netdev_tx_t err; + + err =3D m_can_start_tx(cdev); + if (err !=3D NETDEV_TX_OK) + return err; =20 return m_can_tx_handler(cdev, skb); } --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9673EB64DD for ; Tue, 18 Jul 2023 07:58:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231873AbjGRH6w (ORCPT ); Tue, 18 Jul 2023 03:58:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231912AbjGRH6E (ORCPT ); Tue, 18 Jul 2023 03:58:04 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3E83172C for ; Tue, 18 Jul 2023 00:57:39 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-4fba8f2197bso8855597e87.3 for ; Tue, 18 Jul 2023 00:57:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667042; x=1690271842; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3AK0Rm8Fd4cR85ZcVvm40GzTywtAuoEO7O2YztJGYb0=; b=ruz+IRpF7rE4iBlS32tW+elIkSGs7yR2EjNV4eDI41K9tKTdbbaFFs7+g6BKjgMYUY RvCNZcvG7QJ3RGuVozsvGqaJ8JDXl0K6QqdEM5orl42GP0sjn9X1VMKWuHctTG/3An/s kyvQ7l98WwuRWPCELTkThwfz4HvtTq0VhY2iYTSX07G8LF5HkJbpx0SomFNKvPBo6JHn r14NtqbnWm84D3oD5NLCgwQ4FEsotQSJxUi0E/Qi/dgk1fCl4RpAviBc5dHEnCvO6CSU 3jHCxa/J9LptnX4F0MWnmwOwbxXmDWm3Irxe8n+J4dWkU41f6gDJZ2OEqM1sETyRm36r 25Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667042; x=1690271842; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3AK0Rm8Fd4cR85ZcVvm40GzTywtAuoEO7O2YztJGYb0=; b=Q92cvkfksEZCLNOeye7f8d4yTSKR6u1tbw4TJlaf657V3QzL0MAg42f0VhihvYXLn8 tD6i2T+6icfmQRvJTy8Zfb5HmZCZe1aBCCui+vW4yvlX79B92PaS0+N6AG2L71gFD79L /ydbSac7QQSv306ju4b6IWPd881TvXDlXdjdbrhEnlt6kcZXX7ZvK0lCiVL2A3pW+iZB mxe86JiqroeSGXSTYZjrdN2MBP8QP8Plxa/TCYMLA0Wksd3uHkkeKL3GIovTnTYnMs/8 VjB/kyLd/QhdLUhbmmwU4LESnBAxvwVQsXko5kOC8ozJ8mefsL9fOkp6P4Na33mkVxeJ hkLg== X-Gm-Message-State: ABy/qLbO3KdgkxvfYVKeYzeSOgJCf4579QMJ1Z8aEvo8PLsOwSM5xnjf Y452gkK/7B3cOtvADOjFdzNTbg== X-Google-Smtp-Source: APBJJlEp0ByHQTOfDClnrAWQfVq+D/D3S9r53Hs4xtWuXDl4mz/8VyqXtsyEoni2UMoRBRcPg5xiTw== X-Received: by 2002:a05:6512:23a6:b0:4f9:5a0c:85b8 with SMTP id c38-20020a05651223a600b004f95a0c85b8mr10561931lfv.36.1689667042566; Tue, 18 Jul 2023 00:57:22 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:22 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 11/12] can: m_can: Implement BQL Date: Tue, 18 Jul 2023 09:57:07 +0200 Message-Id: <20230718075708.958094-12-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Implement byte queue limiting in preparation for the use of xmit_more(). Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Tested-by: Martin Hundeb=C3=B8ll --- drivers/net/can/m_can/m_can.c | 49 +++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index c01f60317e31..b775ee8e5ff5 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -468,6 +468,8 @@ static void m_can_clean(struct net_device *net) for (int i =3D 0; i !=3D cdev->can.echo_skb_max; ++i) can_free_echo_skb(cdev->net, i, NULL); =20 + netdev_reset_queue(cdev->net); + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); cdev->tx_fifo_in_flight =3D 0; spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); @@ -1022,29 +1024,34 @@ static int m_can_poll(struct napi_struct *napi, int= quota) * echo. timestamp is used for peripherals to ensure correct ordering * by rx-offload, and is ignored for non-peripherals. */ -static void m_can_tx_update_stats(struct m_can_classdev *cdev, - unsigned int msg_mark, - u32 timestamp) +static unsigned int m_can_tx_update_stats(struct m_can_classdev *cdev, + unsigned int msg_mark, u32 timestamp) { struct net_device *dev =3D cdev->net; struct net_device_stats *stats =3D &dev->stats; + unsigned int frame_len; =20 if (cdev->is_peripheral) stats->tx_bytes +=3D can_rx_offload_get_echo_skb(&cdev->offload, msg_mark, timestamp, - NULL); + &frame_len); else - stats->tx_bytes +=3D can_get_echo_skb(dev, msg_mark, NULL); + stats->tx_bytes +=3D can_get_echo_skb(dev, msg_mark, &frame_len); =20 stats->tx_packets++; + + return frame_len; } =20 -static void m_can_finish_tx(struct m_can_classdev *cdev, int transmitted) +static void m_can_finish_tx(struct m_can_classdev *cdev, int transmitted, + unsigned int transmitted_frame_len) { unsigned long irqflags; =20 + netdev_completed_queue(cdev->net, transmitted, transmitted_frame_len); + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); if (cdev->tx_fifo_in_flight >=3D cdev->tx_fifo_size && transmitted > 0) netif_wake_queue(cdev->net); @@ -1083,6 +1090,7 @@ static int m_can_echo_tx_event(struct net_device *dev) int err =3D 0; unsigned int msg_mark; int processed =3D 0; + unsigned int processed_frame_len =3D 0; =20 struct m_can_classdev *cdev =3D netdev_priv(dev); =20 @@ -1111,7 +1119,9 @@ static int m_can_echo_tx_event(struct net_device *dev) fgi =3D (++fgi >=3D cdev->mcfg[MRAM_TXE].num ? 0 : fgi); =20 /* update stats */ - m_can_tx_update_stats(cdev, msg_mark, timestamp); + processed_frame_len +=3D m_can_tx_update_stats(cdev, msg_mark, + timestamp); + ++processed; } =20 @@ -1119,7 +1129,7 @@ static int m_can_echo_tx_event(struct net_device *dev) m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, ack_fgi)); =20 - m_can_finish_tx(cdev, processed); + m_can_finish_tx(cdev, processed, processed_frame_len); =20 return err; } @@ -1194,11 +1204,12 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) if (ir & IR_TC) { /* Transmission Complete Interrupt*/ u32 timestamp =3D 0; + unsigned int frame_len; =20 if (cdev->is_peripheral) timestamp =3D m_can_get_timestamp(cdev); - m_can_tx_update_stats(cdev, 0, timestamp); - m_can_finish_tx(cdev, 1); + frame_len =3D m_can_tx_update_stats(cdev, 0, timestamp); + m_can_finish_tx(cdev, 1, frame_len); } } else { if (ir & (IR_TEFN | IR_TEFW)) { @@ -1714,6 +1725,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev, u32 cccr, fdflags; int err; u32 putidx; + unsigned int frame_len =3D can_skb_get_frame_len(skb); =20 /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ @@ -1759,7 +1771,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev, } m_can_write(cdev, M_CAN_TXBTIE, 0x1); =20 - can_put_echo_skb(skb, dev, 0, 0); + can_put_echo_skb(skb, dev, 0, frame_len); =20 m_can_write(cdev, M_CAN_TXBAR, 0x1); /* End of xmit function for version 3.0.x */ @@ -1797,7 +1809,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_clas= sdev *cdev, /* Push loopback echo. * Will be looped back on TX interrupt based on message marker */ - can_put_echo_skb(skb, dev, putidx, 0); + can_put_echo_skb(skb, dev, putidx, frame_len); =20 /* Enable TX FIFO element to start transfer */ m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); @@ -1868,14 +1880,23 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff = *skb, struct net_device *dev) { struct m_can_classdev *cdev =3D netdev_priv(dev); + netdev_tx_t ret; + unsigned int frame_len; =20 if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; =20 + frame_len =3D can_skb_get_frame_len(skb); + if (cdev->is_peripheral) - return m_can_start_peripheral_xmit(cdev, skb); + ret =3D m_can_start_peripheral_xmit(cdev, skb); else - return m_can_start_fast_xmit(cdev, skb); + ret =3D m_can_start_fast_xmit(cdev, skb); + + if (ret =3D=3D NETDEV_TX_OK) + netdev_sent_queue(dev, frame_len); + + return ret; } =20 static int m_can_open(struct net_device *dev) --=20 2.40.1 From nobody Sat Feb 7 23:23:06 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8F79EB64DC for ; Tue, 18 Jul 2023 07:58:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231958AbjGRH6y (ORCPT ); Tue, 18 Jul 2023 03:58:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231927AbjGRH6G (ORCPT ); Tue, 18 Jul 2023 03:58:06 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C7A4F173F for ; Tue, 18 Jul 2023 00:57:41 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-31441bc0092so5217671f8f.1 for ; Tue, 18 Jul 2023 00:57:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1689667043; x=1690271843; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SZ6L5uumYKOU4JGWuXQWu7fb4u67lZUK8TfUOaYC8lo=; b=EkOesFd126yLWUnLDj8XN6+vGSPelltoNK6t0wTXx31zvFY5ee6GeslsBzFOTACEgc ZJunRJ5DlZqDeqjrQgZt06Pj/TehLAEpHqMCBB/Jq9xal9Kqgd3d9NrAt0Ol1ap5qzBY dxLIdJ6fop/c/1izZawlhvZIDVz/9ngDm5w666enVboHQES+Y0Pas1QU0tQSMDG3USt9 YxmAHP40cX9Etzwabw/mkYH6XGwNtEroS62ukZniqa/JqjyF251mGeNXpAQvTdbCFA3b N4iOruUmkf0FHWBoIHZU/0zP+lABg7WxIXpGgrf2ELl4lI2kM0Wj7QGzabHKXyq8eVJq +Rhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689667043; x=1690271843; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SZ6L5uumYKOU4JGWuXQWu7fb4u67lZUK8TfUOaYC8lo=; b=QVcUnOs4mwBCxx9+dFxtqORtT4+yZVTDQs2NRVehbRI2FfZXCzEKu8DlwWvN3WLsCN /016W1cur8sGl1o/KUGVej6vHgxld4kd6bSFZ708ilXmCeL1Y+F2PUi6ewWlL+zlcMfr WiEHRFAKbMZaF0+0P3PJi/Yo4/LUtqjmZwM00/UqQUIx1npJx67FRRdOMgKI/pe96a7P XT5bKuiKd+22NDO0SEiKSA9iXO07mIEGUQelMsR3wlT6WUhpMMkQ6m/n96Djj3stN2Qh abZCmKHTLGVs+I5sefUtzU6GTz5qRv+LKgFfDq1iNBLLRTJMdTjpGwxURHTEJ+uUguqM IKLQ== X-Gm-Message-State: ABy/qLZZfZ9ihGmLfXv8hI2jXTU3pdOk/fa5UMcAmi/3hIn6mBavL9gb i6BkVp5oS8NBLHvZ3Y4dAJy/Lg== X-Google-Smtp-Source: APBJJlFVYF+XPug8xCE3Vvq11FheaNmr+0uDVZr/VGmrgyyZlMXLXs86QM1TqAW41sYLAoARgCaQjg== X-Received: by 2002:a05:6000:d2:b0:314:424b:45c3 with SMTP id q18-20020a05600000d200b00314424b45c3mr10740251wrx.57.1689667043516; Tue, 18 Jul 2023 00:57:23 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id x4-20020a5d54c4000000b003142439c7bcsm1585959wrv.80.2023.07.18.00.57.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jul 2023 00:57:23 -0700 (PDT) From: Markus Schneider-Pargmann To: Marc Kleine-Budde , Chandrasekar Ramakrishnan , Wolfgang Grandegger Cc: Vincent MAILHOL , Simon Horman , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Panis , Markus Schneider-Pargmann Subject: [PATCH v5 12/12] can: m_can: Implement transmit submission coalescing Date: Tue, 18 Jul 2023 09:57:08 +0200 Message-Id: <20230718075708.958094-13-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230718075708.958094-1-msp@baylibre.com> References: <20230718075708.958094-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" m_can supports submitting multiple transmits with one register write. This is an interesting option to reduce the number of SPI transfers for peripheral chips. The m_can_tx_op is extended with a bool that signals if it is the last transmission and the submit should be executed immediately. The worker then writes the skb to the FIFO and submits it only if the submit bool is set. If it isn't set, the worker will write the next skb which is waiting in the workqueue to the FIFO, etc. Signed-off-by: Markus Schneider-Pargmann Tested-by: Martin Hundeb=C3=B8ll --- Notes: Notes: - I put this behind the tx-frames ethtool coalescing option as we do wait before submitting packages but it is something different than the tx-frames-irq option. I am not sure if this is the correct option, please let me know. drivers/net/can/m_can/m_can.c | 55 ++++++++++++++++++++++++++++++++--- drivers/net/can/m_can/m_can.h | 6 ++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index b775ee8e5ff5..aa8c5a8445de 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1515,6 +1515,9 @@ static int m_can_start(struct net_device *dev) if (ret) return ret; =20 + netdev_queue_set_dql_min_limit(netdev_get_tx_queue(cdev->net, 0), + cdev->tx_max_coalesced_frames); + cdev->can.state =3D CAN_STATE_ERROR_ACTIVE; =20 m_can_enable_all_interrupts(cdev); @@ -1811,8 +1814,13 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cla= ssdev *cdev, */ can_put_echo_skb(skb, dev, putidx, frame_len); =20 - /* Enable TX FIFO element to start transfer */ - m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); + if (cdev->is_peripheral) { + /* Delay enabling TX FIFO element */ + cdev->tx_peripheral_submit |=3D BIT(putidx); + } else { + /* Enable TX FIFO element to start transfer */ + m_can_write(cdev, M_CAN_TXBAR, BIT(putidx)); + } cdev->tx_fifo_putidx =3D (++cdev->tx_fifo_putidx >=3D cdev->can.echo_skb= _max ? 0 : cdev->tx_fifo_putidx); } @@ -1825,6 +1833,17 @@ static netdev_tx_t m_can_tx_handler(struct m_can_cla= ssdev *cdev, return NETDEV_TX_BUSY; } =20 +static void m_can_tx_submit(struct m_can_classdev *cdev) +{ + if (cdev->version =3D=3D 30) + return; + if (!cdev->is_peripheral) + return; + + m_can_write(cdev, M_CAN_TXBAR, cdev->tx_peripheral_submit); + cdev->tx_peripheral_submit =3D 0; +} + static void m_can_tx_work_queue(struct work_struct *ws) { struct m_can_tx_op *op =3D container_of(ws, struct m_can_tx_op, work); @@ -1833,11 +1852,15 @@ static void m_can_tx_work_queue(struct work_struct = *ws) =20 op->skb =3D NULL; m_can_tx_handler(cdev, skb); + if (op->submit) + m_can_tx_submit(cdev); } =20 -static void m_can_tx_queue_skb(struct m_can_classdev *cdev, struct sk_buff= *skb) +static void m_can_tx_queue_skb(struct m_can_classdev *cdev, struct sk_buff= *skb, + bool submit) { cdev->tx_ops[cdev->next_tx_op].skb =3D skb; + cdev->tx_ops[cdev->next_tx_op].submit =3D submit; queue_work(cdev->tx_wq, &cdev->tx_ops[cdev->next_tx_op].work); =20 ++cdev->next_tx_op; @@ -1849,6 +1872,7 @@ static netdev_tx_t m_can_start_peripheral_xmit(struct= m_can_classdev *cdev, struct sk_buff *skb) { netdev_tx_t err; + bool submit; =20 if (cdev->can.state =3D=3D CAN_STATE_BUS_OFF) { m_can_clean(cdev->net); @@ -1859,7 +1883,15 @@ static netdev_tx_t m_can_start_peripheral_xmit(struc= t m_can_classdev *cdev, if (err !=3D NETDEV_TX_OK) return err; =20 - m_can_tx_queue_skb(cdev, skb); + ++cdev->nr_txs_without_submit; + if (cdev->nr_txs_without_submit >=3D cdev->tx_max_coalesced_frames || + !netdev_xmit_more()) { + cdev->nr_txs_without_submit =3D 0; + submit =3D true; + } else { + submit =3D false; + } + m_can_tx_queue_skb(cdev, skb, submit); =20 return NETDEV_TX_OK; } @@ -1991,6 +2023,7 @@ static int m_can_get_coalesce(struct net_device *dev, =20 ec->rx_max_coalesced_frames_irq =3D cdev->rx_max_coalesced_frames_irq; ec->rx_coalesce_usecs_irq =3D cdev->rx_coalesce_usecs_irq; + ec->tx_max_coalesced_frames =3D cdev->tx_max_coalesced_frames; ec->tx_max_coalesced_frames_irq =3D cdev->tx_max_coalesced_frames_irq; ec->tx_coalesce_usecs_irq =3D cdev->tx_coalesce_usecs_irq; =20 @@ -2035,6 +2068,18 @@ static int m_can_set_coalesce(struct net_device *dev, netdev_err(dev, "tx-frames-irq and tx-usecs-irq can only be set together= \n"); return -EINVAL; } + if (ec->tx_max_coalesced_frames > cdev->mcfg[MRAM_TXE].num) { + netdev_err(dev, "tx-frames %u greater than the TX event FIFO %u\n", + ec->tx_max_coalesced_frames, + cdev->mcfg[MRAM_TXE].num); + return -EINVAL; + } + if (ec->tx_max_coalesced_frames > cdev->mcfg[MRAM_TXB].num) { + netdev_err(dev, "tx-frames %u greater than the TX FIFO %u\n", + ec->tx_max_coalesced_frames, + cdev->mcfg[MRAM_TXB].num); + return -EINVAL; + } if (ec->rx_coalesce_usecs_irq !=3D 0 && ec->tx_coalesce_usecs_irq !=3D 0 = && ec->rx_coalesce_usecs_irq !=3D ec->tx_coalesce_usecs_irq) { netdev_err(dev, "rx-usecs-irq %u needs to be equal to tx-usecs-irq %u if= both are enabled\n", @@ -2045,6 +2090,7 @@ static int m_can_set_coalesce(struct net_device *dev, =20 cdev->rx_max_coalesced_frames_irq =3D ec->rx_max_coalesced_frames_irq; cdev->rx_coalesce_usecs_irq =3D ec->rx_coalesce_usecs_irq; + cdev->tx_max_coalesced_frames =3D ec->tx_max_coalesced_frames; cdev->tx_max_coalesced_frames_irq =3D ec->tx_max_coalesced_frames_irq; cdev->tx_coalesce_usecs_irq =3D ec->tx_coalesce_usecs_irq; =20 @@ -2062,6 +2108,7 @@ static const struct ethtool_ops m_can_ethtool_ops =3D= { .supported_coalesce_params =3D ETHTOOL_COALESCE_RX_USECS_IRQ | ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ | ETHTOOL_COALESCE_TX_USECS_IRQ | + ETHTOOL_COALESCE_TX_MAX_FRAMES | ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, .get_ts_info =3D ethtool_op_get_ts_info, .get_coalesce =3D m_can_get_coalesce, diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index 5c182aece15c..54af26a94042 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -74,6 +74,7 @@ struct m_can_tx_op { struct m_can_classdev *cdev; struct work_struct work; struct sk_buff *skb; + bool submit; }; =20 struct m_can_classdev { @@ -103,6 +104,7 @@ struct m_can_classdev { u32 active_interrupts; u32 rx_max_coalesced_frames_irq; u32 rx_coalesce_usecs_irq; + u32 tx_max_coalesced_frames; u32 tx_max_coalesced_frames_irq; u32 tx_coalesce_usecs_irq; =20 @@ -117,6 +119,10 @@ struct m_can_classdev { int tx_fifo_size; int next_tx_op; =20 + int nr_txs_without_submit; + /* bitfield of fifo elements that will be submitted together */ + u32 tx_peripheral_submit; + struct mram_cfg mcfg[MRAM_CFG_NUM]; }; =20 --=20 2.40.1