Commit a0bfd73d authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-next-for-5.18-20220316' of...

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

Marc Kleine-Budde says:

====================
pull-request: can-next 2022-03-16

the first 3 patches are by Oliver Hartkopp target the CAN ISOTP
protocol and fix a problem found by syzbot in isotp_bind(), return
-EADDRNOTAVAIL in unbound sockets in isotp_recvmsg() and add support
for MSG_TRUNC to isotp_recvmsg().

Amit Kumar Mahapatra converts the xilinx,can device tree bindings to
yaml.

The last patch is by Julia Lawall and fixes typos in the ucan driver.

* tag 'linux-can-next-for-5.18-20220316' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  can: ucan: fix typos in comments
  dt-bindings: can: xilinx_can: Convert Xilinx CAN binding to YAML
  can: isotp: support MSG_TRUNC flag when reading from socket
  can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
  can: isotp: sanitize CAN ID checks in isotp_bind()
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b1351527 c34983c9
Loading
Loading
Loading
Loading
+161 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/can/xilinx,can.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title:
  Xilinx Axi CAN/Zynq CANPS controller

maintainers:
  - Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>

properties:
  compatible:
    enum:
      - xlnx,zynq-can-1.0
      - xlnx,axi-can-1.00.a
      - xlnx,canfd-1.0
      - xlnx,canfd-2.0

  reg:
    maxItems: 1

  interrupts:
    maxItems: 1

  clocks:
    minItems: 1
    maxItems: 2

  clock-names:
    maxItems: 2

  power-domains:
    maxItems: 1

  tx-fifo-depth:
    $ref: "/schemas/types.yaml#/definitions/uint32"
    description: CAN Tx fifo depth (Zynq, Axi CAN).

  rx-fifo-depth:
    $ref: "/schemas/types.yaml#/definitions/uint32"
    description: CAN Rx fifo depth (Zynq, Axi CAN, CAN FD in sequential Rx mode)

  tx-mailbox-count:
    $ref: "/schemas/types.yaml#/definitions/uint32"
    description: CAN Tx mailbox buffer count (CAN FD)

required:
  - compatible
  - reg
  - interrupts
  - clocks
  - clock-names

unevaluatedProperties: false

allOf:
  - $ref: can-controller.yaml#
  - if:
      properties:
        compatible:
          contains:
            enum:
              - xlnx,zynq-can-1.0

    then:
      properties:
        clock-names:
          items:
            - const: can_clk
            - const: pclk
      required:
        - tx-fifo-depth
        - rx-fifo-depth

  - if:
      properties:
        compatible:
          contains:
            enum:
              - xlnx,axi-can-1.00.a

    then:
      properties:
        clock-names:
          items:
            - const: can_clk
            - const: s_axi_aclk
      required:
        - tx-fifo-depth
        - rx-fifo-depth

  - if:
      properties:
        compatible:
          contains:
            enum:
              - xlnx,canfd-1.0
              - xlnx,canfd-2.0

    then:
      properties:
        clock-names:
          items:
            - const: can_clk
            - const: s_axi_aclk
      required:
        - tx-mailbox-count
        - rx-fifo-depth

examples:
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>

    can@e0008000 {
        compatible = "xlnx,zynq-can-1.0";
        reg = <0xe0008000 0x1000>;
        clocks = <&clkc 19>, <&clkc 36>;
        clock-names = "can_clk", "pclk";
        interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-parent = <&intc>;
        tx-fifo-depth = <0x40>;
        rx-fifo-depth = <0x40>;
    };

  - |
    can@40000000 {
        compatible = "xlnx,axi-can-1.00.a";
        reg = <0x40000000 0x10000>;
        clocks = <&clkc 0>, <&clkc 1>;
        clock-names = "can_clk", "s_axi_aclk";
        interrupt-parent = <&intc>;
        interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
        tx-fifo-depth = <0x40>;
        rx-fifo-depth = <0x40>;
    };

  - |
    can@40000000 {
        compatible = "xlnx,canfd-1.0";
        reg = <0x40000000 0x2000>;
        clocks = <&clkc 0>, <&clkc 1>;
        clock-names = "can_clk", "s_axi_aclk";
        interrupt-parent = <&intc>;
        interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
        tx-mailbox-count = <0x20>;
        rx-fifo-depth = <0x20>;
    };

  - |
    can@ff060000 {
        compatible = "xlnx,canfd-2.0";
        reg = <0xff060000 0x6000>;
        clocks = <&clkc 0>, <&clkc 1>;
        clock-names = "can_clk", "s_axi_aclk";
        interrupt-parent = <&intc>;
        interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>;
        tx-mailbox-count = <0x20>;
        rx-fifo-depth = <0x40>;
    };
