// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
 * Copyright (C) 2006 Andrey Volkov, Varma Electronics
 * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
 * Copyright (C) 2021-2025 Vincent Mailhol <mailhol@kernel.org>
 */

#include <linux/can/dev.h>
#include <net/rtnetlink.h>

static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
	[IFLA_CAN_STATE] = { .type = NLA_U32 },
	[IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) },
	[IFLA_CAN_RESTART_MS] = { .type = NLA_U32 },
	[IFLA_CAN_RESTART] = { .type = NLA_U32 },
	[IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) },
	[IFLA_CAN_BITTIMING_CONST] = { .len = sizeof(struct can_bittiming_const) },
	[IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
	[IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
	[IFLA_CAN_DATA_BITTIMING] = { .len = sizeof(struct can_bittiming) },
	[IFLA_CAN_DATA_BITTIMING_CONST] = { .len = sizeof(struct can_bittiming_const) },
	[IFLA_CAN_TERMINATION] = { .type = NLA_U16 },
	[IFLA_CAN_TDC] = { .type = NLA_NESTED },
	[IFLA_CAN_CTRLMODE_EXT] = { .type = NLA_NESTED },
	[IFLA_CAN_XL_DATA_BITTIMING] = { .len = sizeof(struct can_bittiming) },
	[IFLA_CAN_XL_DATA_BITTIMING_CONST] = { .len = sizeof(struct can_bittiming_const) },
	[IFLA_CAN_XL_TDC] = { .type = NLA_NESTED },
	[IFLA_CAN_XL_PWM] = { .type = NLA_NESTED },
};

static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = {
	[IFLA_CAN_TDC_TDCV_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCV_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCO_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCO_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCF_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCF_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCV] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCO] = { .type = NLA_U32 },
	[IFLA_CAN_TDC_TDCF] = { .type = NLA_U32 },
};

static const struct nla_policy can_pwm_policy[IFLA_CAN_PWM_MAX + 1] = {
	[IFLA_CAN_PWM_PWMS_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWMS_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWML_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWML_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWMO_MIN] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWMO_MAX] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWMS] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWML] = { .type = NLA_U32 },
	[IFLA_CAN_PWM_PWMO] = { .type = NLA_U32 },
};

static int can_validate_bittiming(struct nlattr *data[],
				  struct netlink_ext_ack *extack,
				  int ifla_can_bittiming)
{
	struct can_bittiming *bt;

	if (!data[ifla_can_bittiming])
		return 0;

	static_assert(__alignof__(*bt) <= NLA_ALIGNTO);
	bt = nla_data(data[ifla_can_bittiming]);

	/* sample point is in one-tenth of a percent */
	if (bt->sample_point >= 1000) {
		NL_SET_ERR_MSG(extack, "sample point must be between 0 and 100%");
		return -EINVAL;
	}

	return 0;
}

static int can_validate_tdc(struct nlattr *data_tdc,
			    struct netlink_ext_ack *extack, u32 tdc_flags)
{
	bool tdc_manual = tdc_flags & CAN_CTRLMODE_TDC_MANUAL_MASK;
	bool tdc_auto = tdc_flags & CAN_CTRLMODE_TDC_AUTO_MASK;
	int err;

	if (tdc_auto && tdc_manual) {
		NL_SET_ERR_MSG(extack,
			       "TDC manual and auto modes are mutually exclusive");
		return -EOPNOTSUPP;
	}

