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