Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Driver for the standard Archimedes Econet interface, bas...



details:   https://anonhg.NetBSD.org/src/rev/482d164be5de
branches:  trunk
changeset: 514817:482d164be5de
user:      bjh21 <bjh21%NetBSD.org@localhost>
date:      Mon Sep 10 23:41:48 2001 +0000

description:
Driver for the standard Archimedes Econet interface, based around the
Motorola 6854 ADLC.

diffstat:

 sys/arch/arm26/arm26/genassym.cf |    7 +-
 sys/arch/arm26/conf/files.arm26  |    8 +-
 sys/arch/arm26/ioc/if_eca.c      |  482 +++++++++++++++++++++++++++++++++++++++
 sys/arch/arm26/ioc/if_eca_fiq.S  |  155 ++++++++++++
 sys/arch/arm26/ioc/if_ecavar.h   |   78 ++++++
 sys/dev/ic/mc6854reg.h           |  103 ++++++++
 6 files changed, 829 insertions(+), 4 deletions(-)

diffs (truncated from 881 to 300 lines):

diff -r bbf14cdb1bbc -r 482d164be5de sys/arch/arm26/arm26/genassym.cf
--- a/sys/arch/arm26/arm26/genassym.cf  Mon Sep 10 23:40:02 2001 +0000
+++ b/sys/arch/arm26/arm26/genassym.cf  Mon Sep 10 23:41:48 2001 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.3 2001/01/20 17:14:20 bjh21 Exp $
+# $NetBSD: genassym.cf,v 1.4 2001/09/10 23:41:48 bjh21 Exp $
 #
 # Copyright (c) 1999 Ben Harris
 # All rights reserved.
@@ -29,6 +29,7 @@
 
 include <sys/param.h>
 
+include <sys/mbuf.h>
 include <sys/proc.h>
 include <sys/user.h>
 include <machine/pcb.h>
@@ -46,3 +47,7 @@
 define IF_SIZE         sizeof(struct irqframe)
 
 define SIGF_SC         offsetof(struct sigframe, sf_sc)
+
+define M_NEXT          offsetof(struct mbuf, m_next)
+define M_DATA          offsetof(struct mbuf, m_data)
+define M_LEN           offsetof(struct mbuf, m_len)
diff -r bbf14cdb1bbc -r 482d164be5de sys/arch/arm26/conf/files.arm26
--- a/sys/arch/arm26/conf/files.arm26   Mon Sep 10 23:40:02 2001 +0000
+++ b/sys/arch/arm26/conf/files.arm26   Mon Sep 10 23:41:48 2001 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.arm26,v 1.37 2001/08/20 23:08:10 bjh21 Exp $
+# $NetBSD: files.arm26,v 1.38 2001/09/10 23:41:49 bjh21 Exp $
 
 # Copyright (c) 1997, 1998, 2000 Ben Harris
 # All rights reserved.
@@ -111,8 +111,10 @@
 #major {...}
 
 # Econet module (Motorola 6854) (usually at bank 2 fiq 2)
-device ec: ifnet, arp
-attach ec at ioc
+device eca: fiq, eco, ifnet
+attach eca at ioc
+file   arch/arm26/ioc/if_eca.c                 eca
+file   arch/arm26/ioc/if_eca_fiq.S             eca
 
 # On-board Rockwell 6551 serial (usually at bank 3 irq 10/1)
 device rs: tty