	/* 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) {
		NL_SET_ERR_MSG(extack, "TDC parameters are missing");
		return -EOPNOTSUPP;
	}
	if (!(tdc_auto || tdc_manual) && data_tdc) {
		NL_SET_ERR_MSG(extack, "TDC mode (auto or manual) is missing");
		return -EOPNOTSUPP;
	}

	/* 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];

		err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX,
				       data_tdc, can_tdc_policy, extack);
		if (err)
			return err;

		if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
			if (tdc_auto) {
				NL_SET_ERR_MSG(extack,
					       "TDCV is incompatible with TDC auto mode");
				return -EOPNOTSUPP;
			}
		} else {
			if (tdc_manual) {
				NL_SET_ERR_MSG(extack,
					       "TDC manual mode requires TDCV");
				return -EOPNOTSUPP;
			}
		}

		if (!tb_tdc[IFLA_CAN_TDC_TDCO]) {
			NL_SET_ERR_MSG(extack, "TDCO is missing");
			return -EOPNOTSUPP;
		}
	}

	return 0;
}

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 = 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] != !tb_pwm[IFLA_CAN_PWM_PWML]) {
		NL_SET_ERR_MSG(extack,
			       "Provide either both PWMS and PWML, or none for automatic calculation");
		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)
{
	struct nlattr *data_tdc;
	const char *type;
	u32 tdc_flags;
	bool is_on;
	int err;

	/* Make sure that valid CAN FD/XL configurations always consist of
	 * - nominal/arbitration bittiming
	 * - data bittiming
	 * - control mode with CAN_CTRLMODE_{FD,XL} set
	 * - TDC parameters are coherent (details in can_validate_tdc())
	 */

	if (ifla_can_data_bittiming == IFLA_CAN_DATA_BITTIMING) {
		data_tdc = data[IFLA_CAN_TDC];
		tdc_flags = flags & CAN_CTRLMODE_FD_TDC_MASK;
		is_on = flags & CAN_CTRLMODE_FD;
		type = "FD";
	} else {
		data_tdc = data[IFLA_CAN_XL_TDC];
		tdc_flags = flags & CAN_CTRLMODE_XL_TDC_MASK;
		is_on = flags & CAN_CTRLMODE_XL;
		type = "XL";
	}

	if (is_on) {
		if (!data[IFLA_CAN_BITTIMING] || !data[ifla_can_data_bittiming]) {
			NL_SET_ERR_MSG_FMT(extack,
					   "Provide both nominal and %s data bittiming",
					   type);
			return -EOPNOTSUPP;
		}
	} else {
		if (data[ifla_can_data_bittiming]) {
			NL_SET_ERR_MSG_FMT(extack,
					   "%s data bittiming requires CAN %s",
					   type, type);
			return -EOPNOTSUPP;
		}
		if (data_tdc) {
			NL_SET_ERR_MSG_FMT(extack,
					   "%s TDC requires CAN %s",
					   type, type);
			return -EOPNOTSUPP;
		}
	}

	err = can_validate_bittiming(data, extack, ifla_can_data_bittiming);
	if (err)
		return err;

	err = can_validate_tdc(data_tdc, extack, tdc_flags);
	if (err)
		return err;

	return 0;
}

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 = CAN_CTRLMODE_FD |
				CAN_CTRLMODE_XL_TDC_MASK;
			u32 tms_conflicts = 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)
{
	u32 flags = 0;
	int err;

	if (!data)
		return 0;

	if (data[IFLA_CAN_CTRLMODE]) {
		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);

		flags = 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;
		}

		err = can_validate_xl_flags(extack, flags, cm->mask);
		if (err)
			return err;
	}

	err = can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING);
	if (err)
		return err;

	err = can_validate_databittiming(data, extack,
					 IFLA_CAN_DATA_BITTIMING, flags);
	if (err)
		return err;

	err = can_validate_databittiming(data, extack,
					 IFLA_CAN_XL_DATA_BITTIMING, flags);
	if (err)
		return err;

	err = can_validate_pwm(data, extack, flags);
	if (err)
		return err;

	return 0;
}

static int can_ctrlmode_changelink(struct net_device *dev,
				   struct nlattr *data[],
				   struct netlink_ext_ack *extack)
{
	struct can_priv *priv = netdev_priv(dev);
	struct can_ctrlmode *cm;
	u32 ctrlstatic, maskedflags, deactivated, notsupp, ctrlstatic_missing;

	if (!data[IFLA_CAN_CTRLMODE])
		return 0;

	/* Do not allow changing controller mode while running */
	if (dev->flags & IFF_UP)
		return -EBUSY;

	cm = nla_data(data[IFLA_CAN_CTRLMODE]);
	ctrlstatic = can_get_static_ctrlmode(priv);
	maskedflags = cm->flags & cm->mask;
	deactivated = ~cm->flags & cm->mask;
	notsupp = maskedflags & ~(priv->ctrlmode_supported | ctrlstatic);
	ctrlstatic_missing = (maskedflags & ctrlstatic) ^ ctrlstatic;

