From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24A562FD7D2 for ; Wed, 26 Nov 2025 10:17:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; cv=none; b=KiFjMP2oYdhzCtvdUz4dUbx9RWS5FFbDZw53+PFAk/ws8AAc0l2X6gLCkerEl29rnPsZ/Mp4S2DAZRZ4N+TgiSL9Kwh9x5Eie0L/BGrLj+ASwOlLKGOz+m+rhafw5jvopErJaT0gLXTb1cEIyl3Y0NHLre6BSiAu7domdBV1+Gg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; c=relaxed/simple; bh=gM3SyOf9QU2wdFX7Be/+r0/qgWhSCapRqeMuixhfzmw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N3E+s+02I+blyiuwKMKKRO3hFOMakdQAvq7YZTV/1Ckkdv+hRJPCUrvVwBeBFkwzFq2+S1toFg0dyT4EK4BY+iMx0q6QNegzvT+jqzhqPBMzIG92KG7Jw2m4JTbdDhiCOIV6WdkmtpqnCCY7PK4ZzhTdirV7arxpgNbTg9AFiDw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qg-7Z; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZu-002aSa-2p; Wed, 26 Nov 2025 11:16:50 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 9B4FF4A88D2; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:02 +0100 Subject: [PATCH can-next v8 01/17] can: dev: can_get_ctrlmode_str: use capitalized ctrlmode strings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-1-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= , Stephane Grosjean X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1813; i=mkl@pengutronix.de; h=from:subject:message-id; bh=rs0Pl7/UcgAVqu4AJjLmNogiVYwdJnmpuTL4w/fwyFQ=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtNzClLx8LW0G5XbQcpZItJaFjmQqJ64PH1jC M2U5tZgH+aJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTcwAKCRAMdGXf+ZCR nCFuCACnmGgpQ1VjkXlmxoUbA2crbb4hbbVzJxjOfm1mvFlfpqQyF64WvDa7aY4p3756qP0942m Xx1XMo/AzzH6pNnVMge0nld6iTCrS1a6aCQ3bRDZ/MtPj1RmACD9m+G2yoLhGhP+SsmDkGyIqv7 BgeMK/CnBQbO03cCVnHAzGP91ljnOeFWYbXnLJzxNoj6qmrEpRjWhjXbHf6wb1w5W/jmIuvfnCo muYTYv/DKgq/RNz2ms8AXcYQqkKH2b8U2v8MVRC0Io1SM8/TGHec5RD7XnysHSQuuGiVyA7QzbZ oiBkE3UmJAz0wRFlc+LrOSPUyIXgi65RBp/Mi8XsEvPnHZLU X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Oliver Hartkopp Unify the ctrlmode related strings to the command line options of the 'ip' tool from the iproute2 package. The capitalized strings are also shown when the detailed interface configuration is printed by 'ip'. Suggested-by: Stephane Grosjean Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index 80e1ab18de87..b392483e4499 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -92,29 +92,29 @@ const char *can_get_ctrlmode_str(u32 ctrlmode) { switch (ctrlmode & ~(ctrlmode - 1)) { case 0: - return "none"; + return "(none)"; case CAN_CTRLMODE_LOOPBACK: - return "loopback"; + return "LOOPBACK"; case CAN_CTRLMODE_LISTENONLY: - return "listen-only"; + return "LISTEN-ONLY"; case CAN_CTRLMODE_3_SAMPLES: - return "triple-sampling"; + return "TRIPLE-SAMPLING"; case CAN_CTRLMODE_ONE_SHOT: - return "one-shot"; + return "ONE-SHOT"; case CAN_CTRLMODE_BERR_REPORTING: - return "berr-reporting"; + return "BERR-REPORTING"; case CAN_CTRLMODE_FD: - return "fd"; + return "FD"; case CAN_CTRLMODE_PRESUME_ACK: - return "presume-ack"; + return "PRESUME-ACK"; case CAN_CTRLMODE_FD_NON_ISO: - return "fd-non-iso"; + return "FD-NON-ISO"; case CAN_CTRLMODE_CC_LEN8_DLC: - return "cc-len8-dlc"; + return "CC-LEN8-DLC"; case CAN_CTRLMODE_TDC_AUTO: - return "fd-tdc-auto"; + return "TDC-AUTO"; case CAN_CTRLMODE_TDC_MANUAL: - return "fd-tdc-manual"; + return "TDC-MANUAL"; default: return ""; } --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8C2E3009DE for ; Wed, 26 Nov 2025 10:17:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=gQPqYjf9UvDzKCueQTVzrIp006Su1WFMlM6AbrDw/H13INZwq90tmYnS8eyXFMeGrj20LJpBZJJPm1rqru4yXYiO8/mQZUsS9cepEbHxVghrKPdPQpx5GiOyVS13bEG0EGprjYs0MKtaKvcnfzLIxamjyb/Y3MOuVp8CJbYB2eY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=XbwD81IF2hWlAqj8+XiP5Jch3xUbg5Ot/2nn03qkwCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Yrk5mmTqMxjDHyUMa5rcw78qmAgTtSHV/3LjzRRqeSV9OyPFQZHiiYFfGGuCo953SZFxJxbxWSSr7CwgsRreg8i447MfGeCR90+SBTjqRiNzLvAzdKEVzublA26epqgudPB6DX7j7NUN4jfC85WgC18DCGe4ODcXAiLG8Ts+4zM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qh-7Z; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZu-002aSb-2v; Wed, 26 Nov 2025 11:16:50 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id A45904A88D3; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:03 +0100 Subject: [PATCH can-next v8 02/17] can: bittiming: apply NL_SET_ERR_MSG() to can_calc_bittiming() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-2-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1193; i=mkl@pengutronix.de; h=from:subject:message-id; bh=v8m7nKBeI46RR6uNXm/Tz3YaMp4YiXOun4vKbbogbgs=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN1rO+4rE424E9mGwz6GVizQHeA8QyjObr5F dC1IHgLL8WJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTdQAKCRAMdGXf+ZCR nIpdB/9N3sYGeTP/fPZ6UmcnqgjFU4Xsa+gMx+08FgPAEi+NXjw1WLTWM9cBBVBovKFUAR6003j vGHDmIut+FMTS06I/LVoGWnKv0dv+oEZo99IA9a2UDWOtmbMaQEHlkyIbQ0qNxP1KgID02qk9pU ZdzW2h8irgPB+v8hUxQJeuJeZH6wY4sVc61mRWwtCOmrPJDv0ZsEMQegEqoVxnN8qa6ZNlbdGuZ V+kC4HkWtIzCUkfKwYlk6hDJ+7Yw949faiEcnvdVeLgYeJBfipUYu9M0+Z/kFERESbcVlYgBlkQ IA903wwq1Rc6HoF2kNjeTz+KDd+gjj8+Jb7ewp65J4hquyV2 X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol When CONFIG_CAN_CALC_BITTIMING is disabled, the can_calc_bittiming() functions can not be used and the user needs to provide all the bittiming parameters. Currently, can_calc_bittiming() prints an error message to the kernel log. Instead use NL_SET_ERR_MSG() to make it return the error message through the netlink interface so that the user can directly see it. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/bittiming.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/can/bittiming.h b/include/linux/can/bittiming.h index d30816dd93c7..3926c78b2222 100644 --- a/include/linux/can/bittiming.h +++ b/include/linux/can/bittiming.h @@ -141,7 +141,7 @@ static inline int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, const struct can_bittiming_const *btc, struct netlink_ext_ack *extack) { - netdev_err(dev, "bit-timing calculation not available\n"); + NL_SET_ERR_MSG(extack, "bit-timing calculation not available\n"); return -EINVAL; } =20 --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3A722FBE1B for ; Wed, 26 Nov 2025 10:17:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; cv=none; b=FyiziNpGx0t44LX9kqoVdXA70GBLuOZMtSlZxGZrt70EsPT3aNp3KkTa4VZlKqZlXc2Pz606WDdHW4qldT84bajaPt19zJcyCBNA9pYp9hboNeqhaFPn9X05deT+QnxCAmN1HViM37T+o7cDnurfkKG1bwA6KonAD5ypOCmJiAE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; c=relaxed/simple; bh=W884lVKQwWsf/tja4shHUArOad+EqepbzgqQ3lgcujc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lbeS1VNNgqVf7y/Czypbj62UzLFmSmFY+7/tbmlW/+EZrnZF05CTI3gLKdJe94kmdzEiDxyP0JtldAQWh7WngTExQ0Bj7okWiq8vb/Wl185aOqFYQt4lQiGDt7VO+c925gcHNioSDGA+XphP9bbZiLpZ5NgMv2GbKeusdBaRL4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qi-7Y; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZu-002aSc-36; Wed, 26 Nov 2025 11:16:50 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id AD5094A88D4; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:04 +0100 Subject: [PATCH can-next v8 03/17] can: dev: can_dev_dropped_skb: drop CAN FD skbs if FD is off Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-3-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2077; i=mkl@pengutronix.de; h=from:subject:message-id; bh=rf6FlRWB6bK0fuKEFXr+UILKSuqKX6sPqVaAFGkTCss=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN3n3PPLyAE+5JOXvX72EyjXcSURlFssV+WA i4T9sXWbYiJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTdwAKCRAMdGXf+ZCR nEJQB/4/TmLaglNqLvK0JyAqFnlkXGL+PcR+4F5hn42Uf+Y2wJyOz4n6+slJrBX1DALbmlarHoi lbcHdjxQcsr1AbhAVsyhfMCESd5MZmUEEXHjKr4MahNlYqGMaJ987w7AaxvUNILkhFTC7dXNSp6 42ebz1Lu1CBW1QMRmqRc1LoD6AjzAzM27TvYeCxdZatvHk5Rjuu3YEfDTkr7AV7XsUPUH7u9eg9 RdMbV2/GH/+tKKjOmIRKqDl+efbIgRAE53lkDdrAhzWuUveDrsbnWirgxIQyCI8wS41Vdq1Ponj 0DmEr5324WemwWGLQ+zVEsV3mMhnlholrq9+9qkljQM8+wSg X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol Currently, the CAN FD skb validation logic is based on the MTU: the interface is deemed FD capable if and only if its MTU is greater or equal to CANFD_MTU. This logic is showing its limit with the introduction of CAN XL. For example, consider the two scenarios below: 1. An interface configured with CAN FD on and CAN XL on 2. An interface configured with CAN FD off and CAN XL on In those two scenarios, the interfaces would have the same MTU: CANXL_MTU making it impossible to differentiate which one has CAN FD turned on and which one has it off. Because of the limitation, the only non-UAPI-breaking workaround is to do the check at the device level using the can_priv->ctrlmode flags. Unfortunately, the virtual interfaces (vcan, vxcan), which do not have a can_priv, are left behind. Add a check on the CAN_CTRLMODE_FD flag in can_dev_dropped_skb() and drop FD frames whenever the feature is turned off. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/dev.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index bd7410b5d8a6..a7a39a6101d9 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -103,12 +103,20 @@ static inline bool can_dev_dropped_skb(struct net_dev= ice *dev, struct sk_buff *s if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { netdev_info_once(dev, "interface in listen only mode, dropping skb\n"); - kfree_skb(skb); - dev->stats.tx_dropped++; - return true; + goto invalid_skb; + } + + if (!(priv->ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { + netdev_info_once(dev, "CAN FD is disabled, dropping skb\n"); + goto invalid_skb; } =20 return can_dropped_invalid_skb(dev, skb); + +invalid_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return true; } =20 void can_setup(struct net_device *dev); --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8D94301022 for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=BBG3U+Tw8QyQLVpBIoKZeTfyfBNmwNeyDIB6mJuY0grw+VKFbU231JJKbhO1yED76Xnd5hm4hfL8YQVYJwBsTPvZ0/+rP/XlSyuPBb7Ki2bt4WlIZkbPIA55VfwLBY16GKI2CgDKuU702E0Ki+HLJ+6IX+Ra7KctG/92vASEeyo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=MudyV2+Az6NVUbd0rFJJ79+x63NERXYJcrD/ldU2anA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=umnAX/kg0HrPdbndtoaoxlQllaCX9nh9m8e9+BTl5PzviSpczJSpa7ilAV+CTITlLbFTgg8KnlOdz2afCh+y5yeYNGgXxoHt9jtbito3E27OYIww8Gl2rlDBMYKbzR6Xh3cv8ugGVbMgZu81W/gRXTDeZANEbCt7yMSS+n8JgsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qj-85; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSd-01; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id B60BD4A88D5; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:05 +0100 Subject: [PATCH can-next v8 04/17] can: netlink: add CAN_CTRLMODE_RESTRICTED Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-4-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5361; i=mkl@pengutronix.de; h=from:subject:message-id; bh=vv6La5M2jV8ebLvbWsVz47qHm5ZFMKT4yraL+I9/B4o=; b=owEBbAGT/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN5vlHQdCoZLKWUzHP/d9o6+AHk9+3c2UnmO 3CoyzMLPE+JATIEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTeQAKCRAMdGXf+ZCR nIGAB/UbDw91mU3jusTyWgEFXXOTFggA5ZBUPj2rIM7LYHuLHXXWghTumiHoP3AgrjqrvrLfcs5 V7KCXRJQSmJEjIA+g48MVyLWMccbUkvjQdl0e2YebbsSG7STVUasH12mRqXyjaJgemwa6GXK6fa 0FirW9dPeKtKKESWnxdqrkjlOql7alYpmg8XBeGEwtKX/18fOUQufn7gV+pKPvC/ym06T4CvTg6 kA+TKSWCTeNZU7Abt/dvSGx5yXNsZgYoOLcoig5s9HBIhf7Z5UCQIHBcmrOWKrjtGdWJo7Vk413 PZYm36oZFSCKLZ4ufolDmIt8oT6UDARlYQiScgJHQkcxn80= X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol ISO 11898-1:2024 adds a new restricted operation mode. This mode is added as a mandatory feature for nodes which support CAN XL and is retrofitted as optional for legacy nodes (i.e. the ones which only support Classical CAN and CAN FD). The restricted operation mode is nearly the same as the listen only mode: the node can not send data frames or remote frames and can not send dominant bits if an error occurs. The only exception is that the node shall still send the acknowledgment bit. A second niche exception is that the node may still send a data frame containing a time reference message if the node is a primary time provider, but because the time provider feature is not yet implemented in the kernel, this second exception is not relevant to us at the moment. Add the CAN_CTRLMODE_RESTRICTED control mode flag and update the can_dev_dropped_skb() helper function accordingly. Finally, bail out if both CAN_CTRLMODE_LISTENONLY and CAN_CTRLMODE_RESTRICTED are provided. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 2 ++ drivers/net/can/dev/netlink.c | 7 ++++++ include/linux/can/dev.h | 50 +++++++++++++++++++++---------------= ---- include/uapi/linux/can/netlink.h | 1 + 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index b392483e4499..b6980d32e5b4 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -115,6 +115,8 @@ const char *can_get_ctrlmode_str(u32 ctrlmode) return "TDC-AUTO"; case CAN_CTRLMODE_TDC_MANUAL: return "TDC-MANUAL"; + case CAN_CTRLMODE_RESTRICTED: + return "RESTRICTED"; default: return ""; } diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 6f83b87d54fc..87e731527dd7 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -188,6 +188,13 @@ static int can_validate(struct nlattr *tb[], struct nl= attr *data[], struct can_ctrlmode *cm =3D nla_data(data[IFLA_CAN_CTRLMODE]); =20 flags =3D cm->flags & cm->mask; + + if ((flags & CAN_CTRLMODE_LISTENONLY) && + (flags & CAN_CTRLMODE_RESTRICTED)) { + NL_SET_ERR_MSG(extack, + "LISTEN-ONLY and RESTRICTED modes are mutually exclusive"); + return -EOPNOTSUPP; + } } =20 err =3D can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING); diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index a7a39a6101d9..ab11c0e9111b 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -95,30 +95,6 @@ static inline bool can_is_canxl_dev_mtu(unsigned int mtu) return (mtu >=3D CANXL_MIN_MTU && mtu <=3D CANXL_MAX_MTU); } =20 -/* drop skb if it does not contain a valid CAN frame for sending */ -static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_b= uff *skb) -{ - struct can_priv *priv =3D netdev_priv(dev); - - if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { - netdev_info_once(dev, - "interface in listen only mode, dropping skb\n"); - goto invalid_skb; - } - - if (!(priv->ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { - netdev_info_once(dev, "CAN FD is disabled, dropping skb\n"); - goto invalid_skb; - } - - return can_dropped_invalid_skb(dev, skb); - -invalid_skb: - kfree_skb(skb); - dev->stats.tx_dropped++; - return true; -} - void can_setup(struct net_device *dev); =20 struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb= _max, @@ -154,6 +130,32 @@ void can_bus_off(struct net_device *dev); const char *can_get_state_str(const enum can_state state); const char *can_get_ctrlmode_str(u32 ctrlmode); =20 +/* drop skb if it does not contain a valid CAN frame for sending */ +static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_b= uff *skb) +{ + struct can_priv *priv =3D netdev_priv(dev); + u32 silent_mode =3D priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_RESTRICTED); + + if (silent_mode) { + netdev_info_once(dev, "interface in %s mode, dropping skb\n", + can_get_ctrlmode_str(silent_mode)); + goto invalid_skb; + } + + if (!(priv->ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) { + netdev_info_once(dev, "CAN FD is disabled, dropping skb\n"); + goto invalid_skb; + } + + return can_dropped_invalid_skb(dev, skb); + +invalid_skb: + kfree_skb(skb); + dev->stats.tx_dropped++; + return true; +} + void can_state_get_by_berr_counter(const struct net_device *dev, const struct can_berr_counter *bec, enum can_state *tx_state, diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netl= ink.h index ef62f56eaaef..fafd1cce4798 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -103,6 +103,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */ #define CAN_CTRLMODE_TDC_AUTO 0x200 /* FD transceiver automatically calcu= lates TDCV */ #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* FD TDCV is manually set up by us= er */ +#define CAN_CTRLMODE_RESTRICTED 0x800 /* Restricted operation mode */ =20 /* * CAN device statistics --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB8CF3019A4 for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=SdcJJ1R0TXQ2G59FiCoJpVI7BftoKD+DMETBsvuVxXcFQh7FZhZIyMx1E2k1Uo1kXMHTohOrt9xwC8ymlv79dwn3zoIvHpJ2kvnpdNPCjWCiF9mFviWwmBVy1bZvH5ioKctr67LuXfESI7ZoSduoRrk7nm0edmhSaNfwkNo6vDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=A7WTS7anSPZ6YLVdDadGHIINAL5yzAkq2g2WCt6lhp4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DY9upLDi2VT6hgBZsHj/coMnLkAklaNxbjwPLnZ4PHdsmg4Yw9n7L/gmihg5yS9rYFD0gOPL4j6QqCzrbDQNX/kiiBbnCnxyVqzAxFJ9PGEChGjU5k81eHbU8lQq4CzOsVyjALKHQVc4/JxSFQ+1TT10zcHwXGVaMLqkqsSgICU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qk-Dt; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSh-0E; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id C02974A88D6; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:06 +0100 Subject: [PATCH can-next v8 05/17] can: netlink: add initial CAN XL support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-5-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=12616; i=mkl@pengutronix.de; h=from:subject:message-id; bh=pGF0Wy9A8kQ3E4M42mvHQ/wbbHmZTOCn/dS8JuVSjYs=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN7UQwO4e2W6K/augzchsq3aGCvjU5rkNgbm Xnd7ShNidKJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTewAKCRAMdGXf+ZCR nFARB/4yDkaQmWsh+T0VL39MBhJiFu5aXC3v1S3E35s0sBZR3BvppU8GVYiAnEOcA6fdPJGn3O6 NwuNbZPXtR80Th6O1Ijmq8Dk67vM2bxrdyL/Jm+9xaCL+n2kNEfwYOwxURFNeTrZZqHsktA2+hq /CGsowpohj9SmWGQYtoP7HLwAW2VtojB41xSybhZKeSrODPTfityvE82QqnY6T6Zz4eMVEcmR7q /rbvQuKJ2FY6xtkfH/kXP7UOfv8//d4IVpMwHNJN0XTW7Xs7L7OhatixqmjlT1X4cjnY0AnEaAl jABfVfemGZjlnXi3u+tT8StcagGmx/Yxo3EbiK4flGqbv2px X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol CAN XL uses bittiming parameters different from Classical CAN and CAN FD. Thus, all the data bittiming parameters, including TDC, need to be duplicated for CAN XL. Add the CAN XL netlink interface for all the features which are common with CAN FD. Any new CAN XL specific features are added later on. The first time CAN XL is activated, the MTU is set by default to CANXL_MAX_MTU. The user may then configure a custom MTU within the CANXL_MIN_MTU to CANXL_MAX_MTU range, in which case, the custom MTU value will be kept as long as CAN XL remains active. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 14 +++++++- drivers/net/can/dev/netlink.c | 76 +++++++++++++++++++++++++++++++-----= ---- include/linux/can/bittiming.h | 6 ++-- include/linux/can/dev.h | 7 +++- include/uapi/linux/can/netlink.h | 7 ++++ 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index b6980d32e5b4..bdec2c52c8ec 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -117,6 +117,12 @@ const char *can_get_ctrlmode_str(u32 ctrlmode) return "TDC-MANUAL"; case CAN_CTRLMODE_RESTRICTED: return "RESTRICTED"; + case CAN_CTRLMODE_XL: + return "XL"; + case CAN_CTRLMODE_XL_TDC_AUTO: + return "XL-TDC-AUTO"; + case CAN_CTRLMODE_XL_TDC_MANUAL: + return "XL-TDC-MANUAL"; default: return ""; } @@ -350,7 +356,13 @@ void can_set_default_mtu(struct net_device *dev) { struct can_priv *priv =3D netdev_priv(dev); =20 - if (priv->ctrlmode & CAN_CTRLMODE_FD) { + if (priv->ctrlmode & CAN_CTRLMODE_XL) { + if (can_is_canxl_dev_mtu(dev->mtu)) + return; + dev->mtu =3D CANXL_MTU; + dev->min_mtu =3D CANXL_MIN_MTU; + dev->max_mtu =3D CANXL_MAX_MTU; + } else if (priv->ctrlmode & CAN_CTRLMODE_FD) { dev->mtu =3D CANFD_MTU; dev->min_mtu =3D CANFD_MTU; dev->max_mtu =3D CANFD_MTU; diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 87e731527dd7..fdd1fa7cf93a 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -2,7 +2,7 @@ /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix * Copyright (C) 2006 Andrey Volkov, Varma Electronics * Copyright (C) 2008-2009 Wolfgang Grandegger - * Copyright (C) 2021 Vincent Mailhol + * Copyright (C) 2021-2025 Vincent Mailhol */ =20 #include @@ -22,6 +22,9 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + = 1] =3D { [IFLA_CAN_TERMINATION] =3D { .type =3D NLA_U16 }, [IFLA_CAN_TDC] =3D { .type =3D NLA_NESTED }, [IFLA_CAN_CTRLMODE_EXT] =3D { .type =3D NLA_NESTED }, + [IFLA_CAN_XL_DATA_BITTIMING] =3D { .len =3D sizeof(struct can_bittiming) = }, + [IFLA_CAN_XL_DATA_BITTIMING_CONST] =3D { .len =3D sizeof(struct can_bitti= ming_const) }, + [IFLA_CAN_XL_TDC] =3D { .type =3D NLA_NESTED }, }; =20 static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] =3D { @@ -70,7 +73,7 @@ static int can_validate_tdc(struct nlattr *data_tdc, return -EOPNOTSUPP; } =20 - /* If one of the CAN_CTRLMODE_TDC_* flag is set then TDC + /* If one of the CAN_CTRLMODE_{,XL}_TDC_* flags is set then TDC * must be set and vice-versa */ if ((tdc_auto || tdc_manual) && !data_tdc) { @@ -82,8 +85,8 @@ static int can_validate_tdc(struct nlattr *data_tdc, return -EOPNOTSUPP; } =20 - /* If providing TDC parameters, at least TDCO is needed. TDCV - * is needed if and only if CAN_CTRLMODE_TDC_MANUAL is set + /* If providing TDC parameters, at least TDCO is needed. TDCV is + * needed if and only if CAN_CTRLMODE_{,XL}_TDC_MANUAL is set */ if (data_tdc) { struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1]; @@ -126,10 +129,10 @@ static int can_validate_databittiming(struct nlattr *= data[], bool is_on; int err; =20 - /* Make sure that valid CAN FD configurations always consist of + /* Make sure that valid CAN FD/XL configurations always consist of * - nominal/arbitration bittiming * - data bittiming - * - control mode with CAN_CTRLMODE_FD set + * - control mode with CAN_CTRLMODE_{FD,XL} set * - TDC parameters are coherent (details in can_validate_tdc()) */ =20 @@ -139,7 +142,10 @@ static int can_validate_databittiming(struct nlattr *d= ata[], is_on =3D flags & CAN_CTRLMODE_FD; type =3D "FD"; } else { - return -EOPNOTSUPP; /* Place holder for CAN XL */ + data_tdc =3D data[IFLA_CAN_XL_TDC]; + tdc_flags =3D flags & CAN_CTRLMODE_XL_TDC_MASK; + is_on =3D flags & CAN_CTRLMODE_XL; + type =3D "XL"; } =20 if (is_on) { @@ -206,6 +212,11 @@ static int can_validate(struct nlattr *tb[], struct nl= attr *data[], if (err) return err; =20 + err =3D can_validate_databittiming(data, extack, + IFLA_CAN_XL_DATA_BITTIMING, flags); + if (err) + return err; + return 0; } =20 @@ -251,18 +262,26 @@ static int can_ctrlmode_changelink(struct net_device = *dev, /* If a top dependency flag is provided, reset all its dependencies */ if (cm->mask & CAN_CTRLMODE_FD) priv->ctrlmode &=3D ~CAN_CTRLMODE_FD_TDC_MASK; + if (cm->mask & CAN_CTRLMODE_XL) + priv->ctrlmode &=3D ~(CAN_CTRLMODE_XL_TDC_MASK); =20 /* clear bits to be modified and copy the flag values */ priv->ctrlmode &=3D ~cm->mask; priv->ctrlmode |=3D maskedflags; =20 - /* Wipe potential leftovers from previous CAN FD config */ + /* Wipe potential leftovers from previous CAN FD/XL config */ if (!(priv->ctrlmode & CAN_CTRLMODE_FD)) { memset(&priv->fd.data_bittiming, 0, sizeof(priv->fd.data_bittiming)); priv->ctrlmode &=3D ~CAN_CTRLMODE_FD_TDC_MASK; memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc)); } + if (!(priv->ctrlmode & CAN_CTRLMODE_XL)) { + memset(&priv->xl.data_bittiming, 0, + sizeof(priv->fd.data_bittiming)); + priv->ctrlmode &=3D ~CAN_CTRLMODE_XL_TDC_MASK; + memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc)); + } =20 can_set_default_mtu(dev); =20 @@ -337,7 +356,10 @@ static int can_dbt_changelink(struct net_device *dev, = struct nlattr *data[], dbt_params =3D &priv->fd; tdc_mask =3D CAN_CTRLMODE_FD_TDC_MASK; } else { - return -EOPNOTSUPP; /* Place holder for CAN XL */ + data_bittiming =3D data[IFLA_CAN_XL_DATA_BITTIMING]; + data_tdc =3D data[IFLA_CAN_XL_TDC]; + dbt_params =3D &priv->xl; + tdc_mask =3D CAN_CTRLMODE_XL_TDC_MASK; } =20 if (!data_bittiming) @@ -388,7 +410,7 @@ static int can_dbt_changelink(struct net_device *dev, s= truct nlattr *data[], */ can_calc_tdco(&dbt_params->tdc, dbt_params->tdc_const, &dbt, tdc_mask, &priv->ctrlmode, priv->ctrlmode_supported); - } /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly + } /* else: both CAN_CTRLMODE_{,XL}_TDC_{AUTO,MANUAL} are explicitly * turned off. TDC is disabled: do nothing */ =20 @@ -493,6 +515,11 @@ static int can_changelink(struct net_device *dev, stru= ct nlattr *tb[], if (err) return err; =20 + /* CAN XL */ + err =3D can_dbt_changelink(dev, data, false, extack); + if (err) + return err; + if (data[IFLA_CAN_TERMINATION]) { const u16 termval =3D nla_get_u16(data[IFLA_CAN_TERMINATION]); const unsigned int num_term =3D priv->termination_const_cnt; @@ -560,14 +587,14 @@ static size_t can_data_bittiming_get_size(struct data= _bittiming_params *dbt_para { size_t size =3D 0; =20 - if (dbt_params->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ + if (dbt_params->data_bittiming.bitrate) /* IFLA_CAN_{,XL}_DATA_BITTIMING= */ size +=3D nla_total_size(sizeof(dbt_params->data_bittiming)); - if (dbt_params->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ + if (dbt_params->data_bittiming_const) /* IFLA_CAN_{,XL}_DATA_BITTIMING_C= ONST */ size +=3D nla_total_size(sizeof(*dbt_params->data_bittiming_const)); - if (dbt_params->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ + if (dbt_params->data_bitrate_const) /* IFLA_CAN_{,XL}_DATA_BITRATE_CONST= */ size +=3D nla_total_size(sizeof(*dbt_params->data_bitrate_const) * dbt_params->data_bitrate_const_cnt); - size +=3D can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_TDC */ + size +=3D can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_{,XL}_TDC */ =20 return size; } @@ -607,6 +634,9 @@ static size_t can_get_size(const struct net_device *dev) size +=3D can_data_bittiming_get_size(&priv->fd, priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK); =20 + size +=3D can_data_bittiming_get_size(&priv->xl, + priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK); + return size; } =20 @@ -651,7 +681,9 @@ static int can_tdc_fill_info(struct sk_buff *skb, const= struct net_device *dev, tdc_is_enabled =3D can_fd_tdc_is_enabled(priv); tdc_manual =3D priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL; } else { - return -EOPNOTSUPP; /* Place holder for CAN XL */ + dbt_params =3D &priv->xl; + tdc_is_enabled =3D can_xl_tdc_is_enabled(priv); + tdc_manual =3D priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MANUAL; } tdc_const =3D dbt_params->tdc_const; tdc =3D &dbt_params->tdc; @@ -773,7 +805,19 @@ static int can_fill_info(struct sk_buff *skb, const st= ruct net_device *dev) =20 can_tdc_fill_info(skb, dev, IFLA_CAN_TDC) || =20 - can_ctrlmode_ext_fill_info(skb, priv) + can_ctrlmode_ext_fill_info(skb, priv) || + + can_bittiming_fill_info(skb, IFLA_CAN_XL_DATA_BITTIMING, + &priv->xl.data_bittiming) || + + can_bittiming_const_fill_info(skb, IFLA_CAN_XL_DATA_BITTIMING_CONST, + priv->xl.data_bittiming_const) || + + can_bitrate_const_fill_info(skb, IFLA_CAN_XL_DATA_BITRATE_CONST, + priv->xl.data_bitrate_const, + priv->xl.data_bitrate_const_cnt) || + + can_tdc_fill_info(skb, dev, IFLA_CAN_XL_TDC) ) =20 return -EMSGSIZE; diff --git a/include/linux/can/bittiming.h b/include/linux/can/bittiming.h index 3926c78b2222..b6cd2476ffd7 100644 --- a/include/linux/can/bittiming.h +++ b/include/linux/can/bittiming.h @@ -16,10 +16,12 @@ =20 #define CAN_CTRLMODE_FD_TDC_MASK \ (CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_TDC_MANUAL) +#define CAN_CTRLMODE_XL_TDC_MASK \ + (CAN_CTRLMODE_XL_TDC_AUTO | CAN_CTRLMODE_XL_TDC_MANUAL) #define CAN_CTRLMODE_TDC_AUTO_MASK \ - (CAN_CTRLMODE_TDC_AUTO) + (CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_XL_TDC_AUTO) #define CAN_CTRLMODE_TDC_MANUAL_MASK \ - (CAN_CTRLMODE_TDC_MANUAL) + (CAN_CTRLMODE_TDC_MANUAL | CAN_CTRLMODE_XL_TDC_MANUAL) =20 /* * struct can_tdc - CAN FD Transmission Delay Compensation parameters diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index ab11c0e9111b..f15879bd818d 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -47,7 +47,7 @@ struct can_priv { =20 const struct can_bittiming_const *bittiming_const; struct can_bittiming bittiming; - struct data_bittiming_params fd; + struct data_bittiming_params fd, xl; unsigned int bitrate_const_cnt; const u32 *bitrate_const; u32 bitrate_max; @@ -85,6 +85,11 @@ static inline bool can_fd_tdc_is_enabled(const struct ca= n_priv *priv) return !!(priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK); } =20 +static inline bool can_xl_tdc_is_enabled(const struct can_priv *priv) +{ + return !!(priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK); +} + static inline u32 can_get_static_ctrlmode(struct can_priv *priv) { return priv->ctrlmode & ~priv->ctrlmode_supported; diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netl= ink.h index fafd1cce4798..c2c96c5978a8 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -104,6 +104,9 @@ struct can_ctrlmode { #define CAN_CTRLMODE_TDC_AUTO 0x200 /* FD transceiver automatically calcu= lates TDCV */ #define CAN_CTRLMODE_TDC_MANUAL 0x400 /* FD TDCV is manually set up by us= er */ #define CAN_CTRLMODE_RESTRICTED 0x800 /* Restricted operation mode */ +#define CAN_CTRLMODE_XL 0x1000 /* CAN XL mode */ +#define CAN_CTRLMODE_XL_TDC_AUTO 0x2000 /* XL transceiver automatically ca= lculates TDCV */ +#define CAN_CTRLMODE_XL_TDC_MANUAL 0x4000 /* XL TDCV is manually set up by= user */ =20 /* * CAN device statistics @@ -139,6 +142,10 @@ enum { IFLA_CAN_BITRATE_MAX, IFLA_CAN_TDC, /* FD */ IFLA_CAN_CTRLMODE_EXT, + IFLA_CAN_XL_DATA_BITTIMING, + IFLA_CAN_XL_DATA_BITTIMING_CONST, + IFLA_CAN_XL_DATA_BITRATE_CONST, + IFLA_CAN_XL_TDC, =20 /* add new constants above here */ __IFLA_CAN_MAX, --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D2312FFDF7 for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152226; cv=none; b=A+kTJzmUtBWYRo1T+GKFSJUqnRoO44EXjYIzHL98026vhHf3Q90UVjeLW4m/KYdcD8USFkJbtph1nAoK0LkMxfPIDhI9VQrk6TNK0iCFvnM7VDojxZNrGpTsuZ8X+DoIQW9FULaMAJJuRGKRW7tWOk5ZdOgcYoG0tu5tkLlWlCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152226; c=relaxed/simple; bh=fS4hBjxhe4B2rGZw1UE5xJjwx1g9xQ/AJ0ujEbGZZKk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YQN9eGo9/eqyKy5RJHefJgqRPg8WDIQh15bDDZSnCJ/BtrvCyvj0IWhvNeACUvheVwFrA1d32CTbRhkaKB3/PhEZ+euJCderaZ2+cVW6ngLMR3ekRzy/P0Qff1OzVzVnmCTxwZfTPKgWjoWJzzXa8921giD8qDoLsDozrM2N94I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qw-FC; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSj-0Q; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id C97D54A88D7; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:07 +0100 Subject: [PATCH can-next v8 06/17] can: netlink: add CAN_CTRLMODE_XL_TMS flag Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-6-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5426; i=mkl@pengutronix.de; h=from:subject:message-id; bh=si+iHB4Gn53pF8WzEhSdkUrN0R6dWRwd+uuB5d9P99g=; b=owGbwMvMwMXIU5J6/+eEiXMYT6slMWSqXa5l9Nx6RojB64vD9QXp91KKGp9dfzndNmp/V6JR1 OzO7IUmnYzGLAyMXAyyYoos83/z3FifviL+j2jOZ5hBrEwgUxi4OAVgIhuWs/+PnaOVX65cc/nq xFLtQ3ufHs6pz9Ev//z8/YyGj7fnV/x3OCAR/+7CCSYf58ap8fGzd7Y/ell5q4YnRtTFPeUh65/ JVrPuZG3+Y1690iX6jAD73CDHlpcrstXjU45U+b/SXv3FvTGKv3JiNVdCT2Z7sDdPlUHuytkrql olPl3/X8ymody5b8Ph2wyMiZ8cDVdwON+XE1hztKu+P01maY5n3+++G4KfFwSlL7b4KFexP9Tip OQ5/izOr1xX+623t97kTlS/0vXEdNN7Ebs+Jet9+2T+96VV7UvjDKk8WPfmj4qGiKHwbeU0/gcu a84YdhlmnDEM2+ivosBsK1dyU7iGm7eiMmMX39UARXYdAA== X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol The Transceiver Mode Switching (TMS) indicates whether the CAN XL controller shall use the PWM or NRZ encoding during the data phase. The term "transceiver mode switching" is used in both ISO 11898-1 and CiA 612-2 (although only the latter one uses the abbreviation TMS). We adopt the same naming convention here for consistency. Add the CAN_CTRLMODE_XL_TMS flag to the list of the CAN control modes. Add can_validate_xl_flags() to check the coherency of the TMS flag. That function will be reused in upcoming changes to validate the other CAN XL flags. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/dev.c | 2 ++ drivers/net/can/dev/netlink.c | 48 ++++++++++++++++++++++++++++++++++++= +--- include/uapi/linux/can/netlink.h | 1 + 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c index bdec2c52c8ec..091f30e94c61 100644 --- a/drivers/net/can/dev/dev.c +++ b/drivers/net/can/dev/dev.c @@ -123,6 +123,8 @@ const char *can_get_ctrlmode_str(u32 ctrlmode) return "XL-TDC-AUTO"; case CAN_CTRLMODE_XL_TDC_MANUAL: return "XL-TDC-MANUAL"; + case CAN_CTRLMODE_XL_TMS: + return "TMS"; default: return ""; } diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index fdd1fa7cf93a..b2c24439abba 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -181,6 +181,32 @@ static int can_validate_databittiming(struct nlattr *d= ata[], return 0; } =20 +static int can_validate_xl_flags(struct netlink_ext_ack *extack, + u32 masked_flags, u32 mask) +{ + if (masked_flags & CAN_CTRLMODE_XL) { + if (masked_flags & CAN_CTRLMODE_XL_TMS) { + const u32 tms_conflicts_mask =3D CAN_CTRLMODE_FD | + CAN_CTRLMODE_XL_TDC_MASK; + u32 tms_conflicts =3D masked_flags & tms_conflicts_mask; + + if (tms_conflicts) { + NL_SET_ERR_MSG_FMT(extack, + "TMS and %s are mutually exclusive", + can_get_ctrlmode_str(tms_conflicts)); + return -EOPNOTSUPP; + } + } + } else { + if (mask & CAN_CTRLMODE_XL_TMS) { + NL_SET_ERR_MSG(extack, "TMS requires CAN XL"); + return -EOPNOTSUPP; + } + } + + return 0; +} + static int can_validate(struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { @@ -201,6 +227,10 @@ static int can_validate(struct nlattr *tb[], struct nl= attr *data[], "LISTEN-ONLY and RESTRICTED modes are mutually exclusive"); return -EOPNOTSUPP; } + + err =3D can_validate_xl_flags(extack, flags, cm->mask); + if (err) + return err; } =20 err =3D can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING); @@ -226,7 +256,7 @@ static int can_ctrlmode_changelink(struct net_device *d= ev, { struct can_priv *priv =3D netdev_priv(dev); struct can_ctrlmode *cm; - u32 ctrlstatic, maskedflags, notsupp, ctrlstatic_missing; + u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing; =20 if (!data[IFLA_CAN_CTRLMODE]) return 0; @@ -238,6 +268,7 @@ static int can_ctrlmode_changelink(struct net_device *d= ev, cm =3D nla_data(data[IFLA_CAN_CTRLMODE]); ctrlstatic =3D can_get_static_ctrlmode(priv); maskedflags =3D cm->flags & cm->mask; + deactivated =3D ~cm->flags & cm->mask; notsupp =3D maskedflags & ~(priv->ctrlmode_supported | ctrlstatic); ctrlstatic_missing =3D (maskedflags & ctrlstatic) ^ ctrlstatic; =20 @@ -259,11 +290,21 @@ static int can_ctrlmode_changelink(struct net_device = *dev, return -EOPNOTSUPP; } =20 + /* If FD was active and is not turned off, check for XL conflicts */ + if (priv->ctrlmode & CAN_CTRLMODE_FD & ~deactivated) { + if (maskedflags & CAN_CTRLMODE_XL_TMS) { + NL_SET_ERR_MSG(extack, + "TMS can not be activated while CAN FD is on"); + return -EOPNOTSUPP; + } + } + /* If a top dependency flag is provided, reset all its dependencies */ if (cm->mask & CAN_CTRLMODE_FD) priv->ctrlmode &=3D ~CAN_CTRLMODE_FD_TDC_MASK; if (cm->mask & CAN_CTRLMODE_XL) - priv->ctrlmode &=3D ~(CAN_CTRLMODE_XL_TDC_MASK); + priv->ctrlmode &=3D ~(CAN_CTRLMODE_XL_TDC_MASK | + CAN_CTRLMODE_XL_TMS); =20 /* clear bits to be modified and copy the flag values */ priv->ctrlmode &=3D ~cm->mask; @@ -395,7 +436,8 @@ static int can_dbt_changelink(struct net_device *dev, s= truct nlattr *data[], if (data[IFLA_CAN_CTRLMODE]) { struct can_ctrlmode *cm =3D nla_data(data[IFLA_CAN_CTRLMODE]); =20 - need_tdc_calc =3D !(cm->mask & tdc_mask); + if (fd || !(priv->ctrlmode & CAN_CTRLMODE_XL_TMS)) + need_tdc_calc =3D !(cm->mask & tdc_mask); } if (data_tdc) { /* TDC parameters are provided: use them */ diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netl= ink.h index c2c96c5978a8..ebafb091d80f 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -107,6 +107,7 @@ struct can_ctrlmode { #define CAN_CTRLMODE_XL 0x1000 /* CAN XL mode */ #define CAN_CTRLMODE_XL_TDC_AUTO 0x2000 /* XL transceiver automatically ca= lculates TDCV */ #define CAN_CTRLMODE_XL_TDC_MANUAL 0x4000 /* XL TDCV is manually set up by= user */ +#define CAN_CTRLMODE_XL_TMS 0x8000 /* Transceiver Mode Switching */ =20 /* * CAN device statistics --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 249C42FD69F for ; Wed, 26 Nov 2025 10:17:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; cv=none; b=Kmkx+RoEY6mRDPBUn/iym7MrPH8GkkqoO6/hpsaYJO8605/rmwBr2UPH1EPbtUamPvj5kcDuhB9tqBGfV5GH3ou2feVSItckQvMe7bW4HL1fJfx/6aU8nXqdWjZTqCh+Kxp0Vg7Re391MHITihdFmmTw7120bI04FLjue4Ovq6o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152224; c=relaxed/simple; bh=nairXQ9rIPW+imcD7BjKitK2BHOOiL01JpUuX5MLgc8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H9xnXRitDGz91OGghhecgMUmcTLmhQSNFlKOztQybGMzecomaSdJAUTwuhPMfiyqfF0wD1E7CZSyqH+GFrdZLLrQhTfB5+wXXodvelsv2nTfr6hTzqxvQaxhIAaJF0VoOony46PYQtZcuE45cs6PEk51ZbQVMAGoN6mFhP4TjMI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qx-H4; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSl-0Q; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id DAA584A88D8; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:08 +0100 Subject: [PATCH can-next v8 07/17] can: dev: can_dev_dropped_skb: drop CC/FD frames in CANXL-only mode Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-7-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2650; i=mkl@pengutronix.de; h=from:subject:message-id; bh=+xs9GjCtM7BOsuxCHzohc9NNywqTNpj79PW2gV2riAI=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtN+zZfLLPlMTzDKzV20ZAJ0kIkZrI3lIRS8x TRMuOoVHMmJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTfgAKCRAMdGXf+ZCR nJPuB/sFg0o1dDoDJA2av5pFNPf57YuKrcX4DrUNhGigx950d9v1Uz5aflCDKUzoE4RzgcjtrY/ 1PzpWiYT+juf71gqFziQutyda5/47lhjGopd/3zSObtwIdfob/+BUesHSMN4gauCdkW7i6B7fFj +Mmbh1MxMvtf0Yfwg5b5t2xNUpgRevyM3QbOTGAReotaHQRH+anHJMXOINo2lK4fjpKyO27JG2G iWg/yM0okLABdMLHsc4jySTi8DtSKaC0Y+xa/j4/reDkZKaSDtF6yh6JvvQKmhRIuq3Mgjjfwgz Q9dhGN3YafivRo0N2XGwfMqoJStUAb7+NofZc5+QJwJ+/IhG X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Oliver Hartkopp The error-signalling (ES) is a mandatory functionality for CAN CC and CAN FD to report CAN frame format violations by sending an error-frame signal on the bus. A so-called 'mixed-mode' is intended to have (XL-tolerant) CAN FD nodes and CAN XL nodes on one CAN segment, where the FD-controllers can talk CC/FD and the XL-controllers can talk CC/FD/XL. This mixed-mode utilizes the error-signalling for sending CC/FD/XL frames. The CANXL-only mode disables the error-signalling in the CAN XL controller. This mode does not allow CC/FD frames to be sent but additionally offers a CAN XL transceiver mode switching (TMS). Configured with CAN_CTRLMODE_FD and CAN_CTRLMODE_XL this leads to: FD=3D0 XL=3D0 CC-only mode (ES=3D1) FD=3D1 XL=3D0 FD/CC mixed-mode (ES=3D1) FD=3D1 XL=3D1 XL/FD/CC mixed-mode (ES=3D1) FD=3D0 XL=3D1 XL-only mode (ES=3D0, TMS optional) The helper function can_dev_in_xl_only_mode() determines the required value to disable error signalling in the CAN XL controller. Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/dev.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index f15879bd818d..52c8be5c160e 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -135,6 +135,19 @@ void can_bus_off(struct net_device *dev); const char *can_get_state_str(const enum can_state state); const char *can_get_ctrlmode_str(u32 ctrlmode); =20 +static inline bool can_dev_in_xl_only_mode(struct can_priv *priv) +{ + const u32 mixed_mode =3D CAN_CTRLMODE_FD | CAN_CTRLMODE_XL; + + /* When CAN XL is enabled but FD is disabled we are running in + * the so-called 'CANXL-only mode' where the error signalling is + * disabled. This helper function determines the required value + * to disable error signalling in the CAN XL controller. + * The so-called CC/FD/XL 'mixed mode' requires error signalling. + */ + return ((priv->ctrlmode & mixed_mode) =3D=3D CAN_CTRLMODE_XL); +} + /* drop skb if it does not contain a valid CAN frame for sending */ static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_b= uff *skb) { @@ -153,6 +166,12 @@ static inline bool can_dev_dropped_skb(struct net_devi= ce *dev, struct sk_buff *s goto invalid_skb; } =20 + if (can_dev_in_xl_only_mode(priv) && !can_is_canxl_skb(skb)) { + netdev_info_once(dev, + "Error signaling is disabled, dropping skb\n"); + goto invalid_skb; + } + return can_dropped_invalid_skb(dev, skb); =20 invalid_skb: --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8B923009D4 for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=hwiyrQtQXOGRWkDxyGI5cXFYr/Jfld2Amcrh88TpLunlA2Y9/lt9IzMujLpufWNugkNj0NzrfSw2AO0ginjleqCP4w+4olPzgRxU4pStqMewB35kdWzhhkG5H/DUdoMb6zXR6l5witH3C7iGUyQylPLJx1PexwL99/k7emOp6P8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=chJqDi5LNRD1ZQF7VK3RPjMxg7Lxg1i0rVyWyftNFxc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DjsYhuoOkPlZDFGZ+PF0PAOzhQ9gVaVP8AvUuxoI0QBBXyVMj1gXJexyyjsEZMNt3JTV2s72IaPlJj8tqL6w//5ZttKWgp+wYhB1NAjcmKahzPjotKRGPE3eQJr/r9vFfdmZ/xCitST0b9dBQcPYjE80mvZ84TTISgONBRY2aYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qz-S0; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSn-0a; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id E414F4A88D9; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:09 +0100 Subject: [PATCH can-next v8 08/17] can: bittiming: add PWM parameters Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-8-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3285; i=mkl@pengutronix.de; h=from:subject:message-id; bh=8daY6wvWgSakeygHZy4qqebx3N9P6l57fEJmO9+nzEE=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOAtjWgw3EQ1X1DWwwhGpgBv+TvMcIUOuDNn TWQfSBg9M6JATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTgAAKCRAMdGXf+ZCR nDlUCACyvKk3SqZOYebxNZvsl0OJPaaUN95mHuM5OKpYJY1yWrQikYioy1y1mpaU11SIULETdv7 OMRo+0/YW95UnLkJpiT3c46QncpUKBITxuip5fIBTTvXL1N9JAT27M0N2SrSXcpYcqvGsxnz9Cp ObgzFrFKIHguD44S5dSYjh8cjOkaH6Z8TK3d4VXpR1TmuQRr4DHqxNGdXVgA3LbCHiwWEREOhGl lmOJRzYdlLFv/8bQqw7ZgiJZphwgucdI+Pw3tFizGQ/ALYD0Pa5wIMkeog9mMorHA7VCFxSTtXl eWChDvOTd2C00Mi5v5RINalaYmfTD/ucjOATzTAGBSIpI/u2 X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol In CAN XL, higher data bit rates require the CAN transceiver to switch its operation mode to use Pulse-Width Modulation (PWM) transmission mode instead of the classic dominant/recessive transmission mode. The PWM parameters are: - PWMS: pulse width modulation short phase - PWML: pulse width modulation long phase - PWMO: pulse width modulation offset CiA 612-2 specifies PWMS and PWML to be at least 1 (arguably, PWML shall be at least 2 to respect the PWMS < PWML rule). PWMO's minimum is expected to always be zero. It is added more for consistency than anything else. Add struct can_pwm_const so that the different devices can provide their minimum and maximum values. When TMS is on, the runtime PWMS, PWML and PWMO are needed (either calculated or provided by the user): add struct can_pwm to store these. TDC and PWM can not be used at the same time (TDC can only be used when TMS is off and PWM only when TMS is on). struct can_pwm is thus put together with struct can_tdc inside a union to save some space. The netlink logic will be added in an upcoming change. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- include/linux/can/bittiming.h | 41 +++++++++++++++++++++++++++++++++++++++= -- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/include/linux/can/bittiming.h b/include/linux/can/bittiming.h index b6cd2476ffd7..967d76689c4f 100644 --- a/include/linux/can/bittiming.h +++ b/include/linux/can/bittiming.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2020 Pengutronix, Marc Kleine-Budde - * Copyright (c) 2021 Vincent Mailhol + * Copyright (c) 2021-2025 Vincent Mailhol */ =20 #ifndef _CAN_BITTIMING_H @@ -120,11 +120,48 @@ struct can_tdc_const { u32 tdcf_max; }; =20 +/* + * struct can_pwm - CAN Pulse-Width Modulation (PWM) parameters + * + * @pwms: pulse width modulation short phase + * @pwml: pulse width modulation long phase + * @pwmo: pulse width modulation offset + */ +struct can_pwm { + u32 pwms; + u32 pwml; + u32 pwmo; +}; + +/* + * struct can_pwm - CAN hardware-dependent constants for Pulse-Width + * Modulation (PWM) + * + * @pwms_min: PWM short phase minimum value. Must be at least 1. + * @pwms_max: PWM short phase maximum value + * @pwml_min: PWM long phase minimum value. Must be at least 1. + * @pwml_max: PWM long phase maximum value + * @pwmo_min: PWM offset phase minimum value + * @pwmo_max: PWM offset phase maximum value + */ +struct can_pwm_const { + u32 pwms_min; + u32 pwms_max; + u32 pwml_min; + u32 pwml_max; + u32 pwmo_min; + u32 pwmo_max; +}; + struct data_bittiming_params { const struct can_bittiming_const *data_bittiming_const; struct can_bittiming data_bittiming; const struct can_tdc_const *tdc_const; - struct can_tdc tdc; + const struct can_pwm_const *pwm_const; + union { + struct can_tdc tdc; + struct can_pwm pwm; + }; const u32 *data_bitrate_const; unsigned int data_bitrate_const_cnt; int (*do_set_data_bittiming)(struct net_device *dev); --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B0B4301481 for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=TL1ghDy12pjbjWcLrS5i6B/EybZefl1nCaH/rZPh+IJAubsqHgyf35qG+1C0AkcbLCJ+6Simt2qkW3hxXVdrYcEeEQg2Nw67mJ5HIG8TqjGEyrr3GoCrMoBk0Mpkg3rqFN1sWPZYUbWT6qPA8CsegqBKlHxJr6i8suB5u01D2+M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=ZFFwKnOvhSuIBWQDDMv6kaAVREw0gWi28fIysXwta3U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=p+bGUo9hA/I07DqsnxgFRcVt4DCSmPyCdDhiZgKiT+ZKaBjjVcQUyGE7q99hvyI8kGPCoEu1Ami9koIUFExV8I8JUnw3kpog1TPwYh7sVs0T1SsSv1ZrS6o2mdghB4FpwKc7PBjBsG95NfZ3/PpWUsafE6cuQbCRnVzd2P/J/2E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000Qy-R7; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSq-0d; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id F00B44A88DA; Wed, 26 Nov 2025 10:16:50 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:10 +0100 Subject: [PATCH can-next v8 09/17] can: bittiming: add PWM validation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-9-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5299; i=mkl@pengutronix.de; h=from:subject:message-id; bh=yx/q9gOPPA1BdZiOSo8vRRu2MKMazlfUmz0y7rZkgRA=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOC/yX8qNJz2FqhZhSZbU68ALNQaLeZAiO3D KfEmdsL+mWJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTggAKCRAMdGXf+ZCR nJyXCAC1201Z7zcCgT/cbXyHX5ciqqn3iBaApYUR5a8gFh/jPQwa9cmBcqdrZqC92nvu9m9d/Z0 52lmr5fJb/2S1E4luuP7bNcevL2BWrWikIS2GdI9qiHCxIQ3ErTw9t6x52NzbxkpNMb81B+WvMo AMhk0cZG83jI60dyQOd5eAFNeCKmb758mDJaZKV9js+WeEyJcTUMrKlafP8TZ0OK41K5L/nHZgj F95fma3+ISoe+CKMAmdOdaHgvgKCCPjJR0jNZES3RpFjbMj3uthgzw/beD42deb6kbl/Xe5ezac /Ldy3R19chhVt6c4H9TklGWHxwHAqCGnEU/UdGVouFz0tv2o X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol Add can_validate_pwm() to validate the values pwms, pwml and pwml. Error messages are added to each of the checks to inform the user on what went wrong. Refer to those error messages to understand the validation logic. The boundary values CAN_PWM_DECODE_NS (the transceiver minimum decoding margin) and CAN_PWM_NS_MAX (the maximum PWM symbol duration) are hardcoded for the moment. Note that a transceiver capable of bitrates higher than 20 Mbps may be able to handle a CAN_PWM_DECODE_NS below 5 ns. If such transceivers become commercially available, this code could be revisited to make this parameter configurable. For now, leave it static. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/bittiming.c | 63 +++++++++++++++++++++++++++++++++++++= ++++ include/linux/can/bittiming.h | 22 ++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/drivers/net/can/dev/bittiming.c b/drivers/net/can/dev/bittimin= g.c index 0b93900b1dfa..8f82418230ce 100644 --- a/drivers/net/can/dev/bittiming.c +++ b/drivers/net/can/dev/bittiming.c @@ -2,6 +2,7 @@ /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix * Copyright (C) 2006 Andrey Volkov, Varma Electronics * Copyright (C) 2008-2009 Wolfgang Grandegger + * Copyright (c) 2025 Vincent Mailhol */ =20 #include @@ -151,3 +152,65 @@ int can_get_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, =20 return -EINVAL; } + +int can_validate_pwm_bittiming(const struct net_device *dev, + const struct can_pwm *pwm, + struct netlink_ext_ack *extack) +{ + const struct can_priv *priv =3D netdev_priv(dev); + u32 xl_bit_time_tqmin =3D can_bit_time_tqmin(&priv->xl.data_bittiming); + u32 nom_bit_time_tqmin =3D can_bit_time_tqmin(&priv->bittiming); + u32 pwms_ns =3D can_tqmin_to_ns(pwm->pwms, priv->clock.freq); + u32 pwml_ns =3D can_tqmin_to_ns(pwm->pwml, priv->clock.freq); + + if (pwms_ns + pwml_ns > CAN_PWM_NS_MAX) { + NL_SET_ERR_MSG_FMT(extack, + "The PWM symbol duration: %u ns may not exceed %u ns", + pwms_ns + pwml_ns, CAN_PWM_NS_MAX); + return -EINVAL; + } + + if (pwms_ns < CAN_PWM_DECODE_NS) { + NL_SET_ERR_MSG_FMT(extack, + "PWMS: %u ns shall be at least %u ns", + pwms_ns, CAN_PWM_DECODE_NS); + return -EINVAL; + } + + if (pwm->pwms >=3D pwm->pwml) { + NL_SET_ERR_MSG_FMT(extack, + "PWMS: %u tqmin shall be smaller than PWML: %u tqmin", + pwm->pwms, pwm->pwml); + return -EINVAL; + } + + if (pwml_ns - pwms_ns < 2 * CAN_PWM_DECODE_NS) { + NL_SET_ERR_MSG_FMT(extack, + "At least %u ns shall separate PWMS: %u ns from PMWL: %u ns", + 2 * CAN_PWM_DECODE_NS, pwms_ns, pwml_ns); + return -EINVAL; + } + + if (xl_bit_time_tqmin % (pwm->pwms + pwm->pwml) !=3D 0) { + NL_SET_ERR_MSG_FMT(extack, + "PWM duration: %u tqmin does not divide XL's bit time: %u tqmin", + pwm->pwms + pwm->pwml, xl_bit_time_tqmin); + return -EINVAL; + } + + if (pwm->pwmo >=3D pwm->pwms + pwm->pwml) { + NL_SET_ERR_MSG_FMT(extack, + "PWMO: %u tqmin can not be greater than PWMS + PWML: %u tqmin", + pwm->pwmo, pwm->pwms + pwm->pwml); + return -EINVAL; + } + + if (nom_bit_time_tqmin % (pwm->pwms + pwm->pwml) !=3D pwm->pwmo) { + NL_SET_ERR_MSG_FMT(extack, + "Can not assemble nominal bit time: %u tqmin out of PWMS + PMWL and= PWMO", + nom_bit_time_tqmin); + return -EINVAL; + } + + return 0; +} diff --git a/include/linux/can/bittiming.h b/include/linux/can/bittiming.h index 967d76689c4f..2504fafc72e4 100644 --- a/include/linux/can/bittiming.h +++ b/include/linux/can/bittiming.h @@ -87,6 +87,11 @@ struct can_tdc { u32 tdcf; }; =20 +/* The transceiver decoding margin corresponds to t_Decode in ISO 11898-2 = */ +#define CAN_PWM_DECODE_NS 5 +/* Maximum PWM symbol duration. Corresponds to t_SymbolNom_MAX - t_Decode = */ +#define CAN_PWM_NS_MAX (205 - CAN_PWM_DECODE_NS) + /* * struct can_tdc_const - CAN hardware-dependent constant for * Transmission Delay Compensation @@ -203,6 +208,10 @@ int can_get_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, const unsigned int bitrate_const_cnt, struct netlink_ext_ack *extack); =20 +int can_validate_pwm_bittiming(const struct net_device *dev, + const struct can_pwm *pwm, + struct netlink_ext_ack *extack); + /* * can_get_relative_tdco() - TDCO relative to the sample point * @@ -245,4 +254,17 @@ static inline unsigned int can_bit_time(const struct c= an_bittiming *bt) return CAN_SYNC_SEG + bt->prop_seg + bt->phase_seg1 + bt->phase_seg2; } =20 +/* Duration of one bit in minimum time quantum */ +static inline unsigned int can_bit_time_tqmin(const struct can_bittiming *= bt) +{ + return can_bit_time(bt) * bt->brp; +} + +/* Convert a duration from minimum a minimum time quantum to nano seconds = */ +static inline u32 can_tqmin_to_ns(u32 tqmin, u32 clock_freq) +{ + return DIV_U64_ROUND_CLOSEST(mul_u32_u32(tqmin, NSEC_PER_SEC), + clock_freq); +} + #endif /* !_CAN_BITTIMING_H */ --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 99CB5306481 for ; Wed, 26 Nov 2025 10:17:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=J8jMbZJLO/EB/+PhDywVLtotDroQv7qp1/ykN6kZ/P4jp1wuocNKPjA4JWM5XJbGA2A9vUQhEkZ/BBDVMg+T87n1JfYk6ulyXGOLZ/4O++6fS41WW2Fozrz9TS4hLy5HMqypWuFTzV/2A/9I6gGYRWy6/m0v+aoLJd8knNIHCOI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=02qClV8t/neGzU+Om/CXJdNmGkHB1OpYO0cT6QFVG/0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sjFN5iwUIuPavZZI/nRCbx8n9RGSGKjqBDubM7Jn0rRrBYeRkG2+ydPeCxqeWvReNYwmvJd87atC5XOw53qruzdxbxoocZm5KdSdfqsl5yci3n4kOrrkLIId660mwJIxffSXrzPQfp6+ZRSRaZRjbMLmLcd0c7vTEGrvuo+W72k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000RI-Sy; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSt-0n; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 047FC4A88DB; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:11 +0100 Subject: [PATCH can-next v8 10/17] can: calc_bittiming: add PWM calculation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-10-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3958; i=mkl@pengutronix.de; h=from:subject:message-id; bh=98I2zj8GmadKTNMoYs3T+0NKfbxclYA5pvAk5/CSRIA=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtODxuTQ1ocj4WsaZ4Y4pDVGZYITY+t5NEb3E 9RYNfm068WJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTgwAKCRAMdGXf+ZCR nKjxB/43g3Zud+xW093dn7hsyzJ3zCF7xERL0bi1g8eN4ttw4b9u5Xur1ujVNN+Sdt1FLCM0zV+ FiL7skAf967m6OBMbSq+Db3e7jVdv0vsK6QuEw8GUZQYquEW9x/f7cDnc4omtJI6nP4PFRfkeR1 L6K+70z3E1TJBWlyi7vYPs7/0QG7gfJEy4KhStawrQnc3XECqr5f9XDQwWXc7jI3R1J1CxAgIUT enbRzS1XKFosM7FuHhqJwdTKKr1AGcnboz22BoXStLpayzXN6qSNxy3zzBJ6Jmsb0xE4EMOn7il 9PbZsAcIcyIJ7C/OyHXShCGY4qvnXn+DJDAaQQe//LPg5IlS X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol Perform the PWM calculation according to CiA recommendations. Note that for databitrates greater than 5 MBPS, tqmin is less than CAN_PWM_NS_MAX (which is defined to 200 nano seconds), consequently, the result of the division: DIV_ROUND_UP(xl_ns, CAN_PWM_NS_MAX) is one and thus the for loop automatically stops on the first iteration giving a single PWM symbol per bit as expected. Because of that, there is no actual need for a separate conditional branch for when the databitrate is greater than 5 MBPS. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/calc_bittiming.c | 36 ++++++++++++++++++++++++++++++++= ++++ include/linux/can/bittiming.h | 10 ++++++++++ 2 files changed, 46 insertions(+) diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/cal= c_bittiming.c index 394d6974f481..268ec6fa7c49 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -2,6 +2,7 @@ /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix * Copyright (C) 2006 Andrey Volkov, Varma Electronics * Copyright (C) 2008-2009 Wolfgang Grandegger + * Copyright (C) 2021-2025 Vincent Mailhol */ =20 #include @@ -198,3 +199,38 @@ void can_calc_tdco(struct can_tdc *tdc, const struct c= an_tdc_const *tdc_const, *ctrlmode |=3D tdc_auto; } } + +int can_calc_pwm(struct net_device *dev, struct netlink_ext_ack *extack) +{ + struct can_priv *priv =3D netdev_priv(dev); + const struct can_pwm_const *pwm_const =3D priv->xl.pwm_const; + struct can_pwm *pwm =3D &priv->xl.pwm; + u32 xl_tqmin =3D can_bit_time_tqmin(&priv->xl.data_bittiming); + u32 xl_ns =3D can_tqmin_to_ns(xl_tqmin, priv->clock.freq); + u32 nom_tqmin =3D can_bit_time_tqmin(&priv->bittiming); + int pwm_per_bit_max =3D xl_tqmin / (pwm_const->pwms_min + pwm_const->pwml= _min); + int pwm_per_bit; + u32 pwm_tqmin; + + /* For 5 MB/s databitrate or greater, xl_ns < CAN_PWM_NS_MAX + * giving us a pwm_per_bit of 1 and the loop immediately breaks + */ + for (pwm_per_bit =3D DIV_ROUND_UP(xl_ns, CAN_PWM_NS_MAX); + pwm_per_bit <=3D pwm_per_bit_max; pwm_per_bit++) + if (xl_tqmin % pwm_per_bit =3D=3D 0) + break; + + if (pwm_per_bit > pwm_per_bit_max) { + NL_SET_ERR_MSG_FMT(extack, + "Can not divide the XL data phase's bit time: %u tqmin into multipl= e PWM symbols", + xl_tqmin); + return -EINVAL; + } + + pwm_tqmin =3D xl_tqmin / pwm_per_bit; + pwm->pwms =3D DIV_ROUND_UP_POW2(pwm_tqmin, 4); + pwm->pwml =3D pwm_tqmin - pwm->pwms; + pwm->pwmo =3D nom_tqmin % pwm_tqmin; + + return 0; +} diff --git a/include/linux/can/bittiming.h b/include/linux/can/bittiming.h index 2504fafc72e4..726d909e87ce 100644 --- a/include/linux/can/bittiming.h +++ b/include/linux/can/bittiming.h @@ -180,6 +180,8 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_co= nst, const struct can_bittiming *dbt, u32 tdc_mask, u32 *ctrlmode, u32 ctrlmode_supported); + +int can_calc_pwm(struct net_device *dev, struct netlink_ext_ack *extack); #else /* !CONFIG_CAN_CALC_BITTIMING */ static inline int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, @@ -195,6 +197,14 @@ can_calc_tdco(struct can_tdc *tdc, const struct can_td= c_const *tdc_const, u32 tdc_mask, u32 *ctrlmode, u32 ctrlmode_supported) { } + +static inline int +can_calc_pwm(struct net_device *dev, struct netlink_ext_ack *extack) +{ + NL_SET_ERR_MSG(extack, + "bit-timing calculation not available: manually provide PWML and = PWMS\n"); + return -EINVAL; +} #endif /* CONFIG_CAN_CALC_BITTIMING */ =20 void can_sjw_set_default(struct can_bittiming *bt); --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB9483019AA for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=Pu+hhkhoeC1Ui+Y8e1Fu56rWEU5/pOZhLa59+z1gGt99/4ufhPzI3RoijxZpjOwSZpm8Z6oHb5+u1jUTdMR3a37W2S2GRJQk2YfPv0LQUFndncknF6RrKumFau8/8HQGotEtceqtm7yxRPxKcwSZLcfsri7utkLf47CRGJ7loRI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=0LnwSaryQBMHk6XmHaGq2agr5IEiAwcbckke5AFC6tY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q5FgfjGycsz6BlXh5P8w5eHHY9TASlpPyuJBqUT+Z1qIQGhxTkxwjuKjvOl8CGtNNfKeqJWxRPGHMFUeaMD7/R8uaKhFBb04wYDtKvWJ0yWP3kgz44+fXb4HYw6vgh4kjwg7XYmA5VNivZRPXGQAFkbVK+2K+bWMHByLnubOypE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZv-0000RJ-KC; Wed, 26 Nov 2025 11:16:51 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSu-0t; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 0CC344A88DC; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:12 +0100 Subject: [PATCH can-next v8 11/17] can: netlink: add PWM netlink interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-11-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=12073; i=mkl@pengutronix.de; h=from:subject:message-id; bh=K/ytsfr3HPt0YSoH+C7734lsENMIj0Te9uS5x60/zjY=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOFeslrHDjKSQdqdS5Zi68hF2yyh9kYYV2cW NHCehWVcBuJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbThQAKCRAMdGXf+ZCR nPSGCACSGdszjGEEFd8BiLVct3eUQmWIepT2t7qYD/8wizDb6fu8lb0IkhIyIuqAKlQgPUd2dOj ljdtTDQJkHqHMGeD7XP6YAroiS7YSHj2ORDuLRZu2VpUS105CmCVPTzhmBrRSwu8ZIl2Qd5JUNL PtihwO0xteTSV/hgtyR6zCR737vD+Q57zssir3cIkuAaTbec7wGf+H+8wvRnHRKBHYkiTEmEKDu BIl5KdxaqYtx5HODUAlETIR7F60M3A6geWw4/MhPItBUyFEEQ80tmIKptc7+6lW2WpkoVDV70GW rysIdrFsmiq5w5s5fWpZO6rx8gwyW10Eh82tQMNyC/3HVnoV X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol When the TMS is switched on, the node uses PWM (Pulse Width Modulation) during the data phase instead of the classic NRZ (Non Return to Zero) encoding. PWM is configured by three parameters: - PWMS: Pulse Width Modulation Short phase - PWML: Pulse Width Modulation Long phase - PWMO: Pulse Width Modulation Offset time For each of these parameters, define three IFLA symbols: - IFLA_CAN_PWM_PWM*_MIN: the minimum allowed value. - IFLA_CAN_PWM_PWM*_MAX: the maximum allowed value. - IFLA_CAN_PWM_PWM*: the runtime value. This results in a total of nine IFLA symbols which are all nested in a parent IFLA_CAN_XL_PWM symbol. IFLA_CAN_PWM_PWM*_MIN and IFLA_CAN_PWM_PWM*_MAX define the range of allowed values and will match the value statically configured by the device in struct can_pwm_const. IFLA_CAN_PWM_PWM* match the runtime values stored in struct can_pwm. Those parameters may only be configured when the tms mode is on. If the PWMS, PWML and PWMO parameters are provided, check that all the needed parameters are present using can_validate_pwm(), then check their value using can_validate_pwm_bittiming(). PWMO defaults to zero if omitted. Otherwise, if CAN_CTRLMODE_XL_TMS is true but none of the PWM parameters are provided, calculate them using can_calc_pwm(). Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/netlink.c | 192 +++++++++++++++++++++++++++++++++++= +++- include/uapi/linux/can/netlink.h | 25 +++++ 2 files changed, 215 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index b2c24439abba..d6b0e686fb11 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -25,6 +25,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + = 1] =3D { [IFLA_CAN_XL_DATA_BITTIMING] =3D { .len =3D sizeof(struct can_bittiming) = }, [IFLA_CAN_XL_DATA_BITTIMING_CONST] =3D { .len =3D sizeof(struct can_bitti= ming_const) }, [IFLA_CAN_XL_TDC] =3D { .type =3D NLA_NESTED }, + [IFLA_CAN_XL_PWM] =3D { .type =3D NLA_NESTED }, }; =20 static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] =3D { @@ -39,6 +40,18 @@ static const struct nla_policy can_tdc_policy[IFLA_CAN_T= DC_MAX + 1] =3D { [IFLA_CAN_TDC_TDCF] =3D { .type =3D NLA_U32 }, }; =20 +static const struct nla_policy can_pwm_policy[IFLA_CAN_PWM_MAX + 1] =3D { + [IFLA_CAN_PWM_PWMS_MIN] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWMS_MAX] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWML_MIN] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWML_MAX] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWMO_MIN] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWMO_MAX] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWMS] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWML] =3D { .type =3D NLA_U32 }, + [IFLA_CAN_PWM_PWMO] =3D { .type =3D NLA_U32 }, +}; + static int can_validate_bittiming(struct nlattr *data[], struct netlink_ext_ack *extack, int ifla_can_bittiming) @@ -119,6 +132,40 @@ static int can_validate_tdc(struct nlattr *data_tdc, return 0; } =20 +static int can_validate_pwm(struct nlattr *data[], + struct netlink_ext_ack *extack, u32 flags) +{ + struct nlattr *tb_pwm[IFLA_CAN_PWM_MAX + 1]; + int err; + + if (!data[IFLA_CAN_XL_PWM]) + return 0; + + if (!(flags & CAN_CTRLMODE_XL_TMS)) { + NL_SET_ERR_MSG(extack, "PWM requires TMS"); + return -EOPNOTSUPP; + } + + err =3D nla_parse_nested(tb_pwm, IFLA_CAN_PWM_MAX, data[IFLA_CAN_XL_PWM], + can_pwm_policy, extack); + if (err) + return err; + + if (!tb_pwm[IFLA_CAN_PWM_PWMS] !=3D !tb_pwm[IFLA_CAN_PWM_PWML]) { + NL_SET_ERR_MSG(extack, + "Provide either both PWMS and PWML, or none for automatic calcul= ation"); + return -EOPNOTSUPP; + } + + if (tb_pwm[IFLA_CAN_PWM_PWMO] && + (!tb_pwm[IFLA_CAN_PWM_PWMS] || !tb_pwm[IFLA_CAN_PWM_PWML])) { + NL_SET_ERR_MSG(extack, "PWMO requires both PWMS and PWML"); + return -EOPNOTSUPP; + } + + return 0; +} + static int can_validate_databittiming(struct nlattr *data[], struct netlink_ext_ack *extack, int ifla_can_data_bittiming, u32 flags) @@ -247,6 +294,10 @@ static int can_validate(struct nlattr *tb[], struct nl= attr *data[], if (err) return err; =20 + err =3D can_validate_pwm(data, extack, flags); + if (err) + return err; + return 0; } =20 @@ -322,6 +373,7 @@ static int can_ctrlmode_changelink(struct net_device *d= ev, sizeof(priv->fd.data_bittiming)); priv->ctrlmode &=3D ~CAN_CTRLMODE_XL_TDC_MASK; memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc)); + memset(&priv->xl.pwm, 0, sizeof(priv->xl.pwm)); } =20 can_set_default_mtu(dev); @@ -468,6 +520,76 @@ static int can_dbt_changelink(struct net_device *dev, = struct nlattr *data[], return 0; } =20 +static int can_pwm_changelink(struct net_device *dev, + const struct nlattr *pwm_nla, + struct netlink_ext_ack *extack) +{ + struct can_priv *priv =3D netdev_priv(dev); + const struct can_pwm_const *pwm_const =3D priv->xl.pwm_const; + struct nlattr *tb_pwm[IFLA_CAN_PWM_MAX + 1]; + struct can_pwm pwm =3D { 0 }; + int err; + + if (!(priv->ctrlmode & CAN_CTRLMODE_XL_TMS)) + return 0; + + if (!pwm_const) { + NL_SET_ERR_MSG(extack, "The device does not support PWM"); + return -EOPNOTSUPP; + } + + if (!pwm_nla) + return can_calc_pwm(dev, extack); + + err =3D nla_parse_nested(tb_pwm, IFLA_CAN_PWM_MAX, pwm_nla, + can_pwm_policy, extack); + if (err) + return err; + + if (tb_pwm[IFLA_CAN_PWM_PWMS]) { + pwm.pwms =3D nla_get_u32(tb_pwm[IFLA_CAN_PWM_PWMS]); + if (pwm.pwms < pwm_const->pwms_min || + pwm.pwms > pwm_const->pwms_max) { + NL_SET_ERR_MSG_FMT(extack, + "PWMS: %u tqmin is out of range: %u...%u", + pwm.pwms, pwm_const->pwms_min, + pwm_const->pwms_max); + return -EINVAL; + } + } + + if (tb_pwm[IFLA_CAN_PWM_PWML]) { + pwm.pwml =3D nla_get_u32(tb_pwm[IFLA_CAN_PWM_PWML]); + if (pwm.pwml < pwm_const->pwml_min || + pwm.pwml > pwm_const->pwml_max) { + NL_SET_ERR_MSG_FMT(extack, + "PWML: %u tqmin is out of range: %u...%u", + pwm.pwml, pwm_const->pwml_min, + pwm_const->pwml_max); + return -EINVAL; + } + } + + if (tb_pwm[IFLA_CAN_PWM_PWMO]) { + pwm.pwmo =3D nla_get_u32(tb_pwm[IFLA_CAN_PWM_PWMO]); + if (pwm.pwmo < pwm_const->pwmo_min || + pwm.pwmo > pwm_const->pwmo_max) { + NL_SET_ERR_MSG_FMT(extack, + "PWMO: %u tqmin is out of range: %u...%u", + pwm.pwmo, pwm_const->pwmo_min, + pwm_const->pwmo_max); + return -EINVAL; + } + } + + err =3D can_validate_pwm_bittiming(dev, &pwm, extack); + if (err) + return err; + + priv->xl.pwm =3D pwm; + return 0; +} + static int can_changelink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) @@ -559,6 +681,9 @@ static int can_changelink(struct net_device *dev, struc= t nlattr *tb[], =20 /* CAN XL */ err =3D can_dbt_changelink(dev, data, false, extack); + if (err) + return err; + err =3D can_pwm_changelink(dev, data[IFLA_CAN_XL_PWM], extack); if (err) return err; =20 @@ -647,6 +772,30 @@ static size_t can_ctrlmode_ext_get_size(void) nla_total_size(sizeof(u32)); /* IFLA_CAN_CTRLMODE_SUPPORTED */ } =20 +static size_t can_pwm_get_size(const struct can_pwm_const *pwm_const, + bool pwm_on) +{ + size_t size; + + if (!pwm_const || !pwm_on) + return 0; + + size =3D nla_total_size(0); /* nest IFLA_CAN_PWM */ + + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMS_MIN */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMS_MAX */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWML_MIN */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWML_MAX */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMO_MIN */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMO_MAX */ + + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMS */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWML */ + size +=3D nla_total_size(sizeof(u32)); /* IFLA_CAN_PWM_PWMO */ + + return size; +} + static size_t can_get_size(const struct net_device *dev) { struct can_priv *priv =3D netdev_priv(dev); @@ -678,6 +827,8 @@ static size_t can_get_size(const struct net_device *dev) =20 size +=3D can_data_bittiming_get_size(&priv->xl, priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK); + size +=3D can_pwm_get_size(priv->xl.pwm_const, /* IFLA_CAN_XL_PWM */ + priv->ctrlmode & CAN_CTRLMODE_XL_TMS); =20 return size; } @@ -776,6 +927,42 @@ static int can_tdc_fill_info(struct sk_buff *skb, cons= t struct net_device *dev, return -EMSGSIZE; } =20 +static int can_pwm_fill_info(struct sk_buff *skb, const struct can_priv *p= riv) +{ + const struct can_pwm_const *pwm_const =3D priv->xl.pwm_const; + const struct can_pwm *pwm =3D &priv->xl.pwm; + struct nlattr *nest; + + if (!pwm_const) + return 0; + + nest =3D nla_nest_start(skb, IFLA_CAN_XL_PWM); + if (!nest) + return -EMSGSIZE; + + if (nla_put_u32(skb, IFLA_CAN_PWM_PWMS_MIN, pwm_const->pwms_min) || + nla_put_u32(skb, IFLA_CAN_PWM_PWMS_MAX, pwm_const->pwms_max) || + nla_put_u32(skb, IFLA_CAN_PWM_PWML_MIN, pwm_const->pwml_min) || + nla_put_u32(skb, IFLA_CAN_PWM_PWML_MAX, pwm_const->pwml_max) || + nla_put_u32(skb, IFLA_CAN_PWM_PWMO_MIN, pwm_const->pwmo_min) || + nla_put_u32(skb, IFLA_CAN_PWM_PWMO_MAX, pwm_const->pwmo_max)) + goto err_cancel; + + if (priv->ctrlmode & CAN_CTRLMODE_XL_TMS) { + if (nla_put_u32(skb, IFLA_CAN_PWM_PWMS, pwm->pwms) || + nla_put_u32(skb, IFLA_CAN_PWM_PWML, pwm->pwml) || + nla_put_u32(skb, IFLA_CAN_PWM_PWMO, pwm->pwmo)) + goto err_cancel; + } + + nla_nest_end(skb, nest); + return 0; + +err_cancel: + nla_nest_cancel(skb, nest); + return -EMSGSIZE; +} + static int can_ctrlmode_ext_fill_info(struct sk_buff *skb, const struct can_priv *priv) { @@ -859,9 +1046,10 @@ static int can_fill_info(struct sk_buff *skb, const s= truct net_device *dev) priv->xl.data_bitrate_const, priv->xl.data_bitrate_const_cnt) || =20 - can_tdc_fill_info(skb, dev, IFLA_CAN_XL_TDC) - ) + can_tdc_fill_info(skb, dev, IFLA_CAN_XL_TDC) || =20 + can_pwm_fill_info(skb, priv) + ) return -EMSGSIZE; =20 return 0; diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netl= ink.h index ebafb091d80f..c30d16746159 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -5,6 +5,7 @@ * Definitions for the CAN netlink interface * * Copyright (c) 2009 Wolfgang Grandegger + * Copyright (c) 2021-2025 Vincent Mailhol * * This program is free software; you can redistribute it and/or modify * it under the terms of the version 2 of the GNU General Public License @@ -147,6 +148,7 @@ enum { IFLA_CAN_XL_DATA_BITTIMING_CONST, IFLA_CAN_XL_DATA_BITRATE_CONST, IFLA_CAN_XL_TDC, + IFLA_CAN_XL_PWM, =20 /* add new constants above here */ __IFLA_CAN_MAX, @@ -188,6 +190,29 @@ enum { IFLA_CAN_CTRLMODE_MAX =3D __IFLA_CAN_CTRLMODE - 1 }; =20 +/* + * CAN FD/XL Pulse-Width Modulation (PWM) + * + * Please refer to struct can_pwm_const and can_pwm in + * include/linux/can/bittiming.h for further details. + */ +enum { + IFLA_CAN_PWM_UNSPEC, + IFLA_CAN_PWM_PWMS_MIN, /* u32 */ + IFLA_CAN_PWM_PWMS_MAX, /* u32 */ + IFLA_CAN_PWM_PWML_MIN, /* u32 */ + IFLA_CAN_PWM_PWML_MAX, /* u32 */ + IFLA_CAN_PWM_PWMO_MIN, /* u32 */ + IFLA_CAN_PWM_PWMO_MAX, /* u32 */ + IFLA_CAN_PWM_PWMS, /* u32 */ + IFLA_CAN_PWM_PWML, /* u32 */ + IFLA_CAN_PWM_PWMO, /* u32 */ + + /* add new constants above here */ + __IFLA_CAN_PWM, + IFLA_CAN_PWM_MAX =3D __IFLA_CAN_PWM - 1 +}; + /* u16 termination range: 1..65535 Ohms */ #define CAN_TERMINATION_DISABLED 0 =20 --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D8CD13009ED for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=XEdWX7itWo64YGoLxIj4G6hO0RiuoPZEJyVDKXIo7/FxEc22ylhD9nMdvhuOMzgYADvbpwy1Y9PrKC1Ur7zEPh4ovnWz4KVQLshhlDklGHAaFU8mJd4HGdh88sUSBk44+msMzI5OM9csA2yMVtwtyFE/ljof96Q56h8jazrSQCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=M8V6jfE7RgymR7a2gd5FDYaJ9SS0V/zDQuGkP+QUqcs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dafOeDw/FThM3n0r9C6E5XRIQ8Tsg+ulzM9xofAY6dqvSz+xEV7qPKnxGRi5Xi/hBSuYzw7xLS3JkW3U99YrLcaTeFI7CEM9rJGTWAoLj4gVarNKJAUpwWvGF7BOI8P0K1ix1p9PNcGOsp6jcIZeLw4+Anc3otGN6zSQsYkgXm0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000RW-0r; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSx-15; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 16D954A88DD; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:13 +0100 Subject: [PATCH can-next v8 12/17] can: calc_bittiming: replace misleading "nominal" by "reference" Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-12-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4567; i=mkl@pengutronix.de; h=from:subject:message-id; bh=zfU33+qIh3oomxHhxXPcNk3KNLPMvGySxv+hWnX3g7I=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOHbzDxhx+EWLbkJSCzfNeoZI0f8PicE7uS6 m+qoud6d5qJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbThwAKCRAMdGXf+ZCR nJtTCACX+nd0J58YwEE1RF0Hzkw6Ga3Ctpdb7lhxM7/6rW7nXSLu+WKFweIfrBvRPf2Dl/3ORjf Efhnmomz6n9ez3QhBbH5rIoUmu5klevtmMn2Lst25yqN5DSONxVG2W9hmu9wlMTY1ogfDMMToN2 DllCug2iEiq8JIqsCAvTLmMkfOGtsTaY7ynKBk3AlI8QtqTZOkmK+P31NR+pskQ+ga6zqIzu91K FD1SBhe4t2mo0OiRIaezbGvHuUHaRR3e89SBJLOju81JOdcI6lrXztwz9Y1f3cqUD3Tu/hQC1uo ZoJE9YFyGs9RWKkFkV/4Y7ImhNOZORY6eI85ykK6QkRD+qp+ X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol The functions can_update_sample_point() and can_calc_bittiming() are generic and meant to be used for both the nominal and the data bittiming calculation. However, those functions use misleading terminologies such as "bitrate nominal" or "sample point nominal". Replace all places where the word "nominal" appears with "reference" in order to better distinguish it from the calculated values. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/calc_bittiming.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/cal= c_bittiming.c index 268ec6fa7c49..c8c166b383cd 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -24,7 +24,7 @@ */ static int can_update_sample_point(const struct can_bittiming_const *btc, - const unsigned int sample_point_nominal, const unsigned int tseg, + const unsigned int sample_point_reference, const unsigned int tseg, unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, unsigned int *sample_point_error_ptr) { @@ -35,7 +35,7 @@ can_update_sample_point(const struct can_bittiming_const = *btc, =20 for (i =3D 0; i <=3D 1; i++) { tseg2 =3D tseg + CAN_SYNC_SEG - - (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / + (sample_point_reference * (tseg + CAN_SYNC_SEG)) / 1000 - i; tseg2 =3D clamp(tseg2, btc->tseg2_min, btc->tseg2_max); tseg1 =3D tseg - tseg2; @@ -46,9 +46,9 @@ can_update_sample_point(const struct can_bittiming_const = *btc, =20 sample_point =3D 1000 * (tseg + CAN_SYNC_SEG - tseg2) / (tseg + CAN_SYNC_SEG); - sample_point_error =3D abs(sample_point_nominal - sample_point); + sample_point_error =3D abs(sample_point_reference - sample_point); =20 - if (sample_point <=3D sample_point_nominal && + if (sample_point <=3D sample_point_reference && sample_point_error < best_sample_point_error) { best_sample_point =3D sample_point; best_sample_point_error =3D sample_point_error; @@ -68,11 +68,11 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, { struct can_priv *priv =3D netdev_priv(dev); unsigned int bitrate; /* current bitrate */ - unsigned int bitrate_error; /* difference between current and nominal va= lue */ + unsigned int bitrate_error; /* diff between calculated and reference val= ue */ unsigned int best_bitrate_error =3D UINT_MAX; - unsigned int sample_point_error; /* difference between current and nomina= l value */ + unsigned int sample_point_error; /* diff between calculated and reference= value */ unsigned int best_sample_point_error =3D UINT_MAX; - unsigned int sample_point_nominal; /* nominal sample point */ + unsigned int sample_point_reference; /* reference sample point */ unsigned int best_tseg =3D 0; /* current best value for tseg */ unsigned int best_brp =3D 0; /* current best value for brp */ unsigned int brp, tsegall, tseg, tseg1 =3D 0, tseg2 =3D 0; @@ -81,14 +81,14 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, =20 /* Use CiA recommended sample points */ if (bt->sample_point) { - sample_point_nominal =3D bt->sample_point; + sample_point_reference =3D bt->sample_point; } else { if (bt->bitrate > 800 * KILO /* BPS */) - sample_point_nominal =3D 750; + sample_point_reference =3D 750; else if (bt->bitrate > 500 * KILO /* BPS */) - sample_point_nominal =3D 800; + sample_point_reference =3D 800; else - sample_point_nominal =3D 875; + sample_point_reference =3D 875; } =20 /* tseg even =3D round down, odd =3D round up */ @@ -115,7 +115,7 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, if (bitrate_error < best_bitrate_error) best_sample_point_error =3D UINT_MAX; =20 - can_update_sample_point(btc, sample_point_nominal, tseg / 2, + can_update_sample_point(btc, sample_point_reference, tseg / 2, &tseg1, &tseg2, &sample_point_error); if (sample_point_error >=3D best_sample_point_error) continue; @@ -146,7 +146,7 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, } =20 /* real sample point */ - bt->sample_point =3D can_update_sample_point(btc, sample_point_nominal, + bt->sample_point =3D can_update_sample_point(btc, sample_point_reference, best_tseg, &tseg1, &tseg2, NULL); =20 --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF3FA3016F0 for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=e4TaSC0HtElWVBZHDuFEoNwpkuCDUGDj/7DsZOKVDtvDXFSmOGZN7w9qd43T7JB7PgBdA1GEPwej9L7CTAWxG1dkYYoH57mPwPflzqqroifrj8LnToL4cZz5IQD2q3r+KC3No+eyz/RDObARe74el9PGfWdNnSTxpzouEnBccmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=7upFcfNtk02ZrLQVj1Y75LsfDYr/ckHj8RmqRB7L5yg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tg4pXCLAbQY2QRrc+zkVFz2IW4fyB+LuQmVXCY3PYFKakiFYYjPmX4PID51HXB+QLooHM4MLtlOjj7P9jfMh9m8/C2IcqTxmIS93z2j+k9t/rb0a2ez15R5WUsVnzF2q2f5gWLPsn8ExbMlAzf/WlVNQ0lqNQRVL6lmf8SLm1x0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000RV-0c; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aSy-15; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 1EAAB4A88DE; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:14 +0100 Subject: [PATCH can-next v8 13/17] can: calc_bittiming: add can_calc_sample_point_nrz() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-13-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=2123; i=mkl@pengutronix.de; h=from:subject:message-id; bh=h8iUAW6OBOFyCa9dq/JPiYvY0k8Oxvczhn5v3kx3D/4=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOJYtjRl8SeCMThJIdwh0AW+aWDgJuOvFrBE 0cAqpFUooaJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTiQAKCRAMdGXf+ZCR nBc6B/9ghzzQw0+RyLt9eKJ9cAzyR+jbUbNkc5lkT/ZhjA+GXHzdd4N9skB59nJCMU6UTeCJiVa IaNsQNKyO3aISxTVOQmolB/Fsjti+3Hp66uNuYQ44EgV6qKKefTDmeqtRAOFlEclnYPOmO9BVYA fWOmtINg7swiX00EFo2GaMYIqugE214CiIQ1rMEiM0w6yPKQ8an9AlVLTH6VeZ/+eM9rfl4/hX3 kndOboOlAyU9nBZW/D6OYMayxDbNr1QrQgOXHN4kryzTYZmfZYFyx25xBsdF16cNLVwFfnRNo3z oswsP/JlbpW8TocaQF9icCciBKvIinAlIYnWRdxuHUcB1te6 X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol CAN XL optimal sample point for PWM encoding (when TMS is on) differs from the NRZ optimal one. There is thus a need to calculate a different sample point depending whether TMS is on or off. This is a preparation change: move the sample point calculation from can_calc_bittiming() into the new can_calc_sample_point_nrz() function. In an upcoming change, a function will be added to calculate the sample point for PWM encoding. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/calc_bittiming.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/cal= c_bittiming.c index c8c166b383cd..bacdf3b218d3 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -10,6 +10,18 @@ =20 #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ =20 +/* CiA recommended sample points for Non Return to Zero encoding. */ +static int can_calc_sample_point_nrz(const struct can_bittiming *bt) +{ + if (bt->bitrate > 800 * KILO /* BPS */) + return 750; + + if (bt->bitrate > 500 * KILO /* BPS */) + return 800; + + return 875; +} + /* Bit-timing calculation derived from: * * Code based on LinCAN sources and H8S2638 project @@ -79,17 +91,10 @@ int can_calc_bittiming(const struct net_device *dev, st= ruct can_bittiming *bt, u64 v64; int err; =20 - /* Use CiA recommended sample points */ - if (bt->sample_point) { + if (bt->sample_point) sample_point_reference =3D bt->sample_point; - } else { - if (bt->bitrate > 800 * KILO /* BPS */) - sample_point_reference =3D 750; - else if (bt->bitrate > 500 * KILO /* BPS */) - sample_point_reference =3D 800; - else - sample_point_reference =3D 875; - } + else + sample_point_reference =3D can_calc_sample_point_nrz(bt); =20 /* tseg even =3D round down, odd =3D round up */ for (tseg =3D (btc->tseg1_max + btc->tseg2_max) * 2 + 1; --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6853F2E0B6E for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; cv=none; b=O1dvnLpctEWvLVQvWE8Iz9vbg+3sFxvrPJs7lYIagqnlw9JV0lFQ//xVYt4b8WY+1QYg+sbkYGsOqoa38GOKevP/yR1CxXmgFdLU6ZGnqh3ZCWt24aSAbdPmDBJIVCObA2kaYr/3KUzXntyYZHuZpQCuwVn67Y8ErArf9Sbm8M4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152227; c=relaxed/simple; bh=U7sHx0JHfit70X87294eNPlexAjBUfBhDOyNYjh1j4M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=egDpdRhmWD/nLqzQ37F9XTB4DyqHFwhhknW+nkKrUX70TgIPreSs0wgB5mWOKr6lPac9FqW/GDw/+ZKU7n42zWg7Rj+BrVcQa65mOT3bEik8MW+TzFsh5oMFUfDJdKPp3Y7M9c6E3Jpe7barl3ae/+H+x1SXe1umAMPRC+NPsJw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000Ri-14; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aT1-1B; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 28AC04A88DF; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:15 +0100 Subject: [PATCH can-next v8 14/17] can: calc_bittiming: add can_calc_sample_point_pwm() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-14-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3143; i=mkl@pengutronix.de; h=from:subject:message-id; bh=4a1B/+vlW70I8/v+O7LaVAdKn9ZOfWTl31QbKZLswJo=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOLwFLAKekYMJzcaOaOAr7ufNhmz4nPG+p4r nGoh6MQ80OJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTiwAKCRAMdGXf+ZCR nMx1B/48pFn2VNEkNqEBUxI/qRg/+LPJbdgdeToVUjsXVtcSaJNKUIGliz4fhF6p7XlOW2cqDqz jW5b37GSmV3W3GF837bmZMz1jjOSbl3QlL9eaYAq5v/Z874LCaCEp+Dd2I5FMlEsrh65fJFLWUC h6IDjY/1wpYO8KRXpUpIrhAFYyIf4ueUdn5X6mWL63ir+AI9KZBwMlheqU+oUVeEPF7KkkSEyBl ma40Hw4+lBoq1WHnwHntEzip7pouwnGiv5anvDINnoN9kkeMZmF4iSw9QjKo/rPLRO/wo307yew IE/EfIp9I2OHOTPTYiy128/FtfLHBQPUIluOWyXh89qy7KrM X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol The optimum sample point value depends on the bit symmetry. The more asymmetric the bit is, the more the sample point would be located towards the end of the bit. On the contrary, if the transceiver only has a small asymmetry, the optimal sample point would be slightly after the centre of the bit. For NRZ encoding (used by Classical CAN, CAN FD and CAN XL with TMS off), the optimum sample points values are above 70% as implemented in can_calc_sample_point_nrz(). When TMS is on, CAN XL optimum sample points are near to 50% or 60% [1]. Add can_calc_sample_point_pwm() which returns a sample point which is suitable for PWM encoding. We crafted the formula to make it return the same values as below table (source: table 3 of [1]). Bit rate (Mbits/s) Sample point ------------------------------------- 2.0 51.3% 5.0 53.1% 8.0 55.0% 10.0 56.3% 12.3 53.8% 13.3 58.3% 14.5 54.5% 16.0 60.0% 17.7 55.6% 20.0 62.5% The calculation simply consists of setting a slightly too high sample point and then letting can_update_sample_point() correct the values. For now, it is just a formula up our sleeves which matches the empirical observations of [1]. Once CiA recommendations become available, can_calc_sample_point_pwm() should be updated accordingly. [1] CAN XL system design: Clock tolerances and edge deviations edge deviations Link: https://www.can-cia.org/fileadmin/cia/documents/publications/cnlm/dec= ember_2024/cnlm_24-4_p18_can_xl_system_design_clock_tolerances_and_edge_dev= iations_dr_arthur_mutter_bosch.pdf Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/calc_bittiming.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/cal= c_bittiming.c index bacdf3b218d3..60a505ce69de 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -22,6 +22,21 @@ static int can_calc_sample_point_nrz(const struct can_bi= ttiming *bt) return 875; } =20 +/* Sample points for Pulse-Width Modulation encoding. */ +static int can_calc_sample_point_pwm(const struct can_bittiming *bt) +{ + if (bt->bitrate > 15 * MEGA /* BPS */) + return 625; + + if (bt->bitrate > 9 * MEGA /* BPS */) + return 600; + + if (bt->bitrate > 4 * MEGA /* BPS */) + return 560; + + return 520; +} + /* Bit-timing calculation derived from: * * Code based on LinCAN sources and H8S2638 project @@ -93,6 +108,9 @@ int can_calc_bittiming(const struct net_device *dev, str= uct can_bittiming *bt, =20 if (bt->sample_point) sample_point_reference =3D bt->sample_point; + else if (btc =3D=3D priv->xl.data_bittiming_const && + (priv->ctrlmode & CAN_CTRLMODE_XL_TMS)) + sample_point_reference =3D can_calc_sample_point_pwm(bt); else sample_point_reference =3D can_calc_sample_point_nrz(bt); =20 --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF2812FFDE0 for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=mp5ErgZ3fj0mI+do2YqJ0YcVbW4yyO/uVg1sC7lsg/rxxFY0DD/vH/yGKihwAZL1uqUWZt0Sf2tN/mcu4TJ1hnprY0u1STQOaYntUZe6guapK7Rr1oMrN66nEtn/yxxR25BGmQB4Ovr5+egggsTV6vBqz+hs2C0SVwuljmNetN8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=dHh+0CxMZuabS8R/sUctAv5QPvgEtCZMX0p9pffH1DE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FNYMgyABAvpvKLfO7s5Xk9ogp1VbnruKe2T8Z7CQ0nLQAr2zp7gerqEEQlLoZe23+sKzRgoM5md0MUpke1Oav7kX4M5qZZSHEXtnUrQhO8EvzvcdDLYDfMEMfxfQHKW5n7iNVJwKTUYY2x7KFzD6ncf19WbnOxdXCJu1E5yYLZw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000SF-7L; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aTN-1y; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 30C194A88E0; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:16 +0100 Subject: [PATCH can-next v8 15/17] can: add dummy_can driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-15-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11015; i=mkl@pengutronix.de; h=from:subject:message-id; bh=MEu1fb5xA2EjspKTS/EWNMdWezEhy1B7PZP5yjBWc5I=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOM7gAF3b78Msg/sNbDVfaOdPuYmOmp27jbP ihxhe2oKpqJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTjAAKCRAMdGXf+ZCR nMo2CACVXMFjEmmQtUsDVLvvorExZcxSEKUi5JueHeYW2uMvcMBTw9N7O5OJhFwvbRRkwZdm08k fgMX60AXlDwvdVjOElmEl/yq6zXnDYZ7/ea6dJgr+UDf2RxEsMzqzjEtPAnpWYcZADw8VqHzcGf +IrEXz2I2wCGQf70gLZ7v9BFdicbHErzPVBCrnKDvIbv8ic/dIGt1rgENZrM4Qo8LQiDSaznsxP 6sruW10YYwc+iVvWa0JM6j5CBmrGAh+DDwUyUalPopK75mXY2/e9n/ooTo2QwTkGRFEdrL+A0vF 9tDU+opFrWtcatfyEpyF4Y9nUbmK/07FyVr7ETjQua52K3YR X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Vincent Mailhol During the development of CAN XL, we found the need of creating a dummy CAN XL driver in order to test the new netlink interface. While this code was initially intended to be some throwaway, it received some positive feedback. Add the dummy_can driver. This driver acts similarly to the vcan interface in the sense that it will echo back any packet it receives. The difference is that it exposes a set on bittiming parameters as a real device would and thus must be configured as if it was a real physical interface. The driver comes with a debug mode. If debug message are enabled (for example by enabling CONFIG_CAN_DEBUG_DEVICES), it will print in the kernel log all the bittiming values, similar to what a: ip --details link show can0 would do. This driver is mostly intended for debugging and testing, but some developers also may want to look at it as a simple reference implementation. Signed-off-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 17 +++ drivers/net/can/Makefile | 1 + drivers/net/can/dummy_can.c | 285 ++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 303 insertions(+) diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d43d56694667..e15e320db476 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -124,6 +124,23 @@ config CAN_CAN327 =20 If this driver is built as a module, it will be called can327. =20 +config CAN_DUMMY + tristate "Dummy CAN" + help + A dummy CAN module supporting Classical CAN, CAN FD and CAN XL. It + exposes bittiming values which can be configured through the netlink + interface. + + The module will simply echo any frame sent to it. If debug messages + are activated, it prints all the CAN bittiming information in the + kernel log. Aside from that it does nothing. + + This is convenient for testing the CAN netlink interface. Most of the + users will never need this. If unsure, say NO. + + To compile this driver as a module, choose M here: the module will be + called dummy-can. + config CAN_FLEXCAN tristate "Support for Freescale FLEXCAN based chips" depends on OF || COLDFIRE || COMPILE_TEST diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 56138d8ddfd2..d7bc10a6b8ea 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_CAN_CAN327) +=3D can327.o obj-$(CONFIG_CAN_CC770) +=3D cc770/ obj-$(CONFIG_CAN_C_CAN) +=3D c_can/ obj-$(CONFIG_CAN_CTUCANFD) +=3D ctucanfd/ +obj-$(CONFIG_CAN_DUMMY) +=3D dummy_can.o obj-$(CONFIG_CAN_FLEXCAN) +=3D flexcan/ obj-$(CONFIG_CAN_GRCAN) +=3D grcan.o obj-$(CONFIG_CAN_IFI_CANFD) +=3D ifi_canfd/ diff --git a/drivers/net/can/dummy_can.c b/drivers/net/can/dummy_can.c new file mode 100644 index 000000000000..41953655e3d3 --- /dev/null +++ b/drivers/net/can/dummy_can.c @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2025 Vincent Mailhol */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct dummy_can { + struct can_priv can; + struct net_device *dev; +}; + +static struct dummy_can *dummy_can; + +static const struct can_bittiming_const dummy_can_bittiming_const =3D { + .name =3D "dummy_can CC", + .tseg1_min =3D 2, + .tseg1_max =3D 256, + .tseg2_min =3D 2, + .tseg2_max =3D 128, + .sjw_max =3D 128, + .brp_min =3D 1, + .brp_max =3D 512, + .brp_inc =3D 1 +}; + +static const struct can_bittiming_const dummy_can_fd_databittiming_const = =3D { + .name =3D "dummy_can FD", + .tseg1_min =3D 2, + .tseg1_max =3D 256, + .tseg2_min =3D 2, + .tseg2_max =3D 128, + .sjw_max =3D 128, + .brp_min =3D 1, + .brp_max =3D 512, + .brp_inc =3D 1 +}; + +static const struct can_tdc_const dummy_can_fd_tdc_const =3D { + .tdcv_min =3D 0, + .tdcv_max =3D 0, /* Manual mode not supported. */ + .tdco_min =3D 0, + .tdco_max =3D 127, + .tdcf_min =3D 0, + .tdcf_max =3D 127 +}; + +static const struct can_bittiming_const dummy_can_xl_databittiming_const = =3D { + .name =3D "dummy_can XL", + .tseg1_min =3D 2, + .tseg1_max =3D 256, + .tseg2_min =3D 2, + .tseg2_max =3D 128, + .sjw_max =3D 128, + .brp_min =3D 1, + .brp_max =3D 512, + .brp_inc =3D 1 +}; + +static const struct can_tdc_const dummy_can_xl_tdc_const =3D { + .tdcv_min =3D 0, + .tdcv_max =3D 0, /* Manual mode not supported. */ + .tdco_min =3D 0, + .tdco_max =3D 127, + .tdcf_min =3D 0, + .tdcf_max =3D 127 +}; + +static const struct can_pwm_const dummy_can_pwm_const =3D { + .pwms_min =3D 1, + .pwms_max =3D 8, + .pwml_min =3D 2, + .pwml_max =3D 24, + .pwmo_min =3D 0, + .pwmo_max =3D 16, +}; + +static void dummy_can_print_bittiming(struct net_device *dev, + struct can_bittiming *bt) +{ + netdev_dbg(dev, "\tbitrate: %u\n", bt->bitrate); + netdev_dbg(dev, "\tsample_point: %u\n", bt->sample_point); + netdev_dbg(dev, "\ttq: %u\n", bt->tq); + netdev_dbg(dev, "\tprop_seg: %u\n", bt->prop_seg); + netdev_dbg(dev, "\tphase_seg1: %u\n", bt->phase_seg1); + netdev_dbg(dev, "\tphase_seg2: %u\n", bt->phase_seg2); + netdev_dbg(dev, "\tsjw: %u\n", bt->sjw); + netdev_dbg(dev, "\tbrp: %u\n", bt->brp); +} + +static void dummy_can_print_tdc(struct net_device *dev, struct can_tdc *td= c) +{ + netdev_dbg(dev, "\t\ttdcv: %u\n", tdc->tdcv); + netdev_dbg(dev, "\t\ttdco: %u\n", tdc->tdco); + netdev_dbg(dev, "\t\ttdcf: %u\n", tdc->tdcf); +} + +static void dummy_can_print_pwm(struct net_device *dev, struct can_pwm *pw= m, + struct can_bittiming *dbt) +{ + netdev_dbg(dev, "\t\tpwms: %u\n", pwm->pwms); + netdev_dbg(dev, "\t\tpwml: %u\n", pwm->pwml); + netdev_dbg(dev, "\t\tpwmo: %u\n", pwm->pwmo); +} + +static void dummy_can_print_ctrlmode(struct net_device *dev) +{ + struct dummy_can *priv =3D netdev_priv(dev); + struct can_priv *can_priv =3D &priv->can; + unsigned long supported =3D can_priv->ctrlmode_supported; + u32 enabled =3D can_priv->ctrlmode; + + netdev_dbg(dev, "Control modes:\n"); + netdev_dbg(dev, "\tsupported: 0x%08x\n", (u32)supported); + netdev_dbg(dev, "\tenabled: 0x%08x\n", enabled); + + if (supported) { + int idx; + + netdev_dbg(dev, "\tlist:"); + for_each_set_bit(idx, &supported, BITS_PER_TYPE(u32)) + netdev_dbg(dev, "\t\t%s: %s\n", + can_get_ctrlmode_str(BIT(idx)), + enabled & BIT(idx) ? "on" : "off"); + } +} + +static void dummy_can_print_bittiming_info(struct net_device *dev) +{ + struct dummy_can *priv =3D netdev_priv(dev); + struct can_priv *can_priv =3D &priv->can; + + netdev_dbg(dev, "Clock frequency: %u\n", can_priv->clock.freq); + netdev_dbg(dev, "Maximum bitrate: %u\n", can_priv->bitrate_max); + netdev_dbg(dev, "MTU: %u\n", dev->mtu); + netdev_dbg(dev, "\n"); + + dummy_can_print_ctrlmode(dev); + netdev_dbg(dev, "\n"); + + netdev_dbg(dev, "Classical CAN nominal bittiming:\n"); + dummy_can_print_bittiming(dev, &can_priv->bittiming); + netdev_dbg(dev, "\n"); + + if (can_priv->ctrlmode & CAN_CTRLMODE_FD) { + netdev_dbg(dev, "CAN FD databittiming:\n"); + dummy_can_print_bittiming(dev, &can_priv->fd.data_bittiming); + if (can_fd_tdc_is_enabled(can_priv)) { + netdev_dbg(dev, "\tCAN FD TDC:\n"); + dummy_can_print_tdc(dev, &can_priv->fd.tdc); + } + } + netdev_dbg(dev, "\n"); + + if (can_priv->ctrlmode & CAN_CTRLMODE_XL) { + netdev_dbg(dev, "CAN XL databittiming:\n"); + dummy_can_print_bittiming(dev, &can_priv->xl.data_bittiming); + if (can_xl_tdc_is_enabled(can_priv)) { + netdev_dbg(dev, "\tCAN XL TDC:\n"); + dummy_can_print_tdc(dev, &can_priv->xl.tdc); + } + if (can_priv->ctrlmode & CAN_CTRLMODE_XL_TMS) { + netdev_dbg(dev, "\tCAN XL PWM:\n"); + dummy_can_print_pwm(dev, &can_priv->xl.pwm, + &can_priv->xl.data_bittiming); + } + } + netdev_dbg(dev, "\n"); +} + +static int dummy_can_netdev_open(struct net_device *dev) +{ + int ret; + struct can_priv *priv =3D netdev_priv(dev); + + dummy_can_print_bittiming_info(dev); + netdev_dbg(dev, "error-signalling is %s\n", + str_enabled_disabled(!can_dev_in_xl_only_mode(priv))); + + ret =3D open_candev(dev); + if (ret) + return ret; + netif_start_queue(dev); + netdev_dbg(dev, "dummy-can is up\n"); + + return 0; +} + +static int dummy_can_netdev_close(struct net_device *dev) +{ + netif_stop_queue(dev); + close_candev(dev); + netdev_dbg(dev, "dummy-can is down\n"); + + return 0; +} + +static netdev_tx_t dummy_can_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + if (can_dev_dropped_skb(dev, skb)) + return NETDEV_TX_OK; + + can_put_echo_skb(skb, dev, 0, 0); + dev->stats.tx_packets++; + dev->stats.tx_bytes +=3D can_get_echo_skb(dev, 0, NULL); + + return NETDEV_TX_OK; +} + +static const struct net_device_ops dummy_can_netdev_ops =3D { + .ndo_open =3D dummy_can_netdev_open, + .ndo_stop =3D dummy_can_netdev_close, + .ndo_start_xmit =3D dummy_can_start_xmit, +}; + +static const struct ethtool_ops dummy_can_ethtool_ops =3D { + .get_ts_info =3D ethtool_op_get_ts_info, +}; + +static int __init dummy_can_init(void) +{ + struct net_device *dev; + struct dummy_can *priv; + int ret; + + dev =3D alloc_candev(sizeof(*priv), 1); + if (!dev) + return -ENOMEM; + + dev->netdev_ops =3D &dummy_can_netdev_ops; + dev->ethtool_ops =3D &dummy_can_ethtool_ops; + priv =3D netdev_priv(dev); + priv->can.bittiming_const =3D &dummy_can_bittiming_const; + priv->can.bitrate_max =3D 20 * MEGA /* BPS */; + priv->can.clock.freq =3D 160 * MEGA /* Hz */; + priv->can.fd.data_bittiming_const =3D &dummy_can_fd_databittiming_const; + priv->can.fd.tdc_const =3D &dummy_can_fd_tdc_const; + priv->can.xl.data_bittiming_const =3D &dummy_can_xl_databittiming_const; + priv->can.xl.tdc_const =3D &dummy_can_xl_tdc_const; + priv->can.xl.pwm_const =3D &dummy_can_pwm_const; + priv->can.ctrlmode_supported =3D CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_FD | CAN_CTRLMODE_TDC_AUTO | + CAN_CTRLMODE_RESTRICTED | CAN_CTRLMODE_XL | + CAN_CTRLMODE_XL_TDC_AUTO | CAN_CTRLMODE_XL_TMS; + priv->dev =3D dev; + + ret =3D register_candev(priv->dev); + if (ret) { + free_candev(priv->dev); + return ret; + } + + dummy_can =3D priv; + netdev_dbg(dev, "dummy-can ready\n"); + + return 0; +} + +static void __exit dummy_can_exit(void) +{ + struct net_device *dev =3D dummy_can->dev; + + netdev_dbg(dev, "dummy-can bye bye\n"); + unregister_candev(dev); + free_candev(dev); +} + +module_init(dummy_can_init); +module_exit(dummy_can_exit); + +MODULE_DESCRIPTION("A dummy CAN driver, mainly to test the netlink interfa= ce"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vincent Mailhol "); --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6677725A2C9 for ; Wed, 26 Nov 2025 10:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152226; cv=none; b=F3V9J8yjxoxkcQskgDi7JpkhfBj4fhYPexDJ3qcr+q7X3kHnpVsv3fUtHkJlTdeVFTogfiWT0dgH75YvCgXx5bhLnCGXlAYOuht+hRCpBwO/Ijz9VcOmtvzrdnu6hWK1E5Un5mzD+Bm+HnVBVVhirw1bVeidCroOXyLd3XIBRjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152226; c=relaxed/simple; bh=MScOCfDrBIGGLEV5Z/jnAJ1aO10K3UXaIkiluDN85BY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=O+A5Pt1cGdkwJbYFNv+OKhFu2KI1KHiJlFT4HxDVkTXi4vZDCAfgyt8Ij/UJ8hD0g1I9jThLhqSaIOksgYsxTDAbWlPojIjFah7V/VTXyZzz7yTIOltGEzT35SMbdSeOlMRV6Hs3wkLa8jXuOsmdMcKH3+32ULRdIK7EV7y1bk8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000SI-Cx; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aTP-26; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 6D4974A88E1; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:17 +0100 Subject: [PATCH can-next v8 16/17] can: raw: instantly reject unsupported CAN frames Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-16-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3205; i=mkl@pengutronix.de; h=from:subject:message-id; bh=Y3SasBv/Q/I8DywbkyCugANDFbbNJUqqKc8k6Nel8BQ=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOOq5kZGxHteFMg9Lyl168pclqxvKiaKm5pW KamL14NMaqJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTjgAKCRAMdGXf+ZCR nJQJB/9eIG1wvEaC+swgxtejg1VpYunET3OFhxULKYEiWQayN/CEfVfsr3zRZzroLDEkMfYpyqb ZrSyNP/co2DDCqMke+j+xqwGer38ndChMyGeh/UjXSuXbYTQi4Bg/Q8v+Ncozctz2qj5UOmL7K+ Kg4pqA2ZNKDW8R5gXRQB7JzK9wuhmM18zIirlj0MeoxtqWuVHSb9GLCDL/BlPFj6KAbvKWJl7uB Qx1X/YyQy9IanvZDHrVLUU5gsuex1a+lTrnjN2umnCDDQPxdqgDV34jYd0ONAaXg1oUAtzimD7W /ev8r8Omp6x6NHrgpfoAlAzi+pYl8BuotetsQ5KASMzTD8w7 X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Oliver Hartkopp For real CAN interfaces the CAN_CTRLMODE_FD and CAN_CTRLMODE_XL control modes indicate whether an interface can handle those CAN FD/XL frames. In the case a CAN XL interface is configured in CANXL-only mode with disabled error-signalling neither CAN CC nor CAN FD frames can be sent. The checks are performed on CAN_RAW sockets to give an instant feedback to the user when writing unsupported CAN frames to the interface. Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- net/can/raw.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/net/can/raw.c b/net/can/raw.c index f36a83d3447c..be1ef7cf4204 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -892,20 +892,58 @@ static void raw_put_canxl_vcid(struct raw_sock *ro, s= truct sk_buff *skb) } } =20 -static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff = *skb, int mtu) +static inline bool raw_dev_cc_enabled(struct net_device *dev, + struct can_priv *priv) { - /* Classical CAN -> no checks for flags and device capabilities */ - if (can_is_can_skb(skb)) + /* The CANXL-only mode disables error-signalling on the CAN bus + * which is needed to send CAN CC/FD frames + */ + if (priv) + return !can_dev_in_xl_only_mode(priv); + + /* virtual CAN interfaces always support CAN CC */ + return true; +} + +static inline bool raw_dev_fd_enabled(struct net_device *dev, + struct can_priv *priv) +{ + /* check FD ctrlmode on real CAN interfaces */ + if (priv) + return (priv->ctrlmode & CAN_CTRLMODE_FD); + + /* check MTU for virtual CAN FD interfaces */ + return (READ_ONCE(dev->mtu) >=3D CANFD_MTU); +} + +static inline bool raw_dev_xl_enabled(struct net_device *dev, + struct can_priv *priv) +{ + /* check XL ctrlmode on real CAN interfaces */ + if (priv) + return (priv->ctrlmode & CAN_CTRLMODE_XL); + + /* check MTU for virtual CAN XL interfaces */ + return can_is_canxl_dev_mtu(READ_ONCE(dev->mtu)); +} + +static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff = *skb, + struct net_device *dev) +{ + struct can_priv *priv =3D safe_candev_priv(dev); + + /* Classical CAN */ + if (can_is_can_skb(skb) && raw_dev_cc_enabled(dev, priv)) return CAN_MTU; =20 - /* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */ + /* CAN FD */ if (ro->fd_frames && can_is_canfd_skb(skb) && - (mtu =3D=3D CANFD_MTU || can_is_canxl_dev_mtu(mtu))) + raw_dev_fd_enabled(dev, priv)) return CANFD_MTU; =20 - /* CAN XL -> needs to be enabled and a CAN XL device */ + /* CAN XL */ if (ro->xl_frames && can_is_canxl_skb(skb) && - can_is_canxl_dev_mtu(mtu)) + raw_dev_xl_enabled(dev, priv)) return CANXL_MTU; =20 return 0; @@ -961,7 +999,7 @@ static int raw_sendmsg(struct socket *sock, struct msgh= dr *msg, size_t size) err =3D -EINVAL; =20 /* check for valid CAN (CC/FD/XL) frame content */ - txmtu =3D raw_check_txframe(ro, skb, READ_ONCE(dev->mtu)); + txmtu =3D raw_check_txframe(ro, skb, dev); if (!txmtu) goto free_skb; =20 --=20 2.51.0 From nobody Mon Dec 1 22:35:41 2025 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF34F3016EC for ; Wed, 26 Nov 2025 10:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; cv=none; b=WWMBuWADSlQGoDPp6E5nAhXOtxr9mNFFwzZyn8tNH8C5vOb03MquRfhHUNsaZ/51pC1Wjr78SHXPWeOK61uk3tQGvjip6TVVjqPWuEBXMd1Zfuy3SWSqxjcAFfWUXw96RL/8aMW/PPV/z2o6KrZGERZU1FC2epixqgY8ODRqf2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764152228; c=relaxed/simple; bh=nphzJBCUTQlxJNEIZoAIIkAZNQvpkKrkgQSxr+QxPII=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a7GEL7XiKMiawV6nz6E5rSjAbUwqceBsxg7IfrntpKqaoGr9PRf207jHWIEb320FbQe6gWvpibhXS5edQEp8Sy7uIo8ASIS0rqL1q8FnCAHtYLUppXH3YyustEciyNjVB5IsdjVGID86ii1slfcehvCPZJ6uLdL/WJhY7LCy7ao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1vOCZw-0000SH-8u; Wed, 26 Nov 2025 11:16:52 +0100 Received: from moin.white.stw.pengutronix.de ([2a0a:edc0:0:b01:1d::7b] helo=bjornoya.blackshift.org) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vOCZv-002aTR-2E; Wed, 26 Nov 2025 11:16:51 +0100 Received: from hardanger.blackshift.org (p54b152ce.dip0.t-ipconnect.de [84.177.82.206]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mkl-all@blackshift.org) by smtp.blackshift.org (Postfix) with ESMTPSA id 76FD04A88E2; Wed, 26 Nov 2025 10:16:51 +0000 (UTC) From: Marc Kleine-Budde Date: Wed, 26 Nov 2025 11:16:18 +0100 Subject: [PATCH can-next v8 17/17] can: dev: print bitrate error with two decimal digits Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251126-canxl-v8-17-e7e3eb74f889@pengutronix.de> References: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> In-Reply-To: <20251126-canxl-v8-0-e7e3eb74f889@pengutronix.de> To: Marc Kleine-Budde , Vincent Mailhol , Oliver Hartkopp Cc: kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org, =?utf-8?q?St=C3=A9phane_Grosjean?= X-Mailer: b4 0.15-dev-a6db3 X-Developer-Signature: v=1; a=openpgp-sha256; l=1711; i=mkl@pengutronix.de; h=from:subject:message-id; bh=7kyl7e7nsbgVHh+uNt5JmfhY7X+/ImB4fbvttTL6e1Q=; b=owEBbQGS/pANAwAKAQx0Zd/5kJGcAcsmYgBpJtOQ3mXo6FkpURAlFDmmlsklyxJUQ0hnbCxld kdn8cuZhwuJATMEAAEKAB0WIQSf+wzYr2eoX/wVbPMMdGXf+ZCRnAUCaSbTkAAKCRAMdGXf+ZCR nIpcCACP7FaFZd4U6vLne9a5LeZRoW5eNRLPZbBXZ42T5I8l1YPUwO8kP8sgdUsX+E0cYydTvTB WJVyFOGO2iraX7xPoG547XAYYMBNWbsBE79F3VEZUJ+xN/RVSC7Zoq+4sUWGuutgvRdw2yb8tsf BLBti/6qDwT+ntEQEGl8Sh1K/8PxWqztXlSwPpKASnlVltB7CNN2Yqnx5/0q8+/gcACK+Tds3oT bfoGHpPWaUHGU/7xhfjHUyOzeOa0a9VkupjNOYwE8RmUoQyJ7YSjQOhvqlrxY3Lzq6/7LhZV+Pz eNrOcAw3JkL4VCoYZ4GmcCtfGfNDNxNsUYhXgCxM4twXMc/1 X-Developer-Key: i=mkl@pengutronix.de; a=openpgp; fpr=C1400BA0B3989E6FBC7D5B5C2B5EE211C58AEA54 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: mkl@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org From: Oliver Hartkopp Increase the resolution when printing the bitrate error and round-up the value to 0.01% in the case the resolution would still provide values which would lead to 0.00%. Suggested-by: Vincent Mailhol Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev/calc_bittiming.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/cal= c_bittiming.c index 60a505ce69de..cc4022241553 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -153,19 +153,22 @@ int can_calc_bittiming(const struct net_device *dev, = struct can_bittiming *bt, } =20 if (best_bitrate_error) { - /* Error in one-tenth of a percent */ - v64 =3D (u64)best_bitrate_error * 1000; + /* Error in one-hundredth of a percent */ + v64 =3D (u64)best_bitrate_error * 10000; do_div(v64, bt->bitrate); bitrate_error =3D (u32)v64; + /* print at least 0.01% if the error is smaller */ + bitrate_error =3D max(bitrate_error, 1U); if (bitrate_error > CAN_CALC_MAX_ERROR) { NL_SET_ERR_MSG_FMT(extack, - "bitrate error: %u.%u%% too high", - bitrate_error / 10, bitrate_error % 10); + "bitrate error: %u.%02u%% too high", + bitrate_error / 100, + bitrate_error % 100); return -EINVAL; } NL_SET_ERR_MSG_FMT(extack, - "bitrate error: %u.%u%%", - bitrate_error / 10, bitrate_error % 10); + "bitrate error: %u.%02u%%", + bitrate_error / 100, bitrate_error % 100); } =20 /* real sample point */ --=20 2.51.0