+0 −61
Original line number Diff line number Diff line
Xilinx Axi CAN/Zynq CANPS controller Device Tree Bindings
---------------------------------------------------------

Required properties:
- compatible		: Should be:
			  - "xlnx,zynq-can-1.0" for Zynq CAN controllers
			  - "xlnx,axi-can-1.00.a" for Axi CAN controllers
			  - "xlnx,canfd-1.0" for CAN FD controllers
			  - "xlnx,canfd-2.0" for CAN FD 2.0 controllers
- reg			: Physical base address and size of the controller
			  registers map.
- interrupts		: Property with a value describing the interrupt
			  number.
- clock-names		: List of input clock names
			  - "can_clk", "pclk" (For CANPS),
			  - "can_clk", "s_axi_aclk" (For AXI CAN and CAN FD).
			  (See clock bindings for details).
- clocks		: Clock phandles (see clock bindings for details).
- tx-fifo-depth		: Can Tx fifo depth (Zynq, Axi CAN).
- rx-fifo-depth		: Can Rx fifo depth (Zynq, Axi CAN, CAN FD in
                          sequential Rx mode).
- tx-mailbox-count	: Can Tx mailbox buffer count (CAN FD).
- rx-mailbox-count	: Can Rx mailbox buffer count (CAN FD in mailbox Rx
			  mode).


Example:

For Zynq CANPS Dts file:
	zynq_can_0: can@e0008000 {
			compatible = "xlnx,zynq-can-1.0";
			clocks = <&clkc 19>, <&clkc 36>;
			clock-names = "can_clk", "pclk";
			reg = <0xe0008000 0x1000>;
			interrupts = <0 28 4>;
			interrupt-parent = <&intc>;
			tx-fifo-depth = <0x40>;
			rx-fifo-depth = <0x40>;
		};
For Axi CAN Dts file:
	axi_can_0: axi-can@40000000 {
			compatible = "xlnx,axi-can-1.00.a";
			clocks = <&clkc 0>, <&clkc 1>;
			clock-names = "can_clk","s_axi_aclk" ;
			reg = <0x40000000 0x10000>;
			interrupt-parent = <&intc>;
			interrupts = <0 59 1>;
			tx-fifo-depth = <0x40>;
			rx-fifo-depth = <0x40>;
		};
For CAN FD Dts file:
	canfd_0: canfd@40000000 {
			compatible = "xlnx,canfd-1.0";
			clocks = <&clkc 0>, <&clkc 1>;
			clock-names = "can_clk", "s_axi_aclk";
			reg = <0x40000000 0x2000>;
			interrupt-parent = <&intc>;
			interrupts = <0 59 1>;
			tx-mailbox-count = <0x20>;
			rx-fifo-depth = <0x20>;
		};