	if (notsupp) {
		NL_SET_ERR_MSG_FMT(extack,
				   "requested control mode %s not supported",
				   can_get_ctrlmode_str(notsupp));
		return -EOPNOTSUPP;
	}

	/* do not check for static fd-non-iso if 'fd' is disabled */
	if (!(maskedflags & CAN_CTRLMODE_FD))
		ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;

	if (ctrlstatic_missing) {
		NL_SET_ERR_MSG_FMT(extack,
				   "missing required %s static control mode",
				   can_get_ctrlmode_str(ctrlstatic_missing));
		return -EOPNOTSUPP;
	}

	/* 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 &= ~CAN_CTRLMODE_FD_TDC_MASK;
	if (cm->mask & CAN_CTRLMODE_XL)
		priv->ctrlmode &= ~(CAN_CTRLMODE_XL_TDC_MASK |
				    CAN_CTRLMODE_XL_TMS);

	/* clear bits to be modified and copy the flag values */
	priv->ctrlmode &= ~cm->mask;
	priv->ctrlmode |= maskedflags;

	/* 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 &= ~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 &= ~CAN_CTRLMODE_XL_TDC_MASK;
		memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc));
		memset(&priv->xl.pwm, 0, sizeof(priv->xl.pwm));
	}

	can_set_default_mtu(dev);
	can_set_cap_info(dev);

	return 0;
}

static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
			      const struct nlattr *nla,
			      struct netlink_ext_ack *extack)
{
	struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
	struct can_tdc tdc = { 0 };
	const struct can_tdc_const *tdc_const = dbt_params->tdc_const;
	int err;

	if (!tdc_const) {
		NL_SET_ERR_MSG(extack, "The device does not support TDC");
		return -EOPNOTSUPP;
	}

	err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX, nla,
			       can_tdc_policy, extack);
	if (err)
		return err;

	if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
		u32 tdcv = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCV]);

		if (tdcv < tdc_const->tdcv_min || tdcv > tdc_const->tdcv_max)
			return -EINVAL;

		tdc.tdcv = tdcv;
	}

	if (tb_tdc[IFLA_CAN_TDC_TDCO]) {
		u32 tdco = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCO]);

		if (tdco < tdc_const->tdco_min || tdco > tdc_const->tdco_max)
			return -EINVAL;

		tdc.tdco = tdco;
	}

	if (tb_tdc[IFLA_CAN_TDC_TDCF]) {
		u32 tdcf = nla_get_u32(tb_tdc[IFLA_CAN_TDC_TDCF]);

		if (tdcf < tdc_const->tdcf_min || tdcf > tdc_const->tdcf_max)
			return -EINVAL;

		tdc.tdcf = tdcf;
	}

	dbt_params->tdc = tdc;

	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 {
		data_bittiming = data[IFLA_CAN_XL_DATA_BITTIMING];
		data_tdc = data[IFLA_CAN_XL_TDC];
		dbt_params = &priv->xl;
		tdc_mask = CAN_CTRLMODE_XL_TDC_MASK;
	}

	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]);

		if (fd || !(priv->ctrlmode & CAN_CTRLMODE_XL_TMS))
			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,
			      tdc_mask, &priv->ctrlmode, priv->ctrlmode_supported);
	} /* else: both CAN_CTRLMODE_{,XL}_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_pwm_changelink(struct net_device *dev,
			      const struct nlattr *pwm_nla,
			      struct netlink_ext_ack *extack)
{
	struct can_priv *priv = netdev_priv(dev);
	const struct can_pwm_const *pwm_const = priv->xl.pwm_const;
	struct nlattr *tb_pwm[IFLA_CAN_PWM_MAX + 1];
	struct can_pwm pwm = { 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 = 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 = 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 = 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 = 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 = can_validate_pwm_bittiming(dev, &pwm, extack);
	if (err)
		return err;

	priv->xl.pwm = pwm;
	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);
	int err;

	/* We need synchronization with dev->stop() */
	ASSERT_RTNL();

