Message ID | 20230125195059.630377-9-msp@baylibre.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp456216wrn; Wed, 25 Jan 2023 11:52:21 -0800 (PST) X-Google-Smtp-Source: AMrXdXv40cmEv/el0rXa0Rsi41iWBhjMAA5Zi7065HND0ypm994t9ZYcwW0vStsJP1BXLIYo+UDd X-Received: by 2002:a17:902:ce0b:b0:194:9b4e:1c90 with SMTP id k11-20020a170902ce0b00b001949b4e1c90mr36397939plg.57.1674676340826; Wed, 25 Jan 2023 11:52:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674676340; cv=none; d=google.com; s=arc-20160816; b=Kd50+NRqwNGt1cEpXZruDj1xp619UM1iMPKA9zalI5lc76lihGXrX/o81P1yfhc2yC QNZAABgh370i2FGid0uxx9QEWgaE7r9AxDyBTD3RAibeYIWLneuUXSlWNfuacXbXzi4C k6ZumcN20yg9nLEORpIVZPhxlJ7K+gVnduWACZm/nYFwkJ8qOkCSP8tyHdunQpIgR4si gDr1cXKyY4kKV0AtQji6dC6BRHTiZXgykQG3Uefv1DD7EqjDWmWrSeJaY273qQuljAOj egNp86UfxRmKiEulKznPsAvkvhat2hOrOyy9v6oLpAu2quoENSDXDu6JnFHo672B3FPF pLww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gfSXrRwfX7neDYk1hRvs3xyY0TSXIO6TaVWNzYTFpJg=; b=Th3yQq+a+0xjaRW1bMOO8GBYHoPvYJuTkbdTrLrfYNj3QSSkXArwwZsh9/U+CUuoIQ PyTsJPQhv+xTQ+MIqYvQuezhEzhGZMotD/BSlIUD8Z8KL/Iy4DadBP8/ESozdDaYGvGg qoNirdPR0n5g5iAZ4/0mLjCTLl40CStyJokkvU0jhoyhLwTNxePwm3WIvVsJJAWjXWFS pip6eGA+kkPtZsYh5HRjFEMUvd4mHgIUIxXalWIjyWK5z5oN2wfDbi2vfJwq8RrwnOBS AjHkEItsjSVei45I+SfqlHJ7clQDDjpnRCIxwYl4IywZXPFje5LGiUOU5/g/o0MzLWA9 Cq/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=scmdglR0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b8-20020a170903228800b0016efde92292si7206989plh.255.2023.01.25.11.52.09; Wed, 25 Jan 2023 11:52:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20210112.gappssmtp.com header.s=20210112 header.b=scmdglR0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235840AbjAYTvl (ORCPT <rfc822;lekhanya01809@gmail.com> + 99 others); Wed, 25 Jan 2023 14:51:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235836AbjAYTv2 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 25 Jan 2023 14:51:28 -0500 Received: from mail-ej1-x634.google.com (mail-ej1-x634.google.com [IPv6:2a00:1450:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F18DA599B5 for <linux-kernel@vger.kernel.org>; Wed, 25 Jan 2023 11:51:12 -0800 (PST) Received: by mail-ej1-x634.google.com with SMTP id kt14so50660844ejc.3 for <linux-kernel@vger.kernel.org>; Wed, 25 Jan 2023 11:51:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20210112.gappssmtp.com; s=20210112; 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=gfSXrRwfX7neDYk1hRvs3xyY0TSXIO6TaVWNzYTFpJg=; b=scmdglR0kK6ToTgqQkU66fxS6xXrLK/8Z7gJfs3aCCx5gPWsq8u+p0MvW28eWc+aXq MJltcF7XaZBxK5C3wJ6SFp9gehas5nOhwaBIKXbUeE8u+3t7RkwpPO/YW9BY27ETA6D7 WycJ84fgNAy+8iKl0z3rRm/9dfBkZV0VZCFO9uhn5wpguZc8IYV/InkMWwG0070ipcPZ lCZSWQsFS6vbEdgcNOs+ostp36ajh0pFB2SqR207lb8G7CjzrP9QgItNXdQWFaDJ0bwY 7ssoeGE5MqD9EhcepVfA2k1lbeLCqSxaDO8P4n0mVBq8wsDluKTznWPsdoSM5Z2J7R7B QWHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=gfSXrRwfX7neDYk1hRvs3xyY0TSXIO6TaVWNzYTFpJg=; b=Qm77yU/JyS7WDpLf0QsG0/7Ten1wPQJwWo9Ua6ssNWrEhdd4YPKuoo3PFh+wHZleB+ z9y7BaOn4FQAlGPQxX+X+0xKJP1DBfPdarE9qdYWGem/e91le/3IZJDvR++8GJNiiAYl 21j1sN3h1g+h3VfqMuaFAiT5+PH4Jjke0PFNlorlvPocos7heWAqGhrumNmBNyiWzE6P Ul/NI6sUOtyO3JmCpDaw/zsf6aWxUAdAMgESaaehxEsdIWrZZWy5UEXbkVSTYPYgIzB6 k/IgPJmRdJYvtsTzkYM3NeIaFoSzqC4dKTmEgMnVRCMsndAfhDHAuOcVPeQxg0PDuiWw 7Zow== X-Gm-Message-State: AFqh2kqnQb4s7oBihV497+bCIfEsYJoR7OUVd4R9fR5QO70pZR9281nm QoO1Ct97lxTgZAT2jKV6uDRpEw== X-Received: by 2002:a17:907:6a98:b0:855:2c8e:ad52 with SMTP id ri24-20020a1709076a9800b008552c8ead52mr27221046ejc.29.1674676271506; Wed, 25 Jan 2023 11:51:11 -0800 (PST) Received: from blmsp.fritz.box ([2001:4091:a247:815f:ef74:e427:628a:752c]) by smtp.gmail.com with ESMTPSA id s15-20020a170906454f00b00872c0bccab2sm2778830ejq.35.2023.01.25.11.51.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Jan 2023 11:51:11 -0800 (PST) From: Markus Schneider-Pargmann <msp@baylibre.com> To: Marc Kleine-Budde <mkl@pengutronix.de>, Chandrasekar Ramakrishnan <rcsekar@samsung.com>, Wolfgang Grandegger <wg@grandegger.com> Cc: Vincent MAILHOL <mailhol.vincent@wanadoo.fr>, linux-can@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Markus Schneider-Pargmann <msp@baylibre.com> Subject: [PATCH v2 08/18] can: m_can: Write transmit header and data in one transaction Date: Wed, 25 Jan 2023 20:50:49 +0100 Message-Id: <20230125195059.630377-9-msp@baylibre.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125195059.630377-1-msp@baylibre.com> References: <20230125195059.630377-1-msp@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756025418723167502?= X-GMAIL-MSGID: =?utf-8?q?1756025418723167502?= |
Series |
can: m_can: Optimizations for m_can/tcan part 2
|
|
Commit Message
Markus Schneider-Pargmann
Jan. 25, 2023, 7:50 p.m. UTC
Combine header and data before writing to the transmit fifo to reduce
the overhead for peripheral chips.
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
---
drivers/net/can/m_can/m_can.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
Comments
On Wed, Jan 25, 2023 at 08:50:49PM +0100, Markus Schneider-Pargmann wrote: > Combine header and data before writing to the transmit fifo to reduce > the overhead for peripheral chips. > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > --- > drivers/net/can/m_can/m_can.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > index 78f6ed744c36..440bc0536951 100644 > --- a/drivers/net/can/m_can/m_can.c > +++ b/drivers/net/can/m_can/m_can.c > @@ -1681,6 +1681,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > m_can_write(cdev, M_CAN_TXBAR, 0x1); > /* End of xmit function for version 3.0.x */ > } else { > + char buf[TXB_ELEMENT_SIZE]; > /* Transmit routine for version >= v3.1.x */ > > txfqs = m_can_read(cdev, M_CAN_TXFQS); > @@ -1720,12 +1721,11 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > fifo_header.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; > + memcpy(buf, &fifo_header, 8); > + memcpy(&buf[8], &cf->data, cf->len); > > - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, > - cf->data, DIV_ROUND_UP(cf->len, 4)); > + err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, > + buf, 8 + DIV_ROUND_UP(cf->len, 4)); Perhaps I am missing something here, but my reading is that: - 8 is a length in bytes - the 5th argument to m_can_fifo_write is the val_count parameter, whose unit is 4-byte long values. By this logic, perhaps the correct value for this argument is: DIV_ROUND_UP(8 + cf->len, 4) Also: - If cf->len is not a multiple of 4, is there a possibility that uninitialised trailing data in buf will be used indirectly by m_can_fifo_write()? > if (err) > goto out_fail; > > -- > 2.39.0 >
Hi Simon, On Thu, Jan 26, 2023 at 09:04:56AM +0100, Simon Horman wrote: > On Wed, Jan 25, 2023 at 08:50:49PM +0100, Markus Schneider-Pargmann wrote: > > Combine header and data before writing to the transmit fifo to reduce > > the overhead for peripheral chips. > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > --- > > drivers/net/can/m_can/m_can.c | 10 +++++----- > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > > index 78f6ed744c36..440bc0536951 100644 > > --- a/drivers/net/can/m_can/m_can.c > > +++ b/drivers/net/can/m_can/m_can.c > > @@ -1681,6 +1681,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > m_can_write(cdev, M_CAN_TXBAR, 0x1); > > /* End of xmit function for version 3.0.x */ > > } else { > > + char buf[TXB_ELEMENT_SIZE]; > > /* Transmit routine for version >= v3.1.x */ > > > > txfqs = m_can_read(cdev, M_CAN_TXFQS); > > @@ -1720,12 +1721,11 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > fifo_header.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; > > + memcpy(buf, &fifo_header, 8); > > + memcpy(&buf[8], &cf->data, cf->len); > > > > - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, > > - cf->data, DIV_ROUND_UP(cf->len, 4)); > > + err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, > > + buf, 8 + DIV_ROUND_UP(cf->len, 4)); > > Perhaps I am missing something here, but my reading is that: > > - 8 is a length in bytes > - the 5th argument to m_can_fifo_write is the val_count parameter, > whose unit is 4-byte long values. > > By this logic, perhaps the correct value for this argument is: > > DIV_ROUND_UP(8 + cf->len, 4) Thank you for spotting this. You are totally right, I will fix it for the next version. > > Also: > > - If cf->len is not a multiple of 4, is there a possibility > that uninitialised trailing data in buf will be used > indirectly by m_can_fifo_write()? Good point. I think this can only happen for 1, 2, 3, 5, 6, 7 bytes, values above have to be multiple of 4 because of the CAN-FD specification. With 'buf' it should read garbage from the buffer which I think is not a problem as the chip knows how much of the data to use. Also the tx elemnt size is hardcoded to 64 byte in the driver, so we do not overwrite the next element with that. The chip minimum size is 8 bytes for the data field anyways. So I think this is fine. Thanks, Markus > > > if (err) > > goto out_fail; > > > > -- > > 2.39.0 > >
On Mon, Jan 30, 2023 at 09:04:19AM +0100, Markus Schneider-Pargmann wrote: > Hi Simon, > > On Thu, Jan 26, 2023 at 09:04:56AM +0100, Simon Horman wrote: > > On Wed, Jan 25, 2023 at 08:50:49PM +0100, Markus Schneider-Pargmann wrote: > > > Combine header and data before writing to the transmit fifo to reduce > > > the overhead for peripheral chips. > > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > > --- > > > drivers/net/can/m_can/m_can.c | 10 +++++----- > > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > > > index 78f6ed744c36..440bc0536951 100644 > > > --- a/drivers/net/can/m_can/m_can.c > > > +++ b/drivers/net/can/m_can/m_can.c > > > @@ -1681,6 +1681,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > > m_can_write(cdev, M_CAN_TXBAR, 0x1); > > > /* End of xmit function for version 3.0.x */ > > > } else { > > > + char buf[TXB_ELEMENT_SIZE]; > > > /* Transmit routine for version >= v3.1.x */ > > > > > > txfqs = m_can_read(cdev, M_CAN_TXFQS); > > > @@ -1720,12 +1721,11 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > > fifo_header.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; > > > + memcpy(buf, &fifo_header, 8); > > > + memcpy(&buf[8], &cf->data, cf->len); > > > > > > - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, > > > - cf->data, DIV_ROUND_UP(cf->len, 4)); > > > + err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, > > > + buf, 8 + DIV_ROUND_UP(cf->len, 4)); > > > > Perhaps I am missing something here, but my reading is that: > > > > - 8 is a length in bytes > > - the 5th argument to m_can_fifo_write is the val_count parameter, > > whose unit is 4-byte long values. > > > > By this logic, perhaps the correct value for this argument is: > > > > DIV_ROUND_UP(8 + cf->len, 4) > > Thank you for spotting this. You are totally right, I will fix it for > the next version. Thanks. > > Also: > > > > - If cf->len is not a multiple of 4, is there a possibility > > that uninitialised trailing data in buf will be used > > indirectly by m_can_fifo_write()? > > Good point. I think this can only happen for 1, 2, 3, 5, 6, 7 bytes, > values above have to be multiple of 4 because of the CAN-FD > specification. > > With 'buf' it should read garbage from the buffer which I think is not a > problem as the chip knows how much of the data to use. Also the tx > elemnt size is hardcoded to 64 byte in the driver, so we do not overwrite > the next element with that. The chip minimum size is 8 bytes for the > data field anyways. So I think this is fine. I'm not the expert on the hw in question here, but intuitively I do feel that it may be unwise to send uninitialised data. While I'm happy to defer to you on this, I do wonder if it would be somehow better to use memcpy_and_pad() in place of memcpy().
Hi Simon, On Sat, Feb 04, 2023 at 02:05:57PM +0100, Simon Horman wrote: > On Mon, Jan 30, 2023 at 09:04:19AM +0100, Markus Schneider-Pargmann wrote: > > Hi Simon, > > > > On Thu, Jan 26, 2023 at 09:04:56AM +0100, Simon Horman wrote: > > > On Wed, Jan 25, 2023 at 08:50:49PM +0100, Markus Schneider-Pargmann wrote: > > > > Combine header and data before writing to the transmit fifo to reduce > > > > the overhead for peripheral chips. > > > > > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > > > --- > > > > drivers/net/can/m_can/m_can.c | 10 +++++----- > > > > 1 file changed, 5 insertions(+), 5 deletions(-) > > > > > > > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > > > > index 78f6ed744c36..440bc0536951 100644 > > > > --- a/drivers/net/can/m_can/m_can.c > > > > +++ b/drivers/net/can/m_can/m_can.c > > > > @@ -1681,6 +1681,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > > > m_can_write(cdev, M_CAN_TXBAR, 0x1); > > > > /* End of xmit function for version 3.0.x */ > > > > } else { > > > > + char buf[TXB_ELEMENT_SIZE]; > > > > /* Transmit routine for version >= v3.1.x */ > > > > > > > > txfqs = m_can_read(cdev, M_CAN_TXFQS); > > > > @@ -1720,12 +1721,11 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) > > > > fifo_header.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; > > > > + memcpy(buf, &fifo_header, 8); > > > > + memcpy(&buf[8], &cf->data, cf->len); > > > > > > > > - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, > > > > - cf->data, DIV_ROUND_UP(cf->len, 4)); > > > > + err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, > > > > + buf, 8 + DIV_ROUND_UP(cf->len, 4)); > > > > > > Perhaps I am missing something here, but my reading is that: > > > > > > - 8 is a length in bytes > > > - the 5th argument to m_can_fifo_write is the val_count parameter, > > > whose unit is 4-byte long values. > > > > > > By this logic, perhaps the correct value for this argument is: > > > > > > DIV_ROUND_UP(8 + cf->len, 4) > > > > Thank you for spotting this. You are totally right, I will fix it for > > the next version. > > Thanks. > > > > Also: > > > > > > - If cf->len is not a multiple of 4, is there a possibility > > > that uninitialised trailing data in buf will be used > > > indirectly by m_can_fifo_write()? > > > > Good point. I think this can only happen for 1, 2, 3, 5, 6, 7 bytes, > > values above have to be multiple of 4 because of the CAN-FD > > specification. > > > > With 'buf' it should read garbage from the buffer which I think is not a > > problem as the chip knows how much of the data to use. Also the tx > > elemnt size is hardcoded to 64 byte in the driver, so we do not overwrite > > the next element with that. The chip minimum size is 8 bytes for the > > data field anyways. So I think this is fine. > > I'm not the expert on the hw in question here, but intuitively > I do feel that it may be unwise to send uninitialised data. > While I'm happy to defer to you on this, I do wonder if it would be somehow > better to use memcpy_and_pad() in place of memcpy(). Thank you, I think it is safe, but memcpy_and_pad seems like a good solution here to make it even safer. Best, Markus
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 78f6ed744c36..440bc0536951 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1681,6 +1681,7 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) m_can_write(cdev, M_CAN_TXBAR, 0x1); /* End of xmit function for version 3.0.x */ } else { + char buf[TXB_ELEMENT_SIZE]; /* Transmit routine for version >= v3.1.x */ txfqs = m_can_read(cdev, M_CAN_TXFQS); @@ -1720,12 +1721,11 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) fifo_header.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; + memcpy(buf, &fifo_header, 8); + memcpy(&buf[8], &cf->data, cf->len); - err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_DATA, - cf->data, DIV_ROUND_UP(cf->len, 4)); + err = m_can_fifo_write(cdev, putidx, M_CAN_FIFO_ID, + buf, 8 + DIV_ROUND_UP(cf->len, 4)); if (err) goto out_fail;