Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic convert to support non-dma IO (for the isa Riscom...



details:   https://anonhg.NetBSD.org/src/rev/a85137c25ced
branches:  trunk
changeset: 480109:a85137c25ced
user:      chopps <chopps%NetBSD.org@localhost>
date:      Tue Jan 04 06:36:29 2000 +0000

description:
convert to support non-dma IO (for the isa Riscom/N2).
allow the user to set and use the internal baud rate generator
fix the transmission ring logic to support more than 1 frame per interrupt
add autodetection of the base clock frequency.
cleanup the receive ring logic
support dynamically resizing the low-water mark on the fifo in response
        to buffer underruns on transmit.

diffstat:

 sys/dev/ic/hd64570.c    |  1340 +++++++++++++++++++++++++++++-----------------
 sys/dev/ic/hd64570reg.h |   205 +++++-
 sys/dev/ic/hd64570var.h |   137 +++-
 3 files changed, 1099 insertions(+), 583 deletions(-)

diffs (truncated from 2402 to 300 lines):

diff -r 97201eca7c0e -r a85137c25ced sys/dev/ic/hd64570.c
--- a/sys/dev/ic/hd64570.c      Tue Jan 04 06:31:39 2000 +0000
+++ b/sys/dev/ic/hd64570.c      Tue Jan 04 06:36:29 2000 +0000
@@ -1,6 +1,7 @@
-/*     $NetBSD: hd64570.c,v 1.7 1999/10/23 22:20:11 erh Exp $  */
+/*     $NetBSD: hd64570.c,v 1.8 2000/01/04 06:36:29 chopps Exp $       */
 
 /*
+ * Copyright (c) 1999 Christian E. Hopps
  * Copyright (c) 1998 Vixie Enterprises
  * All rights reserved.
  *
@@ -37,34 +38,6 @@
  */
 
 /*
- * hd64570:
- *     From the hitachi docs:
- *     The HD64570 serial communications adaptor (SCA) peripheral chip enables
- *     a host microprocessor to perform asynchronous, byte-synchronous, or
- *     bit-synchronous serial communication.  Its two full-duplex,
- *     multiprotocol serial channels support a wide variety of protocols,
- *     including frame relay, LAPB, LAPD, bisync and DDCMP.  Its build-in
- *     direct memory access controller (DMAC) is equipped with a 32-stage
- *     FIFO and can execure chained-block transfers.  Due to its DMAC and
- *     16-bit bus interface, the SCA supports serial data transfer rates up
- *     to 12 Mbits/s without monopolizing the bus, even in full-duplex
- *     communication.  Other on-chip features of the SCA, including four
- *     types of MPU interfaces, a bus arbiter, timers, and an interrupt
- *     controller, provide added functionality in a wide range of
- *     applications, such as frame relay exchanges/system multiplexes, private
- *     branch exchanges, computer networks, workstations, ISDN terminals,
- *     and facsimile.
- *
- *     For more info: http://semiconductor.hitachi.com
- *     ----
- *
- *     This driver not only talks to the HD64570 chip, but also implements
- *     a version of the HDLC protocol that includes the CISCO keepalive
- *     protocol.  It publishes itself as a network interface that can
- *     handle IP traffic only.
- */
-
-/*
  * TODO:
  *
  *     o  teach the receive logic about errors, and about long frames that
@@ -85,6 +58,10 @@
  *        a single descriptor.
  *     o  use bus_dmamap_sync() with the right offset and lengths, rather
  *        than cheating and always sync'ing the whole region.
+ *
+ *     o  perhaps allow rx and tx to be in more than one page
+ *        if not using dma.  currently the assumption is that
+ *        rx uses a page and tx uses a page.
  */
 
 #include "bpfilter.h"
@@ -128,9 +105,10 @@
 #define SCA_DEBUG_RXPKT                0x0010
 #define SCA_DEBUG_TXPKT                0x0020
 #define SCA_DEBUG_INTR         0x0040
+#define SCA_DEBUG_CLOCK                0x0080
 
 #if 0
-#define SCA_DEBUG_LEVEL        ( SCA_DEBUG_TX )
+#define SCA_DEBUG_LEVEL        ( 0xFFFF )
 #else
 #define SCA_DEBUG_LEVEL 0
 #endif
@@ -146,37 +124,10 @@
 #define SCA_DPRINTF(l, x)
 #endif
 
-#define SCA_MTU                1500    /* hard coded */
-
-/*
- * buffers per tx and rx channels, per port, and the size of each.
- * Don't use these constants directly, as they are really only hints.
- * Use the calculated values stored in struct sca_softc instead.
- *
- * Each must be at least 2, receive would be better at around 20 or so.
- *
- * XXX Due to a damned near impossible to track down bug, transmit buffers
- * MUST be 2, no more, no less.
- */
-#ifndef SCA_NtxBUFS
-#define SCA_NtxBUFS    2
-#endif
-#ifndef SCA_NrxBUFS
-#define SCA_NrxBUFS    20
-#endif
-#ifndef SCA_BSIZE
-#define SCA_BSIZE      (SCA_MTU + 4)   /* room for HDLC as well */
-#endif
-
 #if 0
 #define SCA_USE_FASTQ          /* use a split queue, one for fast traffic */
 #endif
 
-static inline void sca_write_1(struct sca_softc *, u_int, u_int8_t);
-static inline void sca_write_2(struct sca_softc *, u_int, u_int16_t);
-static inline u_int8_t sca_read_1(struct sca_softc *, u_int);
-static inline u_int16_t sca_read_2(struct sca_softc *, u_int);
-
 static inline void msci_write_1(sca_port_t *, u_int, u_int8_t);
 static inline u_int8_t msci_read_1(sca_port_t *, u_int);
 
@@ -185,19 +136,17 @@
 static inline u_int8_t dmac_read_1(sca_port_t *, u_int);
 static inline u_int16_t dmac_read_2(sca_port_t *, u_int);
 
-static int sca_alloc_dma(struct sca_softc *);
-static void sca_setup_dma_memory(struct sca_softc *);
 static void sca_msci_init(struct sca_softc *, sca_port_t *);
 static void sca_dmac_init(struct sca_softc *, sca_port_t *);
 static void sca_dmac_rxinit(sca_port_t *);
 
 static int sca_dmac_intr(sca_port_t *, u_int8_t);
-static int sca_msci_intr(struct sca_softc *, u_int8_t);
+static int sca_msci_intr(sca_port_t *, u_int8_t);
 
 static void sca_get_packets(sca_port_t *);
-static void sca_frame_process(sca_port_t *, sca_desc_t *, u_int8_t *);
-static int sca_frame_avail(sca_port_t *, int *);
-static void sca_frame_skip(sca_port_t *, int);
+static int sca_frame_avail(sca_port_t *);
+static void sca_frame_process(sca_port_t *);
+static void sca_frame_read_done(sca_port_t *);
 
 static void sca_port_starttx(sca_port_t *);
 
@@ -210,35 +159,19 @@
 static void sca_start __P((struct ifnet *));
 static void sca_watchdog __P((struct ifnet *));
 
-static struct mbuf *sca_mbuf_alloc(caddr_t, u_int);
+static struct mbuf *sca_mbuf_alloc(struct sca_softc *, caddr_t, u_int);
 
 #if SCA_DEBUG_LEVEL > 0
 static void sca_frame_print(sca_port_t *, sca_desc_t *, u_int8_t *);
 #endif
 
-static inline void
-sca_write_1(struct sca_softc *sc, u_int reg, u_int8_t val)
-{
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, SCADDR(reg), val);
-}
-
-static inline void
-sca_write_2(struct sca_softc *sc, u_int reg, u_int16_t val)
-{
-       bus_space_write_2(sc->sc_iot, sc->sc_ioh, SCADDR(reg), val);
-}
 