	err = can_ctrlmode_changelink(dev, data, extack);
	if (err)
		return err;

	if (data[IFLA_CAN_BITTIMING]) {
		struct can_bittiming bt;

		/* Do not allow changing bittiming while running */
		if (dev->flags & IFF_UP)
			return -EBUSY;

		/* Calculate bittiming parameters based on
		 * bittiming_const if set, otherwise pass bitrate
		 * directly via do_set_bitrate(). Bail out if neither
		 * is given.
		 */
		if (!priv->bittiming_const && !priv->do_set_bittiming &&
		    !priv->bitrate_const)
			return -EOPNOTSUPP;

		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
		err = can_get_bittiming(dev, &bt,
					priv->bittiming_const,
					priv->bitrate_const,
					priv->bitrate_const_cnt,
					extack);
		if (err)
			return err;

		if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
			NL_SET_ERR_MSG_FMT(extack,
					   "arbitration bitrate %u bps surpasses transceiver capabilities of %u bps",
					   bt.bitrate, priv->bitrate_max);
			return -EINVAL;
		}

		memcpy(&priv->bittiming, &bt, sizeof(bt));

		if (priv->do_set_bittiming) {
			/* Finally, set the bit-timing registers */
			err = priv->do_set_bittiming(dev);
			if (err)
				return err;
		}
	}

	if (data[IFLA_CAN_RESTART_MS]) {
		unsigned int restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);

		if (restart_ms != 0 && !priv->do_set_mode) {
			NL_SET_ERR_MSG(extack,
				       "Device doesn't support restart from Bus Off");
			return -EOPNOTSUPP;
		}

		/* Do not allow changing restart delay while running */
		if (dev->flags & IFF_UP)
			return -EBUSY;
		priv->restart_ms = restart_ms;
	}

	if (data[IFLA_CAN_RESTART]) {
		if (!priv->do_set_mode) {
			NL_SET_ERR_MSG(extack,
				       "Device doesn't support restart from Bus Off");
			return -EOPNOTSUPP;
		}

		/* Do not allow a restart while not running */
		if (!(dev->flags & IFF_UP))
			return -EINVAL;
		err = can_restart_now(dev);
		if (err)
			return err;
	}

	/* CAN FD */
	err = can_dbt_changelink(dev, data, true, extack);
	if (err)
		return err;

	/* CAN XL */
	err = can_dbt_changelink(dev, data, false, extack);
	if (err)
		return err;
	err = can_pwm_changelink(dev, data[IFLA_CAN_XL_PWM], extack);
	if (err)
		return err;

	if (data[IFLA_CAN_TERMINATION]) {
		const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]);
		const unsigned int num_term = priv->termination_const_cnt;
		unsigned int i;

		if (!priv->do_set_termination) {
			NL_SET_ERR_MSG(extack,
				       "Termination is not configurable on this device");
			return -EOPNOTSUPP;
		}

		/* check whether given value is supported by the interface */
		for (i = 0; i < num_term; i++) {
			if (termval == priv->termination_const[i])
				break;
		}
		if (i >= num_term)
			return -EINVAL;

		/* Finally, set the termination value */
		err = priv->do_set_termination(dev, termval);
		if (err)
			return err;

		priv->termination = termval;
	}

	return 0;
}

static size_t can_tdc_get_size(struct data_bittiming_params *dbt_params,
			       u32 tdc_flags)
{
	bool tdc_manual = tdc_flags & CAN_CTRLMODE_TDC_MANUAL_MASK;
	size_t size;

	if (!dbt_params->tdc_const)
		return 0;

	size = nla_total_size(0);			/* nest IFLA_CAN_TDC */
	if (tdc_manual) {
		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCV_MIN */
		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCV_MAX */
	}
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_TDCO_MIN */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_TDCO_MAX */
	if (dbt_params->tdc_const->tdcf_max) {
		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCF_MIN */
		size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCF_MAX */
	}

	if (tdc_flags) {
		if (tdc_manual || dbt_params->do_get_auto_tdcv)
			size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCV */
		size += nla_total_size(sizeof(u32));		/* IFLA_CAN_TDCO */
		if (dbt_params->tdc_const->tdcf_max)
			size += nla_total_size(sizeof(u32));	/* IFLA_CAN_TDCF */
	}

	return size;
}

