linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vincent Mailhol <mailhol@kernel.org>
To: Marc Kleine-Budde <mkl@pengutronix.de>,
	 Oliver Hartkopp <socketcan@hartkopp.net>
Cc: "Vincent Mailhol" <mailhol@kernel.org>,
	"Stéphane Grosjean" <stephane.grosjean@hms-networks.com>,
	"Robert Nawrath" <mbro1689@gmail.com>,
	"Minh Le" <minh.le.aj@renesas.com>,
	"Duy Nguyen" <duy.nguyen.rh@renesas.com>,
	linux-can@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 10/20] can: netlink: add can_dtb_changelink()
Date: Wed, 10 Sep 2025 15:03:35 +0900	[thread overview]
Message-ID: <20250910-canxl-netlink-prep-v2-10-f128d4083721@kernel.org> (raw)
In-Reply-To: <20250910-canxl-netlink-prep-v2-0-f128d4083721@kernel.org>

Factorise the databittiming parsing out of can_changelink() and move
it in the new can_dtb_changelink() function. This is a preparation
patch for the introduction of CAN XL because the databittiming
changelink logic will be reused later on.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
---
Changelog:

v1 -> v2:

  - Change WARN_ON(1) into return -EOPNOTSUPP to suppress a gcc
    warning.
    Link: https://lore.kernel.org/linux-can/202509050404.ZLQknagH-lkp@intel.com/

RFC -> v1:

  - In the RFC, can_dbt_changelink() required 8 parameters. Instead,
    just pass a boolean and then get the FD/XL specific parameters in
    an "if (fd) {} else {}" conditional.
---
 drivers/net/can/dev/netlink.c | 152 ++++++++++++++++++++++++------------------
 1 file changed, 88 insertions(+), 64 deletions(-)

diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index fde6565fa04af0c5615c09ebb094cbf8bcef3172..5812114ca8842baedebd698d3000843dbce3ec7d 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -220,12 +220,95 @@ static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
 	return 0;
 }
 
+static int can_dbt_changelink(struct net_device *dev, struct nlattr *data[],
+			      bool fd, struct netlink_ext_ack *extack)
+{
+	struct nlattr *data_bittiming, *data_tdc;
+	struct can_priv *priv = netdev_priv(dev);
+	struct data_bittiming_params *dbt_params;
+	struct can_bittiming dbt;
+	bool need_tdc_calc = false;
+	u32 tdc_mask;
+	int err;
+
+	if (fd) {
+		data_bittiming = data[IFLA_CAN_DATA_BITTIMING];
+		data_tdc = data[IFLA_CAN_TDC];
+		dbt_params = &priv->fd;
+		tdc_mask = CAN_CTRLMODE_FD_TDC_MASK;
+	} else {
+		return -EOPNOTSUPP; /* Place holder for CAN XL */
+	}
+
+	if (!data_bittiming)
+		return 0;
+
+	/* Do not allow changing bittiming while running */
+	if (dev->flags & IFF_UP)
+		return -EBUSY;
+
+	/* Calculate bittiming parameters based on data_bittiming_const
+	 * if set, otherwise pass bitrate directly via do_set_bitrate().
+	 * Bail out if neither is given.
+	 */
+	if (!dbt_params->data_bittiming_const && !dbt_params->do_set_data_bittiming &&
+	    !dbt_params->data_bitrate_const)
+		return -EOPNOTSUPP;
+
+	memcpy(&dbt, nla_data(data_bittiming), sizeof(dbt));
+	err = can_get_bittiming(dev, &dbt, dbt_params->data_bittiming_const,
+				dbt_params->data_bitrate_const,
+				dbt_params->data_bitrate_const_cnt, extack);
+	if (err)
+		return err;
+
+	if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) {
+		NL_SET_ERR_MSG_FMT(extack,
+				   "CAN data bitrate %u bps surpasses transceiver capabilities of %u bps",
+				   dbt.bitrate, priv->bitrate_max);
+		return -EINVAL;
+	}
+
+	memset(&dbt_params->tdc, 0, sizeof(dbt_params->tdc));
+	if (data[IFLA_CAN_CTRLMODE]) {
+		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+
+		need_tdc_calc = !(cm->mask & tdc_mask);
+	}
+	if (data_tdc) {
+		/* TDC parameters are provided: use them */
+		err = can_tdc_changelink(dbt_params, data_tdc, extack);
+		if (err) {
+			priv->ctrlmode &= ~tdc_mask;
+			return err;
+		}
+	} else if (need_tdc_calc) {
+		/* Neither of TDC parameters nor TDC flags are provided:
+		 * do calculation
+		 */
+		can_calc_tdco(&dbt_params->tdc, dbt_params->tdc_const, &dbt,
+			      &priv->ctrlmode, priv->ctrlmode_supported);
+	} /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly
+	   * turned off. TDC is disabled: do nothing
+	   */
+
+	memcpy(&dbt_params->data_bittiming, &dbt, sizeof(dbt));
+
+	if (dbt_params->do_set_data_bittiming) {
+		/* Finally, set the bit-timing registers */
+		err = dbt_params->do_set_data_bittiming(dev);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 			  struct nlattr *data[],
 			  struct netlink_ext_ack *extack)
 {
 	struct can_priv *priv = netdev_priv(dev);
-	bool fd_tdc_flag_provided = false;
 	int err;
 
 	/* We need synchronization with dev->stop() */
@@ -273,8 +356,6 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 			priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK;
 			memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc));
 		}
-
-		fd_tdc_flag_provided = cm->mask & CAN_CTRLMODE_FD_TDC_MASK;
 	}
 
 	if (data[IFLA_CAN_BITTIMING]) {
@@ -347,67 +428,10 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
 			return err;
 	}
 
