From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B441FC433FE for ; Mon, 16 May 2022 13:58:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244058AbiEPN5c (ORCPT ); Mon, 16 May 2022 09:57:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237808AbiEPNyz (ORCPT ); Mon, 16 May 2022 09:54:55 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7AFB73915D; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id BA982460028; Mon, 16 May 2022 16:48:59 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mcG4Um4CIPgK; Mon, 16 May 2022 16:48:57 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id F214B46001C; Mon, 16 May 2022 16:48:56 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 01/12] can: kvaser_usb_leaf: Fix overread with an invalid command Date: Mon, 16 May 2022 16:47:37 +0300 Message-Id: <20220516134748.3724796-2-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" For command events read from the device, kvaser_usb_leaf_read_bulk_callback() verifies that cmd->len does not exceed the size of the received data, but the actual kvaser_cmd handlers will happily read any kvaser_cmd fields without checking for cmd->len. This can cause an overread if the last cmd in the buffer is shorter than expected for the command type (with cmd->len showing the actual short size). Maximum overread seems to be 22 bytes (CMD_LEAF_LOG_MESSAGE), some of which are delivered to userspace as-is. Fix that by verifying the length of command before handling it. This issue can only occur after RX URBs have been set up, i.e. the interface has been opened at least once. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- A simpler option would be to just zero-pad the data into a stack-allocated struct kvaser_cmd without knowledge of the needed minimum size (so no tables needed), though that would mean incomplete commands would get passed on silently. .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index c805b999c543..d9f40b9702a5 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -320,6 +320,38 @@ struct kvaser_cmd { } u; } __packed; =20 +#define CMD_SIZE_ANY 0xff +#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field) + +static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] =3D { + [CMD_START_CHIP_REPLY] =3D kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] =3D kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] =3D kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] =3D kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] =3D kvaser_fsize(u.leaf.softinfo), + [CMD_RX_STD_MESSAGE] =3D kvaser_fsize(u.leaf.rx_can), + [CMD_RX_EXT_MESSAGE] =3D kvaser_fsize(u.leaf.rx_can), + [CMD_LEAF_LOG_MESSAGE] =3D kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] =3D kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] =3D kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] =3D CMD_SIZE_ANY, +}; + +static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] =3D { + [CMD_START_CHIP_REPLY] =3D kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] =3D kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] =3D kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] =3D kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] =3D kvaser_fsize(u.usbcan.softinfo), + [CMD_RX_STD_MESSAGE] =3D kvaser_fsize(u.usbcan.rx_can), + [CMD_RX_EXT_MESSAGE] =3D kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] =3D kvaser_fsize(u.usbcan.chip_state_event), + [CMD_CAN_ERROR_EVENT] =3D kvaser_fsize(u.usbcan.error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] =3D CMD_SIZE_ANY, +}; + /* Summary of a kvaser error event, for a unified Leaf/Usbcan error * handling. Some discrepancies between the two families exist: * @@ -387,6 +419,43 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf= _dev_cfg_32mhz =3D { .bittiming_const =3D &kvaser_usb_leaf_bittiming_const, }; =20 +static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + /* buffer size >=3D cmd->len ensured by caller */ + u8 min_size =3D 0; + + switch (dev->card_data.leaf.family) { + case KVASER_LEAF: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf)) + min_size =3D kvaser_usb_leaf_cmd_sizes_leaf[cmd->id]; + break; + case KVASER_USBCAN: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan)) + min_size =3D kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id]; + break; + } + + if (min_size =3D=3D CMD_SIZE_ANY) + return 0; + + if (min_size) { + min_size +=3D CMD_HEADER_LEN; + if (cmd->len >=3D min_size) + return 0; + + dev_err_ratelimited(&dev->intf->dev, + "Received command %u too short (size %u, needed %u)", + cmd->id, cmd->len, min_size); + return -EIO; + } + + dev_warn_ratelimited(&dev->intf->dev, + "Unhandled command (%d, size %d)\n", + cmd->id, cmd->len); + return -EINVAL; +} + static void * kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, const struct sk_buff *skb, int *cmd_len, @@ -492,6 +561,9 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser= _usb *dev, u8 id, end: kfree(buf); =20 + if (err =3D=3D 0) + err =3D kvaser_usb_leaf_verify_size(dev, cmd); + return err; } =20 @@ -1113,6 +1185,9 @@ static void kvaser_usb_leaf_stop_chip_reply(const str= uct kvaser_usb *dev, static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { + if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) + return; + switch (cmd->id) { case CMD_START_CHIP_REPLY: kvaser_usb_leaf_start_chip_reply(dev, cmd); --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8BD5DC433EF for ; Mon, 16 May 2022 13:55:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230071AbiEPNzR (ORCPT ); Mon, 16 May 2022 09:55:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50804 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240151AbiEPNyi (ORCPT ); Mon, 16 May 2022 09:54:38 -0400 X-Greylist: delayed 332 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Mon, 16 May 2022 06:54:35 PDT Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31065BE27; Mon, 16 May 2022 06:54:35 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 73FA7460008; Mon, 16 May 2022 16:48:59 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id s0_L6yP0QX6T; Mon, 16 May 2022 16:48:57 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 042AE460028; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 02/12] can: kvaser_usb: Fix use of uninitialized completion Date: Mon, 16 May 2022 16:47:38 +0300 Message-Id: <20220516134748.3724796-3-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" flush_comp is initialized when CMD_FLUSH_QUEUE is sent to the device and completed when the device sends CMD_FLUSH_QUEUE_RESP. This causes completion of uninitialized completion if the device sends CMD_FLUSH_QUEUE_RESP before CMD_FLUSH_QUEUE is ever sent (e.g. as a response to a flush by a previously bound driver, or a misbehaving device). Fix that by initializing flush_comp in kvaser_usb_init_one() like the other completions. This issue is only triggerable after RX URBs have been set up, i.e. the interface has been opened at least once. Fixes: aec5fb2268b7 ("can: kvaser_usb: Add support for Kvaser USB hydra fam= ily") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 1 + drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_core.c index e67658b53d02..47bff40c36b6 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -673,6 +673,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, init_usb_anchor(&priv->tx_submitted); init_completion(&priv->start_comp); init_completion(&priv->stop_comp); + init_completion(&priv->flush_comp); priv->can.ctrlmode_supported =3D 0; =20 priv->dev =3D dev; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/ne= t/can/usb/kvaser_usb/kvaser_usb_hydra.c index a26823c5b62a..4e90a4b7f95a 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -1910,7 +1910,7 @@ static int kvaser_usb_hydra_flush_queue(struct kvaser= _usb_net_priv *priv) { int err; =20 - init_completion(&priv->flush_comp); + reinit_completion(&priv->flush_comp); =20 err =3D kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE, priv->channel); --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DFC6C433FE for ; Mon, 16 May 2022 13:57:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236640AbiEPN5S (ORCPT ); Mon, 16 May 2022 09:57:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243829AbiEPNy5 (ORCPT ); Mon, 16 May 2022 09:54:57 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6FD439168; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 25FBA46001C; Mon, 16 May 2022 16:49:00 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SMTyPmk-8PsC; Mon, 16 May 2022 16:48:57 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 1A31D46002A; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 03/12] can: kvaser_usb: Fix possible completions during init_completion Date: Mon, 16 May 2022 16:47:39 +0300 Message-Id: <20220516134748.3724796-4-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" kvaser_usb uses completions to signal when a response event is received for outgoing commands. However, it uses init_completion() to reinitialize the start_comp and stop_comp completions before sending the start/stop commands. In case the device sends the corresponding response just before the actual command is sent, complete() may be called concurrently with init_completion() which is not safe. This might be triggerable even with a properly functioning device by stopping the interface (CMD_STOP_CHIP) just after it goes bus-off (which also causes the driver to send CMD_STOP_CHIP when restart-ms is off), but that was not tested. Fix the issue by using reinit_completion() instead. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 4 ++-- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/ne= t/can/usb/kvaser_usb/kvaser_usb_hydra.c index 4e90a4b7f95a..b0094f162964 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -1869,7 +1869,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_= usb_net_priv *priv) { int err; =20 - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); =20 err =3D kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ, priv->channel); @@ -1887,7 +1887,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_u= sb_net_priv *priv) { int err; =20 - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); =20 /* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT * see comment in kvaser_usb_hydra_update_state() diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index d9f40b9702a5..09ade66256b2 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -1300,7 +1300,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_u= sb_net_priv *priv) { int err; =20 - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); =20 err =3D kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP, priv->channel); @@ -1318,7 +1318,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_us= b_net_priv *priv) { int err; =20 - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); =20 err =3D kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP, priv->channel); --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88A4FC433EF for ; Mon, 16 May 2022 13:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244008AbiEPNzf (ORCPT ); Mon, 16 May 2022 09:55:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240567AbiEPNyi (ORCPT ); Mon, 16 May 2022 09:54:38 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33C74377CE; Mon, 16 May 2022 06:54:35 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 8FCA846002A; Mon, 16 May 2022 16:49:01 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mtDHU4i6qgiO; Mon, 16 May 2022 16:48:59 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 2605A46002B; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 04/12] can: kvaser_usb: Mark Mini PCIe 2xHS as supporting error counters Date: Mon, 16 May 2022 16:47:40 +0300 Message-Id: <20220516134748.3724796-5-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The 0bfd:0124 Kvaser Mini PCI Express 2xHS (FW 4.18.778) seems to support TX/RX error counters in exactly the same way (via unsolicited cmd 106 on bus errors and via cmd 20 when queried with cmd 19) as 0bfd:0017 Kvaser Memorator Professional HS/HS (FW 2.0.50), but only the latter has KVASER_USB_HAS_TXRX_ERRORS set to enable do_get_berr_counter(). Enable error counter retrieval for Kvaser Mini PCI Express 2xHS, too. Fixes: 71873a9b38d1 ("can: kvaser_usb: Add support for more Kvaser Leaf v2 = devices") Signed-off-by: Anssi Hannula Reported-by: Anssi Hannula --- I'm not really sure what KVASER_USB_HAS_TXRX_ERRORS means, exactly, w.r.t. device behavior, though, i.e. how does a device without it behave. drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_core.c index 47bff40c36b6..7388fdca9079 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -165,7 +165,8 @@ static const struct usb_device_id kvaser_usb_table[] = =3D { { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), + .driver_info =3D KVASER_USB_HAS_TXRX_ERRORS }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) }, --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D588C433F5 for ; Mon, 16 May 2022 13:57:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234702AbiEPN52 (ORCPT ); Mon, 16 May 2022 09:57:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243931AbiEPNy7 (ORCPT ); Mon, 16 May 2022 09:54:59 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D53D39170; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id BB5CA46002B; Mon, 16 May 2022 16:49:01 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RXJB4ho_p1Zw; Mon, 16 May 2022 16:48:59 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 2D4A746002C; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 05/12] can: kvaser_usb_leaf: Set Warning state even without bus errors Date: Mon, 16 May 2022 16:47:41 +0300 Message-Id: <20220516134748.3724796-6-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" kvaser_usb_leaf_rx_error_update_can_state() sets error state according to error counters when the hardware does not indicate a specific state directly. However, this is currently gated behind a check for M16C_STATE_BUS_ERROR which does not always seem to be set when error counters are increasing, and may not be set when error counters are decreasing. This causes the CAN_STATE_ERROR_WARNING state to not be set in some cases even when appropriate. Change the code to set error state from counters even without M16C_STATE_BUS_ERROR. The Error-Passive case seems superfluous as it is already set via M16C_STATE_BUS_PASSIVE flag above, but it is kept for now. Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 09ade66256b2..d7f2d64a8083 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -775,20 +775,16 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvas= er_usb_net_priv *priv, new_state =3D CAN_STATE_BUS_OFF; } else if (es->status & M16C_STATE_BUS_PASSIVE) { new_state =3D CAN_STATE_ERROR_PASSIVE; - } else if (es->status & M16C_STATE_BUS_ERROR) { + } else if ((es->status & M16C_STATE_BUS_ERROR) && + cur_state >=3D CAN_STATE_BUS_OFF) { /* Guard against spurious error events after a busoff */ - if (cur_state < CAN_STATE_BUS_OFF) { - if (es->txerr >=3D 128 || es->rxerr >=3D 128) - new_state =3D CAN_STATE_ERROR_PASSIVE; - else if (es->txerr >=3D 96 || es->rxerr >=3D 96) - new_state =3D CAN_STATE_ERROR_WARNING; - else if (cur_state > CAN_STATE_ERROR_ACTIVE) - new_state =3D CAN_STATE_ERROR_ACTIVE; - } - } - - if (!es->status) + } else if (es->txerr >=3D 128 || es->rxerr >=3D 128) { + new_state =3D CAN_STATE_ERROR_PASSIVE; + } else if (es->txerr >=3D 96 || es->rxerr >=3D 96) { + new_state =3D CAN_STATE_ERROR_WARNING; + } else { new_state =3D CAN_STATE_ERROR_ACTIVE; + } =20 if (new_state !=3D cur_state) { tx_state =3D (es->txerr >=3D es->rxerr) ? new_state : 0; --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DF60C433EF for ; Mon, 16 May 2022 13:57:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244638AbiEPN5P (ORCPT ); Mon, 16 May 2022 09:57:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243834AbiEPNy5 (ORCPT ); Mon, 16 May 2022 09:54:57 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4E573916B; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id EB86646002C; Mon, 16 May 2022 16:49:01 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id mSucQ98qGReJ; Mon, 16 May 2022 16:48:59 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 33AEE46002D; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 06/12] can: kvaser_usb_leaf: Fix TX queue out of sync after restart Date: Mon, 16 May 2022 16:47:42 +0300 Message-Id: <20220516134748.3724796-7-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The TX queue seems to be implicitly flushed by the hardware during bus-off or bus-off recovery, but the driver does not reset the TX bookkeeping. Despite not resetting TX bookkeeping the driver still re-enables TX queue unconditionally, leading to "cannot find free context" / NETDEV_TX_BUSY errors if the TX queue was full at bus-off time. Fix that by resetting TX bookkeeping on CAN restart. Also, add an explicit queue flush in case some hardware versions do not do that implicitly. Tested with 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 ++ drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/= usb/kvaser_usb/kvaser_usb.h index 3a49257f9fa6..f1bea13a3829 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -175,6 +175,8 @@ struct kvaser_usb_dev_cfg { extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; =20 +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); + int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, int *actual_len); =20 diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_core.c index 7388fdca9079..a8d72fb8291a 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -440,7 +440,7 @@ static void kvaser_usb_reset_tx_urb_contexts(struct kva= ser_usb_net_priv *priv) /* This method might sleep. Do not call it in the atomic context * of URB completions. */ -static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) { usb_kill_anchored_urbs(&priv->tx_submitted); kvaser_usb_reset_tx_urb_contexts(priv); diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index d7f2d64a8083..2d30a662edb5 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -1402,6 +1402,12 @@ static int kvaser_usb_leaf_set_mode(struct net_devic= e *netdev, =20 switch (mode) { case CAN_MODE_START: + err =3D kvaser_usb_leaf_flush_queue(priv); + if (err) + return err; + + kvaser_usb_unlink_tx_urbs(priv); + err =3D kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BEC62C43217 for ; Mon, 16 May 2022 13:55:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244044AbiEPNzD (ORCPT ); Mon, 16 May 2022 09:55:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240068AbiEPNyi (ORCPT ); Mon, 16 May 2022 09:54:38 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31508240AF; Mon, 16 May 2022 06:54:35 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 1930246002D; Mon, 16 May 2022 16:49:02 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JZsIOvJJAriA; Mon, 16 May 2022 16:49:00 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 40AE046002E; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 07/12] can: kvaser_usb_leaf: Fix CAN state after restart Date: Mon, 16 May 2022 16:47:43 +0300 Message-Id: <20220516134748.3724796-8-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" can_restart() expects CMD_START_CHIP to set the error state to ERROR_ACTIVE as it calls netif_carrier_on() immediately afterwards. Otherwise the user may immediately trigger restart again and hit a BUG_ON() in can_restart(). Fix kvaser_usb_leaf set_mode(CMD_START_CHIP) to set the expected state. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 2d30a662edb5..5f27c00179c1 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -1411,6 +1411,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device= *netdev, err =3D kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; + + priv->can.state =3D CAN_STATE_ERROR_ACTIVE; break; default: return -EOPNOTSUPP; --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFE53C433EF for ; Mon, 16 May 2022 13:55:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244071AbiEPNzn (ORCPT ); Mon, 16 May 2022 09:55:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234369AbiEPNyu (ORCPT ); Mon, 16 May 2022 09:54:50 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3288126AEA; Mon, 16 May 2022 06:54:35 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 73EB0460031; Mon, 16 May 2022 16:49:04 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qtuwBDk3KX4S; Mon, 16 May 2022 16:49:01 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 47C6546002F; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 08/12] can: kvaser_usb_leaf: Fix improved state not being reported Date: Mon, 16 May 2022 16:47:44 +0300 Message-Id: <20220516134748.3724796-9-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The tested 0bfd:0017 Kvaser Memorator Professional HS/HS FW 2.0.50 and 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 do not seem to send any unsolicited events when error counters decrease or when the device transitions from ERROR_PASSIVE to ERROR_ACTIVE (or WARNING). This causes the interface to e.g. indefinitely stay in the ERROR_PASSIVE state. Fix that by asking for chip state (inc. counters) event every 0.5 secs when error counters are non-zero. Since the driver seems to be prepared for non-error-counter devices (!KVASER_USB_HAS_TXRX_ERRORS) as well, also always poll in ERROR_PASSIVE even if the counters show zero. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 7 +++ .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 18 +++++- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 58 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/= usb/kvaser_usb/kvaser_usb.h index f1bea13a3829..70aa7a9ed35b 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -107,6 +107,9 @@ struct kvaser_usb_net_priv { struct can_priv can; struct can_berr_counter bec; =20 + /* subdriver-specific data */ + void *sub_priv; + struct kvaser_usb *dev; struct net_device *netdev; int channel; @@ -128,6 +131,8 @@ struct kvaser_usb_net_priv { * * @dev_setup_endpoints: setup USB in and out endpoints * @dev_init_card: initialize card + * @dev_init_channel: initialize channel + * @dev_remove_channel: uninitialize channel * @dev_get_software_info: get software info * @dev_get_software_details: get software details * @dev_get_card_info: get card info @@ -149,6 +154,8 @@ struct kvaser_usb_dev_ops { struct can_berr_counter *bec); int (*dev_setup_endpoints)(struct kvaser_usb *dev); int (*dev_init_card)(struct kvaser_usb *dev); + int (*dev_init_channel)(struct kvaser_usb_net_priv *priv); + void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv); int (*dev_get_software_info)(struct kvaser_usb *dev); int (*dev_get_software_details)(struct kvaser_usb *dev); int (*dev_get_card_info)(struct kvaser_usb *dev); diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_core.c index a8d72fb8291a..6a1ebdd9ba85 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -645,6 +645,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_= usb *dev) if (!dev->nets[i]) continue; =20 + if (dev->ops->dev_remove_channel) + dev->ops->dev_remove_channel(dev->nets[i]); + free_candev(dev->nets[i]->netdev); } } @@ -712,17 +715,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, =20 dev->nets[channel] =3D priv; =20 + if (dev->ops->dev_init_channel) { + err =3D dev->ops->dev_init_channel(priv); + if (err) + goto err; + } + err =3D register_candev(netdev); if (err) { dev_err(&dev->intf->dev, "Failed to register CAN device\n"); - free_candev(netdev); - dev->nets[channel] =3D NULL; - return err; + goto err; } =20 netdev_dbg(netdev, "device registered\n"); =20 return 0; + +err: + free_candev(netdev); + dev->nets[channel] =3D NULL; + return err; } =20 static int kvaser_usb_probe(struct usb_interface *intf, diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 5f27c00179c1..abb681808a28 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -21,6 +21,7 @@ #include #include #include +#include =20 #include #include @@ -56,6 +57,7 @@ #define CMD_RX_EXT_MESSAGE 14 #define CMD_TX_EXT_MESSAGE 15 #define CMD_SET_BUS_PARAMS 16 +#define CMD_GET_CHIP_STATE 19 #define CMD_CHIP_STATE_EVENT 20 #define CMD_SET_CTRL_MODE 21 #define CMD_RESET_CHIP 24 @@ -375,6 +377,12 @@ struct kvaser_usb_err_summary { }; }; =20 +struct kvaser_usb_net_leaf_priv { + struct kvaser_usb_net_priv *net; + + struct delayed_work chip_state_req_work; +}; + static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = =3D { .name =3D "kvaser_usb", .tseg1_min =3D KVASER_USB_TSEG1_MIN, @@ -757,6 +765,16 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kva= ser_usb_net_priv *priv, return err; } =20 +static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work) +{ + struct kvaser_usb_net_leaf_priv *leaf =3D + container_of(work, struct kvaser_usb_net_leaf_priv, + chip_state_req_work.work); + struct kvaser_usb_net_priv *priv =3D leaf->net; + + kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE); +} + static void kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, const struct kvaser_usb_err_summary *es, @@ -828,6 +846,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvase= r_usb *dev, struct sk_buff *skb; struct net_device_stats *stats; struct kvaser_usb_net_priv *priv; + struct kvaser_usb_net_leaf_priv *leaf; enum can_state old_state, new_state; =20 if (es->channel >=3D dev->nchannels) { @@ -837,6 +856,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvase= r_usb *dev, } =20 priv =3D dev->nets[es->channel]; + leaf =3D priv->sub_priv; stats =3D &priv->netdev->stats; =20 /* Update all of the CAN interface's state and error counters before @@ -853,6 +873,14 @@ static void kvaser_usb_leaf_rx_error(const struct kvas= er_usb *dev, kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf); new_state =3D priv->can.state; =20 + /* If there are errors, request status updates periodically as we do + * not get automatic notifications of improved state. + */ + if (new_state < CAN_STATE_BUS_OFF && + (es->rxerr || es->txerr || new_state =3D=3D CAN_STATE_ERROR_PASSIVE)) + schedule_delayed_work(&leaf->chip_state_req_work, + msecs_to_jiffies(500)); + skb =3D alloc_can_err_skb(priv->netdev, &cf); if (!skb) { stats->rx_dropped++; @@ -1312,10 +1340,13 @@ static int kvaser_usb_leaf_start_chip(struct kvaser= _usb_net_priv *priv) =20 static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv) { + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; int err; =20 reinit_completion(&priv->stop_comp); =20 + cancel_delayed_work(&leaf->chip_state_req_work); + err =3D kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP, priv->channel); if (err) @@ -1362,6 +1393,31 @@ static int kvaser_usb_leaf_init_card(struct kvaser_u= sb *dev) return 0; } =20 +static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv) +{ + struct kvaser_usb_net_leaf_priv *leaf; + + leaf =3D devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL); + if (!leaf) + return -ENOMEM; + + leaf->net =3D priv; + INIT_DELAYED_WORK(&leaf->chip_state_req_work, + kvaser_usb_leaf_chip_state_req_work); + + priv->sub_priv =3D leaf; + + return 0; +} + +static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *pri= v) +{ + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; + + if (leaf) + cancel_delayed_work_sync(&leaf->chip_state_req_work); +} + static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) { struct kvaser_usb_net_priv *priv =3D netdev_priv(netdev); @@ -1463,6 +1519,8 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_o= ps =3D { .dev_get_berr_counter =3D kvaser_usb_leaf_get_berr_counter, .dev_setup_endpoints =3D kvaser_usb_leaf_setup_endpoints, .dev_init_card =3D kvaser_usb_leaf_init_card, + .dev_init_channel =3D kvaser_usb_leaf_init_channel, + .dev_remove_channel =3D kvaser_usb_leaf_remove_channel, .dev_get_software_info =3D kvaser_usb_leaf_get_software_info, .dev_get_software_details =3D NULL, .dev_get_card_info =3D kvaser_usb_leaf_get_card_info, --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 74FDBC433EF for ; Mon, 16 May 2022 13:57:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244158AbiEPN5I (ORCPT ); Mon, 16 May 2022 09:57:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243948AbiEPNzA (ORCPT ); Mon, 16 May 2022 09:55:00 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1D4E23916F; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 9423846002F; Mon, 16 May 2022 16:49:04 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hShTY1n9AqvL; Mon, 16 May 2022 16:49:01 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 4FA24460030; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 09/12] can: kvaser_usb_leaf: Fix silently failing bus params setup Date: Mon, 16 May 2022 16:47:45 +0300 Message-Id: <20220516134748.3724796-10-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The device may reject bus params with cmd 45, which is an unhandled error event that does not contain any channel reference. In such cases set_bittiming() callback returns 0 so upper levels will think setting bitrate succeeded and proceed with starting the interface with wrong parameters, causing bus errors (the kernel log will have "Unhandled command (45)", though). Fix that by verifying the bus params took hold by reading them back. Also, add a handler for cmd 45 that simply prints out the error. This condition can be triggered on 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 by trying to set bitrate 1300000 and on 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 by trying to set bitrate 1000000. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Reported-by: Anssi Hannula --- Not sure about the best/correct naming for cmd 45. kvaser_usb_hydra calls it CMD_ERROR_EVENT but kvaser_usb_leaf already has CMD_CAN_ERROR_EVENT (kvaser_cmd.u.leaf.error_event) so I made it ctrl_error_event to clearly differentiate it. drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 + .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 2 +- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 108 ++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/= usb/kvaser_usb/kvaser_usb.h index 70aa7a9ed35b..b618ce299dbc 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -182,6 +182,8 @@ struct kvaser_usb_dev_cfg { extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; =20 +int kvaser_usb_setup_rx_urbs(struct kvaser_usb *dev); + void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); =20 int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_core.c index 6a1ebdd9ba85..ff0119c74b49 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -326,7 +326,7 @@ static void kvaser_usb_read_bulk_callback(struct urb *u= rb) } } =20 -static int kvaser_usb_setup_rx_urbs(struct kvaser_usb *dev) +int kvaser_usb_setup_rx_urbs(struct kvaser_usb *dev) { int i, err =3D 0; =20 diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index abb681808a28..7ed2ced8ba08 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -57,6 +57,8 @@ #define CMD_RX_EXT_MESSAGE 14 #define CMD_TX_EXT_MESSAGE 15 #define CMD_SET_BUS_PARAMS 16 +#define CMD_GET_BUS_PARAMS 17 +#define CMD_GET_BUS_PARAMS_REPLY 18 #define CMD_GET_CHIP_STATE 19 #define CMD_CHIP_STATE_EVENT 20 #define CMD_SET_CTRL_MODE 21 @@ -72,6 +74,7 @@ #define CMD_GET_CARD_INFO_REPLY 35 #define CMD_GET_SOFTWARE_INFO 38 #define CMD_GET_SOFTWARE_INFO_REPLY 39 +#define CMD_CTRL_ERROR_EVENT 45 #define CMD_FLUSH_QUEUE 48 #define CMD_TX_ACKNOWLEDGE 50 #define CMD_CAN_ERROR_EVENT 51 @@ -290,6 +293,15 @@ struct leaf_cmd_log_message { u8 data[8]; } __packed; =20 +struct kvaser_cmd_ctrl_error_event { + u8 unknown[2]; + __le16 timestamp[3]; + u8 reserved; + u8 error_code; + __le16 info1; + __le16 info2; +} __packed; + struct kvaser_cmd { u8 len; u8 id; @@ -319,6 +331,7 @@ struct kvaser_cmd { struct kvaser_cmd_tx_can tx_can; struct kvaser_cmd_ctrl_mode ctrl_mode; struct kvaser_cmd_flush_queue flush_queue; + struct kvaser_cmd_ctrl_error_event ctrl_error_event; } u; } __packed; =20 @@ -336,6 +349,8 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] =3D { [CMD_LEAF_LOG_MESSAGE] =3D kvaser_fsize(u.leaf.log_message), [CMD_CHIP_STATE_EVENT] =3D kvaser_fsize(u.leaf.chip_state_event), [CMD_CAN_ERROR_EVENT] =3D kvaser_fsize(u.leaf.error_event), + [CMD_GET_BUS_PARAMS_REPLY] =3D kvaser_fsize(u.busparams), + [CMD_CTRL_ERROR_EVENT] =3D kvaser_fsize(u.ctrl_error_event), /* ignored events: */ [CMD_FLUSH_QUEUE_REPLY] =3D CMD_SIZE_ANY, }; @@ -350,6 +365,8 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] =3D { [CMD_RX_EXT_MESSAGE] =3D kvaser_fsize(u.usbcan.rx_can), [CMD_CHIP_STATE_EVENT] =3D kvaser_fsize(u.usbcan.chip_state_event), [CMD_CAN_ERROR_EVENT] =3D kvaser_fsize(u.usbcan.error_event), + [CMD_GET_BUS_PARAMS_REPLY] =3D kvaser_fsize(u.busparams), + [CMD_CTRL_ERROR_EVENT] =3D kvaser_fsize(u.ctrl_error_event), /* ignored events: */ [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] =3D CMD_SIZE_ANY, }; @@ -380,6 +397,9 @@ struct kvaser_usb_err_summary { struct kvaser_usb_net_leaf_priv { struct kvaser_usb_net_priv *net; =20 + struct completion get_bus_params_comp; + struct kvaser_cmd_busparams params_response; + struct delayed_work chip_state_req_work; }; =20 @@ -1206,6 +1226,44 @@ static void kvaser_usb_leaf_stop_chip_reply(const st= ruct kvaser_usb *dev, complete(&priv->stop_comp); } =20 +static void kvaser_usb_leaf_get_bus_params_reply(const struct kvaser_usb *= dev, + const struct kvaser_cmd *cmd) +{ + struct kvaser_usb_net_leaf_priv *leaf; + u8 channel =3D cmd->u.busparams.channel; + + if (channel >=3D dev->nchannels) { + dev_err(&dev->intf->dev, + "Invalid channel number (%d)\n", channel); + return; + } + + leaf =3D dev->nets[channel]->sub_priv; + memcpy(&leaf->params_response, &cmd->u.busparams, sizeof(leaf->params_res= ponse)); + + complete(&leaf->get_bus_params_comp); +} + +static void kvaser_usb_leaf_ctrl_error_event(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + const char *desc =3D ""; + + if (cmd->u.ctrl_error_event.error_code =3D=3D 0x00 && + cmd->u.ctrl_error_event.info1 =3D=3D CMD_SET_BUS_PARAMS) + desc =3D "bus params not accepted"; + + dev_err_ratelimited(&dev->intf->dev, + "received error (cmd 45)%s%s: %02x %02x, code 0x%02x, info1 %u info= 2 %u\n", + desc ? ", " : "", + desc, + cmd->u.ctrl_error_event.unknown[0], + cmd->u.ctrl_error_event.unknown[1], + cmd->u.ctrl_error_event.error_code, + le16_to_cpu(cmd->u.ctrl_error_event.info1), + le16_to_cpu(cmd->u.ctrl_error_event.info2)); +} + static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { @@ -1244,6 +1302,14 @@ static void kvaser_usb_leaf_handle_command(const str= uct kvaser_usb *dev, kvaser_usb_leaf_tx_acknowledge(dev, cmd); break; =20 + case CMD_GET_BUS_PARAMS_REPLY: + kvaser_usb_leaf_get_bus_params_reply(dev, cmd); + break; + + case CMD_CTRL_ERROR_EVENT: + kvaser_usb_leaf_ctrl_error_event(dev, cmd); + break; + /* Ignored commands */ case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: if (dev->card_data.leaf.family !=3D KVASER_USBCAN) @@ -1402,6 +1468,7 @@ static int kvaser_usb_leaf_init_channel(struct kvaser= _usb_net_priv *priv) return -ENOMEM; =20 leaf->net =3D priv; + init_completion(&leaf->get_bus_params_comp); INIT_DELAYED_WORK(&leaf->chip_state_req_work, kvaser_usb_leaf_chip_state_req_work); =20 @@ -1418,9 +1485,34 @@ static void kvaser_usb_leaf_remove_channel(struct kv= aser_usb_net_priv *priv) cancel_delayed_work_sync(&leaf->chip_state_req_work); } =20 +static int kvaser_usb_leaf_get_bus_params(struct kvaser_usb_net_priv *priv) +{ + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; + int err; + + /* we need RX urbs enabled to get the reply */ + err =3D kvaser_usb_setup_rx_urbs(priv->dev); + if (err) + return err; + + reinit_completion(&leaf->get_bus_params_comp); + + err =3D kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS, + priv->channel); + if (err) + return err; + + if (!wait_for_completion_timeout(&leaf->get_bus_params_comp, + msecs_to_jiffies(KVASER_USB_TIMEOUT))) + return -ETIMEDOUT; + + return 0; +} + static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) { struct kvaser_usb_net_priv *priv =3D netdev_priv(netdev); + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; struct can_bittiming *bt =3D &priv->can.bittiming; struct kvaser_usb *dev =3D priv->dev; struct kvaser_cmd *cmd; @@ -1446,6 +1538,22 @@ static int kvaser_usb_leaf_set_bittiming(struct net_= device *netdev) =20 rc =3D kvaser_usb_send_cmd(dev, cmd, cmd->len); =20 + if (rc < 0) + goto out; + + /* check that the parameters were accepted */ + + rc =3D kvaser_usb_leaf_get_bus_params(priv); + if (rc < 0) + goto out; + + if (memcmp(&leaf->params_response, &cmd->u.busparams, + sizeof(leaf->params_response)) !=3D 0) { + rc =3D -EINVAL; + goto out; + } + +out: kfree(cmd); return rc; } --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C8B1C433EF for ; Mon, 16 May 2022 13:58:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244185AbiEPN4E (ORCPT ); Mon, 16 May 2022 09:56:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51116 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243935AbiEPNzA (ORCPT ); Mon, 16 May 2022 09:55:00 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F9042ACC; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 3DFF646002E; Mon, 16 May 2022 16:49:04 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1tcgcijmrJA4; Mon, 16 May 2022 16:49:02 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 58193460031; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 10/12] can: kvaser_usb_leaf: Fix wrong CAN state after stopping Date: Mon, 16 May 2022 16:47:46 +0300 Message-Id: <20220516134748.3724796-11-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 sends a CMD_CHIP_STATE_EVENT indicating bus-off after stopping the device, causing a stopped device to appear as CAN_STATE_BUS_OFF instead of CAN_STATE_STOPPED. Fix that by not handling error events on stopped devices. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 7ed2ced8ba08..742626e69dd8 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -879,6 +879,10 @@ static void kvaser_usb_leaf_rx_error(const struct kvas= er_usb *dev, leaf =3D priv->sub_priv; stats =3D &priv->netdev->stats; =20 + /* Ignore e.g. state change to bus-off reported just after stopping */ + if (!netif_running(priv->netdev)) + return; + /* Update all of the CAN interface's state and error counters before * trying any memory allocation that can actually fail with -ENOMEM. * --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0FD47C433FE for ; Mon, 16 May 2022 13:55:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244120AbiEPNzq (ORCPT ); Mon, 16 May 2022 09:55:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242718AbiEPNyy (ORCPT ); Mon, 16 May 2022 09:54:54 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2969F273C; Mon, 16 May 2022 06:54:35 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 1F3AC460030; Mon, 16 May 2022 16:49:05 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EkXywVdTKueF; Mon, 16 May 2022 16:49:02 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 61E6E460032; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 11/12] can: kvaser_usb_leaf: Ignore stale bus-off after start Date: Mon, 16 May 2022 16:47:47 +0300 Message-Id: <20220516134748.3724796-12-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" With 0bfd:0124 Kvaser Mini PCI Express 2xHS FW 4.18.778 it was observed that if the device was bus-off when stopped, at next start (either via interface down/up or manual bus-off restart) the initial CMD_CHIP_STATE_EVENT received just after CMD_START_CHIP_REPLY will have the M16C_STATE_BUS_OFF bit still set, causing the interface to immediately go bus-off again. The bit seems to internally clear quickly afterwards but we do not get another CMD_CHIP_STATE_EVENT. Fix the issue by ignoring any initial bus-off state until we see at least one bus-on state. Also, poll the state periodically until that occurs. It is possible we lose one actual immediately occurring bus-off event here in which case the HW will auto-recover and we see the recovery event. We will then catch the next bus-off event, if any. This issue did not reproduce with 0bfd:0017 Kvaser Memorator Professional HS/HS FW 2.0.50. Fixes: 71873a9b38d1 ("can: kvaser_usb: Add support for more Kvaser Leaf v2 = devices") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 742626e69dd8..4125074c7066 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -401,6 +401,9 @@ struct kvaser_usb_net_leaf_priv { struct kvaser_cmd_busparams params_response; =20 struct delayed_work chip_state_req_work; + + /* started but not reported as bus-on yet */ + bool joining_bus; }; =20 static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = =3D { @@ -800,6 +803,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser= _usb_net_priv *priv, const struct kvaser_usb_err_summary *es, struct can_frame *cf) { + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; struct kvaser_usb *dev =3D priv->dev; struct net_device_stats *stats =3D &priv->netdev->stats; enum can_state cur_state, new_state, tx_state, rx_state; @@ -824,6 +828,22 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvase= r_usb_net_priv *priv, new_state =3D CAN_STATE_ERROR_ACTIVE; } =20 + /* 0bfd:0124 FW 4.18.778 was observed to send the initial + * CMD_CHIP_STATE_EVENT after CMD_START_CHIP with M16C_STATE_BUS_OFF + * bit set if the channel was bus-off when it was last stopped (even + * across chip resets). This bit will clear shortly afterwards, without + * triggering a second unsolicited chip state event. + * Ignore this initial bus-off. + */ + if (leaf->joining_bus) { + if (new_state =3D=3D CAN_STATE_BUS_OFF) { + netdev_dbg(priv->netdev, "ignoring bus-off during startup"); + new_state =3D cur_state; + } else { + leaf->joining_bus =3D false; + } + } + if (new_state !=3D cur_state) { tx_state =3D (es->txerr >=3D es->rxerr) ? new_state : 0; rx_state =3D (es->txerr <=3D es->rxerr) ? new_state : 0; @@ -899,9 +919,12 @@ static void kvaser_usb_leaf_rx_error(const struct kvas= er_usb *dev, =20 /* If there are errors, request status updates periodically as we do * not get automatic notifications of improved state. + * Also request updates if we saw a stale BUS_OFF during startup + * (joining_bus). */ if (new_state < CAN_STATE_BUS_OFF && - (es->rxerr || es->txerr || new_state =3D=3D CAN_STATE_ERROR_PASSIVE)) + (es->rxerr || es->txerr || new_state =3D=3D CAN_STATE_ERROR_PASSIVE || + leaf->joining_bus)) schedule_delayed_work(&leaf->chip_state_req_work, msecs_to_jiffies(500)); =20 @@ -1392,8 +1415,11 @@ static int kvaser_usb_leaf_set_opt_mode(const struct= kvaser_usb_net_priv *priv) =20 static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv) { + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; int err; =20 + leaf->joining_bus =3D true; + reinit_completion(&priv->start_comp); =20 err =3D kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP, @@ -1566,6 +1592,7 @@ static int kvaser_usb_leaf_set_mode(struct net_device= *netdev, enum can_mode mode) { struct kvaser_usb_net_priv *priv =3D netdev_priv(netdev); + struct kvaser_usb_net_leaf_priv *leaf =3D priv->sub_priv; int err; =20 switch (mode) { @@ -1576,6 +1603,8 @@ static int kvaser_usb_leaf_set_mode(struct net_device= *netdev, =20 kvaser_usb_unlink_tx_urbs(priv); =20 + leaf->joining_bus =3D true; + err =3D kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; --=20 2.34.1 From nobody Fri May 8 00:10:53 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18C6FC433F5 for ; Mon, 16 May 2022 13:57:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229779AbiEPNz4 (ORCPT ); Mon, 16 May 2022 09:55:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243945AbiEPNzA (ORCPT ); Mon, 16 May 2022 09:55:00 -0400 Received: from mail.bitwise.fi (mail.bitwise.fi [109.204.228.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B833739171; Mon, 16 May 2022 06:54:40 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by mail.bitwise.fi (Postfix) with ESMTP id 35A2F460032; Mon, 16 May 2022 16:49:06 +0300 (EEST) X-Virus-Scanned: Debian amavisd-new at Received: from mail.bitwise.fi ([127.0.0.1]) by localhost (mustetatti.dmz.bitwise.fi [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7GrzYXufvKsM; Mon, 16 May 2022 16:49:04 +0300 (EEST) Received: from localhost.net (fw1.dmz.bitwise.fi [192.168.69.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: anssiha) by mail.bitwise.fi (Postfix) with ESMTPSA id 6BEF0460033; Mon, 16 May 2022 16:48:57 +0300 (EEST) From: Anssi Hannula To: Jimmy Assarsson Cc: linux-can@vger.kernel.org, Marc Kleine-Budde , linux-kernel@vger.kernel.org Subject: [PATCH 12/12] can: kvaser_usb_leaf: Fix bogus restart events Date: Mon, 16 May 2022 16:47:48 +0300 Message-Id: <20220516134748.3724796-13-anssi.hannula@bitwise.fi> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> References: <20220516134748.3724796-1-anssi.hannula@bitwise.fi> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When auto-restart is enabled, the kvaser_usb_leaf driver considers transition from any state >=3D CAN_STATE_BUS_OFF as a bus-off recovery event (restart). However, these events may occur at interface startup time before kvaser_usb_open() has set the state to CAN_STATE_ERROR_ACTIVE, causing restarts counter to increase and CAN_ERR_RESTARTED to be sent despite no actual restart having occurred. Fix that by making the auto-restart condition checks more strict so that they only trigger when the interface was actually in the BUS_OFF state. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devic= es") Signed-off-by: Anssi Hannula Tested-by: Jimmy Assarsson --- drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net= /can/usb/kvaser_usb/kvaser_usb_leaf.c index 4125074c7066..b280d315673f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -735,7 +735,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct= kvaser_usb *dev, context =3D &priv->tx_contexts[tid % dev->max_tx_urbs]; =20 /* Sometimes the state change doesn't come after a bus-off event */ - if (priv->can.restart_ms && priv->can.state >=3D CAN_STATE_BUS_OFF) { + if (priv->can.restart_ms && priv->can.state =3D=3D CAN_STATE_BUS_OFF) { struct sk_buff *skb; struct can_frame *cf; =20 @@ -852,7 +852,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser= _usb_net_priv *priv, } =20 if (priv->can.restart_ms && - cur_state >=3D CAN_STATE_BUS_OFF && + cur_state =3D=3D CAN_STATE_BUS_OFF && new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++; =20 @@ -945,7 +945,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvase= r_usb *dev, } =20 if (priv->can.restart_ms && - old_state >=3D CAN_STATE_BUS_OFF && + old_state =3D=3D CAN_STATE_BUS_OFF && new_state < CAN_STATE_BUS_OFF) { cf->can_id |=3D CAN_ERR_RESTARTED; netif_carrier_on(priv->netdev); --=20 2.34.1