static size_t can_data_bittiming_get_size(struct data_bittiming_params *dbt_params,
					  u32 tdc_flags)
{
	size_t size = 0;

	if (dbt_params->data_bittiming.bitrate)		/* IFLA_CAN_{,XL}_DATA_BITTIMING */
		size += nla_total_size(sizeof(dbt_params->data_bittiming));
	if (dbt_params->data_bittiming_const)		/* IFLA_CAN_{,XL}_DATA_BITTIMING_CONST */
		size += nla_total_size(sizeof(*dbt_params->data_bittiming_const));
	if (dbt_params->data_bitrate_const)		/* IFLA_CAN_{,XL}_DATA_BITRATE_CONST */
		size += nla_total_size(sizeof(*dbt_params->data_bitrate_const) *
				       dbt_params->data_bitrate_const_cnt);
	size += can_tdc_get_size(dbt_params, tdc_flags);/* IFLA_CAN_{,XL}_TDC */

	return size;
}

static size_t can_ctrlmode_ext_get_size(void)
{
	return nla_total_size(0) +		/* nest IFLA_CAN_CTRLMODE_EXT */
		nla_total_size(sizeof(u32));	/* IFLA_CAN_CTRLMODE_SUPPORTED */
}

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 = nla_total_size(0);			/* nest IFLA_CAN_PWM */

	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWMS_MIN */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWMS_MAX */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWML_MIN */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWML_MAX */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWMO_MIN */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWMO_MAX */

	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWMS */
	size += nla_total_size(sizeof(u32));		/* IFLA_CAN_PWM_PWML */
	size += 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 = netdev_priv(dev);
	size_t size = 0;

	if (priv->bittiming.bitrate)				/* IFLA_CAN_BITTIMING */
		size += nla_total_size(sizeof(struct can_bittiming));
	if (priv->bittiming_const)				/* IFLA_CAN_BITTIMING_CONST */
		size += nla_total_size(sizeof(struct can_bittiming_const));
	size += nla_total_size(sizeof(struct can_clock));	/* IFLA_CAN_CLOCK */
	size += nla_total_size(sizeof(u32));			/* IFLA_CAN_STATE */
	size += nla_total_size(sizeof(struct can_ctrlmode));	/* IFLA_CAN_CTRLMODE */
	size += nla_total_size(sizeof(u32));			/* IFLA_CAN_RESTART_MS */
	if (priv->do_get_berr_counter)				/* IFLA_CAN_BERR_COUNTER */
		size += nla_total_size(sizeof(struct can_berr_counter));
	if (priv->termination_const) {
		size += nla_total_size(sizeof(priv->termination));		/* IFLA_CAN_TERMINATION */
		size += nla_total_size(sizeof(*priv->termination_const) *	/* IFLA_CAN_TERMINATION_CONST */
				       priv->termination_const_cnt);
	}
	if (priv->bitrate_const)				/* IFLA_CAN_BITRATE_CONST */
		size += nla_total_size(sizeof(*priv->bitrate_const) *
				       priv->bitrate_const_cnt);
	size += sizeof(priv->bitrate_max);			/* IFLA_CAN_BITRATE_MAX */
	size += can_ctrlmode_ext_get_size();			/* IFLA_CAN_CTRLMODE_EXT */

	size += can_data_bittiming_get_size(&priv->fd,
					    priv->ctrlmode & CAN_CTRLMODE_FD_TDC_MASK);

	size += can_data_bittiming_get_size(&priv->xl,
					    priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MASK);
	size += can_pwm_get_size(priv->xl.pwm_const,		/* IFLA_CAN_XL_PWM */
				 priv->ctrlmode & CAN_CTRLMODE_XL_TMS);

	return size;
}

static int can_bittiming_fill_info(struct sk_buff *skb, int ifla_can_bittiming,
				   struct can_bittiming *bittiming)
{
	return bittiming->bitrate != CAN_BITRATE_UNSET &&
		bittiming->bitrate != CAN_BITRATE_UNKNOWN &&
		nla_put(skb, ifla_can_bittiming, sizeof(*bittiming), bittiming);
}

static int can_bittiming_const_fill_info(struct sk_buff *skb,
					 int ifla_can_bittiming_const,
					 const struct can_bittiming_const *bittiming_const)
{
	return bittiming_const &&
		nla_put(skb, ifla_can_bittiming_const,
			sizeof(*bittiming_const), bittiming_const);
}

static int can_bitrate_const_fill_info(struct sk_buff *skb,
				       int ifla_can_bitrate_const,
				       const u32 *bitrate_const, unsigned int cnt)
{
	return bitrate_const &&
		nla_put(skb, ifla_can_bitrate_const,
			sizeof(*bitrate_const) * cnt, bitrate_const);
}

static int can_tdc_fill_info(struct sk_buff *skb, const struct net_device *dev,
			     int ifla_can_tdc)
{
	struct can_priv *priv = netdev_priv(dev);
	struct data_bittiming_params *dbt_params;
	const struct can_tdc_const *tdc_const;
	struct can_tdc *tdc;
	struct nlattr *nest;
	bool tdc_is_enabled, tdc_manual;

	if (ifla_can_tdc == IFLA_CAN_TDC) {
		dbt_params = &priv->fd;
		tdc_is_enabled = can_fd_tdc_is_enabled(priv);
		tdc_manual = priv->ctrlmode & CAN_CTRLMODE_TDC_MANUAL;
	} else {
		dbt_params = &priv->xl;
		tdc_is_enabled = can_xl_tdc_is_enabled(priv);
		tdc_manual = priv->ctrlmode & CAN_CTRLMODE_XL_TDC_MANUAL;
	}
	tdc_const = dbt_params->tdc_const;
	tdc = &dbt_params->tdc;

	if (!tdc_const)
		return 0;

	nest = nla_nest_start(skb, ifla_can_tdc);
	if (!nest)
		return -EMSGSIZE;

	if (tdc_manual &&
	    (nla_put_u32(skb, IFLA_CAN_TDC_TDCV_MIN, tdc_const->tdcv_min) ||
	     nla_put_u32(skb, IFLA_CAN_TDC_TDCV_MAX, tdc_const->tdcv_max)))
		goto err_cancel;
	if (nla_put_u32(skb, IFLA_CAN_TDC_TDCO_MIN, tdc_const->tdco_min) ||
	    nla_put_u32(skb, IFLA_CAN_TDC_TDCO_MAX, tdc_const->tdco_max))
		goto err_cancel;
	if (tdc_const->tdcf_max &&
	    (nla_put_u32(skb, IFLA_CAN_TDC_TDCF_MIN, tdc_const->tdcf_min) ||
	     nla_put_u32(skb, IFLA_CAN_TDC_TDCF_MAX, tdc_const->tdcf_max)))
		goto err_cancel;

	if (tdc_is_enabled) {
		u32 tdcv;
		int err = -EINVAL;

		if (tdc_manual) {
			tdcv = tdc->tdcv;
			err = 0;
		} else if (dbt_params->do_get_auto_tdcv) {
			err = dbt_params->do_get_auto_tdcv(dev, &tdcv);
		}
		if (!err && nla_put_u32(skb, IFLA_CAN_TDC_TDCV, tdcv))
			goto err_cancel;
		if (nla_put_u32(skb, IFLA_CAN_TDC_TDCO, tdc->tdco))
			goto err_cancel;
		if (tdc_const->tdcf_max &&
		    nla_put_u32(skb, IFLA_CAN_TDC_TDCF, tdc->tdcf))
			goto err_cancel;
	}

	nla_nest_end(skb, nest);
	return 0;

err_cancel:
	nla_nest_cancel(skb, nest);
	return -EMSGSIZE;
}

