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