CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Thu May 25 18:26:36 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: abort may clear sc_m_transmit but leave OACTIVE, so unconditionally clear OACTIVE in TX interrupt. To generate a diff of this commit: cvs rdiff -u -r1.1.2.7 -r1.1.2.8 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.7 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.8 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.7 Thu May 25 18:23:15 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Thu May 25 18:26:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.7 2017/05/25 18:23:15 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.8 2017/05/25 18:26:36 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.7 2017/05/25 18:23:15 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.8 2017/05/25 18:26:36 bouyer Exp $"); #include #include @@ -297,9 +297,8 @@ awin_can_tx_intr(struct awin_can_softc * can_input(ifp, m); /* loopback */ sc->sc_m_transmit = NULL; ifp->if_timer = 0; - ifp->if_flags &= ~IFF_OACTIVE; } - + ifp->if_flags &= ~IFF_OACTIVE; if_schedule_deferred_start(ifp); }
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Thu May 25 18:23:16 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: Do not call bpf_mtap() from interrupt context. Mostly from Ryota Ozaki: on receive, use bpf_mtap_softint(). On send, call awin_can_ifstart() through if_schedule_deferred_start(). To generate a diff of this commit: cvs rdiff -u -r1.1.2.6 -r1.1.2.7 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.6 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.7 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.6 Mon May 22 16:11:23 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Thu May 25 18:23:15 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.6 2017/05/22 16:11:23 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.7 2017/05/25 18:23:15 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.6 2017/05/22 16:11:23 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.7 2017/05/25 18:23:15 bouyer Exp $"); #include #include @@ -50,6 +50,7 @@ __KERNEL_RCSID(1, "$NetBSD: awin_can.c,v #include #include +#include #ifdef CAN #include @@ -209,6 +210,8 @@ awin_can_attach(device_t parent, device_ * Attach the interface. */ can_ifattach(ifp); + if_deferred_start_init(ifp, NULL); + bpf_mtap_softint_init(ifp); rnd_attach_source(&sc->sc_rnd_source, device_xname(self), RND_TYPE_NET, RND_FLAG_DEFAULT); #ifdef MBUFTRACE @@ -275,7 +278,7 @@ awin_can_rx_intr(struct awin_can_softc * ifp->if_ipackets++; ifp->if_ibytes += m->m_len; m_set_rcvif(m, ifp); - can_bpf_mtap(ifp, m); + can_bpf_mtap(ifp, m, 1); can_input(ifp, m); } @@ -284,10 +287,6 @@ awin_can_tx_intr(struct awin_can_softc * { struct ifnet * const ifp = sc->sc_ifp; struct mbuf *m; - struct can_frame *cf; - int regd; - uint32_t reg0val; - int i; KASSERT(mutex_owned(&sc->sc_intr_lock)); if ((m = sc->sc_m_transmit) != NULL) { @@ -298,58 +297,10 @@ awin_can_tx_intr(struct awin_can_softc * can_input(ifp, m); /* loopback */ sc->sc_m_transmit = NULL; ifp->if_timer = 0; - } - - IF_DEQUEUE(&ifp->if_snd, m); - - if (m == NULL) { ifp->if_flags &= ~IFF_OACTIVE; - return; - } - MCLAIM(m, ifp->if_mowner); - sc->sc_m_transmit = m; - - KASSERT((m->m_flags & M_PKTHDR) != 0); - KASSERT(m->m_len == m->m_pkthdr.len); - - cf = mtod(m, struct can_frame *); - reg0val = cf->can_dlc & AWIN_CAN_TXBUF0_DL; - if (cf->can_id & CAN_RTR_FLAG) - reg0val |= AWIN_CAN_TXBUF0_RTR; - - if (cf->can_id & CAN_EFF_FLAG) { - reg0val |= AWIN_CAN_TXBUF0_EFF; - awin_can_write(sc, AWIN_CAN_TXBUF1_REG, - (cf->can_id >> 21) & 0xff); - awin_can_write(sc, AWIN_CAN_TXBUF2_REG, - (cf->can_id >> 13) & 0xff); - awin_can_write(sc, AWIN_CAN_TXBUF3_REG, - (cf->can_id >> 5) & 0xff); - awin_can_write(sc, AWIN_CAN_TXBUF4_REG, - (cf->can_id << 3) & 0xf8); - regd = AWIN_CAN_TXBUF5_REG; - } else { - awin_can_write(sc, AWIN_CAN_TXBUF1_REG, - (cf->can_id >> 3) & 0xff); - awin_can_write(sc, AWIN_CAN_TXBUF2_REG, - (cf->can_id << 5) & 0xe0); - regd = AWIN_CAN_TXBUF3_REG; } - for (i = 0; i < cf->can_dlc; i++) { - awin_can_write(sc, regd + i * 4, cf->data[i]); - } - awin_can_write(sc, AWIN_CAN_TXBUF0_REG, reg0val); - - if (sc->sc_linkmodes & CAN_LINKMODE_LOOPBACK) { - awin_can_write(sc, AWIN_CAN_CMD_REG, - AWIN_CAN_CMD_TANS_REQ | AWIN_CAN_CMD_SELF_REQ); - } else { - awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_TANS_REQ); - } - ifp->if_flags |= IFF_OACTIVE; - ifp->if_timer = 5; - can_bpf_mtap(ifp, m); + if_schedule_deferred_start(ifp); } static int @@ -446,10 +397,66 @@ void awin_can_ifstart(struct ifnet *ifp) { struct awin_can_softc * const sc = ifp->if_softc; + struct mbuf *m; + struct can_frame *cf; + int regd; + uint32_t reg0val; + int i; mutex_enter(&sc->sc_intr_lock); - KASSERT((ifp->if_flags & IFF_OACTIVE) == 0); - awin_can_tx_intr(sc); + if (ifp->if_flags & IFF_OACTIVE) + goto out; + + IF_DEQUEUE(&ifp->if_snd, m); + + if (m == NULL) + goto out; + + MCLAIM(m, ifp->if_mowner); + sc->sc_m_transmit = m; + + KASSERT((m->m_flags & M_PKTHDR) != 0); + KASSERT(m->m_len == m->m_pkthdr.len); + + cf = mtod(m, struct can_frame *); + reg0val = cf->can_dlc & AWIN_CAN_TXBUF0_DL; + if (cf->can_id & CAN_RTR_FLAG) + reg0val |= AWIN_CAN_TXBUF0_RTR; + + if (cf->can_id & CAN_EFF_FLAG) { + reg0val |= AWIN_CAN_TXBUF0_EFF; + awin_can_write(sc, AWIN_CAN_TXBUF1_REG, + (cf->can_id >> 21) & 0xff); + awin_can_write(sc, AWIN_CAN_TXBUF2_REG, + (cf->can_id >> 13) & 0xff); + awin_can_write(sc, AWIN_CAN_TXBUF3_REG, + (cf->can_id >> 5) & 0xff); + awin_can_write(sc, AWIN_CAN_TXBUF4_REG, + (cf->can_id << 3) & 0xf8); + regd
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Fri Apr 21 13:08:55 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: can4linux code, and experiments, shows that the CAN clock frequency is AWIN_REF_FREQ, not AWIN_REF_FREQ / 2 as the A20 doc suggests. Always set the mbuf len to CAN_MTU, this is what linux does. Set accept filters and clear errors counters on ifconfig up. We can now send and receive CAN frames. To generate a diff of this commit: cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.4 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.5 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.4 Thu Apr 20 17:30:52 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Fri Apr 21 13:08:55 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.4 2017/04/20 17:30:52 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.5 2017/04/21 13:08:55 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.4 2017/04/20 17:30:52 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.5 2017/04/21 13:08:55 bouyer Exp $"); #include #include @@ -168,7 +168,7 @@ awin_can_attach(device_t parent, device_ sc->sc_timecaps.cltc_brp_min = 1; sc->sc_timecaps.cltc_brp_max = 64; sc->sc_timecaps.cltc_brp_inc = 1; - sc->sc_timecaps.cltc_clock_freq = AWIN_REF_FREQ / 2; + sc->sc_timecaps.cltc_clock_freq = AWIN_REF_FREQ; sc->sc_timecaps.cltc_linkmode_caps = CAN_LINKMODE_3SAMPLES | CAN_LINKMODE_LISTENONLY | CAN_LINKMODE_LOOPBACK; @@ -274,13 +274,11 @@ awin_can_rx_intr(struct awin_can_softc * } } awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_REL_RX_BUF); - m->m_len = m->m_pkthdr.len = - offsetof(struct can_frame, data[0]) + cf->can_dlc; + m->m_len = m->m_pkthdr.len = CAN_MTU; ifp->if_ipackets++; ifp->if_ibytes += m->m_len; m_set_rcvif(m, ifp); bpf_mtap(ifp, m); - printf("can_input1\n"); can_input(ifp, m); } @@ -300,7 +298,6 @@ awin_can_tx_intr(struct awin_can_softc * ifp->if_opackets++; can_mbuf_tag_clean(m); m_set_rcvif(m, ifp); - printf("can_input2\n"); can_input(ifp, m); /* loopback */ sc->sc_m_transmit = NULL; ifp->if_timer = 0; @@ -503,6 +500,14 @@ awin_can_ifup(struct awin_can_softc * co awin_can_write(sc, AWIN_CAN_BUS_TIME_REG, reg); + /* set filters to accept all frames */ + awin_can_write(sc, AWIN_CAN_ACPC, 0x); + awin_can_write(sc, AWIN_CAN_ACPM, 0x); + + /* clear errors counter */ + awin_can_write(sc, AWIN_CAN_REC_REG, 0); + + /* leave reset mode and enable interrupts */ awin_can_exit_reset(sc); awin_can_write(sc, AWIN_CAN_INTE_REG, AWIN_CAN_INT_TX_FLAG | AWIN_CAN_INT_RX_FLAG | AWIN_CAN_INT_ALLERRS);
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Thu Apr 20 17:30:52 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: Print some informations for error interrupts. Fix some registers values. Now we can transmit frames. Receive still doesn't work. To generate a diff of this commit: cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.3 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.4 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.3 Thu Apr 20 13:00:52 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Thu Apr 20 17:30:52 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.3 2017/04/20 13:00:52 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.4 2017/04/20 17:30:52 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.3 2017/04/20 13:00:52 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.4 2017/04/20 17:30:52 bouyer Exp $"); #include #include @@ -303,6 +303,7 @@ awin_can_tx_intr(struct awin_can_softc * printf("can_input2\n"); can_input(ifp, m); /* loopback */ sc->sc_m_transmit = NULL; + ifp->if_timer = 0; } IF_DEQUEUE(&ifp->if_snd, m); @@ -382,13 +383,17 @@ awin_can_err_intr(struct awin_can_softc struct ifnet * const ifp = sc->sc_ifp; KASSERT(mutex_owned(&sc->sc_intr_lock)); int txerr = 0; + uint32_t reg; if (irq & AWIN_CAN_INT_DATA_OR) { ifp->if_ierrors++; awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_CLR_OR); } if (irq & AWIN_CAN_INT_ERR) { - /* XXX todo */ + reg = awin_can_read(sc, AWIN_CAN_REC_REG); + printf("%s: ERR interrupt status 0x%x counters 0x%x\n", + device_xname(sc->sc_dev), sts, reg); + } if (irq & AWIN_CAN_INT_BERR) { if (sts & AWIN_CAN_STA_TX) @@ -397,7 +402,8 @@ awin_can_err_intr(struct awin_can_softc ifp->if_ierrors++; } if (irq & AWIN_CAN_INT_ERR_PASSIVE) { - /* XXX todo */ + printf("%s: PASSV interrupt status 0x%x\n", + device_xname(sc->sc_dev), sts); } if (irq & AWIN_CAN_INT_ARB_LOST) { txerr++; @@ -459,7 +465,7 @@ awin_can_ifup(struct awin_can_softc * co uint32_t reg; /* setup timings and mode - has to be done in reset */ - reg = 0; + reg = AWIN_CAN_MODSEL_RST; if (sc->sc_linkmodes & CAN_LINKMODE_LISTENONLY) reg |= AWIN_CAN_MODSEL_LST_ONLY;
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Thu Apr 20 13:00:52 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: Handle interface errors. Use a watchdog for transmit. To generate a diff of this commit: cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.2 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.3 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.2 Wed Apr 19 17:54:18 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Thu Apr 20 13:00:52 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.2 2017/04/19 17:54:18 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.3 2017/04/20 13:00:52 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.2 2017/04/19 17:54:18 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.3 2017/04/20 13:00:52 bouyer Exp $"); #include #include @@ -60,6 +60,15 @@ __KERNEL_RCSID(1, "$NetBSD: awin_can.c,v #include #include +/* shortcut for all error interrupts */ +#define AWIN_CAN_INT_ALLERRS (\ + AWIN_CAN_INT_BERR | \ + AWIN_CAN_INT_ARB_LOST | \ + AWIN_CAN_INT_ERR_PASSIVE | \ + AWIN_CAN_INT_DATA_OR | \ + AWIN_CAN_INT_ERR \ +) + struct awin_can_softc { struct canif_softc sc_cansc; bus_space_tag_t sc_bst; @@ -164,6 +173,8 @@ awin_can_attach(device_t parent, device_ CAN_LINKMODE_3SAMPLES | CAN_LINKMODE_LISTENONLY | CAN_LINKMODE_LOOPBACK; can_ifinit_timings(&sc->sc_cansc); + sc->sc_timings.clt_prop = 0; + sc->sc_timings.clt_sjw = 1; aprint_naive("\n"); aprint_normal(": CAN bus controller\n"); @@ -222,6 +233,7 @@ awin_can_rx_intr(struct awin_can_softc * int dlc; int regd, i; + KASSERT(mutex_owned(&sc->sc_intr_lock)); reg0v = awin_can_read(sc, AWIN_CAN_TXBUF0_REG); dlc = reg0v & AWIN_CAN_TXBUF0_DL; @@ -268,6 +280,7 @@ awin_can_rx_intr(struct awin_can_softc * ifp->if_ibytes += m->m_len; m_set_rcvif(m, ifp); bpf_mtap(ifp, m); + printf("can_input1\n"); can_input(ifp, m); } @@ -281,11 +294,13 @@ awin_can_tx_intr(struct awin_can_softc * uint32_t reg0val; int i; + KASSERT(mutex_owned(&sc->sc_intr_lock)); if ((m = sc->sc_m_transmit) != NULL) { ifp->if_obytes += m->m_len; ifp->if_opackets++; can_mbuf_tag_clean(m); m_set_rcvif(m, ifp); + printf("can_input2\n"); can_input(ifp, m); /* loopback */ sc->sc_m_transmit = NULL; } @@ -331,11 +346,68 @@ awin_can_tx_intr(struct awin_can_softc * } awin_can_write(sc, AWIN_CAN_TXBUF0_REG, reg0val); - awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_TANS_REQ); + if (sc->sc_linkmodes & CAN_LINKMODE_LOOPBACK) { + awin_can_write(sc, AWIN_CAN_CMD_REG, + AWIN_CAN_CMD_TANS_REQ | AWIN_CAN_CMD_SELF_REQ); + } else { + awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_TANS_REQ); + } ifp->if_flags |= IFF_OACTIVE; + ifp->if_timer = 5; bpf_mtap(ifp, m); } +static int +awin_can_tx_abort(struct awin_can_softc *sc) +{ + KASSERT(mutex_owned(&sc->sc_intr_lock)); + if (sc->sc_m_transmit) { + m_freem(sc->sc_m_transmit); + sc->sc_m_transmit = NULL; + sc->sc_ifp->if_timer = 0; + /* + * the transmit abort will trigger a TX interrupt + * which will restart the queue or cleae OACTIVE, + * as appropriate + */ + awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_ABT_REQ); + return 1; + } + return 0; +} + +static void +awin_can_err_intr(struct awin_can_softc *sc, uint32_t irq, uint32_t sts) +{ + struct ifnet * const ifp = sc->sc_ifp; + KASSERT(mutex_owned(&sc->sc_intr_lock)); + int txerr = 0; + + if (irq & AWIN_CAN_INT_DATA_OR) { + ifp->if_ierrors++; + awin_can_write(sc, AWIN_CAN_CMD_REG, AWIN_CAN_CMD_CLR_OR); + } + if (irq & AWIN_CAN_INT_ERR) { + /* XXX todo */ + } + if (irq & AWIN_CAN_INT_BERR) { + if (sts & AWIN_CAN_STA_TX) + txerr++; + if (sts & AWIN_CAN_STA_RX) + ifp->if_ierrors++; + } + if (irq & AWIN_CAN_INT_ERR_PASSIVE) { + /* XXX todo */ + } + if (irq & AWIN_CAN_INT_ARB_LOST) { + txerr++; + } + if (txerr) { + ifp->if_oerrors += txerr; + (void) awin_can_tx_abort(sc); + } +} + int awin_can_intr(void *arg) { @@ -358,6 +430,9 @@ awin_can_intr(void *arg) sts = awin_can_read(sc, AWIN_CAN_STA_REG); } } + if (irq & AWIN_CAN_INT_ALLERRS) { + awin_can_err_intr(sc, irq, sts); + } awin_can_write(sc, AWIN_CAN_INT_REG, irq); rnd_add_uint32(&sc->sc_rnd_source, irq); @@ -424,7 +499,7 @@ awin_can_ifup(struct awin_can_softc * co awin_can_exit_reset(sc); awin_can_write(sc, AWIN_CAN_INTE_REG, - AWIN_CAN_INT_TX_FLAG | AWIN_CAN_INT_RX_FLAG); + AWIN_CAN_INT_TX_FLAG | AWIN_CAN_INT_RX_FLAG | AWIN_CAN_INT_ALLERRS); sc->sc_ifp->if_flags |= IFF_RUNNING; return 0; } @@ -433,6 +508,7 @@ static void awin
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Wed Apr 19 17:54:18 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: Fix the reset code clear the IFF_UP flag if we can't get the interface running. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/arch/arm/allwinner/awin_can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u src/sys/arch/arm/allwinner/awin_can.c:1.1.2.1 src/sys/arch/arm/allwinner/awin_can.c:1.1.2.2 --- src/sys/arch/arm/allwinner/awin_can.c:1.1.2.1 Tue Apr 18 21:30:38 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Wed Apr 19 17:54:18 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_can.c,v 1.1.2.1 2017/04/18 21:30:38 bouyer Exp $ */ +/* $NetBSD: awin_can.c,v 1.1.2.2 2017/04/19 17:54:18 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.1 2017/04/18 21:30:38 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.2 2017/04/19 17:54:18 bouyer Exp $"); #include #include @@ -119,8 +119,9 @@ awin_can_match(device_t parent, cfdata_t KASSERT(cf->cf_loc[AWINIOCF_PORT] == AWINIOCF_PORT_DEFAULT || cf->cf_loc[AWINIOCF_PORT] == loc->loc_port); - if (!awin_gpio_pinset_available(pinset)) + if (!awin_gpio_pinset_available(pinset)) { return 0; + } return 1; } @@ -465,6 +466,9 @@ awin_can_ifioctl(struct ifnet *ifp, u_lo if ((ifp->if_flags & IFF_UP) != 0 && (ifp->if_flags & IFF_RUNNING) == 0) { error = awin_can_ifup(sc); +if (error) { + ifp->if_flags &= ~IFF_UP; +} } else if ((ifp->if_flags & IFF_UP) == 0 && (ifp->if_flags & IFF_RUNNING) != 0) { awin_can_ifdown(sc); @@ -493,7 +497,7 @@ awin_can_enter_reset(struct awin_can_sof val |= AWIN_CAN_MODSEL_RST; awin_can_write(sc, AWIN_CAN_MODSEL_REG, val); val = awin_can_read(sc, AWIN_CAN_MODSEL_REG); - if (val & AWIN_CAN_MODSEL_REG) + if (val & AWIN_CAN_MODSEL_RST) return; } printf("%s: couldn't enter reset mode\n", device_xname(sc->sc_dev)); @@ -510,7 +514,7 @@ awin_can_exit_reset(struct awin_can_soft val &= ~AWIN_CAN_MODSEL_RST; awin_can_write(sc, AWIN_CAN_MODSEL_REG, val); val = awin_can_read(sc, AWIN_CAN_MODSEL_REG); - if ((val & AWIN_CAN_MODSEL_REG) == 0) + if ((val & AWIN_CAN_MODSEL_RST) == 0) return; } printf("%s: couldn't leave reset mode\n", device_xname(sc->sc_dev));
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Wed Apr 19 17:53:32 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_io.c Log Message: Add awincan To generate a diff of this commit: cvs rdiff -u -r1.46 -r1.46.4.1 src/sys/arch/arm/allwinner/awin_io.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_io.c diff -u src/sys/arch/arm/allwinner/awin_io.c:1.46 src/sys/arch/arm/allwinner/awin_io.c:1.46.4.1 --- src/sys/arch/arm/allwinner/awin_io.c:1.46 Wed May 11 18:33:40 2016 +++ src/sys/arch/arm/allwinner/awin_io.c Wed Apr 19 17:53:32 2017 @@ -31,7 +31,7 @@ #include -__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.46 2016/05/11 18:33:40 bouyer Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.46.4.1 2017/04/19 17:53:32 bouyer Exp $"); #include #include @@ -192,6 +192,7 @@ static const struct awin_locators awin_l { "awinir", OFFANDSIZE(A31_CIR), NOPORT, AWIN_A31_IRQ_CIR, A31 }, { "awinir", OFFANDSIZE(A80_CIR), NOPORT, AWIN_A80_IRQ_R_CIR, A80 }, { "awinlradc", OFFANDSIZE(LRADC), NOPORT, AWIN_IRQ_LRADC, A20 }, + { "awincan", OFFANDSIZE(CAN), NOPORT, AWIN_IRQ_CAN, A20 }, }; static int
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Tue Apr 18 21:30:38 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: files.awin Added Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_can.c Log Message: First draft of a driver for the CAN controller found in the Allwinner A20 SoC. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/arm/allwinner/awin_can.c cvs rdiff -u -r1.36 -r1.36.4.1 src/sys/arch/arm/allwinner/files.awin Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/files.awin diff -u src/sys/arch/arm/allwinner/files.awin:1.36 src/sys/arch/arm/allwinner/files.awin:1.36.4.1 --- src/sys/arch/arm/allwinner/files.awin:1.36 Fri May 27 20:01:49 2016 +++ src/sys/arch/arm/allwinner/files.awin Tue Apr 18 21:30:38 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.awin,v 1.36 2016/05/27 20:01:49 bouyer Exp $ +# $NetBSD: files.awin,v 1.36.4.1 2017/04/18 21:30:38 bouyer Exp $ # # Configuration info for Allwinner ARM Peripherals # @@ -110,6 +110,11 @@ file arch/arm/allwinner/awin_eth.c awin attach awge at awinio with awin_gige file arch/arm/allwinner/awin_gige.c awin_gige +# A20 CAN +device awincan { } : ifnet +attach awincan at awinio with awin_can +file arch/arm/allwinner/awin_can.c awin_can + # USB2 OTG Controller attach motg at awinio with awin_otg file arch/arm/allwinner/awin_otg.c awin_otg Added files: Index: src/sys/arch/arm/allwinner/awin_can.c diff -u /dev/null src/sys/arch/arm/allwinner/awin_can.c:1.1.2.1 --- /dev/null Tue Apr 18 21:30:38 2017 +++ src/sys/arch/arm/allwinner/awin_can.c Tue Apr 18 21:30:38 2017 @@ -0,0 +1,517 @@ +/* $NetBSD: awin_can.c,v 1.1.2.1 2017/04/18 21:30:38 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. + */ + + +#include "locators.h" +#include "opt_can.h" + + +#include + +__KERNEL_RCSID(1, "$NetBSD: awin_can.c,v 1.1.2.1 2017/04/18 21:30:38 bouyer Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CAN +#include +#include +#endif +#include + +#include +#include + +struct awin_can_softc { + struct canif_softc sc_cansc; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + kmutex_t sc_intr_lock; + void *sc_ih; + struct ifnet *sc_ifp; + krndsource_t sc_rnd_source; /* random source */ + struct mbuf *sc_m_transmit; /* mbuf being transmitted */ +}; +#define sc_dev sc_cansc.csc_dev +#define sc_timecaps sc_cansc.csc_timecaps +#define sc_timings sc_cansc.csc_timings +#define sc_linkmodes sc_cansc.csc_linkmodes + +static int awin_can_match(device_t, cfdata_t, void *); +static void awin_can_attach(device_t, device_t, void *); + +static int awin_can_intr(void *); + +static void awin_can_ifstart(struct ifnet *); +static int awin_can_ifioctl(struct ifnet *, u_long, void *); +static void awin_can_ifwatchdog(struct ifnet *); + +static void awin_can_enter_reset(struct awin_can_softc *); +static void awin_can_exit_reset(struct awin_can_softc *); + +CFATTACH_DECL_NEW(awin_can, sizeof(struct awin_can_softc), + awin_can_match, awin_can_attach, NULL, NULL); + +static const struct awin_gpio_pinset awin_can_pinsets[2] = { +[0] = { 'A', AWIN_PIO_PA_CAN_FUNC, AWIN_PIO_PA_CAN_PINS }, +[1] = { 'H', AWIN_PIO_PH_CAN_FUNC, AWIN_PIO_PH_CAN_PINS }, +}; + +static inline uint32_t +awin_can_read(struct awin_can_softc *sc, bus_size_t o) +{ + retu
CVS commit: [bouyer-socketcan] src/sys/arch/arm/allwinner
Module Name:src Committed By: bouyer Date: Mon Apr 17 20:41:55 UTC 2017 Modified Files: src/sys/arch/arm/allwinner [bouyer-socketcan]: awin_reg.h Log Message: Add CAN registers To generate a diff of this commit: cvs rdiff -u -r1.90 -r1.90.2.1 src/sys/arch/arm/allwinner/awin_reg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/arch/arm/allwinner/awin_reg.h diff -u src/sys/arch/arm/allwinner/awin_reg.h:1.90 src/sys/arch/arm/allwinner/awin_reg.h:1.90.2.1 --- src/sys/arch/arm/allwinner/awin_reg.h:1.90 Mon Dec 26 16:20:17 2016 +++ src/sys/arch/arm/allwinner/awin_reg.h Mon Apr 17 20:41:55 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_reg.h,v 1.90 2016/12/26 16:20:17 rjs Exp $ */ +/* $NetBSD: awin_reg.h,v 1.90.2.1 2017/04/17 20:41:55 bouyer Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -3071,4 +3071,120 @@ struct awin_a31_dma_desc { #define AWIN_LRADC_DATA0_REG 0x0c #define AWIN_LRADC_DATA1_REG 0x10 +/* CAN mode select register */ +#define AWIN_CAN_MODSEL_REG 0x00 +#define AWIN_CAN_MODSEL_SLEEP __BIT(4) +#define AWIN_CAN_MODSEL_ACP_FLT_MOD __BIT(3) +#define AWIN_CAN_MODSEL_LB_MOD __BIT(2) +#define AWIN_CAN_MODSEL_LST_ONLY __BIT(1) +#define AWIN_CAN_MODSEL_RST __BIT(0) + +/* CAN command register */ +#define AWIN_CAN_CMD_REG 0x04 +#define AWIN_CAN_CMD_BUS_OFF __BIT(5) +#define AWIN_CAN_CMD_SELF_REQ __BIT(4) +#define AWIN_CAN_CMD_CLR_OR __BIT(3) +#define AWIN_CAN_CMD_REL_RX_BUF __BIT(2) +#define AWIN_CAN_CMD_ABT_REQ __BIT(1) +#define AWIN_CAN_CMD_TANS_REQ __BIT(0) + +/* CAN status register */ +#define AWIN_CAN_STA_REG 0x08 +#define AWIN_CAN_STA_ERR_CODE __BITS(23,22) +#define AWIN_CAN_STA_ERR_CODE_BIT 0 +#define AWIN_CAN_STA_ERR_CODE_FORM 1 +#define AWIN_CAN_STA_ERR_CODE_STUFF 2 +#define AWIN_CAN_STA_ERR_CODE_OTHER 3 +#define AWIN_CAN_STA_ERR_DIR _BIT(21) +#define AWIN_CAN_STA_ERR_SEG_CODE __BITS(20,16) +#define AWIN_CAN_STA_ARB_LOST __BITS(12,8) +#define AWIN_CAN_STA_BUS __BIT(7) +#define AWIN_CAN_STA_ERR __BIT(6) +#define AWIN_CAN_STA_TX __BIT(5) +#define AWIN_CAN_STA_RX __BIT(4) +#define AWIN_CAN_STA_TX_OVER __BIT(3) +#define AWIN_CAN_STA_TX_RDY __BIT(2) +#define AWIN_CAN_STA_DATA_OR __BIT(1) +#define AWIN_CAN_STA_RX_RDY __BIT(0) + +/* CAN interrupt register */ +#define AWIN_CAN_INT_REG 0x0c +#define AWIN_CAN_INT_BERR __BIT(7) +#define AWIN_CAN_INT_ARB_LOST __BIT(6) +#define AWIN_CAN_INT_ERR_PASSIVE __BIT(5) +#define AWIN_CAN_INT_WAKEUP __BIT(4) +#define AWIN_CAN_INT_DATA_OR __BIT(3) +#define AWIN_CAN_INT_ERR __BIT(2) +#define AWIN_CAN_INT_TX_FLAG __BIT(1) +#define AWIN_CAN_INT_RX_FLAG __BIT(0) + +/* CAN interrupt enable register */ +#define AWIN_CAN_INTE_REG 0x10 + +/* CAN bus timing register */ +#define AWIN_CAN_BUS_TIME_REG 0x14 +#define AWIN_CAN_BUS_TIME_SAM __BIT(23) +#define AWIN_CAN_BUS_TIME_PHSEG2 __BITS(22,20) +#define AWIN_CAN_BUS_TIME_PHSEG1 __BITS(19,16) +#define AWIN_CAN_BUS_TIME_SJW __BITS(15,14) +#define AWIN_CAN_BUS_TIME_TQ_BRP __BITS(9,0) + +/* CAN tx error warning limit register */ +#define AWIN_CAN_EWL_REG 0x18 +#define AWIN_CAN_EWL_ERR_WRN_LMT __BITS(7,0) + +/* CAN error counter register */ +#define AWIN_CAN_REC_REG 0x1c +#define AWIN_CAN_REC_RX_ERR_CNT __BITS(23,16) +#define AWIN_CAN_REC_TX_ERR_CNT __BITS(7,0) + +/* CAN receive message register */ +#define AWIN_CAN_RMSGC_REG 0x20 +#define AWIN_CAN_RMSGC_RX_MSG_CNT __BITS(7,0) + +/* CAN receive buffer start address register */ +#define AWIN_CAN_RSADDR_REG 0x24 +#define AWIN_CAN_RSADDR_RX_BUF_SADDR __BITS(5,0) + +/* CAN rx/tx message buffer 0 register */ +#define AWIN_CAN_TXBUF0_REG 0x40 +#define AWIN_CAN_TXBUF0_EFF __BIT(7) +#define AWIN_CAN_TXBUF0_RTR __BIT(6) +#define AWIN_CAN_TXBUF0_DL __BITS(3,0) + +/* CAN rx/tx message buffer registers */ +#define AWIN_CAN_TXBUF1_REG 0x44 +#define AWIN_CAN_TXBUF2_REG 0x48 +#define AWIN_CAN_TXBUF3_REG 0x4c +#define AWIN_CAN_TXBUF4_REG 0x50 +#define AWIN_CAN_TXBUF5_REG 0x54 +#define AWIN_CAN_TXBUF6_REG 0x58 +#define AWIN_CAN_TXBUF7_REG 0x5c +#define AWIN_CAN_TXBUF8_REG 0x60 +#define AWIN_CAN_TXBUF9_REG 0x64 +#define AWIN_CAN_TXBUF10_REG 0x68 +#define AWIN_CAN_TXBUF11_REG 0x6c +#define AWIN_CAN_TXBUF12_REG 0x70 + +/* CAN acceptance code 0 register */ +#define AWIN_CAN_ACPC 0x40 + +/* CAN acceptance mask 0 register */ +#define AWIN_CAN_ACPM 0x44 + +/* CAN transmit buffer for read back registers */ +#define AWIN_CAN_RBUF_RBACK0 0x180 +#define AWIN_CAN_RBUF_RBACK1 0x184 +#define AWIN_CAN_RBUF_RBACK2 0x188 +#define AWIN_CAN_RBUF_RBACK3 0x18c +#define AWIN_CAN_RBUF_RBACK4 0x190 +#define AWIN_CAN_RBUF_RBACK5 0x194 +#define AWIN_CAN_RBUF_RBACK6 0x198 +#define AWIN_CAN_RBUF_RBACK7 0x19c +#define AWIN_CAN_RBUF_RBACK8 0x1a0 +#define AWIN_CAN_RBUF_RBACK9 0x1a4 +#define AWIN_CAN_RBUF_RBACK10 0x1a8 +#define AWIN_CAN_RBUF_RBACK11 0x1ac +#define AWIN_CAN_RBUF_RBACK12 0x1b0 + #endif /* _ARM_ALLWINNER_AWIN_REG_H_ */