+2 −2
Original line number Diff line number Diff line
@@ -1392,7 +1392,7 @@ static int ucan_probe(struct usb_interface *intf,
	 * Stage 3 for the final driver initialisation.
	 */

	/* Prepare Memory for control transferes */
	/* Prepare Memory for control transfers */
	ctl_msg_buffer = devm_kzalloc(&udev->dev,
				      sizeof(union ucan_ctl_payload),
				      GFP_KERNEL);
@@ -1526,7 +1526,7 @@ static int ucan_probe(struct usb_interface *intf,
	ret = ucan_device_request_in(up, UCAN_DEVICE_GET_FW_STRING, 0,
				     sizeof(union ucan_ctl_payload));
	if (ret > 0) {
		/* copy string while ensuring zero terminiation */
		/* copy string while ensuring zero termination */
		strncpy(firmware_str, up->ctl_msg_buffer->raw,
			sizeof(union ucan_ctl_payload));
		firmware_str[sizeof(union ucan_ctl_payload)] = '\0';
+40 −32
Original line number Diff line number Diff line
@@ -1046,26 +1046,29 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
{
	struct sock *sk = sock->sk;
	struct sk_buff *skb;
	int err = 0;
	int noblock;
	struct isotp_sock *so = isotp_sk(sk);
	int noblock = flags & MSG_DONTWAIT;
	int ret = 0;

	noblock = flags & MSG_DONTWAIT;
	flags &= ~MSG_DONTWAIT;
	if (flags & ~(MSG_DONTWAIT | MSG_TRUNC))
		return -EINVAL;

	if (!so->bound)
		return -EADDRNOTAVAIL;

	skb = skb_recv_datagram(sk, flags, noblock, &err);
	flags &= ~MSG_DONTWAIT;
	skb = skb_recv_datagram(sk, flags, noblock, &ret);
	if (!skb)
		return err;
		return ret;

	if (size < skb->len)
		msg->msg_flags |= MSG_TRUNC;
	else
		size = skb->len;

	err = memcpy_to_msg(msg, skb->data, size);
	if (err < 0) {
		skb_free_datagram(sk, skb);
		return err;
	}
	ret = memcpy_to_msg(msg, skb->data, size);
	if (ret < 0)
		goto out_err;

	sock_recv_timestamp(msg, sk, skb);

@@ -1075,9 +1078,13 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
	}

	/* set length of return value */
	ret = (flags & MSG_TRUNC) ? skb->len : size;

out_err:
	skb_free_datagram(sk, skb);

	return size;
	return ret;
}

static int isotp_release(struct socket *sock)
@@ -1148,6 +1155,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
	struct net *net = sock_net(sk);
	int ifindex;
	struct net_device *dev;
	canid_t tx_id, rx_id;
	int err = 0;
	int notify_enetdown = 0;
	int do_rx_reg = 1;
@@ -1155,8 +1163,18 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
	if (len < ISOTP_MIN_NAMELEN)
		return -EINVAL;

	if (addr->can_addr.tp.tx_id & (CAN_ERR_FLAG | CAN_RTR_FLAG))
		return -EADDRNOTAVAIL;
	/* sanitize tx/rx CAN identifiers */
	tx_id = addr->can_addr.tp.tx_id;
	if (tx_id & CAN_EFF_FLAG)
		tx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK);
	else
		tx_id &= CAN_SFF_MASK;

	rx_id = addr->can_addr.tp.rx_id;
	if (rx_id & CAN_EFF_FLAG)
		rx_id &= (CAN_EFF_FLAG | CAN_EFF_MASK);
	else
		rx_id &= CAN_SFF_MASK;

	if (!addr->can_ifindex)
		return -ENODEV;
@@ -1168,21 +1186,13 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
		do_rx_reg = 0;

	/* do not validate rx address for functional addressing */
	if (do_rx_reg) {
		if (addr->can_addr.tp.rx_id == addr->can_addr.tp.tx_id) {
			err = -EADDRNOTAVAIL;
			goto out;
		}

		if (addr->can_addr.tp.rx_id & (CAN_ERR_FLAG | CAN_RTR_FLAG)) {
	if (do_rx_reg && rx_id == tx_id) {
		err = -EADDRNOTAVAIL;
		goto out;
	}
	}

	if (so->bound && addr->can_ifindex == so->ifindex &&
	    addr->can_addr.tp.rx_id == so->rxid &&
	    addr->can_addr.tp.tx_id == so->txid)
	    rx_id == so->rxid && tx_id == so->txid)
		goto out;

	dev = dev_get_by_index(net, addr->can_ifindex);
@@ -1206,16 +1216,14 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
	ifindex = dev->ifindex;

	if (do_rx_reg) {
		can_rx_register(net, dev, addr->can_addr.tp.rx_id,
				SINGLE_MASK(addr->can_addr.tp.rx_id),
		can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
				isotp_rcv, sk, "isotp", sk);

		/* no consecutive frame echo skb in flight */
		so->cfecho = 0;

		/* register for echo skb's */
		can_rx_register(net, dev, addr->can_addr.tp.tx_id,
				SINGLE_MASK(addr->can_addr.tp.tx_id),
		can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
				isotp_rcv_echo, sk, "isotpe", sk);
	}

@@ -1239,8 +1247,8 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)

	/* switch to new settings */
	so->ifindex = ifindex;
	so->rxid = addr->can_addr.tp.rx_id;
	so->txid = addr->can_addr.tp.tx_id;
	so->rxid = rx_id;
	so->txid = tx_id;
	so->bound = 1;

out: