From: Marc Kleine-Budde <mkl@pengutronix.de>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, kuba@kernel.org, linux-can@vger.kernel.org,
kernel@pengutronix.de, Marc Kleine-Budde <mkl@pengutronix.de>,
Alibek Omarov <a1ba.omarov@gmail.com>,
Heiko Stuebner <heiko@sntech.de>
Subject: [PATCH net-next 12/20] can: rockchip_canfd: implement workaround for erratum 6
Date: Wed, 4 Sep 2024 11:38:47 +0200 [thread overview]
Message-ID: <20240904094218.1925386-13-mkl@pengutronix.de> (raw)
In-Reply-To: <20240904094218.1925386-1-mkl@pengutronix.de>
The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
says:
| The CAN controller's transmission of extended frames may
| intermittently change into standard frames.
|
| When using the CAN controller to send extended frames, if the
| 'tx_req' is configured as 1 and coincides with the internal
| transmission point, the extended frame will be transmitted onto the
| bus in the format of a standard frame.
To work around Erratum 6, the driver is in self-receiving mode (RXSTX)
and all received CAN frames are passed through rkcanfd_rxstx_filter().
Add a check in rkcanfd_rxstx_filter() whether the received frame
corresponds to the current outgoing frame, but the extended CAN ID has
been mangled to a standard ID. In this case re-send the original CAN
frame.
Tested-by: Alibek Omarov <a1ba.omarov@gmail.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20240904-rockchip-canfd-v5-12-8ae22bcb27cc@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/rockchip/rockchip_canfd-rx.c | 44 ++++++++++++++++++++
drivers/net/can/rockchip/rockchip_canfd-tx.c | 8 ++++
drivers/net/can/rockchip/rockchip_canfd.h | 19 +++++++++
3 files changed, 71 insertions(+)
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 650dfd41e0a0..31cee3362f1e 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -95,6 +95,7 @@ static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
const struct canfd_frame *cfd_rx, const u32 ts,
bool *tx_done)
{
+ struct net_device_stats *stats = &priv->ndev->stats;
const struct canfd_frame *cfd_nominal;
const struct sk_buff *skb;
unsigned int tx_tail;
@@ -130,6 +131,49 @@ static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
return 0;
}
+ if (!(priv->devtype_data.quirks & RKCANFD_QUIRK_RK3568_ERRATUM_6))
+ return 0;
+
+ /* Erratum 6: Extended frames may be send as standard frames.
+ *
+ * Not affected if:
+ * - TX'ed a standard frame -or-
+ * - RX'ed an extended frame
+ */
+ if (!(cfd_nominal->can_id & CAN_EFF_FLAG) ||
+ (cfd_rx->can_id & CAN_EFF_FLAG))
+ return 0;
+
+ /* Not affected if:
+ * - standard part and RTR flag of the TX'ed frame
+ * is not equal the CAN-ID and RTR flag of the RX'ed frame.
+ */
+ if ((cfd_nominal->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK)) !=
+ (cfd_rx->can_id & (CAN_RTR_FLAG | CAN_SFF_MASK)))
+ return 0;
+
+ /* Not affected if:
+ * - length is not the same
+ */
+ if (cfd_nominal->len != cfd_rx->len)
+ return 0;
+
+ /* Not affected if:
+ * - the data of non RTR frames is different
+ */
+ if (!(cfd_nominal->can_id & CAN_RTR_FLAG) &&
+ memcmp(cfd_nominal->data, cfd_rx->data, cfd_nominal->len))
+ return 0;
+
+ /* Affected by Erratum 6 */
+
+ *tx_done = true;
+
+ stats->tx_packets++;
+ stats->tx_errors++;
+
+ rkcanfd_xmit_retry(priv);
+
return 0;
}
diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
index 668a902f4c2a..e98e7a836b83 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
@@ -14,6 +14,14 @@ static void rkcanfd_start_xmit_write_cmd(const struct rkcanfd_priv *priv,
rkcanfd_write(priv, RKCANFD_REG_CMD, reg_cmd);
}
+void rkcanfd_xmit_retry(struct rkcanfd_priv *priv)
+{
+ const unsigned int tx_head = rkcanfd_get_tx_head(priv);
+ const u32 reg_cmd = RKCANFD_REG_CMD_TX_REQ(tx_head);
+
+ rkcanfd_start_xmit_write_cmd(priv, reg_cmd);
+}
+
int rkcanfd_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct rkcanfd_priv *priv = netdev_priv(ndev);
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index a4688411e586..3fe6ddcdd8ac 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -342,6 +342,24 @@
/* Erratum 6: The CAN controller's transmission of extended frames may
* intermittently change into standard frames
+ *
+ * Work around this issue by activating self reception (RXSTX). If we
+ * have pending TX CAN frames, check all RX'ed CAN frames in
+ * rkcanfd_rxstx_filter().
+ *
+ * If it's a frame we've send and it's OK, call the TX complete
+ * handler: rkcanfd_handle_tx_done_one(). Mask the TX complete IRQ.
+ *
+ * If it's a frame we've send, but the CAN-ID is mangled, resend the
+ * original extended frame.
+ *
+ * To reproduce:
+ * host:
+ * canfdtest -evx -g can0
+ * candump any,0:80000000 -cexdtA
+ * dut:
+ * canfdtest -evx can0
+ * ethtool -S can0
*/
#define RKCANFD_QUIRK_RK3568_ERRATUM_6 BIT(5)
@@ -499,6 +517,7 @@ int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv);
void rkcanfd_timestamp_init(struct rkcanfd_priv *priv);
+void rkcanfd_xmit_retry(struct rkcanfd_priv *priv);
int rkcanfd_start_xmit(struct sk_buff *skb, struct net_device *ndev);
void rkcanfd_handle_tx_done_one(struct rkcanfd_priv *priv, const u32 ts,
unsigned int *frame_len_p);
--
2.45.2
next prev parent reply other threads:[~2024-09-04 9:42 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-04 9:38 [PATCH net-next 0/20] pull-request: can-next 2024-09-04 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 01/20] dt-bindings: can: rockchip_canfd: add rockchip CAN-FD controller Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 02/20] arm64: dts: rockchip: add CAN-FD controller nodes to rk3568 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 03/20] arm64: dts: rockchip: mecsbc: add CAN0 and CAN1 interfaces Marc Kleine-Budde
2024-09-04 11:51 ` Krzysztof Kozlowski
2024-09-04 11:57 ` Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 04/20] can: rockchip_canfd: add driver for Rockchip CAN-FD controller Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 05/20] can: rockchip_canfd: add quirks for errata workarounds Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 06/20] can: rockchip_canfd: add quirk for broken CAN-FD support Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 07/20] can: rockchip_canfd: add support for rk3568v3 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 08/20] can: rockchip_canfd: add notes about known issues Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 09/20] can: rockchip_canfd: rkcanfd_handle_rx_int_one(): implement workaround for erratum 5: check for empty FIFO Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 10/20] can: rockchip_canfd: rkcanfd_register_done(): add warning for erratum 5 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 11/20] can: rockchip_canfd: add TX PATH Marc Kleine-Budde
2024-09-04 9:38 ` Marc Kleine-Budde [this message]
2024-09-04 9:38 ` [PATCH net-next 13/20] can: rockchip_canfd: implement workaround for erratum 12 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 14/20] can: rockchip_canfd: rkcanfd_get_berr_counter_corrected(): work around broken {RX,TX}ERRORCNT register Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 15/20] can: rockchip_canfd: add stats support for errata workarounds Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 16/20] can: rockchip_canfd: prepare to use full TX-FIFO depth Marc Kleine-Budde
2024-09-04 16:13 ` Christoph Fritz
2024-09-05 6:35 ` Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 17/20] can: rockchip_canfd: enable full TX-FIFO depth of 2 Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 18/20] can: rockchip_canfd: add hardware timestamping support Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 19/20] can: rockchip_canfd: add support for CAN_CTRLMODE_LOOPBACK Marc Kleine-Budde
2024-09-04 9:38 ` [PATCH net-next 20/20] can: rockchip_canfd: add support for CAN_CTRLMODE_BERR_REPORTING Marc Kleine-Budde
2024-09-04 12:56 ` [PATCH net-next 0/20] pull-request: can-next 2024-09-04 Marc Kleine-Budde
2024-09-04 13:04 ` Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240904094218.1925386-13-mkl@pengutronix.de \
--to=mkl@pengutronix.de \
--cc=a1ba.omarov@gmail.com \
--cc=davem@davemloft.net \
--cc=heiko@sntech.de \
--cc=kernel@pengutronix.de \
--cc=kuba@kernel.org \
--cc=linux-can@vger.kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox