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