linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH 0/2] LIN support for Linux
@ 2022-11-27 19:02 Christoph Fritz
  2022-11-27 19:02 ` [PATCH 1/2] [RFC] can: Introduce LIN bus as CANFD abstraction Christoph Fritz
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Christoph Fritz @ 2022-11-27 19:02 UTC (permalink / raw)
  To: Oliver Hartkopp, Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet
  Cc: linux-can, netdev, linux-kernel

The intention of this series is to kick off a discussion about how to
support LIN (ISO 17987) [0] in Linux.

This series consist of two patches which are two individual proposals
for adding LIN abstraction into the kernel.

One approach is to add LIN ontop of CANFD:
  [RFC] can: introduce LIN abstraction

The other approach is adding a new type of CAN-socket:
  [RFC] can: Add LIN proto skeleton

These patches are abstracting LIN so that actual device drivers can
make use of it.

For reference, the LIN-ontop-of-CANFD variant already has a device
driver using it (not part of this series). It is a specially built USB
LIN-BUS adapter hardware called hexLIN [1].  Its purpose is mainly to
test, adapt and discuss different LIN APIs for mainline Linux kernel.
But it can already be used productively as a Linux LIN node in
controller (master) and responder (slave) mode. By sysfs, hexLIN
supports different checksum calculations and setting up a
responder-table.

For more info about hexLIN, see link below [1].

We are looking for partners with Linux based LIN projects for funding. 

[0]: https://en.wikipedia.org/wiki/Local_Interconnect_Network
[1]: https://hexdev.de/hexlin/

Christoph Fritz (1):
  [RFC] can: Introduce LIN bus as CANFD abstraction

Richard Weinberger (1):
  [RFC] can: Add LIN proto skeleton

 drivers/net/can/Kconfig          |  10 ++
 drivers/net/can/Makefile         |   1 +
 drivers/net/can/lin.c            | 181 +++++++++++++++++++++++++++
 include/net/lin.h                |  30 +++++
 include/uapi/linux/can.h         |   8 +-
 include/uapi/linux/can/lin.h     |  15 +++
 include/uapi/linux/can/netlink.h |   1 +
 net/can/Kconfig                  |   5 +
 net/can/Makefile                 |   3 +
 net/can/lin.c                    | 207 +++++++++++++++++++++++++++++++
 10 files changed, 460 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/can/lin.c
 create mode 100644 include/net/lin.h
 create mode 100644 include/uapi/linux/can/lin.h
 create mode 100644 net/can/lin.c

-- 
2.30.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/2] [RFC] can: Introduce LIN bus as CANFD abstraction
  2022-11-27 19:02 [RFC][PATCH 0/2] LIN support for Linux Christoph Fritz
@ 2022-11-27 19:02 ` Christoph Fritz
  2022-11-27 19:02 ` [PATCH 2/2] [RFC] can: Add LIN proto skeleton Christoph Fritz
  2022-11-28  8:21 ` [RFC][PATCH 0/2] LIN support for Linux Oliver Hartkopp
  2 siblings, 0 replies; 12+ messages in thread
From: Christoph Fritz @ 2022-11-27 19:02 UTC (permalink / raw)
  To: Oliver Hartkopp, Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet
  Cc: linux-can, netdev, linux-kernel

This patch adds a LIN bus abstraction ontop of CANFD. It is a glue
driver adapting CAN on one side while offering LIN abstraction on the
other side. So that upcoming LIN device drivers can make use of it.

Signed-off-by: Christoph Fritz <christoph.fritz@hexdev.de>
---
 drivers/net/can/Kconfig          |  10 ++
 drivers/net/can/Makefile         |   1 +
 drivers/net/can/lin.c            | 181 +++++++++++++++++++++++++++++++
 include/net/lin.h                |  30 +++++
 include/uapi/linux/can.h         |   1 +
 include/uapi/linux/can/netlink.h |   1 +
 6 files changed, 224 insertions(+)
 create mode 100644 drivers/net/can/lin.c
 create mode 100644 include/net/lin.h

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 3048ad77edb3..d091994ea4fe 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -152,6 +152,16 @@ config CAN_KVASER_PCIEFD
 	    Kvaser Mini PCI Express HS v2
 	    Kvaser Mini PCI Express 2xHS v2
 
+config CAN_LIN
+	tristate "LIN mode support"
+	  help
+	  This is a glue driver for LIN-BUS support.
+
+	  The local interconnect (LIN) bus is a simple bus with a feature
+	  subset of CAN. It is often combined with CAN for simple controls.
+
+	  Actual device drivers need to be enabled too.
+
 config CAN_SLCAN
 	tristate "Serial / USB serial CAN Adaptors (slcan)"
 	depends on TTY
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 61c75ce9d500..9114d9e97c0c 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_CAN_GRCAN)		+= grcan.o
 obj-$(CONFIG_CAN_IFI_CANFD)	+= ifi_canfd/
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
 obj-$(CONFIG_CAN_KVASER_PCIEFD)	+= kvaser_pciefd.o
+obj-$(CONFIG_CAN_LIN)		+= lin.o
 obj-$(CONFIG_CAN_MSCAN)		+= mscan/
 obj-$(CONFIG_CAN_M_CAN)		+= m_can/
 obj-$(CONFIG_CAN_PEAK_PCIEFD)	+= peak_canfd/
diff --git a/drivers/net/can/lin.c b/drivers/net/can/lin.c
new file mode 100644
index 000000000000..25eaccc18ab6
--- /dev/null
+++ b/drivers/net/can/lin.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 hexDEV GmbH
+ */
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <net/lin.h>
+
+static void lin_tx_work_handler(struct work_struct *ws)
+{
+	struct lin_device *priv = container_of(ws, struct lin_device,
+						tx_work);
+	struct net_device *net = priv->net;
+	struct device *dev = priv->dev;
+	struct canfd_frame *frame;
+	u8 id, n;
+
+	priv->tx_busy = true;
+
+	frame = (struct canfd_frame *)priv->tx_skb->data;
+	id = (u8)frame->can_id & 0xff;
+	n = frame->len;
+
+	priv->lindev_ops->ldo_tx(dev, id, n, frame->data);
+	priv->tx_busy = false;
+	netif_wake_queue(net);
+}
+
+static netdev_tx_t lin_start_xmit(struct sk_buff *skb,
+				  struct net_device *netdev)
+{
+	struct lin_device *priv = netdev_priv(netdev);
+
+	if (priv->tx_busy)
+		return NETDEV_TX_BUSY;
+
+	netif_stop_queue(netdev);
+	priv->tx_skb = skb;
+	queue_work(priv->wq, &priv->tx_work);
+
+	return NETDEV_TX_OK;
+}
+
+static int lin_open(struct net_device *netdev)
+{
+	struct lin_device *priv = netdev_priv(netdev);
+	int ret;
+
+	priv->tx_busy = false;
+
+	ret = open_candev(netdev);
+	if (ret)
+		return ret;
+
+	netif_wake_queue(netdev);
+
+	return 0;
+}
+
+static int lin_stop(struct net_device *net)
+{
+	close_candev(net);
+
+	return 0;
+}
+
+static const struct net_device_ops lin_netdev_ops = {
+	.ndo_open = lin_open,
+	.ndo_stop = lin_stop,
+	.ndo_start_xmit = lin_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+int lin_rx(struct lin_device *priv, u8 id, u8 n, u8 *data, u8 checksum)
+{
+	struct net_device *ndev = priv->net;
+	struct net_device_stats *stats = &ndev->stats;
+	struct canfd_frame *cfd;
+	struct sk_buff *skb;
+
+	skb = alloc_canfd_skb(ndev, &cfd);
+	if (unlikely(!skb)) {
+		stats->rx_dropped++;
+		return -ENOMEM;
+	}
+
+	cfd->flags = CANFD_LIN;
+	cfd->can_id = id;
+	cfd->len = n + 1;	/* n of data + checksum */
+	memcpy(cfd->data, data, n);
+	cfd->data[n] = checksum;
+
+	stats->rx_bytes += cfd->len;
+	stats->rx_packets++;
+
+	netif_receive_skb(skb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lin_rx);
+
+static int lin_set_bittiming(struct net_device *netdev)
+{
+	struct lin_device *priv = netdev_priv(netdev);
+	struct device *dev = priv->dev;
+	int ret;
+
+	ret = priv->lindev_ops->update_bitrate(dev, priv->can.bittiming.bitrate);
+
+	return ret;
+}
+
+static const u32 lin_bitrate[] = { 2400, 4800, 9600, 19200 };
+
+struct lin_device *register_lin(struct device *dev,
+				const struct lin_device_ops *ldops)
+{
+	struct net_device *ndev;
+	struct lin_device *priv;
+	int ret;
+
+	ndev = alloc_candev(sizeof(struct lin_device), 1);
+	if (!ndev)
+		return NULL;
+
+	ndev->netdev_ops = &lin_netdev_ops;
+	ndev->flags |= IFF_ECHO;
+	ndev->mtu = CANFD_MTU;
+
+	priv = netdev_priv(ndev);
+	priv->lindev_ops = ldops;
+	priv->can.bittiming.bitrate = 9600;
+	priv->can.ctrlmode_supported = CAN_CTRLMODE_LIN;
+	priv->can.bitrate_const = lin_bitrate;
+	priv->can.bitrate_const_cnt = ARRAY_SIZE(lin_bitrate);
+	priv->can.do_set_bittiming = lin_set_bittiming;
+	priv->net = ndev;
+	priv->dev = dev;
+
+	SET_NETDEV_DEV(ndev, dev);
+
+	ret = register_candev(ndev);
+	if (ret)
+		goto exit_free;
+
+	priv->wq = alloc_workqueue(dev_name(dev), WQ_FREEZABLE | WQ_MEM_RECLAIM,
+				   0);
+	if (!priv->wq) {
+		ret = -ENOMEM;
+		goto exit_free;
+	}
+	INIT_WORK(&priv->tx_work, lin_tx_work_handler);
+
+	netdev_info(ndev, "LIN initialized.\n");
+
+	return priv;
+
+exit_free:
+	free_candev(ndev);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(register_lin);
+
+void unregister_lin(struct lin_device *priv)
+{
+	unregister_candev(priv->net);
+
+	destroy_workqueue(priv->wq);
+	priv->wq = NULL;
+
+	free_candev(priv->net);
+}
+EXPORT_SYMBOL_GPL(unregister_lin);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christoph Fritz <christoph.fritz@hexdev.de>");
+MODULE_DESCRIPTION("LIN bus to CAN glue driver");
diff --git a/include/net/lin.h b/include/net/lin.h
new file mode 100644
index 000000000000..d3264844ce16
--- /dev/null
+++ b/include/net/lin.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef _NET_LIN_H_
+#define _NET_LIN_H_
+
+#include <linux/can/dev.h>
+#include <linux/device.h>
+
+struct lin_device_ops {
+	int (*ldo_tx)(struct device *dev, u8 id, u8 n, u8 *data);
+	int (*update_bitrate)(struct device *dev, u16 bitrate);
+};
+
+struct lin_device {
+	struct can_priv can;
+	struct net_device *net;
+	const struct lin_device_ops *lindev_ops;
+	struct device *dev;
+	struct workqueue_struct *wq;
+	struct work_struct tx_work;
+	bool tx_busy;
+	struct sk_buff *tx_skb;
+};
+
+int lin_rx(struct lin_device *dev, u8 id, u8 n, u8 *bytes, u8 checksum);
+
+struct lin_device *register_lin(struct device *dev,
+				const struct lin_device_ops *ldops);
+void unregister_lin(struct lin_device *lbd);
+
+#endif /* _NET_LIN_H_ */
diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
index 90801ada2bbe..8596f9b23c68 100644
--- a/include/uapi/linux/can.h
+++ b/include/uapi/linux/can.h
@@ -147,6 +147,7 @@ struct can_frame {
 #define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
 #define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
 #define CANFD_FDF 0x04 /* mark CAN FD for dual use of struct canfd_frame */
+#define CANFD_LIN 0x08 /* indicate LIN mode */
 
 /**
  * struct canfd_frame - CAN flexible data rate frame structure
diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h
index 02ec32d69474..d65a24b2aa3c 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	/* CAN transiver automatically calculates TDCV */
 #define CAN_CTRLMODE_TDC_MANUAL		0x400	/* TDCV is manually set up by user */
+#define CAN_CTRLMODE_LIN		0x800	/* LIN BUS mode */
 
 /*
  * CAN device statistics
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/2] [RFC] can: Add LIN proto skeleton
  2022-11-27 19:02 [RFC][PATCH 0/2] LIN support for Linux Christoph Fritz
  2022-11-27 19:02 ` [PATCH 1/2] [RFC] can: Introduce LIN bus as CANFD abstraction Christoph Fritz
@ 2022-11-27 19:02 ` Christoph Fritz
  2022-11-28  8:21 ` [RFC][PATCH 0/2] LIN support for Linux Oliver Hartkopp
  2 siblings, 0 replies; 12+ messages in thread
From: Christoph Fritz @ 2022-11-27 19:02 UTC (permalink / raw)
  To: Oliver Hartkopp, Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet
  Cc: linux-can, netdev, linux-kernel

From: Richard Weinberger <richard@nod.at>

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/uapi/linux/can.h     |   7 +-
 include/uapi/linux/can/lin.h |  15 +++
 net/can/Kconfig              |   5 +
 net/can/Makefile             |   3 +
 net/can/lin.c                | 207 +++++++++++++++++++++++++++++++++++
 5 files changed, 236 insertions(+), 1 deletion(-)
 create mode 100644 include/uapi/linux/can/lin.h
 create mode 100644 net/can/lin.c

diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
index 8596f9b23c68..73526805dc5f 100644
--- a/include/uapi/linux/can.h
+++ b/include/uapi/linux/can.h
@@ -178,7 +178,8 @@ struct canfd_frame {
 #define CAN_MCNET	5 /* Bosch MCNet */
 #define CAN_ISOTP	6 /* ISO 15765-2 Transport Protocol */
 #define CAN_J1939	7 /* SAE J1939 */
-#define CAN_NPROTO	8
+#define CAN_LIN		8 /* LIN Bus */
+#define CAN_NPROTO	9
 
 #define SOL_CAN_BASE 100
 
@@ -212,6 +213,10 @@ struct sockaddr_can {
 			__u8 addr;
 		} j1939;
 
+		struct {
+			__u8 addr; //Dummy for now
+		} lin;
+
 		/* reserved for future CAN protocols address information */
 	} can_addr;
 };
diff --git a/include/uapi/linux/can/lin.h b/include/uapi/linux/can/lin.h
new file mode 100644
index 000000000000..7e9f44992b7d
--- /dev/null
+++ b/include/uapi/linux/can/lin.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: (GPL-2.0-only WITH Linux-syscall-note) */
+/*
+ * linux/can/lin.h
+ * TODO
+ */
+
+#ifndef _UAPI_CAN_LIN_H
+#define _UAPI_CAN_LIN_H
+
+#include <linux/types.h>
+#include <linux/can.h>
+
+#define SOL_CAN_LIN (SOL_CAN_BASE + CAN_LIN)
+
+#endif /* !_UAPI_CAN_LIN_H */
diff --git a/net/can/Kconfig b/net/can/Kconfig
index cb56be8e3862..d05e3fa813e2 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -70,4 +70,9 @@ config CAN_ISOTP
 	  If you want to perform automotive vehicle diagnostic services (UDS),
 	  say 'y'.
 
+config CAN_LIN
+	tristate "Support for LIN bus"
+	help
+	  TODO
+
 endif
diff --git a/net/can/Makefile b/net/can/Makefile
index 58f2c31c1ef3..5db51a56a78a 100644
--- a/net/can/Makefile
+++ b/net/can/Makefile
@@ -20,3 +20,6 @@ obj-$(CONFIG_CAN_J1939)	+= j1939/
 
 obj-$(CONFIG_CAN_ISOTP)	+= can-isotp.o
 can-isotp-y		:= isotp.o
+
+obj-$(CONFIG_CAN_LIN)	+= can-lin.o
+can-lin-y		:= lin.o
diff --git a/net/can/lin.c b/net/can/lin.c
new file mode 100644
index 000000000000..f8c8217efc8c
--- /dev/null
+++ b/net/can/lin.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+
+//TODO copyright
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/wait.h>
+#include <linux/uio.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <linux/can/skb.h>
+#include <linux/can/lin.h>
+#include <linux/slab.h>
+#include <net/sock.h>
+#include <net/net_namespace.h>
+
+MODULE_DESCRIPTION("PF_CAN LIN protocol");
+MODULE_LICENSE("GPLv2");
+MODULE_ALIAS("can-proto-8");
+
+struct lin_sock {
+	struct sock sk;
+};
+
+static inline struct lin_sock *lin_sk(const struct sock *sk)
+{
+	return (struct lin_sock *)sk;
+}
+
+static int lin_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	struct lin_sock *so;
+	struct net *net;
+
+	if (!sk)
+		return 0;
+
+	so = lin_sk(sk);
+	net = sock_net(sk);
+
+	// Nothing do to so far
+
+	sock_orphan(sk);
+	sock->sk = NULL;
+
+	release_sock(sk);
+	sock_put(sk);
+
+	return 0;
+}
+
+static int lin_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+{
+	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
+	struct net_device *dev;
+	int err = 0;
+
+	//TODO
+	dev = dev_get_by_index(net, addr->can_ifindex);
+	if (!dev) {
+		err = -ENODEV;
+		goto out;
+	}
+	if (dev->type != ARPHRD_CAN) {
+		dev_put(dev);
+		err = -ENODEV;
+		goto out;
+	}
+
+out:
+	return err;
+}
+
+static int lin_setsockopt_locked(struct socket *sock, int level, int optname,
+			    sockptr_t optval, unsigned int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct lin_sock *so = lin_sk(sk);
+	int ret = 0;
+
+	(void)so;
+
+	switch (optname) {
+	// Nothing to do so far
+	default:
+		ret = -ENOPROTOOPT;
+	}
+
+	return ret;
+}
+
+static int lin_setsockopt(struct socket *sock, int level, int optname,
+			    sockptr_t optval, unsigned int optlen)
+
+{
+	struct sock *sk = sock->sk;
+	int ret;
+
+	if (level != SOL_CAN_LIN)
+		return -EINVAL;
+
+	lock_sock(sk);
+	ret = lin_setsockopt_locked(sock, level, optname, optval, optlen);
+	release_sock(sk);
+	return ret;
+}
+
+static int lin_getsockopt(struct socket *sock, int level, int optname,
+			    char __user *optval, int __user *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct lin_sock *so = lin_sk(sk);
+	int len;
+	void *val;
+
+	(void)so;
+
+	if (level != SOL_CAN_LIN)
+		return -EINVAL;
+	if (get_user(len, optlen))
+		return -EFAULT;
+	if (len < 0)
+		return -EINVAL;
+
+	switch (optname) {
+	//Nothing to do so far.
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+	if (copy_to_user(optval, val, len))
+		return -EFAULT;
+	return 0;
+}
+
+static int lin_init(struct sock *sk)
+{
+	struct lin_sock *so = lin_sk(sk);
+
+	(void)so;
+	// Nothing to do so far
+
+	return 0;
+}
+
+static const struct proto_ops lin_ops = {
+	.family = PF_CAN,
+	.release = lin_release,
+	.bind = lin_bind,
+	.connect = sock_no_connect,
+	.socketpair = sock_no_socketpair,
+	.accept = sock_no_accept,
+	.getname = sock_no_getname,
+	.poll = datagram_poll,
+	.ioctl = sock_no_ioctl,
+	.gettstamp = sock_gettstamp,
+	.listen = sock_no_listen,
+	.shutdown = sock_no_shutdown,
+	.setsockopt = lin_setsockopt,
+	.getsockopt = lin_getsockopt,
+	.sendmsg = sock_no_sendmsg,
+	.recvmsg = sock_no_recvmsg,
+	.mmap = sock_no_mmap,
+	.sendpage = sock_no_sendpage,
+};
+
+static struct proto lin_proto __read_mostly = {
+	.name = "CAN_LIN",
+	.owner = THIS_MODULE,
+	.obj_size = sizeof(struct lin_sock),
+	.init = lin_init,
+};
+
+static const struct can_proto lin_can_proto = {
+	.type = SOCK_DGRAM,
+	.protocol = CAN_LIN,
+	.ops = &lin_ops,
+	.prot = &lin_proto,
+};
+
+static __init int lin_module_init(void)
+{
+	pr_info("can: lin protocol\n");
+
+	return can_proto_register(&lin_can_proto);
+}
+
+static __exit void lin_module_exit(void)
+{
+	can_proto_unregister(&lin_can_proto);
+}
+
+module_init(lin_module_init);
+module_exit(lin_module_exit);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-27 19:02 [RFC][PATCH 0/2] LIN support for Linux Christoph Fritz
  2022-11-27 19:02 ` [PATCH 1/2] [RFC] can: Introduce LIN bus as CANFD abstraction Christoph Fritz
  2022-11-27 19:02 ` [PATCH 2/2] [RFC] can: Add LIN proto skeleton Christoph Fritz
@ 2022-11-28  8:21 ` Oliver Hartkopp
  2022-11-28 10:16   ` Christoph Fritz
  2 siblings, 1 reply; 12+ messages in thread
From: Oliver Hartkopp @ 2022-11-28  8:21 UTC (permalink / raw)
  To: Christoph Fritz, Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet
  Cc: linux-can, netdev, linux-kernel

Hello Christoph,

are you already aware of this LIN project that uses the Linux SocketCAN 
infrastructure and implements the LIN protocol based on a serial tty 
adaption (which the serial LIN protocol mainly is)?

https://github.com/lin-bus

IIRC the implementation of the master/slave timings was the biggest 
challenge and your approach seems to offload this problem to your 
USB-attached hardware right?

Can I assume there will be a similar CAN-controlled programming 
interface to create real time master/slave protocol frames like in a 
usual CAN/LIN adapter (e.g. 
https://www.peak-system.com/PCAN-LIN.213.0.html) ??

Best regards,
Oliver


On 27.11.22 20:02, Christoph Fritz wrote:
> The intention of this series is to kick off a discussion about how to
> support LIN (ISO 17987) [0] in Linux.
> 
> This series consist of two patches which are two individual proposals
> for adding LIN abstraction into the kernel.
> 
> One approach is to add LIN ontop of CANFD:
>    [RFC] can: introduce LIN abstraction
> 
> The other approach is adding a new type of CAN-socket:
>    [RFC] can: Add LIN proto skeleton
> 
> These patches are abstracting LIN so that actual device drivers can
> make use of it.
> 
> For reference, the LIN-ontop-of-CANFD variant already has a device
> driver using it (not part of this series). It is a specially built USB
> LIN-BUS adapter hardware called hexLIN [1].  Its purpose is mainly to
> test, adapt and discuss different LIN APIs for mainline Linux kernel.
> But it can already be used productively as a Linux LIN node in
> controller (master) and responder (slave) mode. By sysfs, hexLIN
> supports different checksum calculations and setting up a
> responder-table.
> 
> For more info about hexLIN, see link below [1].
> 
> We are looking for partners with Linux based LIN projects for funding.
> 
> [0]: https://en.wikipedia.org/wiki/Local_Interconnect_Network
> [1]: https://hexdev.de/hexlin/
> 
> Christoph Fritz (1):
>    [RFC] can: Introduce LIN bus as CANFD abstraction
> 
> Richard Weinberger (1):
>    [RFC] can: Add LIN proto skeleton
> 
>   drivers/net/can/Kconfig          |  10 ++
>   drivers/net/can/Makefile         |   1 +
>   drivers/net/can/lin.c            | 181 +++++++++++++++++++++++++++
>   include/net/lin.h                |  30 +++++
>   include/uapi/linux/can.h         |   8 +-
>   include/uapi/linux/can/lin.h     |  15 +++
>   include/uapi/linux/can/netlink.h |   1 +
>   net/can/Kconfig                  |   5 +
>   net/can/Makefile                 |   3 +
>   net/can/lin.c                    | 207 +++++++++++++++++++++++++++++++
>   10 files changed, 460 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/net/can/lin.c
>   create mode 100644 include/net/lin.h
>   create mode 100644 include/uapi/linux/can/lin.h
>   create mode 100644 net/can/lin.c
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28  8:21 ` [RFC][PATCH 0/2] LIN support for Linux Oliver Hartkopp
@ 2022-11-28 10:16   ` Christoph Fritz
  2022-11-28 14:49     ` Pavel Pisa
  2022-11-30 21:02     ` Oliver Hartkopp
  0 siblings, 2 replies; 12+ messages in thread
From: Christoph Fritz @ 2022-11-28 10:16 UTC (permalink / raw)
  To: Oliver Hartkopp
  Cc: Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet,
	linux-can, netdev, linux-kernel

Hello Oliver

> are you already aware of this LIN project that uses the Linux SocketCAN
> infrastructure and implements the LIN protocol based on a serial tty
> adaption (which the serial LIN protocol mainly is)?
> 
> https://github.com/lin-bus

Sure, that's why I initially added Pavel Pisa to the recipients of this
RFC patch series. When there is an internal kernel API for LIN, his
sllin (tty-line-discipline driver for LIN) could be adjusted and finally
go mainline.

Adding LIN only as a tty-line-discipline does not fit all the currently
available hardware. Another argument against a tty-line-discipline only
approach as a LIN-API is, that there is no off the shelf standard
computer UART with LIN-break-detection (necessary to meet timing
constraints), so it always needs specially crafted hardware like USB
adapters or PCIe-cards.

For the handful of specialized embedded UARTs with LIN-break-detection I
guess it could make more sense to go the RS485-kind-of-path and
integrate LIN support into the tty-driver while not using a
tty-line-discipline there at all.

> IIRC the implementation of the master/slave timings was the biggest

Currently sllin only supports master mode, I guess because of the tight
timing constraints.

> challenge and your approach seems to offload this problem to your
> USB-attached hardware right?

The hexLIN USB adapter processes slave mode answer table on its own,
just to meet timing constraints.  For master mode, it is currently not
offloaded (but could be if really necessary).

The amount of offloading (if any at all) is totally up to the device and
its device-driver (the entity actually processing data). So sllin does
not do offloading but can only work in relaxed timing constrained
environments.
An UART with built in LIN-break-detection (there are a few) might be
able to fully meet timing constraints without offloading (as well as
e.g. a PCIe card).

> Can I assume there will be a similar CAN-controlled programming interface to
> create real time master/slave protocol frames like in a usual CAN/LIN
> adapter (e.g. https://www.peak-system.com/PCAN-LIN.213.0.html) ??

I already did some tests letting hexLIN and PCAN talk to each other in a
real time manner. Please see my preliminary PDF docu at
https://hexdev.de/hexlin/

Thanks
 -- Christoph

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 10:16   ` Christoph Fritz
@ 2022-11-28 14:49     ` Pavel Pisa
  2022-11-28 17:02       ` Ryan Edwards
  2022-11-30 21:02     ` Oliver Hartkopp
  1 sibling, 1 reply; 12+ messages in thread
From: Pavel Pisa @ 2022-11-28 14:49 UTC (permalink / raw)
  To: Christoph Fritz
  Cc: Oliver Hartkopp, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet,
	linux-can, netdev, linux-kernel

Hello Christoph and Oliver,

On Monday 28 of November 2022 11:16:05 Christoph Fritz wrote:
> > are you already aware of this LIN project that uses the Linux SocketCAN
> > infrastructure and implements the LIN protocol based on a serial tty
> > adaption (which the serial LIN protocol mainly is)?
> >
> > https://github.com/lin-bus
>
> Sure, that's why I initially added Pavel Pisa to the recipients of this
> RFC patch series. When there is an internal kernel API for LIN, his
> sllin (tty-line-discipline driver for LIN) could be adjusted and finally
> go mainline.

Some layer common for UART based and dedicated LIN hardware would
be usesfull. The main think to decide is if the solution encoding
LIN interface control into CAN messages is the right one and how
the encoding should work. Actual mapping keeps LIN and CAN data
1:1 and puts control into identifier and flags. It has advantage
that common SocketCAN infrastructure can be used. There is disadvantage
that in the case of real CAN to LIN gateway connected to CAN bus
almost whole identifiers range is occupied by gateway control.
If the response table control and LIN identifier is part of the data
field then I can imagine, that more real gateway devices can be
be connected to the single CAN bus. But if there is not standard
followed by all such gateways producers then it is not of much help.
So probably actual mechanism is reasonable. 

> Adding LIN only as a tty-line-discipline does not fit all the currently
> available hardware. Another argument against a tty-line-discipline only
> approach as a LIN-API is, that there is no off the shelf standard
> computer UART with LIN-break-detection (necessary to meet timing
> constraints), so it always needs specially crafted hardware like USB
> adapters or PCIe-cards.

Break is not so big problem, slave side baudate automatic setup
is and then control of Rx FIFO depth and if not possible then its
switchinch off which needs generic UART level API longterm

  https://github.com/lin-bus/linux-lin/issues/13

> For the handful of specialized embedded UARTs with LIN-break-detection I
> guess it could make more sense to go the RS485-kind-of-path and
> integrate LIN support into the tty-driver while not using a
> tty-line-discipline there at all.

The state automata is required and its implementation in userspace
complicates the design and would result in higher latencies
(memory context switch etc.) but may be not so critical for 19200 baud
or similar. Kernel with RT preempt support is quite capable and for
master side there is time when driver does not lost Rx characters.

> > IIRC the implementation of the master/slave timings was the biggest
>
> Currently sllin only supports master mode, I guess because of the tight
> timing constraints.

On the UART with FIFO control, there is no problem with response
latency on moderately loaded fully preemptive kernel and slLIN
supports both modes.

I see as the main problem for actual integration of both modes
to select acceptable names for standard defined entities "master node"
and "slave task". May it be "coordinator", "initiator" and "responder"
or "target".... Probably N_SLLIN and N_SLLIN_SLAVE are unacceptable
today...

> > challenge and your approach seems to offload this problem to your
> > USB-attached hardware right?
>
> The hexLIN USB adapter processes slave mode answer table on its own,
> just to meet timing constraints.  For master mode, it is currently not
> offloaded (but could be if really necessary).

Yes, for USB the responses uploading to device is a must and API has
to count with it.

> The amount of offloading (if any at all) is totally up to the device and
> its device-driver (the entity actually processing data). So sllin does
> not do offloading but can only work in relaxed timing constrained
> environments.
> An UART with built in LIN-break-detection (there are a few) might be
> able to fully meet timing constraints without offloading (as well as
> e.g. a PCIe card).

In theory request/response loop up to RT user space task but keeping in
the kernel is better and less error prone to applications errors.

> > Can I assume there will be a similar CAN-controlled programming interface
> > to create real time master/slave protocol frames like in a usual CAN/LIN
> > adapter (e.g. https://www.peak-system.com/PCAN-LIN.213.0.html) ??
>
> I already did some tests letting hexLIN and PCAN talk to each other in a
> real time manner. Please see my preliminary PDF docu at
> https://hexdev.de/hexlin/

Best wishes,

                Pavel Pisa
    phone:      +420 603531357
    e-mail:     pisa@cmp.felk.cvut.cz
    Department of Control Engineering FEE CVUT
    Karlovo namesti 13, 121 35, Prague 2
    university: http://control.fel.cvut.cz/
    personal:   http://cmp.felk.cvut.cz/~pisa
    projects:   https://www.openhub.net/accounts/ppisa
    CAN related:http://canbus.pages.fel.cvut.cz/
    RISC-V education: https://comparch.edu.cvut.cz/
    Open Technologies Research Education and Exchange Services
    https://gitlab.fel.cvut.cz/otrees/org/-/wikis/home


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 14:49     ` Pavel Pisa
@ 2022-11-28 17:02       ` Ryan Edwards
  2022-11-28 17:52         ` Pavel Pisa
  0 siblings, 1 reply; 12+ messages in thread
From: Ryan Edwards @ 2022-11-28 17:02 UTC (permalink / raw)
  To: Pavel Pisa
  Cc: Christoph Fritz, Oliver Hartkopp, Richard Weinberger,
	Andreas Lauser, Wolfgang Grandegger, Marc Kleine-Budde,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jonathan Corbet, linux-can, netdev, linux-kernel

All,

On Mon, Nov 28, 2022 at 10:09 AM Pavel Pisa <pisa@cmp.felk.cvut.cz> wrote:
>
> Hello Christoph and Oliver,
>
> On Monday 28 of November 2022 11:16:05 Christoph Fritz wrote:
> > > are you already aware of this LIN project that uses the Linux SocketCAN
> > > infrastructure and implements the LIN protocol based on a serial tty
> > > adaption (which the serial LIN protocol mainly is)?
> > >
> > > https://github.com/lin-bus
> >
> > Sure, that's why I initially added Pavel Pisa to the recipients of this
> > RFC patch series. When there is an internal kernel API for LIN, his
> > sllin (tty-line-discipline driver for LIN) could be adjusted and finally
> > go mainline.
>
> Some layer common for UART based and dedicated LIN hardware would
> be usesfull. The main think to decide is if the solution encoding
> LIN interface control into CAN messages is the right one and how
> the encoding should work. Actual mapping keeps LIN and CAN data
> 1:1 and puts control into identifier and flags. It has advantage
> that common SocketCAN infrastructure can be used. There is disadvantage
> that in the case of real CAN to LIN gateway connected to CAN bus
> almost whole identifiers range is occupied by gateway control.
> If the response table control and LIN identifier is part of the data
> field then I can imagine, that more real gateway devices can be
> be connected to the single CAN bus. But if there is not standard
> followed by all such gateways producers then it is not of much help.
> So probably actual mechanism is reasonable.
>
> > Adding LIN only as a tty-line-discipline does not fit all the currently
> > available hardware. Another argument against a tty-line-discipline only
> > approach as a LIN-API is, that there is no off the shelf standard
> > computer UART with LIN-break-detection (necessary to meet timing
> > constraints), so it always needs specially crafted hardware like USB
> > adapters or PCIe-cards.
>
> Break is not so big problem, slave side baudate automatic setup
> is and then control of Rx FIFO depth and if not possible then its
> switchinch off which needs generic UART level API longterm
>
>   https://github.com/lin-bus/linux-lin/issues/13
>
> > For the handful of specialized embedded UARTs with LIN-break-detection I
> > guess it could make more sense to go the RS485-kind-of-path and
> > integrate LIN support into the tty-driver while not using a
> > tty-line-discipline there at all.
>
> The state automata is required and its implementation in userspace
> complicates the design and would result in higher latencies
> (memory context switch etc.) but may be not so critical for 19200 baud
> or similar. Kernel with RT preempt support is quite capable and for
> master side there is time when driver does not lost Rx characters.
>
> > > IIRC the implementation of the master/slave timings was the biggest
> >
> > Currently sllin only supports master mode, I guess because of the tight
> > timing constraints.
>
> On the UART with FIFO control, there is no problem with response
> latency on moderately loaded fully preemptive kernel and slLIN
> supports both modes.
>
> I see as the main problem for actual integration of both modes
> to select acceptable names for standard defined entities "master node"
> and "slave task". May it be "coordinator", "initiator" and "responder"
> or "target".... Probably N_SLLIN and N_SLLIN_SLAVE are unacceptable
> today...
>
> > > challenge and your approach seems to offload this problem to your
> > > USB-attached hardware right?
> >
> > The hexLIN USB adapter processes slave mode answer table on its own,
> > just to meet timing constraints.  For master mode, it is currently not
> > offloaded (but could be if really necessary).
>
> Yes, for USB the responses uploading to device is a must and API has
> to count with it.
>
> > The amount of offloading (if any at all) is totally up to the device and
> > its device-driver (the entity actually processing data). So sllin does
> > not do offloading but can only work in relaxed timing constrained
> > environments.
> > An UART with built in LIN-break-detection (there are a few) might be
> > able to fully meet timing constraints without offloading (as well as
> > e.g. a PCIe card).
>
> In theory request/response loop up to RT user space task but keeping in
> the kernel is better and less error prone to applications errors.
>
> > > Can I assume there will be a similar CAN-controlled programming interface
> > > to create real time master/slave protocol frames like in a usual CAN/LIN
> > > adapter (e.g. https://www.peak-system.com/PCAN-LIN.213.0.html) ??
> >
> > I already did some tests letting hexLIN and PCAN talk to each other in a
> > real time manner. Please see my preliminary PDF docu at
> > https://hexdev.de/hexlin/

Marc gave me a heads on on this discussion and I have some insight.

I've spent quite a bit of time trying to craft a solution for the LIN
problem.  Even with a TTY solution the best I was able to achieve was
40ms turnaround between the header and response which exceeded the
timeout of the master.  This was in userspace and I assume that a
kernel solution would better be able to meet the timing but this
solution would only work for devices with embedded UART.

I did create a solution that uses the gs_usb driver using "pseduo" CAN
frames that currently supports slave and monitor mode.  I had no use
cases for master mode up to this point so it has not yet been
implemented.  The framework is there if it needs to be added.

The README contains the HOWTO on usage of the driver.  Right now it's
a hack but could be better designed using message flags or a seperate
CAN channel.

In my design the device contains a slave response table which is
configured via CAN frames via socketcan.  Currently up to 10 master
frames can be responded to.  It also allows the LIN node to be put
into monitor mode and gate those messages to the host via a CAN
message.

https://github.com/ryedwards/budgetcan_fw

Thanks,

--Ryan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 17:02       ` Ryan Edwards
@ 2022-11-28 17:52         ` Pavel Pisa
  2022-11-28 18:47           ` Ryan Edwards
  0 siblings, 1 reply; 12+ messages in thread
From: Pavel Pisa @ 2022-11-28 17:52 UTC (permalink / raw)
  To: Ryan Edwards
  Cc: Christoph Fritz, Oliver Hartkopp, Richard Weinberger,
	Andreas Lauser, Wolfgang Grandegger, Marc Kleine-Budde,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jonathan Corbet, linux-can, netdev, linux-kernel

Hello Ryan, 

On Monday 28 of November 2022 18:02:04 Ryan Edwards wrote:
> On Mon, Nov 28, 2022 at 10:09 AM Pavel Pisa <pisa@cmp.felk.cvut.cz> wrote:
...
> > > I already did some tests letting hexLIN and PCAN talk to each other in
> > > a real time manner. Please see my preliminary PDF docu at
> > > https://hexdev.de/hexlin/
>
> Marc gave me a heads on on this discussion and I have some insight.
>
> I've spent quite a bit of time trying to craft a solution for the LIN
> problem.  Even with a TTY solution the best I was able to achieve was
> 40ms turnaround between the header and response which exceeded the
> timeout of the master. 

This is indication of some serious problem. We have been able to
achieve right timing even from userspace on PC 10 years ago
when RT task priorities are used and mlock all even on standard kernel...
Yes under load that could be a problem but on RT kernel and in kernel
slLIN driver it was reliable even on relatively slow MPC5200.

See FIGURE 3: Master: MPC5200 with slLIN; Slave: MPC5200 with slLIN
of our comprehensive RTLWS 20212 UART-based LIN-bus Support for Linux
with SocketCAN Interface article. For the complete protocol designed
on basis of Oliver's proposal and then our finalization see complete
report for VolkWagen. The timing is shown there as well
Figure 5.2: Master: MPC5200 with sllin; Slave: MPC5200 with sllin

https://github.com/lin-bus/linux-lin/wiki

The problem with typical UARTs is then when they have enabled FIFO
then drivers select trigger level higher than one and sometimes
even minimal level is 1/4 of Rx FIFO depth. Then when trigger
level is not reached the Rx interrupt waits for eventual
more characters to come for (typically) 3 character times.
So this is a problem. Because of 1/4 FIFO minimal threshold
for 16C450+ UARTs, it is only solution to achieve right slave/response
function to switch off the FIFO, there some internal API for that
but not exposed o drivers. For 16V450, there is option

  echo 1 >/sys/class/tty/ttyS0/rx_trig_bytes

See https://github.com/lin-bus/linux-lin/issues/13

> This was in userspace and I assume that a 
> kernel solution would better be able to meet the timing but this
> solution would only work for devices with embedded UART.

Yes, and on fully preemptive it is not problem. We run control
loops in userpace at 5 kHz on Xilinx Zynq systems and used
up to 30 kHz on PC for mainboard without MSI issues.
So this seems that problems are in programing area.

We have achieved correct slLIN functionality on more embedded systems,
AM335x, MPC5200 etc. But it required to check UART driver
and found how to set Rx trigger level to 1 or disable FIFO.
Often by nasty parch. But most hardware could provide
knob to tune required parameters. Some RFC for the proposed API
there

   https://marc.info/?l=linux-serial&m=164259988122122&w=2

int (*rx_trigger)(struct uart_port *, int mode, int *rx_trigger_bytes,
                  int *rx_trigger_iddle_time)

I think that all/the most of the UART HW I have seen can
adjust what necessary, in the worst case by switching FIFO
off in UART_RX_TRIGGER_MODE_CHECK_ROUND_DOWN mode.

> I did create a solution that uses the gs_usb driver using "pseduo" CAN
> frames that currently supports slave and monitor mode.  I had no use
> cases for master mode up to this point so it has not yet been
> implemented.  The framework is there if it needs to be added.

The set of frames has been defined in slLIN 10 years ago and
there is even defined control for LIN 1.0 and 2.0 check sum
selection for individual IDs. I do not insist that our design
is the best mapping but try to compare it to yours and describe
advantages that the best decision can be made for futire.

> The README contains the HOWTO on usage of the driver.  Right now it's
> a hack but could be better designed using message flags or a seperate
> CAN channel.
>
> In my design the device contains a slave response table which is
> configured via CAN frames via socketcan.  Currently up to 10 master
> frames can be responded to. 

I think that even on embedded HW it is not problem to keep
data for all 64 LIN IDs. So I would not complicate thing with some mapping
etc. We have reused already present BCM (SocketCAN Broadcast Manager)
to periodically send LIN headers.

> It also allows the LIN node to be put 
> into monitor mode and gate those messages to the host via a CAN
> message.
>
> https://github.com/ryedwards/budgetcan_fw

Great, version connected over USB with local response table
is more reliable with timing than software solution on big(err)
complex system like Linux kernel is. So if the well defined
open protocol is designed or some CAN USB devices one is reused
for LIN than it is advantage.

I would be happy if the project moves forward. The critical is
some settlement on unified API. Please, compare and map functionality
between our solution and your proposal and we can discuss what
worth to keep or change. slLIN solution seems to be used in more
project not only that two for Volkswagen and Digiteq Automotive,
I have directly participated.

Best wishes,

                Pavel Pisa
    phone:      +420 603531357
    e-mail:     pisa@cmp.felk.cvut.cz
    Department of Control Engineering FEE CVUT
    Karlovo namesti 13, 121 35, Prague 2
    university: http://control.fel.cvut.cz/
    personal:   http://cmp.felk.cvut.cz/~pisa
    projects:   https://www.openhub.net/accounts/ppisa
    CAN related:http://canbus.pages.fel.cvut.cz/
    RISC-V education: https://comparch.edu.cvut.cz/
    Open Technologies Research Education and Exchange Services
    https://gitlab.fel.cvut.cz/otrees/org/-/wikis/home


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 17:52         ` Pavel Pisa
@ 2022-11-28 18:47           ` Ryan Edwards
  2022-11-28 21:48             ` Christoph Fritz
  0 siblings, 1 reply; 12+ messages in thread
From: Ryan Edwards @ 2022-11-28 18:47 UTC (permalink / raw)
  To: Pavel Pisa
  Cc: Christoph Fritz, Oliver Hartkopp, Richard Weinberger,
	Andreas Lauser, Wolfgang Grandegger, Marc Kleine-Budde,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Jonathan Corbet, linux-can, netdev, linux-kernel

Hello Pavel,

On Mon, Nov 28, 2022 at 12:52 PM Pavel Pisa <pisa@cmp.felk.cvut.cz> wrote:
>
> Hello Ryan,
>
> On Monday 28 of November 2022 18:02:04 Ryan Edwards wrote:
> > On Mon, Nov 28, 2022 at 10:09 AM Pavel Pisa <pisa@cmp.felk.cvut.cz> wrote:
> > Marc gave me a heads on on this discussion and I have some insight.
> >
> > I've spent quite a bit of time trying to craft a solution for the LIN
> > problem.  Even with a TTY solution the best I was able to achieve was
> > 40ms turnaround between the header and response which exceeded the
> > timeout of the master.
>
> This is indication of some serious problem. We have been able to
> achieve right timing even from userspace on PC 10 years ago
> when RT task priorities are used and mlock all even on standard kernel...
> Yes under load that could be a problem but on RT kernel and in kernel
> slLIN driver it was reliable even on relatively slow MPC5200.
>
> See FIGURE 3: Master: MPC5200 with slLIN; Slave: MPC5200 with slLIN
> of our comprehensive RTLWS 20212 UART-based LIN-bus Support for Linux
> with SocketCAN Interface article. For the complete protocol designed
> on basis of Oliver's proposal and then our finalization see complete
> report for VolkWagen. The timing is shown there as well
> Figure 5.2: Master: MPC5200 with sllin; Slave: MPC5200 with sllin
>
> https://github.com/lin-bus/linux-lin/wiki
>
> The problem with typical UARTs is then when they have enabled FIFO
> then drivers select trigger level higher than one and sometimes
> even minimal level is 1/4 of Rx FIFO depth. Then when trigger
> level is not reached the Rx interrupt waits for eventual
> more characters to come for (typically) 3 character times.
> So this is a problem. Because of 1/4 FIFO minimal threshold
> for 16C450+ UARTs, it is only solution to achieve right slave/response
> function to switch off the FIFO, there some internal API for that
> but not exposed o drivers. For 16V450, there is option
>
>   echo 1 >/sys/class/tty/ttyS0/rx_trig_bytes
>
> See https://github.com/lin-bus/linux-lin/issues/13

This test was done 2-3 years ago on a RaspberryPi.  I was testing as a
slave and had a hard time responding to the master any faster than
40ms.  I assume based on the work that you've done that I must have
not been accessing the TTY correctly.  Wish I would have found the
work already done on linux-lin.  Would have saved me some time and
headaches.

> > The README contains the HOWTO on usage of the driver.  Right now it's
> > a hack but could be better designed using message flags or a seperate
> > CAN channel.
> >
> > In my design the device contains a slave response table which is
> > configured via CAN frames via socketcan.  Currently up to 10 master
> > frames can be responded to.
>
> I think that even on embedded HW it is not problem to keep
> data for all 64 LIN IDs. So I would not complicate thing with some mapping
> etc. We have reused already present BCM (SocketCAN Broadcast Manager)
> to periodically send LIN headers.
>
> > It also allows the LIN node to be put
> > into monitor mode and gate those messages to the host via a CAN
> > message.
> >
> > https://github.com/ryedwards/budgetcan_fw
>
> Great, version connected over USB with local response table
> is more reliable with timing than software solution on big(err)
> complex system like Linux kernel is. So if the well defined
> open protocol is designed or some CAN USB devices one is reused
> for LIN than it is advantage.
>
> I would be happy if the project moves forward. The critical is
> some settlement on unified API. Please, compare and map functionality
> between our solution and your proposal and we can discuss what
> worth to keep or change. slLIN solution seems to be used in more
> project not only that two for Volkswagen and Digiteq Automotive,
> I have directly participated.
>

I think that what I have built is a high level embedded solution.  The
fundamental code is the same as it was developed from the state
diagram in the LIN specification.

I understand now that this project is to build on and implement the
work already done on slLIN.  I'll review the slLIN driver and see if
there is any input I can provide based on the work I've done in my
code.  I'd be very interested if the driver could be implemented in a
way that easily allows for dynamic slave repsonses.

Thanks,

--Ryan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 18:47           ` Ryan Edwards
@ 2022-11-28 21:48             ` Christoph Fritz
  2022-11-28 22:47               ` Andrew Lunn
  0 siblings, 1 reply; 12+ messages in thread
From: Christoph Fritz @ 2022-11-28 21:48 UTC (permalink / raw)
  To: Ryan Edwards, Oliver Hartkopp, Pavel Pisa, Andreas Lauser,
	Richard Weinberger, Wolfgang Grandegger, Marc Kleine-Budde,
	David S . Miller, Jakub Kicinski, Eric Dumazet, Paolo Abeni
  Cc: Jonathan Corbet, linux-can, netdev, linux-kernel

Thanks for all the participation and feedback. Here is my attempt at a
summary of what we have discussed so far:

- Common goal: A solid LIN UAPI and API
  - LIN fits CAN well and could be embedded into Linux CAN infrastructure
  - LIN support cannot be a tty-line-discipline driver for all devices
    out there

  - slLIN should become a user of this API
    - slLIN itself needs some more options in the line-discipline
      configuraion (to tweak UART FIFO settings and e.g. enable
      LIN-break-detection for supported UARTs) _or_ tty-LIN support
      becomes something more like RS485 and get integrated into
      tty-drivers directly.

  - LIN devices with off loading capabilities are a bit special.
    - one approach is to have a kfifo for the slavetable (64 entries a 8
      bytes + checksum and some extra flags for some LIN special cases)
      while updating it from userland through CAN or a simple sysfs
      interface
    - when we agree that "dumb" UARTs have no need for an
      in-kernel-off-load slavetable (because of RT-Linux), then there
      are only devices left (e.g. some USB adapters) maintaining their
      own table, so a simple e.g. sysfs update mechanism would be
      enough (without the need for an in-kernel kfifo buffer).

  - LIN slavetable might need another name

  - LIN needs rx, tx, set bitrate, set checksum variant and maybe update
    a slavetable (or whatever it is called then...)

What do you think? Any objections, corrections, enhancements?

My question is: Which approach of an API is favored: Patch 1 or 2 of
this RFC series or something completely different?

Thanks
  -- Christoph

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 21:48             ` Christoph Fritz
@ 2022-11-28 22:47               ` Andrew Lunn
  0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2022-11-28 22:47 UTC (permalink / raw)
  To: Christoph Fritz
  Cc: Ryan Edwards, Oliver Hartkopp, Pavel Pisa, Andreas Lauser,
	Richard Weinberger, Wolfgang Grandegger, Marc Kleine-Budde,
	David S . Miller, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
	Jonathan Corbet, linux-can, netdev, linux-kernel

>   - LIN devices with off loading capabilities are a bit special.

For networking in general, we try very hard to make offload to
hardware not special at all. It should just transparently work.

One example of this is Ethernet switches which Linux controls. The
ports of the switch are just normal Linux interfaces. You can put an
IP address onto the ports in the normal way, you can add a port to a
linux bridge in the normal way. If the switch can perform bridging in
hardware, the linux bridge will offload it to the hardware. But for
the user, its just a port added to a bridge, nothing special. And
there are a lot more examples like this.

I don't know CAN at all, but please try to avoid doing anything
special for hardware offload. We don't want one way for software, and
then 42 different ways for 42 different offload engines. Just one uAPI
which works for everything.

    Andrew

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/2] LIN support for Linux
  2022-11-28 10:16   ` Christoph Fritz
  2022-11-28 14:49     ` Pavel Pisa
@ 2022-11-30 21:02     ` Oliver Hartkopp
  1 sibling, 0 replies; 12+ messages in thread
From: Oliver Hartkopp @ 2022-11-30 21:02 UTC (permalink / raw)
  To: Christoph Fritz
  Cc: Pavel Pisa, Richard Weinberger, Andreas Lauser,
	Wolfgang Grandegger, Marc Kleine-Budde, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jonathan Corbet,
	linux-can, netdev, linux-kernel

Hi Christoph, all,

On 28.11.22 11:16, Christoph Fritz wrote:

>> IIRC the implementation of the master/slave timings was the biggest
> 
> Currently sllin only supports master mode, I guess because of the tight
> timing constraints.

I think this has to be corrected.

In the master mode the SocketCAN Broadcast Manager (BCM) is configured 
to periodically send LIN headers
(according to LIN schedule table).

https://www.kernel.org/doc/html/latest/networking/can.html#broadcast-manager-protocol-sockets-sock-dgram

This is a very easy approach to precisely send the the LIN frames from 
kernel space and also atomically change the content of (all) the 
configured LIN frames while the schedule table is continuously processed.

Sending LIN frames directly from *userspace* (and handling timers there) 
was *never* intended for real LIN communication - although the examples 
(with cangen) in the document look like this.

Same applies to the slave mode:

If you check out 
https://raw.githubusercontent.com/wiki/lin-bus/linux-lin/sllin-doc.pdf 
on page 11 you are able to enable the slave mode with

	insmod ./sllin.ko master=0

The 'trick' about this mode is that the RTR-functionality of the BCM is 
able process the incoming CAN/LIN identifier and *instantly* send back 
some pre-defined data for that specific LIN-ID, so that the SLLIN driver 
sends/answers the 'data' section of the received LIN-ID within the 
required timing constrains for LIN slaves.

Not sure if the info about this concept got lost somehow, but the 
CAN_BCM is the key for handling the LIN protocol and offload the LIN 
scheduling (master/slave) to the kernel for the comparably dumb tty 
interfaces.

Best regards,
Oliver

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-11-30 21:02 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-27 19:02 [RFC][PATCH 0/2] LIN support for Linux Christoph Fritz
2022-11-27 19:02 ` [PATCH 1/2] [RFC] can: Introduce LIN bus as CANFD abstraction Christoph Fritz
2022-11-27 19:02 ` [PATCH 2/2] [RFC] can: Add LIN proto skeleton Christoph Fritz
2022-11-28  8:21 ` [RFC][PATCH 0/2] LIN support for Linux Oliver Hartkopp
2022-11-28 10:16   ` Christoph Fritz
2022-11-28 14:49     ` Pavel Pisa
2022-11-28 17:02       ` Ryan Edwards
2022-11-28 17:52         ` Pavel Pisa
2022-11-28 18:47           ` Ryan Edwards
2022-11-28 21:48             ` Christoph Fritz
2022-11-28 22:47               ` Andrew Lunn
2022-11-30 21:02     ` Oliver Hartkopp

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