Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/bouyer-socketcan]: src/sys/netcan Add infranstructure to configure timin...
details: https://anonhg.NetBSD.org/src/rev/f3b7221ad035
branches: bouyer-socketcan
changeset: 820873:f3b7221ad035
user: bouyer <bouyer%NetBSD.org@localhost>
date: Mon Apr 17 20:32:27 2017 +0000
description:
Add infranstructure to configure timings from userland on a can interface.
This uses the SIOCGDRVSPEC/SIOCSDRVSPEC ioctls.
Compile-tested only.
diffstat:
sys/netcan/Makefile | 4 +-
sys/netcan/can.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++---
sys/netcan/can.h | 8 +----
sys/netcan/can_link.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++
sys/netcan/can_var.h | 15 ++++++++-
5 files changed, 178 insertions(+), 15 deletions(-)
diffs (273 lines):
diff -r 5a31749b9bad -r f3b7221ad035 sys/netcan/Makefile
--- a/sys/netcan/Makefile Mon Apr 17 14:01:20 2017 +0000
+++ b/sys/netcan/Makefile Mon Apr 17 20:32:27 2017 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $
+# $NetBSD: Makefile,v 1.1.2.2 2017/04/17 20:32:27 bouyer Exp $
KDIR= /sys/netcan
INCSDIR= /usr/include/netcan
-INCS= can.h
+INCS= can.h can_link.h
.include <bsd.kinc.mk>
diff -r 5a31749b9bad -r f3b7221ad035 sys/netcan/can.c
--- a/sys/netcan/can.c Mon Apr 17 14:01:20 2017 +0000
+++ b/sys/netcan/can.c Mon Apr 17 20:32:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $ */
+/* $NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,6 +90,77 @@
/*
* Generic control operations (ioctl's).
*/
+static int
+can_get_netlink(struct ifnet *ifp, struct ifdrv *ifd)
+{
+ struct canif_softc *csc = ifp->if_softc;
+
+ if (ifp->if_dlt != DLT_CAN_SOCKETCAN || csc == NULL)
+ return EOPNOTSUPP;
+
+ switch(ifd->ifd_cmd) {
+ case CANGLINKTIMECAP:
+ if (ifd->ifd_len != sizeof(struct can_link_timecaps))
+ return EINVAL;
+ return copyout(&csc->csc_timecaps, ifd->ifd_data, ifd->ifd_len);
+ case CANGLINKTIMINGS:
+ if (ifd->ifd_len != sizeof(struct can_link_timings))
+ return EINVAL;
+ return copyout(&csc->csc_timings, ifd->ifd_data, ifd->ifd_len);
+ case CANGLINKMODE:
+ if (ifd->ifd_len != sizeof(uint32_t))
+ return EINVAL;
+ return copyout(&csc->csc_linkmodes, ifd->ifd_data, ifd->ifd_len);
+ }
+ return EOPNOTSUPP;
+}
+
+static int
+can_set_netlink(struct ifnet *ifp, struct ifdrv *ifd)
+{
+ struct canif_softc *csc = ifp->if_softc;
+ uint32_t mode;
+ int error;
+
+ if (ifp->if_dlt != DLT_CAN_SOCKETCAN || csc == NULL)
+ return EOPNOTSUPP;
+
+ error = kauth_authorize_network(curlwp->l_cred,
+ KAUTH_NETWORK_INTERFACE,
+ KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp,
+ (void *)SIOCSDRVSPEC, NULL);
+ if (error != 0)
+ return error;
+
+ if ((ifp->if_flags & IFF_UP) != 0) {
+ return EBUSY;
+ }
+
+ switch(ifd->ifd_cmd) {
+ case CANSLINKTIMINGS:
+ if (ifd->ifd_len != sizeof(struct can_link_timings))
+ return EINVAL;
+ return copyin(ifd->ifd_data, &csc->csc_timings, ifd->ifd_len);
+
+ case CANSLINKMODE:
+ case CANCLINKMODE:
+ if (ifd->ifd_len != sizeof(uint32_t))
+ return EINVAL;
+ error = copyout(ifd->ifd_data, &mode, ifd->ifd_len);
+ if (error)
+ return error;
+ if ((mode & csc->csc_timecaps.cltc_linkmode_caps) != mode)
+ return EINVAL;
+ /* XXX locking */
+ if (ifd->ifd_cmd == CANSLINKMODE)
+ csc->csc_linkmodes |= mode;
+ else
+ csc->csc_linkmodes &= ~mode;
+ return 0;
+ }
+ return EOPNOTSUPP;
+}
+
/* ARGSUSED */
static int
can_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
@@ -98,12 +169,16 @@
struct can_ifreq *cfr = (struct can_ifreq *)data;
int error = 0;
#endif
-
+ if (ifp == NULL)
+ return (EOPNOTSUPP);
switch (cmd) {
-
+ case SIOCGDRVSPEC:
+ return can_get_netlink(ifp, (struct ifdrv *) data);
+ case SIOCSDRVSPEC:
+ return can_set_netlink(ifp, (struct ifdrv *) data);
default:
- if (ifp == 0 || ifp->if_ioctl == 0)
+ if (ifp->if_ioctl == 0)
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, data));
}
diff -r 5a31749b9bad -r f3b7221ad035 sys/netcan/can.h
--- a/sys/netcan/can.h Mon Apr 17 14:01:20 2017 +0000
+++ b/sys/netcan/can.h Mon Apr 17 20:32:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can.h,v 1.1.2.3 2017/01/16 18:03:38 bouyer Exp $ */
+/* $NetBSD: can.h,v 1.1.2.4 2017/04/17 20:32:27 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -118,12 +118,6 @@
#define CAN_INV_FILTER 0x20000000U
#ifdef _NETBSD_SOURCE
-
-/* CAN sockets ioctl */
-
-#define SIOCSCANBAUD _IOW('i', 134, int) /* set interface speed */
-#define SIOCGCANBAUD _IOR('i', 135, int) /* get interface speed */
-
#ifdef _KERNEL
#define satoscan(sa) ((struct sockaddr_can *)(sa))
diff -r 5a31749b9bad -r f3b7221ad035 sys/netcan/can_link.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/netcan/can_link.h Mon Apr 17 20:32:27 2017 +0000
@@ -0,0 +1,81 @@
+/* $NetBSD: can_link.h,v 1.1.2.1 2017/04/17 20:32:27 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NETCAN_CAN_LINK_H
+#define _NETCAN_CAN_LINK_H
+
+/*
+ * CAN bus link-layer related commands, from the SIOCSDRVSPEC
+ */
+
+/* get timing capabilities from HW */
+struct can_link_timecaps {
+ uint32_t cltc_prop_min; /* prop seg, in tq */
+ uint32_t cltc_prop_max;
+ uint32_t cltc_ps1_min; /* phase1 seg, in tq */
+ uint32_t cltc_ps1_max;
+ uint32_t cltc_ps2_min; /* phase 2 seg, in tq */
+ uint32_t cltc_ps2_max;
+ uint32_t cltc_sjw_max; /* Synchronisation Jump Width */
+ uint32_t cltc_brp_min; /* bit-rate prescaler */
+ uint32_t cltc_brp_max;
+ uint32_t cltc_brp_inc;
+ uint32_t cltc_clock_freq; /* prescaler input clock, in hz */
+ uint32_t cltc_linkmode_caps; /* link mode, see below */
+};
+#define CANGLINKTIMECAP 0 /* get struct can_link_timecaps */
+
+/* get/set timing parameters */
+struct can_link_timings {
+ uint32_t clt_clock_freq; /* prescaler input clock, in hz */
+ uint32_t clt_brp; /* prescaler value */
+ uint32_t clt_prop; /* Propagation segment in tq */
+ uint32_t clt_ps1; /* Phase segment 1 in tq */
+ uint32_t clt_ps2; /* Phase segment 2 in tq */
+ uint32_t clt_sjw; /* Synchronisation jump width in tq */
+};
+#define CANGLINKTIMINGS 1 /* get struct can_link_timings */
+#define CANSLINKTIMINGS 2 /* set struct can_link_timings */
+
+/* link-level modes */
+#define CAN_LINKMODE_LOOPBACK 0x01 /* Loopback mode */
+#define CAN_LINKMODE_LISTENONLY 0x02 /* Listen-only mode */
+#define CAN_LINKMODE_3SAMPLES 0x04 /* Triple sampling mode */
+#define CAN_LINKMODE_PRESUME_ACK 0x08 /* Ignore missing CAN ACKs */
+#define CAN_IFFBITS \
+ "\020\1LOOPBACK\2LISTENONLY\3TRIPLESAMPLE\4PRESUMEACK"
+
+#define CANGLINKMODE 3 /* (uint32_t) get bits */
+#define CANSLINKMODE 4 /* (uint32_t) set bits */
+#define CANCLINKMODE 5 /* (uint32_t) clear bits */
+
+#endif /* _NETCAN_CAN_LINK_H */
+
diff -r 5a31749b9bad -r f3b7221ad035 sys/netcan/can_var.h
--- a/sys/netcan/can_var.h Mon Apr 17 14:01:20 2017 +0000
+++ b/sys/netcan/can_var.h Mon Apr 17 20:32:27 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can_var.h,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $ */
+/* $NetBSD: can_var.h,v 1.1.2.5 2017/04/17 20:32:27 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -33,6 +33,8 @@
#define _NETCAN_CAN_VAR_H_
#include <sys/queue.h>
+#include <sys/device.h>
+#include <netcan/can_link.h>
struct can_ifreq {
char cfr_name[IFNAMSIZ]; /* if name, e.g. "sja0" */
@@ -40,6 +42,17 @@
#ifdef _KERNEL
+/*
+ * common structure for CAN interface drivers. Should be at the start of
+ * each driver's softc.
+ */
+struct canif_softc {
+ device_t csc_dev;
+ struct can_link_timecaps csc_timecaps; /* timing capabilities */
+ struct can_link_timings csc_timings; /* operating timing values */
+ uint32_t csc_linkmodes;
+};
+
extern struct ifqueue canintrq;
extern struct domain candomain;
Home |
Main Index |
Thread Index |
Old Index