-	if (data[IFLA_CAN_DATA_BITTIMING]) {
-		struct can_bittiming dbt;
-
-		/* Do not allow changing bittiming while running */
-		if (dev->flags & IFF_UP)
-			return -EBUSY;
-
-		/* Calculate bittiming parameters based on
-		 * data_bittiming_const if set, otherwise pass bitrate
-		 * directly via do_set_bitrate(). Bail out if neither
-		 * is given.
-		 */
-		if (!priv->fd.data_bittiming_const && !priv->fd.do_set_data_bittiming &&
-		    !priv->fd.data_bitrate_const)
-			return -EOPNOTSUPP;
-
-		memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
-		       sizeof(dbt));
-		err = can_get_bittiming(dev, &dbt,
-					priv->fd.data_bittiming_const,
-					priv->fd.data_bitrate_const,
-					priv->fd.data_bitrate_const_cnt,
-					extack);
-		if (err)
-			return err;
-
-		if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) {
-			NL_SET_ERR_MSG_FMT(extack,
-					   "CANFD data bitrate %u bps surpasses transceiver capabilities of %u bps",
-					   dbt.bitrate, priv->bitrate_max);
-			return -EINVAL;
-		}
-
-		memset(&priv->fd.tdc, 0, sizeof(priv->fd.tdc));
-		if (data[IFLA_CAN_TDC]) {
-			/* TDC parameters are provided: use them */
-			err = can_tdc_changelink(&priv->fd,
-						 data[IFLA_CAN_TDC], extack);
-			if (err) {
-				priv->ctrlmode &= ~CAN_CTRLMODE_FD_TDC_MASK;
-				return err;
-			}
-		} else if (!fd_tdc_flag_provided) {
-			/* Neither of TDC parameters nor TDC flags are
-			 * provided: do calculation
-			 */
-			can_calc_tdco(&priv->fd.tdc, priv->fd.tdc_const, &dbt,
-				      &priv->ctrlmode, priv->ctrlmode_supported);
-		} /* else: both CAN_CTRLMODE_TDC_{AUTO,MANUAL} are explicitly
-		   * turned off. TDC is disabled: do nothing
-		   */
-
-		memcpy(&priv->fd.data_bittiming, &dbt, sizeof(dbt));
-
-		if (priv->fd.do_set_data_bittiming) {
-			/* Finally, set the bit-timing registers */
-			err = priv->fd.do_set_data_bittiming(dev);
-			if (err)
-				return err;
-		}
-	}
+	/* CAN FD */
+	err = can_dbt_changelink(dev, data, true, extack);
+	if (err)
+		return err;
 
 	if (data[IFLA_CAN_TERMINATION]) {
 		const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);

-- 
2.49.1


  parent reply	other threads:[~2025-09-10  6:05 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-10  6:03 [PATCH v2 00/20] can: netlink: preparation before introduction of CAN XL step 2/2 Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 01/20] can: dev: move struct data_bittiming_params to linux/can/bittiming.h Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 02/20] can: dev: make can_get_relative_tdco() FD agnostic and move it to bittiming.h Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 03/20] can: netlink: document which symbols are FD specific Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 04/20] can: netlink: refactor can_validate_bittiming() Vincent Mailhol
2025-09-10  6:13   ` Marc Kleine-Budde
2025-09-10  6:43     ` Vincent Mailhol
2025-09-10 10:55       ` Marc Kleine-Budde
2025-09-10 11:12         ` Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 05/20] can: netlink: add can_validate_tdc() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 06/20] can: netlink: add can_validate_databittiming() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 07/20] can: netlink: refactor CAN_CTRLMODE_TDC_{AUTO,MANUAL} flag reset logic Vincent Mailhol
2025-09-20  7:24   ` Vincent Mailhol
2025-09-22  9:43     ` Marc Kleine-Budde
2025-09-22 11:14       ` Vincent Mailhol
2025-09-22 13:06         ` Marc Kleine-Budde
2025-09-23  7:04           ` Vincent Mailhol
2025-09-23  9:08             ` Marc Kleine-Budde
2025-09-23  9:36               ` Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 08/20] can: netlink: remove useless check in can_tdc_changelink() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 09/20] can: netlink: make can_tdc_changelink() FD agnostic Vincent Mailhol
2025-09-10  6:03 ` Vincent Mailhol [this message]
2025-09-10  6:03 ` [PATCH v2 11/20] can: netlink: add can_ctrlmode_changelink() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 12/20] can: netlink: make can_tdc_get_size() FD agnostic Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 13/20] can: netlink: add can_data_bittiming_get_size() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 14/20] can: netlink: add can_bittiming_fill_info() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 15/20] can: netlink: add can_bittiming_const_fill_info() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 16/20] can: netlink: add can_bitrate_const_fill_info() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 17/20] can: netlink: make can_tdc_fill_info() FD agnostic Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 18/20] can: calc_bittiming: make can_calc_tdco() " Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 19/20] can: dev: add can_get_ctrlmode_str() Vincent Mailhol
2025-09-10  6:03 ` [PATCH v2 20/20] can: netlink: add userland error messages Vincent Mailhol

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250910-canxl-netlink-prep-v2-10-f128d4083721@kernel.org \
    --to=mailhol@kernel.org \
    --cc=duy.nguyen.rh@renesas.com \
    --cc=linux-can@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbro1689@gmail.com \
    --cc=minh.le.aj@renesas.com \
    --cc=mkl@pengutronix.de \
    --cc=socketcan@hartkopp.net \
    --cc=stephane.grosjean@hms-networks.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).