-static inline u_int8_t
-sca_read_1(struct sca_softc *sc, u_int reg)
-{
-       return bus_space_read_1(sc->sc_iot, sc->sc_ioh, SCADDR(reg));
-}
+#define        sca_read_1(sc, reg)             (sc)->sc_read_1(sc, reg)
+#define        sca_read_2(sc, reg)             (sc)->sc_read_2(sc, reg)
+#define        sca_write_1(sc, reg, val)       (sc)->sc_write_1(sc, reg, val)
+#define        sca_write_2(sc, reg, val)       (sc)->sc_write_2(sc, reg, val)
 
-static inline u_int16_t
-sca_read_2(struct sca_softc *sc, u_int reg)
-{
-       return bus_space_read_2(sc->sc_iot, sc->sc_ioh, SCADDR(reg));
-}
+#define        sca_page_addr(sc, addr) ((bus_addr_t)(addr) & (sc)->scu_pagemask)
 
 static inline void
 msci_write_1(sca_port_t *scp, u_int reg, u_int8_t val)
@@ -276,26 +209,131 @@
        return sca_read_2(scp->sca, scp->dmac_off + reg);
 }
 
-int
-sca_init(struct sca_softc *sc, u_int nports)
+/*
+ * read the chain pointer
+ */
+static inline u_int16_t
+sca_desc_read_chainp(struct sca_softc *sc, struct sca_desc *dp)
+{
+       if (sc->sc_usedma)
+               return ((dp)->sd_chainp);
+       return (bus_space_read_2(sc->scu_memt, sc->scu_memh,
+           sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_chainp)));
+}
+
+/*
+ * write the chain pointer
+ */
+static inline void
+sca_desc_write_chainp(struct sca_softc *sc, struct sca_desc *dp, u_int16_t cp)
+{
+       if (sc->sc_usedma)
+               (dp)->sd_chainp = cp;
+       else
+               bus_space_write_2(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp)
+                   + offsetof(struct sca_desc, sd_chainp), cp);
+}
+
+/*
+ * read the buffer pointer
+ */
+static inline u_int32_t
+sca_desc_read_bufp(struct sca_softc *sc, struct sca_desc *dp)
+{
+       u_int32_t address;
+
+       if (sc->sc_usedma)
+               address = dp->sd_bufp | dp->sd_hbufp << 16;
+       else {
+               address = bus_space_read_2(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_bufp));
+               address |= bus_space_read_1(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp)
+                   + offsetof(struct sca_desc, sd_hbufp)) << 16;
+       }
+       return (address);
+}
+
+/*
+ * write the buffer pointer
+ */
+static inline void
+sca_desc_write_bufp(struct sca_softc *sc, struct sca_desc *dp, u_int32_t bufp)
+{
+       if (sc->sc_usedma) {
+               dp->sd_bufp = bufp & 0xFFFF;
+               dp->sd_hbufp = (bufp & 0x00FF0000) >> 16;
+       } else {
+               bus_space_write_2(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_bufp),
+                   bufp & 0xFFFF);
+               bus_space_write_1(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_hbufp),
+                   (bufp & 0x00FF0000) >> 16);
+       }
+}
+
+/*
+ * read the buffer length
+ */
+static inline u_int16_t
+sca_desc_read_buflen(struct sca_softc *sc, struct sca_desc *dp)
+{
+       if (sc->sc_usedma)
+               return ((dp)->sd_buflen);
+       return (bus_space_read_2(sc->scu_memt, sc->scu_memh,
+           sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_buflen)));
+}
+           
+/*
+ * write the buffer length
+ */
+static inline void
+sca_desc_write_buflen(struct sca_softc *sc, struct sca_desc *dp, u_int16_t len)
+{
+       if (sc->sc_usedma)
+               (dp)->sd_buflen = len;
+       else
+               bus_space_write_2(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp)
+                   + offsetof(struct sca_desc, sd_buflen), len);
+}
+
+/*
+ * read the descriptor status
+ */
+static inline u_int8_t
+sca_desc_read_stat(struct sca_softc *sc, struct sca_desc *dp)
+{
+       if (sc->sc_usedma)
+               return ((dp)->sd_stat);
+       return (bus_space_read_1(sc->scu_memt, sc->scu_memh,
+           sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_stat)));
+}
+
+/*
+ * write the descriptor status
+ */
+static inline void
+sca_desc_write_stat(struct sca_softc *sc, struct sca_desc *dp, u_int8_t stat)
+{
+       if (sc->sc_usedma)
+               (dp)->sd_stat = stat;
+       else
+               bus_space_write_1(sc->scu_memt, sc->scu_memh,
+                   sca_page_addr(sc, dp) + offsetof(struct sca_desc, sd_stat),
+                   stat);
+}
+
+void
+sca_init(struct sca_softc *sc)
 {



Home | Main Index | Thread Index | Old Index