Commit 61d731e6 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge tag 'linux-can-next-for-6.3-20230206' of...

Merge tag 'linux-can-next-for-6.3-20230206' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2023-02-06

this is a pull request of 47 patches for net-next/master.

The first two patch is by Oliver Hartkopp. One adds missing error
checking to the CAN_GW protocol, the other adds a missing CAN address
family check to the CAN ISO TP protocol.

Thomas Kopp contributes a performance optimization to the mcp251xfd
driver.

The next 11 patches are by Geert Uytterhoeven and add support for
R-Car V4H systems to the rcar_canfd driver.

Stephane Grosjean and Lukas Magel contribute 8 patches to the peak_usb
driver, which add support for configurable CAN channel ID.

The last 17 patches are by me and target the CAN bit timing
configuration. The bit timing is cleaned up, error messages are
improved and forwarded to user space via NL_SET_ERR_MSG_FMT() instead
of netdev_err(), and the SJW handling is updated, including the
definition of a new default value that will benefit CAN-FD
controllers, by increasing their oscillator tolerance.

* tag 'linux-can-next-for-6.3-20230206' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next: (47 commits)
  can: bittiming: can_validate_bitrate(): report error via netlink
  can: bittiming: can_calc_bittiming(): convert from netdev_err() to NL_SET_ERR_MSG_FMT()
  can: bittiming: can_calc_bittiming(): clean up SJW handling
  can: bittiming: can_sjw_set_default(): use Phase Seg2 / 2 as default for SJW
  can: bittiming: can_sjw_check(): check that SJW is not longer than either Phase Buffer Segment
  can: bittiming: can_sjw_check(): report error via netlink and harmonize error value
  can: bittiming: can_fixup_bittiming(): report error via netlink and harmonize error value
  can: bittiming: factor out can_sjw_set_default() and can_sjw_check()
  can: bittiming: can_changelink() pass extack down callstack
  can: netlink: can_changelink(): convert from netdev_err() to NL_SET_ERR_MSG_FMT()
  can: netlink: can_validate(): validate sample point for CAN and CAN-FD
  can: dev: register_candev(): bail out if both fixed bit rates and bit timing constants are provided
  can: dev: register_candev(): ensure that bittiming const are valid
  can: bittiming: can_get_bittiming(): use direct return and remove unneeded else
  can: bittiming: can_fixup_bittiming(): set effective tq
  can: bittiming: can_fixup_bittiming(): use CAN_SYNC_SEG instead of 1
  can: bittiming(): replace open coded variants of can_bit_time()
  can: peak_usb: Reorder include directives alphabetically
  can: peak_usb: align CAN channel ID format in log with sysfs attribute
  can: peak_usb: export PCAN CAN channel ID as sysfs device attribute
  ...
====================

Link: https://lore.kernel.org/r/20230206131620.2758724-1-mkl@pengutronix.de


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents ca8e4cbf 3dafbe5c
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line

What:		/sys/class/net/<iface>/peak_usb/can_channel_id
Date:		November 2022
KernelVersion:	6.2
Contact:	Stephane Grosjean <s.grosjean@peak-system.com>
Description:
		PEAK PCAN-USB devices support user-configurable CAN channel
		identifiers. Contrary to a USB serial number, these identifiers
		are writable and can be set per CAN interface. This means that
		if a USB device exports multiple CAN interfaces, each of them
		can be assigned a unique channel ID.
		This attribute provides read-only access to the currently
		configured value of the channel identifier. Depending on the
		device type, the identifier has a length of 8 or 32 bit. The
		value read from this attribute is always an 8 digit 32 bit
		hexadecimal value in big endian format. If the device only
		supports an 8 bit identifier, the upper 24 bit of the value are
		set to zero.
+12 −4
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@ properties:
              - renesas,r8a77995-canfd     # R-Car D3
          - const: renesas,rcar-gen3-canfd # R-Car Gen3 and RZ/G2

      - items:
          - enum:
              - renesas,r8a779a0-canfd     # R-Car V3U
              - renesas,r8a779g0-canfd     # R-Car V4H
          - const: renesas,rcar-gen4-canfd # R-Car Gen4

      - items:
          - enum:
              - renesas,r9a07g043-canfd    # RZ/G2UL and RZ/Five
@@ -35,8 +41,6 @@ properties:
              - renesas,r9a07g054-canfd    # RZ/V2L
          - const: renesas,rzg2l-canfd     # RZ/G2L family

      - const: renesas,r8a779a0-canfd      # R-Car V3U

  reg:
    maxItems: 1

@@ -60,7 +64,7 @@ properties:
    $ref: /schemas/types.yaml#/definitions/flag
    description:
      The controller can operate in either CAN FD only mode (default) or
      Classical CAN only mode.  The mode is global to both the channels.
      Classical CAN only mode.  The mode is global to all channels.
      Specify this property to put the controller in Classical CAN only mode.

  assigned-clocks:
@@ -80,6 +84,10 @@ patternProperties:
      The controller supports multiple channels and each is represented as a
      child node.  Each channel can be enabled/disabled individually.

    properties:
      phys:
        maxItems: 1

    additionalProperties: false

required:
@@ -159,7 +167,7 @@ allOf:
        properties:
          compatible:
            contains:
              const: renesas,r8a779a0-canfd
              const: renesas,rcar-gen4-canfd
    then:
      patternProperties:
        "^channel[2-7]$": false
+93 −27
Original line number Diff line number Diff line
@@ -6,25 +6,81 @@

#include <linux/can/dev.h>

void can_sjw_set_default(struct can_bittiming *bt)
{
	if (bt->sjw)
		return;

	/* If user space provides no sjw, use sane default of phase_seg2 / 2 */
	bt->sjw = max(1U, min(bt->phase_seg1, bt->phase_seg2 / 2));
}

int can_sjw_check(const struct net_device *dev, const struct can_bittiming *bt,
		  const struct can_bittiming_const *btc, struct netlink_ext_ack *extack)
{
	if (bt->sjw > btc->sjw_max) {
		NL_SET_ERR_MSG_FMT(extack, "sjw: %u greater than max sjw: %u",
				   bt->sjw, btc->sjw_max);
		return -EINVAL;
	}

	if (bt->sjw > bt->phase_seg1) {
		NL_SET_ERR_MSG_FMT(extack,
				   "sjw: %u greater than phase-seg1: %u",
				   bt->sjw, bt->phase_seg1);
		return -EINVAL;
	}

	if (bt->sjw > bt->phase_seg2) {
		NL_SET_ERR_MSG_FMT(extack,
				   "sjw: %u greater than phase-seg2: %u",
				   bt->sjw, bt->phase_seg2);
		return -EINVAL;
	}

	return 0;
}

/* Checks the validity of the specified bit-timing parameters prop_seg,
 * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
 * prescaler value brp. You can find more information in the header
 * file linux/can/netlink.h.
 */
static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt,
			       const struct can_bittiming_const *btc)
			       const struct can_bittiming_const *btc,
			       struct netlink_ext_ack *extack)
{
	const unsigned int tseg1 = bt->prop_seg + bt->phase_seg1;
	const struct can_priv *priv = netdev_priv(dev);
	unsigned int tseg1, alltseg;
	u64 brp64;
	int err;

	tseg1 = bt->prop_seg + bt->phase_seg1;
	if (!bt->sjw)
		bt->sjw = 1;
	if (bt->sjw > btc->sjw_max ||
	    tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
	    bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
		return -ERANGE;
	if (tseg1 < btc->tseg1_min) {
		NL_SET_ERR_MSG_FMT(extack, "prop-seg + phase-seg1: %u less than tseg1-min: %u",
				   tseg1, btc->tseg1_min);
		return -EINVAL;
	}
	if (tseg1 > btc->tseg1_max) {
		NL_SET_ERR_MSG_FMT(extack, "prop-seg + phase-seg1: %u greater than tseg1-max: %u",
				   tseg1, btc->tseg1_max);
		return -EINVAL;
	}
	if (bt->phase_seg2 < btc->tseg2_min) {
		NL_SET_ERR_MSG_FMT(extack, "phase-seg2: %u less than tseg2-min: %u",
				   bt->phase_seg2, btc->tseg2_min);
		return -EINVAL;
	}
	if (bt->phase_seg2 > btc->tseg2_max) {
		NL_SET_ERR_MSG_FMT(extack, "phase-seg2: %u greater than tseg2-max: %u",
				   bt->phase_seg2, btc->tseg2_max);
		return -EINVAL;
	}

	can_sjw_set_default(bt);

	err = can_sjw_check(dev, bt, btc, extack);
	if (err)
		return err;

	brp64 = (u64)priv->clock.freq * (u64)bt->tq;
	if (btc->brp_inc > 1)
@@ -35,12 +91,21 @@ static int can_fixup_bittiming(const struct net_device *dev, struct can_bittimin
		brp64 *= btc->brp_inc;
	bt->brp = (u32)brp64;

	if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
	if (bt->brp < btc->brp_min) {
		NL_SET_ERR_MSG_FMT(extack, "resulting brp: %u less than brp-min: %u",
				   bt->brp, btc->brp_min);
		return -EINVAL;
	}
	if (bt->brp > btc->brp_max) {
		NL_SET_ERR_MSG_FMT(extack, "resulting brp: %u greater than brp-max: %u",
				   bt->brp, btc->brp_max);
		return -EINVAL;
	}

	alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
	bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
	bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
	bt->bitrate = priv->clock.freq / (bt->brp * can_bit_time(bt));
	bt->sample_point = ((CAN_SYNC_SEG + tseg1) * 1000) / can_bit_time(bt);
	bt->tq = DIV_U64_ROUND_CLOSEST(mul_u32_u32(bt->brp, NSEC_PER_SEC),
				       priv->clock.freq);

	return 0;
}
@@ -49,7 +114,8 @@ static int can_fixup_bittiming(const struct net_device *dev, struct can_bittimin
static int
can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt,
		     const u32 *bitrate_const,
		     const unsigned int bitrate_const_cnt)
		     const unsigned int bitrate_const_cnt,
		     struct netlink_ext_ack *extack)
{
	unsigned int i;

@@ -58,30 +124,30 @@ can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *b
			return 0;
	}

	NL_SET_ERR_MSG_FMT(extack, "bitrate %u bps not supported",
			   bt->brp);

	return -EINVAL;
}

int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt,
		      const struct can_bittiming_const *btc,
		      const u32 *bitrate_const,
		      const unsigned int bitrate_const_cnt)
		      const unsigned int bitrate_const_cnt,
		      struct netlink_ext_ack *extack)
{
	int err;

	/* Depending on the given can_bittiming parameter structure the CAN
	 * timing parameters are calculated based on the provided bitrate OR
	 * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
	 * provided directly which are then checked and fixed up.
	 */
	if (!bt->tq && bt->bitrate && btc)
		err = can_calc_bittiming(dev, bt, btc);
	else if (bt->tq && !bt->bitrate && btc)
		err = can_fixup_bittiming(dev, bt, btc);
	else if (!bt->tq && bt->bitrate && bitrate_const)
		err = can_validate_bitrate(dev, bt, bitrate_const,
					   bitrate_const_cnt);
	else
		err = -EINVAL;
		return can_calc_bittiming(dev, bt, btc, extack);
	if (bt->tq && !bt->bitrate && btc)
		return can_fixup_bittiming(dev, bt, btc, extack);
	if (!bt->tq && bt->bitrate && bitrate_const)
		return can_validate_bitrate(dev, bt, bitrate_const,
					    bitrate_const_cnt, extack);

	return err;
	return -EINVAL;
}
+15 −19
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ can_update_sample_point(const struct can_bittiming_const *btc,
}

int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
		       const struct can_bittiming_const *btc)
		       const struct can_bittiming_const *btc, struct netlink_ext_ack *extack)
{
	struct can_priv *priv = netdev_priv(dev);
	unsigned int bitrate;			/* current bitrate */
@@ -76,6 +76,7 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
	unsigned int best_brp = 0;		/* current best value for brp */
	unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0;
	u64 v64;
	int err;

	/* Use CiA recommended sample points */
	if (bt->sample_point) {
@@ -133,12 +134,13 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
		do_div(v64, bt->bitrate);
		bitrate_error = (u32)v64;
		if (bitrate_error > CAN_CALC_MAX_ERROR) {
			netdev_err(dev,
				   "bitrate error %d.%d%% too high\n",
			NL_SET_ERR_MSG_FMT(extack,
					   "bitrate error: %u.%u%% too high",
					   bitrate_error / 10, bitrate_error % 10);
			return -EDOM;
			return -EINVAL;
		}
		netdev_warn(dev, "bitrate error %d.%d%%\n",
		NL_SET_ERR_MSG_FMT(extack,
				   "bitrate error: %u.%u%%",
				   bitrate_error / 10, bitrate_error % 10);
	}

@@ -154,23 +156,17 @@ int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt,
	bt->phase_seg1 = tseg1 - bt->prop_seg;
	bt->phase_seg2 = tseg2;

	/* check for sjw user settings */
	if (!bt->sjw || !btc->sjw_max) {
		bt->sjw = 1;
	} else {
		/* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
		if (bt->sjw > btc->sjw_max)
			bt->sjw = btc->sjw_max;
		/* bt->sjw must not be higher than tseg2 */
		if (tseg2 < bt->sjw)
			bt->sjw = tseg2;
	}
	can_sjw_set_default(bt);

	err = can_sjw_check(dev, bt, btc, extack);
	if (err)
		return err;

	bt->brp = best_brp;

	/* real bitrate */
	bt->bitrate = priv->clock.freq /
		(bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2));
		(bt->brp * can_bit_time(bt));

	return 0;
}
+21 −0
Original line number Diff line number Diff line
@@ -498,6 +498,18 @@ static int can_get_termination(struct net_device *ndev)
	return 0;
}

static bool
can_bittiming_const_valid(const struct can_bittiming_const *btc)
{
	if (!btc)
		return true;

	if (!btc->sjw_max)
		return false;

	return true;
}

/* Register the CAN network device */
int register_candev(struct net_device *dev)
{
@@ -518,6 +530,15 @@ int register_candev(struct net_device *dev)
	if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt)
		return -EINVAL;

	/* We only support either fixed bit rates or bit timing const. */
	if ((priv->bitrate_const || priv->data_bitrate_const) &&
	    (priv->bittiming_const || priv->data_bittiming_const))
		return -EINVAL;

	if (!can_bittiming_const_valid(priv->bittiming_const) ||
	    !can_bittiming_const_valid(priv->data_bittiming_const))
		return -EINVAL;

	if (!priv->termination_const) {
		err = can_get_termination(dev);
		if (err)
Loading