From patchwork Wed Jun 21 09:23:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286947 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A945D2E0 for ; Wed, 21 Jun 2023 09:24:17 +0000 (UTC) Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F2D219BB for ; Wed, 21 Jun 2023 02:23:58 -0700 (PDT) Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-3f9bdb01ec0so5678935e9.2 for ; Wed, 21 Jun 2023 02:23:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339437; x=1689931437; 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=IztrjGfMix5tskQ3YAq+GbppbknMQpNbHYwT+eFcuyg=; b=SSp73YYGJCLinA3gBiXji4iBZRTLr1zODBJib8/+eDTd0p8hHxbpzpM4rDaJTwBI2q wUXpB2ygTtS94+2COr8bDgaPanKW63gfCFh8/wUg0IxDRX1gjlJZwbSnb626jiDo8gaf VUzhtMUnB8UGGPKQD3cV5kEMtsMlUPtg+ydQr0DRUnOOT6d7kEAyuEs36aMiVDVXMVS5 M8SpQtwBxKw/HIZpqdgdixsdKHnbZpzrVMsyD4tJC0Ooaked6WlOqngC6HkK5U1rDriR hW+86VycgFP9UpOLwPDHBfgK4bxIvKl52rvFKyjT9maD01ncc+frQmQ2c4O8C5GI+GyG LzuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339437; x=1689931437; 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=IztrjGfMix5tskQ3YAq+GbppbknMQpNbHYwT+eFcuyg=; b=V+USY3h/Kf9VVzjS1XRDvIZLHKFEPJs9gG9Y1HEDZKFwmrevLj1nxmXTsk9bEscVvd bx6gG/ZKPAXuoZyjCBSH9S39Hmn8/fgT2MAtI+KC467E+gPgHGKylxPtydMgYvkFyzpm 1zlxNdw910+0h30GKg4ZrRlWC4iN9QFAESVZe3aqAel/cJL9slW+1Y/gJzrMg6t2Qf0r 9z+LkbCQw9syD3lMLWvrQkqO47raZAjJ51aexKwgBjKsd7PjQhMesrKy1+cGGzSXUtJk aGMO01ybdy7smJDQNZ9RCKc9RKFd44dSP6Qphgw1dymKvQIZbME9dpXbfDED3uN0Mzn8 sJ0g== X-Gm-Message-State: AC+VfDxYy0OtPPzHpAkCrLwrUw5jsDCf9pCRyo9OhBmxfI7KMt3i+R0Q xJx3bkT6eU5yNPrZG0WFcazlYg== X-Google-Smtp-Source: ACHHUZ7Vo13JGDVZQSjULWo0WPguFw67QsOvIqSW0HuJYblfXvkL1s9M7ZcAEi86X/sdw/NPQyzlbQ== X-Received: by 2002:a7b:c405:0:b0:3f9:b1c5:ece0 with SMTP id k5-20020a7bc405000000b003f9b1c5ece0mr5500353wmi.10.1687339437046; Wed, 21 Jun 2023 02:23:57 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.23.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:23:56 -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 v4 01/12] can: m_can: Write transmit header and data in one transaction Date: Wed, 21 Jun 2023 11:23:39 +0200 Message-Id: <20230621092350.3130866-2-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Combine header and data before writing to the transmit fifo to reduce the overhead for peripheral chips. Signed-off-by: Markus Schneider-Pargmann --- drivers/net/can/m_can/m_can.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index a5003435802b..5251073987ee 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; }; +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 reg) { return cdev->ops->read_reg(cdev, reg); @@ -1622,6 +1628,8 @@ static int m_can_next_echo_skb_occupied(struct net_device *dev, int putidx) static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) { struct canfd_frame *cf = (struct canfd_frame *)cdev->tx_skb->data; + u8 len_padded = DIV_ROUND_UP(cf->len, 4); + struct m_can_fifo_element fifo_element; struct net_device *dev = cdev->net; struct sk_buff *skb = cdev->tx_skb; struct id_and_dlc fifo_header; @@ -1635,27 +1643,27 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *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 = cf->can_id & CAN_EFF_MASK; - fifo_header.id |= TX_BUF_XTD; + fifo_element.id = cf->can_id & CAN_EFF_MASK; + fifo_element.id |= TX_BUF_XTD; } else { - fifo_header.id = ((cf->can_id & CAN_SFF_MASK) << 18); + fifo_element.id = ((cf->can_id & CAN_SFF_MASK) << 18); } if (cf->can_id & CAN_RTR_FLAG) - fifo_header.id |= TX_BUF_RTR; + fifo_element.id |= TX_BUF_RTR; if (cdev->version == 30) { netif_stop_queue(dev); - fifo_header.dlc = can_fd_len2dlc(cf->len) << 16; + fifo_element.dlc = can_fd_len2dlc(cf->len) << 16; /* Write the frame ID, DLC, and payload to the FIFO element. */ - err = m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, &fifo_header, 2); + err = m_can_fifo_write(cdev, 0, M_CAN_FIFO_ID, &fifo_element, 2); if (err) goto out_fail; err = 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; @@ -1717,15 +1725,15 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) fdflags |= TX_BUF_BRS; } - fifo_header.dlc = FIELD_PREP(TX_BUF_MM_MASK, putidx) | + fifo_element.dlc = FIELD_PREP(TX_BUF_MM_MASK, putidx) | FIELD_PREP(TX_BUF_DLC_MASK, can_fd_len2dlc(cf->len)) | fdflags | TX_BUF_EFC; - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, &fifo_header, 2); - if (err) - goto out_fail; - err = 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 = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, + &fifo_element, 2 + len_padded); if (err) goto out_fail; From patchwork Wed Jun 21 09:23:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286948 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBBB8D534 for ; Wed, 21 Jun 2023 09:24:18 +0000 (UTC) Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C3CF1BFC for ; Wed, 21 Jun 2023 02:23:59 -0700 (PDT) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-3f8f3786f20so66788795e9.2 for ; Wed, 21 Jun 2023 02:23:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339438; x=1689931438; 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=YG6xa4Mbl+d0vaAdAyRdBK5qcXVedx+n3F0VVlmxXq4=; b=o7gQISJbu5AFv6piaVytdRxRrDk6G7BRNFqjAZYFCSw/ZswAdv+NrzyRHFaIO29+B0 OlSBDO56lBGikCjgmcbj1drM6C/xE3Wu+OAThQIDgIpRCGp+QB0qYXYlZ1ed+xE6ELxO SHdwvleOro53n3sx6iLX2jF+hO5ojaRhOAqrrOKE7OBG0oH6Vt2wH6uPAyE9BBmnTod0 rpsn6Aft1C7vKF+v1qpQX8Yplg132muYNxvZwdM56j8eW0XDd+DNzd894BTKBNbUTymV uV7zE9c+PxzquJb90JYAhFfhNoE1XdEGghe7vVvmuxMAkB87e4EP7fajG3yynP3WtHAk Hpsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339438; x=1689931438; 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=YG6xa4Mbl+d0vaAdAyRdBK5qcXVedx+n3F0VVlmxXq4=; b=dbCRtYApJ3/+tGOQ9TxlzMyHdKnGOHCmY9g2WHYPJPIxpnUZ3XiQnr1+M8M02gJB90 Ozw30dGOXv5nnAxY61hY0Vu8Y3jgqMr7V9eG6YB1SQEzcYyVe+cNWGWXd6R81AhTyVy+ x3nrG+NE2BDRdMZ1GwC3b9u/j0Jp7azcZGoXCPpZ0jlpzPwdQuNZdaCcwU+t70N/np6z vI9uKwgafQ4BGAXlI4ZkCekPoT9Mhq12/tzSzGEKFqOm/UkJPMbIYptGThkVLC45XeYL uAOTD++pe/8M/TAvKz/WaMiEzIaHO9LH/RX2G6V/eFrAi6rc0+lw/4LpMhBZzBT564k6 voOg== X-Gm-Message-State: AC+VfDw53pXlGx3d2i0auHMB5wKFek5ansPk14VDgqwjMXdE94O93Kal GPLPfqNy1oF0A3Zce9HSZ0Aohw== X-Google-Smtp-Source: ACHHUZ6Hb9HpnncPgQ9LdPdtiAT+mz4NwKMXpLveLYbH7GGbIH7UayOOYMk5VicZoZRUYHq26goIWw== X-Received: by 2002:a5d:4d4e:0:b0:311:d5d:1326 with SMTP id a14-20020a5d4d4e000000b003110d5d1326mr15128365wru.27.1687339438053; Wed, 21 Jun 2023 02:23:58 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.23.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:23:57 -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 v4 02/12] can: m_can: Implement receive coalescing Date: Wed, 21 Jun 2023 11:23:40 +0200 Message-Id: <20230621092350.3130866-3-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 5251073987ee..02dfb416fbd2 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_classdev *cdev, bool enable) } } +static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interrupts) +{ + if (cdev->active_interrupts == interrupts) + return; + cdev->ops->write_reg(cdev, M_CAN_IE, interrupts); + cdev->active_interrupts = interrupts; +} + +static void m_can_coalescing_disable(struct m_can_classdev *cdev) +{ + u32 new_interrupts = 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) static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev) { + m_can_coalescing_disable(cdev); m_can_write(cdev, M_CAN_ILE, 0x0); } @@ -1076,15 +1093,39 @@ static int m_can_echo_tx_event(struct net_device *dev) return err; } +static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir) +{ + u32 new_interrupts = cdev->active_interrupts; + bool enable_timer = false; + + if (cdev->rx_coalesce_usecs_irq > 0 && (ir & (IR_RF0N | IR_RF0W))) { + enable_timer = true; + new_interrupts &= ~IR_RF0N; + } else if (!hrtimer_active(&cdev->irq_timer)) { + new_interrupts |= 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 = (struct net_device *)dev_id; struct m_can_classdev *cdev = netdev_priv(dev); u32 ir; - if (pm_runtime_suspended(cdev->dev)) + if (pm_runtime_suspended(cdev->dev)) { + m_can_coalescing_disable(cdev); return IRQ_NONE; + } + ir = m_can_read(cdev, M_CAN_IR); + m_can_coalescing_update(cdev, ir); if (!ir) return IRQ_NONE; @@ -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 = 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 = m_can_rx_peripheral(dev, ir); + if (pkts < 0) + goto out_fail; } } @@ -1141,6 +1186,15 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static enum hrtimer_restart m_can_irq_timer(struct hrtimer *timer) +{ + struct m_can_classdev *cdev = 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 = { .name = KBUILD_MODNAME, .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ @@ -1281,7 +1335,7 @@ static int m_can_chip_config(struct net_device *dev) /* Disable unused interrupts */ interrupts &= ~(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); m_can_config_endisable(cdev, true); @@ -1325,6 +1379,7 @@ static int m_can_chip_config(struct net_device *dev) /* 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); @@ -1383,7 +1438,7 @@ static int m_can_chip_config(struct net_device *dev) else interrupts &= ~(IR_ERR_LEC_31X); } - m_can_write(cdev, M_CAN_IE, interrupts); + m_can_interrupt_enable(cdev, interrupts); /* route all interrupts to INT0 */ m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); @@ -2048,6 +2103,9 @@ int m_can_class_register(struct m_can_classdev *cdev) of_can_transceiver(cdev->net); + hrtimer_init(&cdev->irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + cdev->irq_timer.function = m_can_irq_timer; + dev_info(cdev->dev, "%s device registered (irq=%d, version=%d)\n", KBUILD_MODNAME, cdev->net->irq, cdev->version); 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; + struct hrtimer irq_timer; + struct m_can_ops *ops; int version; @@ -92,6 +94,11 @@ struct m_can_classdev { int pm_clock_support; int is_peripheral; + // 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]; }; From patchwork Wed Jun 21 09:23:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286949 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F160DDB0 for ; Wed, 21 Jun 2023 09:24:19 +0000 (UTC) Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A227F1BFF for ; Wed, 21 Jun 2023 02:24:00 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-3112f2b9625so4058904f8f.1 for ; Wed, 21 Jun 2023 02:24:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339439; x=1689931439; 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=8v5k5o/gMnpilWzbPmb6WUpQE5lj/WdytRr00JhzuWo=; b=1yoEyFt5GM967nuJr28zmMpjw2qA3oiqhf6CIy3w8pbT15KKygG3KPEktVrKijFGpv jj54cY3E0rWzM3U4xGlY+88q4YnZPTIXzO9K28Yqujd+Mvephs5uAKvnCjiKebdHpg9D Ptb0y2cm3Arhxo0rgUABNoe9Cn3qEWPmdIowVDiOLyzViuV3iM6/blucHS8zl0GOQKcn Q7Ja1geYPZE+/Axv0QnDiBNNPHUbvXeoxbGcZWJW1qyjdEAJqaCerkIScCpSZ12jQ4eI dxdb3Qz5o8wLtARdXWmd4OWlLWBIie+xGD1scLZ5DHtycSymIuO7m6h1iLzI3CcIWDrB 4Uig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339439; x=1689931439; 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=8v5k5o/gMnpilWzbPmb6WUpQE5lj/WdytRr00JhzuWo=; b=SWLYT1QrfUCM7Vh5s8m7eRJBwoHhie9JZyeWyHrTou70/v7YFu0uQ9I6+Oc2VZA9lJ KOKhpczqK9l/r/mRlFOkUAzigwOcLCYB6htLdDlmYn/VM1RA4wWmvFgWN6zGvdzh71Z2 44dwN2juNiSexkrkO4pyxj84Jmf6MPhsoNZB+wtNEX+P+7wXyJyGbiaLChvkrAKa4vMW 4DfLoGrGMJw78i4RSHjMIprNgO3D/yrKFInmbfv4oa3MEsgDfXAOsxXA61AI7vsbyoRo vZaSEYpM5ne+JLlJAAI/mNDsGupsl6Z75rhLG84oel/1FcdabaSZzOM7zEctQ1ZIEcdN v47A== X-Gm-Message-State: AC+VfDyQnJUaGgMApbxmmG5sr+FDxZCELPYi8+nPsuMQFc3FoldHQuPX qnmYcdO3byN3GcY7M+sBZy5rfg== X-Google-Smtp-Source: ACHHUZ4o2qzAHjJHwF5qlNPj90KrxHnrbA+4OWsUz/y8LumJsVxdyHo2OT7agpu/llRmxMyxikmQJQ== X-Received: by 2002:adf:dcc3:0:b0:311:1946:fe7d with SMTP id x3-20020adfdcc3000000b003111946fe7dmr11672853wrm.53.1687339439115; Wed, 21 Jun 2023 02:23:59 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.23.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:23:58 -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 v4 03/12] can: m_can: Implement transmit coalescing Date: Wed, 21 Jun 2023 11:23:41 +0200 Message-Id: <20230621092350.3130866-4-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 02dfb416fbd2..781f287e7ce4 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 /* Tx Event FIFO Configuration (TXEFC) */ +#define TXEFC_EFWM_MASK GENMASK(29, 24) #define TXEFC_EFS_MASK GENMASK(21, 16) /* Tx Event FIFO Status (TXEFS) */ @@ -429,7 +430,7 @@ static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interrupts) static void m_can_coalescing_disable(struct m_can_classdev *cdev) { - u32 new_interrupts = cdev->active_interrupts | IR_RF0N; + u32 new_interrupts = cdev->active_interrupts | IR_RF0N | IR_TEFN; 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 *dev) static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir) { u32 new_interrupts = cdev->active_interrupts; - bool enable_timer = false; + bool enable_rx_timer = false; + bool enable_tx_timer = false; if (cdev->rx_coalesce_usecs_irq > 0 && (ir & (IR_RF0N | IR_RF0W))) { - enable_timer = true; + enable_rx_timer = true; new_interrupts &= ~IR_RF0N; - } else if (!hrtimer_active(&cdev->irq_timer)) { - new_interrupts |= IR_RF0N; } + if (cdev->tx_coalesce_usecs_irq > 0 && (ir & (IR_TEFN | IR_TEFW))) { + enable_tx_timer = true; + new_interrupts &= ~IR_TEFN; + } + if (!enable_rx_timer && !hrtimer_active(&cdev->irq_timer)) + new_interrupts |= IR_RF0N; + if (!enable_tx_timer && !hrtimer_active(&cdev->irq_timer)) + new_interrupts |= IR_TEFN; 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); - } } 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) != 0) goto out_fail; @@ -1333,9 +1339,8 @@ static int m_can_chip_config(struct net_device *dev) } /* Disable unused interrupts */ - interrupts &= ~(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 &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TFE | IR_TCF | + IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | IR_RF0F); m_can_config_endisable(cdev, true); @@ -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; struct hrtimer irq_timer; + ktime_t irq_timer_wait; struct m_can_ops *ops; @@ -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; struct mram_cfg mcfg[MRAM_CFG_NUM]; }; From patchwork Wed Jun 21 09:23:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286950 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C41BFDF4F for ; Wed, 21 Jun 2023 09:24:20 +0000 (UTC) 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 A94071FC8 for ; Wed, 21 Jun 2023 02:24:01 -0700 (PDT) Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-311367a3e12so4736634f8f.2 for ; Wed, 21 Jun 2023 02:24:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339440; x=1689931440; 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=hZrlIC4UOKpv9upRfhGvF2jtmIJyO/l6blnJN/Kvfh8=; b=5AJVy31qidMPxttaXsZUnYinlqnN0ERHOCEPlFbpjhFQL0d2YW5FREmg5TuJvUv2zo ecphYqOVzQxJJgvfgN5yoHmX9CrOqcIEYtbUk3uS39swqBrpXxvulFYG5DWRE5729iQZ 3FzNnptBBB/Pk+4DuPLO5YoRsA8Durq9oiW1ETBphaiHhSQ06U2920rL8Lk+SYNOSCzb AUTywM8/yoxyC+wVvrnqoTdv4ldgiiBHmq8zCFWlx+JKvX9lqF+PwhGXTi0lUBtu10PI DXcGyfuzb2tCDlD4yt5Kj29fe+zHBBHvF2aZ45gUwPyHO7hdKqdH1SdhtO1aX8u7wBVT bvHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339440; x=1689931440; 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=hZrlIC4UOKpv9upRfhGvF2jtmIJyO/l6blnJN/Kvfh8=; b=hAu84su1rzBZnyhsijQDrT9HsPA1YF2biwPiIww8Aa9IRw+XbeW+m6DftPpUzCGYVF cqcf5Q2l3i8NBjew84M1OYD4pcdNTOKCfTG3xTaLGDzTFR7yPAtRVYjqLDx8LiMrNQWS nG1s4KMUbiVd1WZVJ5MouNMiIV6O5/oMP0PhhDAywhnHmCYQBg5lzAZGcQblYOV+mVoX SeQSVAJLMQAZODyvhNjtqX22ocN7RFIZMrS088BuL/SP1FixYTw0QT/qLrrdLxFNHX2M t/CJ7YS4iTXgaRqd+x0orvn2indFnixZ0aMs55OLEiW537oTTSY0Z7M2RGsHMrUwG0tL MZLw== X-Gm-Message-State: AC+VfDybEDNEWwTuboES4lztVjOQvPzv7T/nZlmAuhQe9NMsrsIjbXYS kjHsxMuTHnGqNBKDlKd4FaJlZg== X-Google-Smtp-Source: ACHHUZ4I4CXR0xNnIv4BMV2cNzxpyr/Fi8tYkheKPje8OH+K7Bjdom7tQPVeaNpOFeaZUNhwsffxnA== X-Received: by 2002:adf:fd82:0:b0:30f:ce87:9db3 with SMTP id d2-20020adffd82000000b0030fce879db3mr13025821wrr.23.1687339440208; Wed, 21 Jun 2023 02:24:00 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.23.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:23:59 -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 v4 04/12] can: m_can: Add rx coalescing ethtool support Date: Wed, 21 Jun 2023 11:23:42 +0200 Message-Id: <20230621092350.3130866-5-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 781f287e7ce4..5238a5967971 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1944,8 +1944,54 @@ static const struct net_device_ops m_can_netdev_ops = { .ndo_change_mtu = can_change_mtu, }; +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 = netdev_priv(dev); + + ec->rx_max_coalesced_frames_irq = cdev->rx_max_coalesced_frames_irq; + ec->rx_coalesce_usecs_irq = 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 = netdev_priv(dev); + + if (cdev->can.state != 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 == 0 != ec->rx_coalesce_usecs_irq == 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 = ec->rx_max_coalesced_frames_irq; + cdev->rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; + + return 0; +} + static const struct ethtool_ops m_can_ethtool_ops = { + .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ | + ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ, .get_ts_info = ethtool_op_get_ts_info, + .get_coalesce = m_can_get_coalesce, + .set_coalesce = m_can_set_coalesce, }; static int register_m_can_dev(struct net_device *dev) From patchwork Wed Jun 21 09:23:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286951 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2CC71E57E for ; Wed, 21 Jun 2023 09:24:22 +0000 (UTC) Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ECB731FCB for ; Wed, 21 Jun 2023 02:24:02 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-3112f5ab0b1so3626588f8f.0 for ; Wed, 21 Jun 2023 02:24:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339441; x=1689931441; 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=S3yb9swE3xTiKnV49xmW7qQT7kAh84V+/Srm0DQQmxA=; b=x4YWo/dRgd3X1CXi35YBtv7s4YeY0ryc8LBoz5C1znXUZ4qpZmvgbeA75ObRCxYC5M h1XBldnohWKXdZpZtDM3VAU7/kkv5vP0Qho9j1LvleCyUJPglEcq/jPLE9n6DdjU9Qu+ Ng2VjFCleB6NhIxz0uE0YJoAKEExD/0cOZCkerXlzsEELo2fqCTDKUbxx8riLQMtYsb2 89SmXnAjPt81FEv8oatHcckOq2p6JhqAXtfUoUyaB1N5Tku4lKDoUEUHBRKbVWz0Ayt9 BTmqCDy2K13LALirN5MlP02JiisY3IzrSOwagkN2XIEQEovHLnOp2jl+4v4YWGt61wt0 zLpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339441; x=1689931441; 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=S3yb9swE3xTiKnV49xmW7qQT7kAh84V+/Srm0DQQmxA=; b=VzVSy6/c1Q8hvf7KTPs/TfxEpREp4j0gr6PVNXP8nn4289vpnv1mpPPvwBvpiBxXaU 0QMJkoxWT1XuGReXFJVWZW4eCOEpwxBde1yrSZgsvyA7MwVs987DIYyxAhIPBfXtETBL Ogs68Y/R0vswai9rUpCftqoaXI7IgQbWF1rQGbrcmqXIcVS61pYOHpN49KtKO36VKH+l 9F1zcWYWJ8WdwNFuaKMg7kxeChh4u4anKG3GmGpbllRgv+jHT8EbzTbk1DWziFJCoUMx i76g6kQR/31JZ2+tG89Yfdu8tTMk+B3SOKamWcooYn9HMfVFi8zUdsuG8OiTBvcwP7Ti 9LuA== X-Gm-Message-State: AC+VfDwAXHRjKOFpFbg09MRRLBzOEWb8YQlxEs/BoeUTlE4olNxy6unD vgBgXhBGymm+KF6hzpClaJGYxg== X-Google-Smtp-Source: ACHHUZ4bqQlJaFCvx+3AffW3dpFHExJEQziJdGScuvpiXckJsPH9Jmtck1XrxSNuUqtVz1m0fTMbAw== X-Received: by 2002:adf:ffce:0:b0:30f:b045:8b60 with SMTP id x14-20020adfffce000000b0030fb0458b60mr9833679wrs.69.1687339441432; Wed, 21 Jun 2023 02:24:01 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:01 -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 v4 05/12] can: m_can: Add tx coalescing ethtool support Date: Wed, 21 Jun 2023 11:23:43 +0200 Message-Id: <20230621092350.3130866-6-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 5238a5967971..d1435d1466b2 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1953,6 +1953,8 @@ static int m_can_get_coalesce(struct net_device *dev, ec->rx_max_coalesced_frames_irq = cdev->rx_max_coalesced_frames_irq; ec->rx_coalesce_usecs_irq = cdev->rx_coalesce_usecs_irq; + ec->tx_max_coalesced_frames_irq = cdev->tx_max_coalesced_frames_irq; + ec->tx_coalesce_usecs_irq = cdev->tx_coalesce_usecs_irq; return 0; } @@ -1979,16 +1981,50 @@ static int m_can_set_coalesce(struct net_device *dev, 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 == 0 != ec->tx_coalesce_usecs_irq == 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 != 0 && ec->tx_coalesce_usecs_irq != 0 && + ec->rx_coalesce_usecs_irq != 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; + } cdev->rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq; cdev->rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; + cdev->tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq; + cdev->tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; + + if (cdev->rx_coalesce_usecs_irq) + cdev->irq_timer_wait = + ns_to_ktime(cdev->rx_coalesce_usecs_irq * NSEC_PER_USEC); + else + cdev->irq_timer_wait = + ns_to_ktime(cdev->tx_coalesce_usecs_irq * NSEC_PER_USEC); return 0; } static const struct ethtool_ops m_can_ethtool_ops = { .supported_coalesce_params = 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 = ethtool_op_get_ts_info, .get_coalesce = m_can_get_coalesce, .set_coalesce = m_can_set_coalesce, From patchwork Wed Jun 21 09:23:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286952 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C2642FBE1 for ; Wed, 21 Jun 2023 09:24:23 +0000 (UTC) Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4910619B5 for ; Wed, 21 Jun 2023 02:24:04 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-98862e7e3e6so517122566b.0 for ; Wed, 21 Jun 2023 02:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339442; x=1689931442; 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=LE1vT+gVNirEsJxbTiTmA/33w+JDDyn/z8+OkH6Uatg=; b=dh/Yscpx9g50WP8aUQec7esEdqkMVckT3xmVw5qZUmxNn8Lnkpby8IzbVZxOkbudQ1 dR5a6nkp17Pn0vSgWzUsFeApujZpPlq8DvW9F6cn4SoKlOPPHmvyWvXo/XEgH/v1Xjhp d0gzl7pJo4T/8Ea7xeTevcKvSQAm4tg84t6Li6oi2XxrgDKYJKUrU5QO+OJZUmcn/pW8 WgN3lJONfebk19tQqqGWv1PBAFnjqam9Hm3hhUp/V1h9hKt/3nybAv0+65aU0McJ3Sct U+MigjS8Fq7nIP9+sx1pDlBh59lrTSFdqy1cYRhDwwYdcIAfIhrkmUsd1f5G+ApwD6Ex LGTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339442; x=1689931442; 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=LE1vT+gVNirEsJxbTiTmA/33w+JDDyn/z8+OkH6Uatg=; b=DZFvELiqJKdak5QNQUSxgOzyQo3yL4tFusxUOuGWgRpIOoO8x6Bm8ewRWN7wTa0yEe h2qGaz1DPPg9fC3oJyBc+E5jLi8NCnNRTMmi1mhSN8DiXFeH9xSx5WAycLpm7BJ6RyH6 XZQ/zNOBk0+x76qCpKkIs6I/NWGJBJdb7Pojj2nZRgzXdf6oaVLxLun3pkVOTtS0R34g d7Nsh8VTUUUGq/orlQFU2ePyBv6KZfLeN2NsUQKROeRV3D5sj25rFaAgTxPZNWrHnu20 sBmuLrZ9JRAu2tNopFQHOmUYOioqCilEWFLMo5kljBbZl7swh91snoMqI9hkoPw/IGTv 9eRQ== X-Gm-Message-State: AC+VfDzfvvWLUodKWuheIzyDG41G08yNmQx7qplDM5IJK1oGYmc9newb 2TVJJAqkiXNJfwQhSRXPnDCPEQ== X-Google-Smtp-Source: ACHHUZ7IYIJzPl+IZdr+yo0zGtbLHILTndtfPgoJd1ib2x2wssIJxDu9j+PC5fysl1booVNBKkNFgA== X-Received: by 2002:a17:906:58d2:b0:988:8a11:ab88 with SMTP id e18-20020a17090658d200b009888a11ab88mr8539198ejs.33.1687339442703; Wed, 21 Jun 2023 02:24:02 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:02 -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 v4 06/12] can: m_can: Use u32 for putidx Date: Wed, 21 Jun 2023 11:23:44 +0200 Message-Id: <20230621092350.3130866-7-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 d1435d1466b2..6f8043636c54 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 = netdev_priv(net); if (cdev->tx_skb) { - int putidx = 0; + u32 putidx = 0; net->stats.tx_errors++; if (cdev->version > 30) @@ -1673,12 +1673,12 @@ static int m_can_close(struct net_device *dev) return 0; } -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 = netdev_priv(dev); /*get wrap around for loopback skb index */ unsigned int wrap = cdev->can.echo_skb_max; - int next_idx; + u32 next_idx; /* calculate next index */ next_idx = (++putidx >= wrap ? 0 : putidx); @@ -1698,7 +1698,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) u32 cccr, fdflags; u32 txfqs; int err; - int putidx; + u32 putidx; cdev->tx_skb = NULL; From patchwork Wed Jun 21 09:23:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286953 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B86D6FBE1 for ; Wed, 21 Jun 2023 09:24:24 +0000 (UTC) Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7198B1BC0 for ; Wed, 21 Jun 2023 02:24:05 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-311394406d0so3223723f8f.2 for ; Wed, 21 Jun 2023 02:24:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339444; x=1689931444; 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=DG8roE6DhQwhU2xd4+PBx8NOhVWjNvN1rf2zoTDzpOE=; b=zfMj4yE/E3JiduSidiDhmkVb1PXwnXSoIAD/BKOKSWThF0Medj9ixH10zxIDtLxPwi 2u5tw1TqtyfHQ1Ctp/9EzjrlTcV6AszrGml9w9YE8qRNS/7YG9GBzZfpbjfBNM8jAHkU +fv7lEHKsdHaCFA0piyEIzF91CNZ64CXXBubRHgGuc1WjKzZDi6tPFhDT7ethE7Zdwsp dVLviscYJfyVQABy9gDorl63pM6C+IWVPjEnyn6YaWUBwLlbJbHDoiv6Olnn9f5k3w81 sSJPU3pitUMYXAiknhVsoqycNSJYPjo0yPokeccIwxfDzqw5JfywxN9sK04wZICKixI6 u3kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339444; x=1689931444; 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=DG8roE6DhQwhU2xd4+PBx8NOhVWjNvN1rf2zoTDzpOE=; b=KONjGvEHq4R4wXnkrFj/mrrRIHZO6VwfrjAeJBw9TWtUewLvOmVA9PP7V9Bqo8CK+3 hi3wRdcSIIMd+n1huUXSzicZI6IaHpMLVyuAH5LjR/N2WGssOuIawjtApY1v0XODArgG we3SPyIoB6WB2qYkg4zwL/U5zY7kTUK5EvgNs+U00SEQW7s188ehPu0ImruXEHGmu4Mc LxftQ3HF4ldPrdUAbG58lBXA2zbOcQDfU2+0k1b6BSTJ3vOH5/N03SZ88wBxaskSiaMi 6aw9milD32Wdjqc7lwjh7VkVLIz9QdeJymcIcvWcY7WZPssXvydAbh/8qpU4Jqasl8QD by3Q== X-Gm-Message-State: AC+VfDyz8TG/qz1XFQnYF248eSdZXBUO6NDmpbMbJvvEThQJP2uLVDOh 0ow/jMCOTxGzgTfhjVY88eGHVwL5Zpye1Q+2+7I= X-Google-Smtp-Source: ACHHUZ6sId7l7j6whJo/YkV2dFIsFAmiVsuGwurxB3iRA7J0C+YrFMOc/j4DJGLUWFIDR5obcw2EGQ== X-Received: by 2002:a5d:628d:0:b0:30d:5cce:3bb5 with SMTP id k13-20020a5d628d000000b0030d5cce3bb5mr10729727wru.60.1687339444004; Wed, 21 Jun 2023 02:24:04 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:03 -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 v4 07/12] can: m_can: Cache tx putidx Date: Wed, 21 Jun 2023 11:23:45 +0200 Message-Id: <20230621092350.3130866-8-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 6f8043636c54..40acd78cc0ed 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) m_can_enable_all_interrupts(cdev); + if (cdev->version > 30) + cdev->tx_fifo_putidx = FIELD_GET(TXFQS_TFQPI_MASK, + m_can_read(cdev, M_CAN_TXFQS)); + return 0; } @@ -1772,7 +1776,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) } /* get put index for frame */ - putidx = FIELD_GET(TXFQS_TFQPI_MASK, txfqs); + putidx = cdev->tx_fifo_putidx; /* Construct DLC Field, with CAN-FD configuration. * Use the put index of the fifo as the message marker, @@ -1806,6 +1810,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) /* Enable TX FIFO element to start transfer */ m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); + cdev->tx_fifo_putidx = (++cdev->tx_fifo_putidx >= cdev->can.echo_skb_max ? + 0 : cdev->tx_fifo_putidx); /* 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; + // Store this internally to avoid fetch delays on peripheral chips + int tx_fifo_putidx; + struct mram_cfg mcfg[MRAM_CFG_NUM]; }; From patchwork Wed Jun 21 09:23:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286954 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8D25101CE for ; Wed, 21 Jun 2023 09:24:25 +0000 (UTC) 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 753981BC5 for ; Wed, 21 Jun 2023 02:24:06 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-307d20548adso4592123f8f.0 for ; Wed, 21 Jun 2023 02:24:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339445; x=1689931445; 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=UURWqBUXOBW/vgexjIMqvywbeKsg0EBaKHEuKuyo96o=; b=O4mT4gGylvPiW0VFn3USiYztPupBUDZj+DJB0DhCa19DiFIOSt+vzlu4yV7TWEh6R0 QfUJMBOlykfgzF17rzLqLM7O3y67yYzI7a275Dzp6BtU6abmDMbHMs4a9yJbruonrlS+ 3yUxVM9fJKBPe8lUV3IVUMiU1e7wkf5bR1n+72DL0fMLmabpq5HNQuzwm0EhSyr7+Epb B75mjtHp8kO0FMFZR7ClCI2XeNYQ11QkIxWOzM5mLCTRkXj2tJM5oLtV3MXiY3mgDcJT +JHVi9fmMzN+5hLKWn5BP3eWC5m4KQThNmRd0o36Wnfwx8dJdAWUfAXmOozQ+8MGiNbq yyeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339445; x=1689931445; 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=UURWqBUXOBW/vgexjIMqvywbeKsg0EBaKHEuKuyo96o=; b=kdyY1Hbu5nVgL9g8M+K8wJkIAV6SI8XeIDHS4XQLFdcIgS1N8NA53BIB4+US1gSj10 hyUVPZnpEeOeBhQgLiacj0O96J0qnkKGwHmxZS+1wzU7BZYBQq8IkPta7mHrny5MiAOZ MshH+/YXoZD2fdvT/Urorc8FpCXx8aNR/M9sQXegVqn7BmvtklH/IpIQLd/cel7du77X k/E5wCSLmXmZsFog+C7WT92p537KOmKNFRfc/DuPooGuR76kBm89F4v59HbhDjv65otS gHwQfP5SOzbnSIZtvLFlWDeF4rky4TjCrMNc9x2GgpsZiAyqbeh5q/pkfGSUSzdBFItp J2hw== X-Gm-Message-State: AC+VfDyhccR1sFM2F0RFnFB80eMfmej8BDi55osY+D+XdVWaJguOzwJg l/mDQlkPFcISpL+6TNaPWpSfrQ== X-Google-Smtp-Source: ACHHUZ5X+Lxa/yPBHXRZWcjID6A0d87xTj+VU2DOGrwmBVM6bPxUMvj5HyMgXm+D1JqsmQ5co87ZSw== X-Received: by 2002:adf:fa06:0:b0:30f:be04:5b5e with SMTP id m6-20020adffa06000000b0030fbe045b5emr9288732wrr.37.1687339444992; Wed, 21 Jun 2023 02:24:04 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:04 -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 v4 08/12] can: m_can: Use the workqueue as queue Date: Wed, 21 Jun 2023 11:23:46 +0200 Message-Id: <20230621092350.3130866-9-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 40acd78cc0ed..88c8d6a418f0 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 = netdev_priv(net); - if (cdev->tx_skb) { - u32 putidx = 0; + for (int i = 0; i != cdev->tx_fifo_size; ++i) { + if (!cdev->tx_ops[i].skb) + continue; net->stats.tx_errors++; - if (cdev->version > 30) - putidx = FIELD_GET(TXFQS_TFQPI_MASK, - m_can_read(cdev, M_CAN_TXFQS)); - - can_free_echo_skb(cdev->net, putidx, NULL); - cdev->tx_skb = NULL; + cdev->tx_ops[i].skb = NULL; } + + for (int i = 0; i != cdev->can.echo_skb_max; ++i) + can_free_echo_skb(cdev->net, i, NULL); } /* 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); + m_can_clean(dev); + if (cdev->is_peripheral) { - cdev->tx_skb = NULL; destroy_workqueue(cdev->tx_wq); cdev->tx_wq = NULL; can_rx_offload_disable(&cdev->offload); @@ -1691,21 +1691,19 @@ static int m_can_next_echo_skb_occupied(struct net_device *dev, u32 putidx) return !!cdev->can.echo_skb[next_idx]; } -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 = (struct canfd_frame *)cdev->tx_skb->data; + struct canfd_frame *cf = (struct canfd_frame *)skb->data; u8 len_padded = DIV_ROUND_UP(cf->len, 4); struct m_can_fifo_element fifo_element; struct net_device *dev = cdev->net; - struct sk_buff *skb = cdev->tx_skb; struct id_and_dlc fifo_header; u32 cccr, fdflags; u32 txfqs; int err; u32 putidx; - cdev->tx_skb = NULL; - /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ if (cf->can_id & CAN_EFF_FLAG) { @@ -1829,10 +1827,36 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) static void m_can_tx_work_queue(struct work_struct *ws) { - struct m_can_classdev *cdev = container_of(ws, struct m_can_classdev, - tx_work); + struct m_can_tx_op *op = container_of(ws, struct m_can_tx_op, work); + struct m_can_classdev *cdev = op->cdev; + struct sk_buff *skb = op->skb; - m_can_tx_handler(cdev); + op->skb = 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 = skb; + queue_work(cdev->tx_wq, &cdev->tx_ops[cdev->next_tx_op].work); + + ++cdev->next_tx_op; + if (cdev->next_tx_op >= cdev->tx_fifo_size) + cdev->next_tx_op = 0; +} + +static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev, + struct sk_buff *skb) +{ + if (cdev->can.state == 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; } static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, @@ -1843,30 +1867,10 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; - 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 == 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 = skb; - netif_stop_queue(cdev->net); - queue_work(cdev->tx_wq, &cdev->tx_work); - } - } else { - cdev->tx_skb = 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); } static int m_can_open(struct net_device *dev) @@ -1894,15 +1898,17 @@ static int m_can_open(struct net_device *dev) /* register interrupt handler */ if (cdev->is_peripheral) { - cdev->tx_skb = NULL; - cdev->tx_wq = alloc_workqueue("mcan_wq", - WQ_FREEZABLE | WQ_MEM_RECLAIM, 0); + cdev->tx_wq = alloc_ordered_workqueue("mcan_wq", + WQ_FREEZABLE | WQ_MEM_RECLAIM); if (!cdev->tx_wq) { err = -ENOMEM; goto out_wq_fail; } - INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); + for (int i = 0; i != cdev->tx_fifo_size; ++i) { + cdev->tx_ops[i].cdev = cdev; + INIT_WORK(&cdev->tx_ops[i].work, m_can_tx_work_queue); + } err = request_threaded_irq(dev->irq, NULL, m_can_isr, IRQF_ONESHOT, @@ -2172,6 +2178,19 @@ int m_can_class_register(struct m_can_classdev *cdev) { int ret; + cdev->tx_fifo_size = max(1, min(cdev->mcfg[MRAM_TXB].num, + cdev->mcfg[MRAM_TXE].num)); + if (cdev->is_peripheral) { + cdev->tx_ops = + 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 = 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); }; +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; struct workqueue_struct *tx_wq; - struct work_struct tx_work; - struct sk_buff *tx_skb; struct phy *transceiver; struct hrtimer irq_timer; @@ -103,7 +107,11 @@ struct m_can_classdev { u32 tx_coalesce_usecs_irq; // 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; struct mram_cfg mcfg[MRAM_CFG_NUM]; }; From patchwork Wed Jun 21 09:23:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286955 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E55C101CE for ; Wed, 21 Jun 2023 09:24:26 +0000 (UTC) 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 8DB6F1BC6 for ; Wed, 21 Jun 2023 02:24:07 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-311099fac92so6620625f8f.0 for ; Wed, 21 Jun 2023 02:24:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339446; x=1689931446; 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=wgGolVUD4UXN/bgzsidi7fKnE4pGiXRO6QM6WC6v+Ds=; b=eeErYS/yb7l1i94wnKW/4Cz9K5CztVnCkeoHKYlRJbv6aKHhjqDbxr5yk1K8Dh6Wyt 40pkE4VoeBGzSSC6tms4qeLrWDSDYvoWGiaBdoxIJHvuwS7uLp52NWnvyo/zAOewXd6U 6I1dUMnevaP8a7cVpGeYHO2M1aQNTM0fmy/8cprYfhLSYhLHqjZim0w0rIcA57DqKmpt 0ZU3Po/sP+qBwzIu+JJym4fqY8wvZJklDDIvXwMGMSbzcAKnGoQT8jorbUbN++Daxi9R XlXoifqwqUqQYfB7+1KUcNiHhBvhdZ1AREav+zvUbRIRJ0Wj7Jo6czmgHUuQzP4x+a/r RCEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339446; x=1689931446; 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=wgGolVUD4UXN/bgzsidi7fKnE4pGiXRO6QM6WC6v+Ds=; b=KAHzsn7cYD+VNUI2lRqDGzGVV/iDpXnruLRhPqbnS/crmAW3oMl5DD3/1V7Z9m1i3N aya4wgBBt+HepZNUycGy7mGU4kPzi7apLMZgiTaKObDSwbwnEjbxznA/L2oLqmxxMb30 CiOHPNrtWp6yPde5v3PSf4X2TIupYnqm4zjLoOj2UaZSHAfofzDjLb9LAZU1bkYpbw8L IqYwOfRXZQw+FQko8VsDGEI+HlpGkfvFE21S7ujlQzWO3SL6rQvVeDPkVh9RbbgmD9x/ 2z9dIyJ9FMOKwodz043AGSxaiPgiS4o7R6Hyxo2nNdDHXMGfDY0EK8lbcm9eDIjN21Eb 6UVQ== X-Gm-Message-State: AC+VfDw6zlmVA/xQy0x7TMip6A3ZfP5GtHshlNEE5O3pJ9hrgBMngWwE HiPXYDHl5YTn8bYAD4uY80nEvX7jLyxcvQbMwvc= X-Google-Smtp-Source: ACHHUZ6Q5XHXe8GPfNxwkYzofX+JhnhyhMamRQS6suM/w5rFj1aiAFzwbLttIaFm4TwvZo2i7ahFHg== X-Received: by 2002:a05:6000:11d2:b0:30f:c473:dfd0 with SMTP id i18-20020a05600011d200b0030fc473dfd0mr11415466wrx.12.1687339446086; Wed, 21 Jun 2023 02:24:06 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:05 -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 v4 09/12] can: m_can: Introduce a tx_fifo_in_flight counter Date: Wed, 21 Jun 2023 11:23:47 +0200 Message-Id: <20230621092350.3130866-10-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 88c8d6a418f0..3353fd9fb3a2 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 *cdev) static void m_can_clean(struct net_device *net) { struct m_can_classdev *cdev = netdev_priv(net); + unsigned long irqflags; for (int i = 0; i != cdev->tx_fifo_size; ++i) { if (!cdev->tx_ops[i].skb) @@ -476,6 +477,10 @@ static void m_can_clean(struct net_device *net) for (int i = 0; i != 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 = 0; + spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); } /* 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_classdev *cdev, stats->tx_packets++; } +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 -= 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 = 0; @@ -1055,6 +1078,7 @@ static int m_can_echo_tx_event(struct net_device *dev) int i = 0; int err = 0; unsigned int msg_mark; + int processed = 0; struct m_can_classdev *cdev = netdev_priv(dev); @@ -1084,12 +1108,15 @@ static int m_can_echo_tx_event(struct net_device *dev) /* update stats */ m_can_tx_update_stats(cdev, msg_mark, timestamp); + ++processed; } if (ack_fgi != -1) m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, ack_fgi)); + m_can_finish_tx(cdev, processed); + return err; } @@ -1168,6 +1195,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) timestamp = 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)) { @@ -1854,11 +1882,22 @@ static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev, } netif_stop_queue(cdev->net); + + m_can_start_tx(cdev); + m_can_tx_queue_skb(cdev, skb); return NETDEV_TX_OK; } +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) { @@ -1870,7 +1909,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, 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); } 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; + /* 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; From patchwork Wed Jun 21 09:23:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286956 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9295711C8A for ; Wed, 21 Jun 2023 09:24:27 +0000 (UTC) Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9FCB71BCF for ; Wed, 21 Jun 2023 02:24:08 -0700 (PDT) Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-30fbf253dc7so4554476f8f.0 for ; Wed, 21 Jun 2023 02:24:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339447; x=1689931447; 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=P6rWS7bREqVUPkH2+6lOc5shnNXmaz1zo3KIcC701tw=; b=IdEDUigz2e/1Ljo91fcbJy4qTNc9c2A1u+FPRbyB8azGWrnWOlz8CI9bAgex0hX5Ji lAYk97/j3J9lMM1ctK9UHR2RWC3j355Hhwpm8vmbM9ZQEBWPuiVzcIkVjSA9gAi6fIYG O8EMOLbEGToTe7G4tBI6j58uRHEIQusPTHaqqKISVYBNirpiJiCylWAGn7MYYkKD+LYA lg7YIDwv9hXrGUcqEWn9z/ER8DCRNlFuLykGE/ScENkQxi32fE7segAodG6Za+A9uxf9 UPbJRYKHPbZ5ByaCIzmM/wKjXLyKB0yo1RwawzcljcSnpmlFhMZJvyD8ydmuzfH8TJyf NQNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339447; x=1689931447; 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=P6rWS7bREqVUPkH2+6lOc5shnNXmaz1zo3KIcC701tw=; b=RPNBksM4Fm+5OL4xPQY1813QQLIZ0xnPER+YiIvzsZ9eHoqI1aN3Rcr0YOL62SXtH/ r78IWqVaj2saZ5PL6A5JErbmhL5mu3kPVbOyf9Un6O/1efiDaj388xpjHDo/XX1dGpZp Tdut+tyhprU9eQJxfLyiUG0gxKmrU5IAA0J5rRf5qRhYQVpANy7feXXaXGZJlNRxzLUv Ihh3LRln0pxa62deawhtkCqV57gXzOnFcBvawtH6HY/ZX9gnpNUvmP2W86XUl0l5i1nw 5fipXkHvpIWmkPtob1lnCG/k9WalLRjf7UhHILU8mR+BtTopgYaBCfDZSzxMASIQyKBC Bbpg== X-Gm-Message-State: AC+VfDwSw31y5YMaETxTLpL2Hw9JW0vsJhoojNYXyR8fh0/V7+aPwZbu yz1ZzYmGh8ZBnhTFPK4UWsYamg== X-Google-Smtp-Source: ACHHUZ7Hf03F0mBOItRu/4VKUOpNvvg+HFqjLdZlDboDYL+3+UE5WRdooJkg/Wd1jJz1qWmXU1PPIw== X-Received: by 2002:adf:f409:0:b0:311:3eaf:f011 with SMTP id g9-20020adff409000000b003113eaff011mr7583058wro.19.1687339447165; Wed, 21 Jun 2023 02:24:07 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:06 -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 v4 10/12] can: m_can: Use tx_fifo_in_flight for netif_queue control Date: Wed, 21 Jun 2023 11:23:48 +0200 Message-Id: <20230621092350.3130866-11-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 3353fd9fb3a2..38bdab9b5cd6 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 fgi, u32 offset, u32 *val) return cdev->ops->read_fifo(cdev, addr_offset, val, 1); } -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 enable) { u32 cccr = 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; spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); + if (cdev->tx_fifo_in_flight >= cdev->tx_fifo_size && transmitted > 0) + netif_wake_queue(cdev->net); cdev->tx_fifo_in_flight -= transmitted; spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); } -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; spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); - ++cdev->tx_fifo_in_flight; + tx_fifo_in_flight = cdev->tx_fifo_in_flight + 1; + if (tx_fifo_in_flight >= 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 = tx_fifo_in_flight; spin_unlock_irqrestore(&cdev->tx_handling_spinlock, irqflags); + + return NETDEV_TX_OK; } 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 = 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) != 0) goto out_fail; - - if (netif_queue_stopped(dev) && - !m_can_tx_fifo_full(cdev)) - netif_wake_queue(dev); } } @@ -1705,20 +1704,6 @@ static int m_can_close(struct net_device *dev) return 0; } -static int m_can_next_echo_skb_occupied(struct net_device *dev, u32 putidx) -{ - struct m_can_classdev *cdev = netdev_priv(dev); - /*get wrap around for loopback skb index */ - unsigned int wrap = cdev->can.echo_skb_max; - u32 next_idx; - - /* calculate next index */ - next_idx = (++putidx >= 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) { @@ -1728,7 +1713,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, struct net_device *dev = cdev->net; struct id_and_dlc fifo_header; u32 cccr, fdflags; - u32 txfqs; int err; u32 putidx; @@ -1783,24 +1767,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, } else { /* Transmit routine for version >= v3.1.x */ - txfqs = 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 = cdev->tx_fifo_putidx; @@ -1838,11 +1804,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); cdev->tx_fifo_putidx = (++cdev->tx_fifo_putidx >= 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); } return NETDEV_TX_OK; @@ -1876,14 +1837,16 @@ static void m_can_tx_queue_skb(struct m_can_classdev *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 == CAN_STATE_BUS_OFF) { m_can_clean(cdev->net); return NETDEV_TX_OK; } - netif_stop_queue(cdev->net); - - m_can_start_tx(cdev); + err = m_can_start_tx(cdev); + if (err != NETDEV_TX_OK) + return err; m_can_tx_queue_skb(cdev, skb); @@ -1893,7 +1856,11 @@ static netdev_tx_t m_can_start_peripheral_xmit(struct 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 = m_can_start_tx(cdev); + if (err != NETDEV_TX_OK) + return err; return m_can_tx_handler(cdev, skb); } From patchwork Wed Jun 21 09:23:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286957 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21F78125AF for ; Wed, 21 Jun 2023 09:24:28 +0000 (UTC) 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 DDC761BD3 for ; Wed, 21 Jun 2023 02:24:09 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-311367a3e12so4736773f8f.2 for ; Wed, 21 Jun 2023 02:24:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339448; x=1689931448; 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=YnUnzSIjjASfPwMtskRGblxnthY3N6SsU/Hyarpa4rM=; b=yjtIIVhkCxt+LK4zSutC32yInmFrQPo5BiQFauqWivAsL1FhOmTYP0rQ5Lx8m5N7wc ZFefMPgm0r3cPw6uYOVgeDMe837pyzSLVvSyCk6JtWgZP+VV+/v26YLldf9XYQ1vvuk9 ceMef06EL50wQBiJloKbb+dd+4xvgkZg/a1Au1OioI2Q0uCumXRgMMLL5d4Nc9X0lnAW sovSPJe3MXmpZWX5SMO2Zv4FLEEr5MTK3EifoPa/0EHJvUrKu3lPgISvCxaKCVxkL9Yz RYl5gftoSeS/WkyZXZlG5s3iXNx1oURdhOBg1ITYQCzcKct13A0I/fb6rrvG+1Gpvdro 00zQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339448; x=1689931448; 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=YnUnzSIjjASfPwMtskRGblxnthY3N6SsU/Hyarpa4rM=; b=iCC32CXkFAy+CuCG0c7dx/02zv9+UvdrTmBqxhDR9Xd2bhFgzU+tNvdf4dvMy4gw// IpLi1ysocFNBwl0yrtNM+gUReoGa5S0VOEL/mncFa/998OsQgcMyPlMmr1wpjicPdANx cKTGHq1hntn8b//lYaLt77BTXGuaG8x5WQ6jaVvPYxZ6292GJRn850Yn3SZivR/HLeVN HrB1oXFho5afWQ2z04zCJle6q14uFSi8seH+Wg0OfF4+t/lW5tGkNZfBIzuXdPMutTJs m8arwLr9L8pSjZiab+khXCBnDJcDORw9axu2gt96yy7cTcJYoTHgy9pbF8GxmyPYeJxX G0iw== X-Gm-Message-State: AC+VfDx5VJyIvfLqFq3IVdv4w11KB3fl4fp0TWAzQzH2Zl39KNvHWSHV E7DbEwtM8jxfK52ybaXDMwvr+w== X-Google-Smtp-Source: ACHHUZ67eiO14Pu0Mziq4FMbdAuhxUlX/AOXJx8zGLQAp+oleHDmnpGNQHpIOEBFogxNuKTbSdnYNA== X-Received: by 2002:adf:fc47:0:b0:30f:b953:f9fa with SMTP id e7-20020adffc47000000b0030fb953f9famr12220712wrs.16.1687339448146; Wed, 21 Jun 2023 02:24:08 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:07 -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 v4 11/12] can: m_can: Implement BQL Date: Wed, 21 Jun 2023 11:23:49 +0200 Message-Id: <20230621092350.3130866-12-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Implement byte queue limiting in preparation for the use of xmit_more(). Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman --- 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 38bdab9b5cd6..62e275c87c29 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 = 0; i != cdev->can.echo_skb_max; ++i) can_free_echo_skb(cdev->net, i, NULL); + netdev_reset_queue(cdev->net); + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); cdev->tx_fifo_in_flight = 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 = cdev->net; struct net_device_stats *stats = &dev->stats; + unsigned int frame_len; if (cdev->is_peripheral) stats->tx_bytes += can_rx_offload_get_echo_skb(&cdev->offload, msg_mark, timestamp, - NULL); + &frame_len); else - stats->tx_bytes += can_get_echo_skb(dev, msg_mark, NULL); + stats->tx_bytes += can_get_echo_skb(dev, msg_mark, &frame_len); stats->tx_packets++; + + return frame_len; } -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; + netdev_completed_queue(cdev->net, transmitted, transmitted_frame_len); + spin_lock_irqsave(&cdev->tx_handling_spinlock, irqflags); if (cdev->tx_fifo_in_flight >= 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 = 0; unsigned int msg_mark; int processed = 0; + unsigned int processed_frame_len = 0; struct m_can_classdev *cdev = netdev_priv(dev); @@ -1111,7 +1119,9 @@ static int m_can_echo_tx_event(struct net_device *dev) fgi = (++fgi >= cdev->mcfg[MRAM_TXE].num ? 0 : fgi); /* update stats */ - m_can_tx_update_stats(cdev, msg_mark, timestamp); + processed_frame_len += m_can_tx_update_stats(cdev, msg_mark, + timestamp); + ++processed; } @@ -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)); - m_can_finish_tx(cdev, processed); + m_can_finish_tx(cdev, processed, processed_frame_len); 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 = 0; + unsigned int frame_len; if (cdev->is_peripheral) timestamp = m_can_get_timestamp(cdev); - m_can_tx_update_stats(cdev, 0, timestamp); - m_can_finish_tx(cdev, 1); + frame_len = m_can_tx_update_stats(cdev, 0, timestamp); + m_can_finish_tx(cdev, 1, frame_len); } } else { if (ir & (IR_TEFN | IR_TEFW)) { @@ -1715,6 +1726,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, u32 cccr, fdflags; int err; u32 putidx; + unsigned int frame_len = can_skb_get_frame_len(skb); /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ @@ -1760,7 +1772,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, } m_can_write(cdev, M_CAN_TXBTIE, 0x1); - can_put_echo_skb(skb, dev, 0, 0); + can_put_echo_skb(skb, dev, 0, frame_len); m_can_write(cdev, M_CAN_TXBAR, 0x1); /* End of xmit function for version 3.0.x */ @@ -1798,7 +1810,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *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); /* Enable TX FIFO element to start transfer */ m_can_write(cdev, M_CAN_TXBAR, (1 << putidx)); @@ -1869,14 +1881,23 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct m_can_classdev *cdev = netdev_priv(dev); + netdev_tx_t ret; + unsigned int frame_len; if (can_dev_dropped_skb(dev, skb)) return NETDEV_TX_OK; + frame_len = can_skb_get_frame_len(skb); + if (cdev->is_peripheral) - return m_can_start_peripheral_xmit(cdev, skb); + ret = m_can_start_peripheral_xmit(cdev, skb); else - return m_can_start_fast_xmit(cdev, skb); + ret = m_can_start_fast_xmit(cdev, skb); + + if (ret == NETDEV_TX_OK) + netdev_sent_queue(dev, frame_len); + + return ret; } static int m_can_open(struct net_device *dev) From patchwork Wed Jun 21 09:23:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Schneider-Pargmann X-Patchwork-Id: 13286958 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D386134BF for ; Wed, 21 Jun 2023 09:24:29 +0000 (UTC) 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 261F31BD9 for ; Wed, 21 Jun 2023 02:24:10 -0700 (PDT) Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-3112f2b9625so4059057f8f.1 for ; Wed, 21 Jun 2023 02:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20221208.gappssmtp.com; s=20221208; t=1687339449; x=1689931449; 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=tSaqA2+LFEta6gdn/o/4wTZ/gzZyVMVxUFSu8tBDIgo=; b=PIgwGsjqRRBnD4wUED0zMgDd90izGj+VUDD9EgoqqxSaxj/EA/sixV9j0Puhbj6yvd i1Ac0Rlms2EVdNwTS5h1sPCi/JjPPAK6m66f+HEwmgOh8D8uZMrVbGn/biLYxZI+BECq XpkAWKQlObsxZ/I51tzMmRbncT39WnbXS+8nl9N5uTZhSuuTZfacrHmIfwjzyHlPZsKB aNAtUdSAbjgLFLrTvaE0GMxn4YiN0CZOBqxzkMr3lFGuEwx9aqn/Vg5a3G+9ZUchNjL+ Yk0OrNCbOU/PGc9uO3FRpdu9urD98t0PRfv23kLIMGEvZ9KcdBruuqTU7Y9EsBjTkh72 YvtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687339449; x=1689931449; 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=tSaqA2+LFEta6gdn/o/4wTZ/gzZyVMVxUFSu8tBDIgo=; b=K4eR6K6TsZu8rW7SXVgufCT3y4mpz67ZH3OFBo7rJ7Wcg11/u/dnf1R4DFvOyX3Eqb mcB2ux3oCONqFi5+f+d9UZupyciAN930KUA7W9Z5sCoRIlQBFqv6JPszwbi0XQGXBoSd Y6QCD0D/XH9gjA68xbSiX6siOtuX+3eLg45wsOBB31MgC47T8NIg8nSgi+Cx6shR/O9p 6EKlg4Kgupxz+v4NV/1Yi6j7Fcfh/LQDpxXFBRa3HBS3Jrmo+DCedkBvMjfPFAu9o40J P+JRGflideaLLHjLDPDXEo3bJYHVySfyPr5JmExeHsO0GMjrqeiYJLJy56TEKhYW4vAk K8aQ== X-Gm-Message-State: AC+VfDzwnrg57gCmzRh2QpCItzdeNl8DimWaWHf/F8nLwXYDaeKE6kG/ BOsrrh+P45vFOfbwQ4kICUx5cg== X-Google-Smtp-Source: ACHHUZ5eMijZ66B67qzvTYMfOslqJVRgfNlBhd2Q6VbMh1hl/bA8gcUR75BYlVUAvnnZHPXYM8lJ+Q== X-Received: by 2002:adf:f203:0:b0:30f:ca58:39ca with SMTP id p3-20020adff203000000b0030fca5839camr11486248wro.31.1687339449246; Wed, 21 Jun 2023 02:24:09 -0700 (PDT) Received: from blmsp.fritz.box ([2001:4091:a247:82fa:b762:4f68:e1ed:5041]) by smtp.gmail.com with ESMTPSA id i11-20020adffdcb000000b002fda1b12a0bsm4022115wrs.2.2023.06.21.02.24.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jun 2023 02:24:08 -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 v4 12/12] can: m_can: Implement transmit submission coalescing Date: Wed, 21 Jun 2023 11:23:50 +0200 Message-Id: <20230621092350.3130866-13-msp@baylibre.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230621092350.3130866-1-msp@baylibre.com> References: <20230621092350.3130866-1-msp@baylibre.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org 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 --- Notes: Notes: - I ran into lost messages in the receive FIFO when using this implementation. I guess this only shows up with my test setup in loopback mode and maybe not enough CPU power. - 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 62e275c87c29..50909b9c0e7c 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; + netdev_queue_set_dql_min_limit(netdev_get_tx_queue(cdev->net, 0), + cdev->tx_max_coalesced_frames); + cdev->can.state = CAN_STATE_ERROR_ACTIVE; m_can_enable_all_interrupts(cdev); @@ -1812,8 +1815,13 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, */ can_put_echo_skb(skb, dev, putidx, frame_len); - /* 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 |= BIT(putidx); + } else { + /* Enable TX FIFO element to start transfer */ + m_can_write(cdev, M_CAN_TXBAR, BIT(putidx)); + } cdev->tx_fifo_putidx = (++cdev->tx_fifo_putidx >= cdev->can.echo_skb_max ? 0 : cdev->tx_fifo_putidx); } @@ -1826,6 +1834,17 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, return NETDEV_TX_BUSY; } +static void m_can_tx_submit(struct m_can_classdev *cdev) +{ + if (cdev->version == 30) + return; + if (!cdev->is_peripheral) + return; + + m_can_write(cdev, M_CAN_TXBAR, cdev->tx_peripheral_submit); + cdev->tx_peripheral_submit = 0; +} + static void m_can_tx_work_queue(struct work_struct *ws) { struct m_can_tx_op *op = container_of(ws, struct m_can_tx_op, work); @@ -1834,11 +1853,15 @@ static void m_can_tx_work_queue(struct work_struct *ws) op->skb = NULL; m_can_tx_handler(cdev, skb); + if (op->submit) + m_can_tx_submit(cdev); } -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 = skb; + cdev->tx_ops[cdev->next_tx_op].submit = submit; queue_work(cdev->tx_wq, &cdev->tx_ops[cdev->next_tx_op].work); ++cdev->next_tx_op; @@ -1850,6 +1873,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; if (cdev->can.state == CAN_STATE_BUS_OFF) { m_can_clean(cdev->net); @@ -1860,7 +1884,15 @@ static netdev_tx_t m_can_start_peripheral_xmit(struct m_can_classdev *cdev, if (err != NETDEV_TX_OK) return err; - m_can_tx_queue_skb(cdev, skb); + ++cdev->nr_txs_without_submit; + if (cdev->nr_txs_without_submit >= cdev->tx_max_coalesced_frames || + !netdev_xmit_more()) { + cdev->nr_txs_without_submit = 0; + submit = true; + } else { + submit = false; + } + m_can_tx_queue_skb(cdev, skb, submit); return NETDEV_TX_OK; } @@ -1992,6 +2024,7 @@ static int m_can_get_coalesce(struct net_device *dev, ec->rx_max_coalesced_frames_irq = cdev->rx_max_coalesced_frames_irq; ec->rx_coalesce_usecs_irq = cdev->rx_coalesce_usecs_irq; + ec->tx_max_coalesced_frames = cdev->tx_max_coalesced_frames; ec->tx_max_coalesced_frames_irq = cdev->tx_max_coalesced_frames_irq; ec->tx_coalesce_usecs_irq = cdev->tx_coalesce_usecs_irq; @@ -2036,6 +2069,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 != 0 && ec->tx_coalesce_usecs_irq != 0 && ec->rx_coalesce_usecs_irq != 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", @@ -2046,6 +2091,7 @@ static int m_can_set_coalesce(struct net_device *dev, cdev->rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq; cdev->rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; + cdev->tx_max_coalesced_frames = ec->tx_max_coalesced_frames; cdev->tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq; cdev->tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; @@ -2063,6 +2109,7 @@ static const struct ethtool_ops m_can_ethtool_ops = { .supported_coalesce_params = 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 = ethtool_op_get_ts_info, .get_coalesce = 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; }; 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; @@ -117,6 +119,10 @@ struct m_can_classdev { int tx_fifo_size; int next_tx_op; + 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]; };