static int can_pwm_fill_info(struct sk_buff *skb, const struct can_priv *priv)
{
	const struct can_pwm_const *pwm_const = priv->xl.pwm_const;
	const struct can_pwm *pwm = &priv->xl.pwm;
	struct nlattr *nest;

	if (!pwm_const)
		return 0;

	nest = 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)
{
	struct nlattr *nest;

	nest = nla_nest_start(skb, IFLA_CAN_CTRLMODE_EXT);
	if (!nest)
		return -EMSGSIZE;

	if (nla_put_u32(skb, IFLA_CAN_CTRLMODE_SUPPORTED,
			priv->ctrlmode_supported)) {
		nla_nest_cancel(skb, nest);
		return -EMSGSIZE;
	}

	nla_nest_end(skb, nest);
	return 0;
}

static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
	struct can_priv *priv = netdev_priv(dev);
	struct can_ctrlmode cm = {.flags = priv->ctrlmode};
	struct can_berr_counter bec = { };
	enum can_state state = priv->state;

	if (priv->do_get_state)
		priv->do_get_state(dev, &state);

	if (can_bittiming_fill_info(skb, IFLA_CAN_BITTIMING,
				    &priv->bittiming) ||

	    can_bittiming_const_fill_info(skb, IFLA_CAN_BITTIMING_CONST,
					  priv->bittiming_const) ||

	    nla_put(skb, IFLA_CAN_CLOCK, sizeof(priv->clock), &priv->clock) ||
	    nla_put_u32(skb, IFLA_CAN_STATE, state) ||
	    nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
	    nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||

	    (priv->do_get_berr_counter &&
	     !priv->do_get_berr_counter(dev, &bec) &&
	     nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||

	    can_bittiming_fill_info(skb, IFLA_CAN_DATA_BITTIMING,
				    &priv->fd.data_bittiming) ||

	    can_bittiming_const_fill_info(skb, IFLA_CAN_DATA_BITTIMING_CONST,
					  priv->fd.data_bittiming_const) ||

	    (priv->termination_const &&
	     (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) ||
	      nla_put(skb, IFLA_CAN_TERMINATION_CONST,
		      sizeof(*priv->termination_const) *
		      priv->termination_const_cnt,
		      priv->termination_const))) ||

	    can_bitrate_const_fill_info(skb, IFLA_CAN_BITRATE_CONST,
					priv->bitrate_const,
					priv->bitrate_const_cnt) ||

	    can_bitrate_const_fill_info(skb, IFLA_CAN_DATA_BITRATE_CONST,
					priv->fd.data_bitrate_const,
					priv->fd.data_bitrate_const_cnt) ||

	    (nla_put(skb, IFLA_CAN_BITRATE_MAX,
		     sizeof(priv->bitrate_max),
		     &priv->bitrate_max)) ||

	    can_tdc_fill_info(skb, dev, IFLA_CAN_TDC) ||

	    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) ||

	    can_pwm_fill_info(skb, priv)
	    )
		return -EMSGSIZE;

	return 0;
}

static size_t can_get_xstats_size(const struct net_device *dev)
{
	return sizeof(struct can_device_stats);
}

static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
{
	struct can_priv *priv = netdev_priv(dev);

	if (nla_put(skb, IFLA_INFO_XSTATS,
		    sizeof(priv->can_stats), &priv->can_stats))
		goto nla_put_failure;
	return 0;

nla_put_failure:
	return -EMSGSIZE;
}

static int can_newlink(struct net_device *dev,
		       struct rtnl_newlink_params *params,
		       struct netlink_ext_ack *extack)
{
	return -EOPNOTSUPP;
}

static void can_dellink(struct net_device *dev, struct list_head *head)
{
}

struct rtnl_link_ops can_link_ops __read_mostly = {
	.kind		= "can",
	.netns_refund	= true,
	.maxtype	= IFLA_CAN_MAX,
	.policy		= can_policy,
	.setup		= can_setup,
	.validate	= can_validate,
	.newlink	= can_newlink,
	.changelink	= can_changelink,
	.dellink	= can_dellink,
	.get_size	= can_get_size,
	.fill_info	= can_fill_info,
	.get_xstats_size = can_get_xstats_size,
	.fill_xstats	= can_fill_xstats,
};

int can_netlink_register(void)
{
	return rtnl_link_register(&can_link_ops);
}

void can_netlink_unregister(void)
{
	rtnl_link_unregister(&can_link_ops);
}