diff -r bbf14cdb1bbc -r 482d164be5de sys/arch/arm26/ioc/if_eca.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm26/ioc/if_eca.c       Mon Sep 10 23:41:48 2001 +0000
@@ -0,0 +1,482 @@
+/*     $NetBSD: if_eca.c,v 1.1 2001/09/10 23:41:49 bjh21 Exp $ */
+
+/*-
+ * Copyright (c) 2001 Ben Harris
+ * All rights reserved.
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/param.h>
+
+__KERNEL_RCSID(0, "$NetBSD: if_eca.c,v 1.1 2001/09/10 23:41:49 bjh21 Exp $");
+
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_eco.h>
+
+#include <machine/bus.h>
+#include <machine/fiq.h>
+#include <machine/intr.h>
+#include <machine/machdep.h>
+
+#include <arch/arm26/iobus/iocvar.h>
+
+#include <dev/ic/mc6854reg.h>
+#include <arch/arm26/ioc/if_ecavar.h>
+
+static int eca_match(struct device *, struct cfdata *, void *);
+static void eca_attach(struct device *, struct device *, void *);
+
+static int eca_init(struct ifnet *);
+static void eca_stop(struct ifnet *ifp, int disable);
+
+static int eca_claimwire(struct ifnet *);
+static void eca_txframe(struct ifnet *, struct mbuf *);
+
+static void eca_tx_downgrade(void);
+static void eca_txdone(void *);
+
+static int eca_init_rxbuf(struct eca_softc *sc, int flags);
+static void eca_init_rx(struct eca_softc *sc);
+
+static void eca_rx_downgrade(void);
+static void eca_gotframe(void *);
+
+struct eca_softc *eca_fiqowner;
+
+struct cfattach eca_ca = {
+       sizeof(struct eca_softc), eca_match, eca_attach
+};
+
+static int
+eca_match(struct device *parent, struct cfdata *cf, void *aux)
+{
+       struct ioc_attach_args *ioc = aux;
+
+       /* Econet never uses LOOP mode. */
+       if ((bus_space_read_1(ioc->ioc_sync_t, ioc->ioc_sync_h, MC6854_SR1) &
+           MC6854_SR1_LOOP) != 0)
+               return 0;
+
+       return 1;
+}
+
+static void
+eca_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct eca_softc *sc = (void *)self;
+       struct ioc_attach_args *ioc = aux;
+       struct ifnet *ifp = &sc->sc_ec.ec_if;
+       u_int8_t myaddr[ECO_ADDR_LEN];
+
+       sc->sc_iot = ioc->ioc_sync_t;
+       sc->sc_ioh = ioc->ioc_sync_h;
+
+       myaddr[0] = cmos_read(0x40);
+       myaddr[1] = 0;
+
+       printf(": station %s", eco_sprintf(myaddr));
+       /* It's traditional to print the clock state at boot. */
+       if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, MC6854_SR2) &
+           MC6854_SR2_NDCD))
+               printf(", no clock");
+
+       /* Initialise ifnet structure. */
+
+       strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
+       ifp->if_softc = sc;
+       ifp->if_init = eca_init;
+       ifp->if_stop = eca_stop;
+       ifp->if_flags = IFF_SIMPLEX | IFF_NOTRAILERS;
+       IFQ_SET_READY(&ifp->if_snd);
+       sc->sc_ec.ec_claimwire = eca_claimwire;
+       sc->sc_ec.ec_txframe = eca_txframe;
+
+       sc->sc_rx_soft = softintr_establish(IPL_SOFTNET, eca_gotframe, sc);
+       sc->sc_tx_soft = softintr_establish(IPL_SOFTNET, eca_txdone, sc);
+       if (sc->sc_rx_soft == NULL || sc->sc_tx_soft == NULL) {
+               printf("\n%s: failed to establish software interrupt\n",
+                   sc->sc_dev.dv_xname);
+               return;
+       }
+
+       if_attach(ifp);
+       eco_ifattach(ifp, myaddr);
+
+       printf("\n");
+}
+
+static int
+eca_init(struct ifnet *ifp)
+{
+       struct eca_softc *sc = ifp->if_softc;
+       bus_space_tag_t iot = sc->sc_iot;
+       bus_space_handle_t ioh = sc->sc_ioh;
+       int sr1, sr2;
+       int err;
+
+       /* Claim the FIQ early, in case we don't get it. */
+       if (fiq_claim(eca_fiqhandler_rx,
+           eca_efiqhandler_rx - eca_fiqhandler_rx))
+               return EBUSY;
+
+       if (sc->sc_rcvmbuf == NULL) {
+               err = eca_init_rxbuf(sc, M_WAIT);
+               if (err != 0)
+                       return err;
+       }
+
+       sc->sc_transmitting = 0;
+
+       /* Interrupts disabled, no DMA, hold Tx and Rx in reset. */
+       sc->sc_cr1 = MC6854_CR1_RX_RS | MC6854_CR1_TX_RS;
+       /* 1-byte transfers, mark idle. */
+       sc->sc_cr2 = 0;
+       /* Nothing exciting. */
+       sc->sc_cr3 = 0;
+       /* single flag, 8 data bits, NRZ */
+       sc->sc_cr4 = MC6854_CR4_TX_WL_8BITS | MC6854_CR4_RX_WL_8BITS;
+
+       bus_space_write_1(iot, ioh, MC6854_CR1, sc->sc_cr1);
+       bus_space_write_1(iot, ioh, MC6854_CR2, sc->sc_cr2);
+       bus_space_write_1(iot, ioh, MC6854_CR1, sc->sc_cr1 | MC6854_CR1_AC);
+       bus_space_write_1(iot, ioh, MC6854_CR3, sc->sc_cr3);
+       bus_space_write_1(iot, ioh, MC6854_CR4, sc->sc_cr4);
+       bus_space_write_1(iot, ioh, MC6854_CR1, sc->sc_cr1);
+
+       /* Everything's set up.  Take chip out of reset. */
+       sc->sc_cr1 &= ~(MC6854_CR1_RX_RS | MC6854_CR1_TX_RS);
+       bus_space_write_1(iot, ioh, MC6854_CR1, sc->sc_cr1);
+
+       /* Read and clear status registers. */
+       sr1 = bus_space_read_1(iot, ioh, MC6854_SR1);
+       sr2 = bus_space_read_1(iot, ioh, MC6854_SR2);
+       bus_space_write_1(iot, ioh, MC6854_CR2, sc->sc_cr2 | 
+               MC6854_CR2_CLR_RX_ST | MC6854_CR2_CLR_TX_ST);
+
+       /* Set up FIQ registers and enable FIQs */
+       eca_init_rx(sc);
+
+       ifp->if_flags |= IFF_RUNNING;
+
+       return 0;
+}
+
+/*
+ * Check if the network's idle, and if it is, start flag-filling.
+ */
+static int
+eca_claimwire(struct ifnet *ifp)
+{
+       struct eca_softc *sc = ifp->if_softc;
+       bus_space_tag_t iot = sc->sc_iot;
+       bus_space_handle_t ioh = sc->sc_ioh;
+
+       if (bus_space_read_1(iot, ioh, MC6854_SR2) & MC6854_SR2_RX_IDLE) {
+               /* Start flag fill. */
+               sc->sc_cr2 |= MC6854_CR2_RTS | MC6854_CR2_F_M_IDLE;
+               bus_space_write_1(iot, ioh, MC6854_CR2, sc->sc_cr2);
+               return 0;
+       }
+       return EBUSY;
+}
+
+static void
+eca_txframe(struct ifnet *ifp, struct mbuf *m)
+{
+       struct eca_softc *sc = ifp->if_softc;
+       bus_space_tag_t iot = sc->sc_iot;
+       bus_space_handle_t ioh = sc->sc_ioh;
+       struct fiq_regs fr;
+
+       ioc_fiq_setmask(0);
+       /* Start flag-filling while we work out what to do next. */
+       sc->sc_cr2 |= MC6854_CR2_RTS | MC6854_CR2_F_M_IDLE;
+       bus_space_write_1(iot, ioh, MC6854_CR2, sc->sc_cr2);
+       fiq_installhandler(eca_fiqhandler_tx,
+           eca_efiqhandler_tx - eca_fiqhandler_tx);
+       sc->sc_transmitting = 1;
+       sc->sc_txmbuf = m;
+       fr.r8_fiq = (register_t)sc->sc_ioh.a1;
+       fr.r9_fiq = (register_t)sc->sc_txmbuf->m_data;
+       fr.r10_fiq = (register_t)sc->sc_txmbuf->m_len;
+       fr.r11_fiq = (register_t)&sc->sc_txstate;
+       fiq_setregs(&fr);
+       sc->sc_txstate.etx_curmbuf = sc->sc_txmbuf;
+       fiq_downgrade_handler = eca_tx_downgrade;
+       /* Read and clear Tx status. */
+       bus_space_read_1(iot, ioh, MC6854_SR1);
+       bus_space_write_1(iot, ioh, MC6854_CR2,
+           sc->sc_cr2 | MC6854_CR2_CLR_TX_ST);
+       sc->sc_cr1 = MC6854_CR1_TIE;
+       bus_space_write_1(iot, ioh, MC6854_CR1, sc->sc_cr1 |
+           MC6854_CR1_DISCONTINUE);
+       ioc_fiq_setmask(IOC_FIQ_BIT(FIQ_EFIQ));
+}
+
+static void
+eca_tx_downgrade(void)
+{
+       struct eca_softc *sc = eca_fiqowner;
+       bus_space_tag_t iot = sc->sc_iot;
+       bus_space_handle_t ioh = sc->sc_ioh;



Home | Main Index | Thread Index | Old Index