Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/qbus Driver for the DELQA-PLUS card in Turbo mode, f...
details: https://anonhg.NetBSD.org/src/rev/5aa04a389736
branches: trunk
changeset: 551052:5aa04a389736
user: ragge <ragge%NetBSD.org@localhost>
date: Thu Aug 28 10:03:32 2003 +0000
description:
Driver for the DELQA-PLUS card in Turbo mode, from 2.11BSD, written by
Steven M. Schultz.
diffstat:
sys/dev/qbus/if_qt.c | 920 ++++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/qbus/if_qtreg.h | 208 ++++++++++
2 files changed, 1128 insertions(+), 0 deletions(-)
diffs (truncated from 1136 to 300 lines):
diff -r 6a228297d1b2 -r 5aa04a389736 sys/dev/qbus/if_qt.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/qbus/if_qt.c Thu Aug 28 10:03:32 2003 +0000
@@ -0,0 +1,920 @@
+/* $NetBSD: if_qt.c,v 1.1 2003/08/28 10:03:32 ragge Exp $ */
+/*
+ * Copyright (c) 1992 Steven M. Schultz
+ * 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.
+ *
+ * @(#)if_qt.c 1.2 (2.11BSD) 2/20/93
+ */
+/*
+ *
+ * Modification History
+ * 23-Feb-92 -- sms
+ * Rewrite the buffer handling so that fewer than the maximum number of
+ * buffers may be used (32 receive and 12 transmit buffers consume 66+kb
+ * of main system memory in addition to the internal structures in the
+ * networking code). A freelist of available buffers is maintained now.
+ * When I/O operations complete the associated buffer is placed on the
+ * freelist (a single linked list for simplicity) and when an I/O is
+ * started a buffer is pulled off the list.
+ *
+ * 20-Feb-92 -- sms
+ * It works! Darned board couldn't handle "short" rings - those rings
+ * where only half the entries were made available to the board (the
+ * ring descriptors were the full size, merely half the entries were
+ * flagged as belonging always to the driver). Grrrr. Would have thought
+ * the board could skip over those entries reserved by the driver.
+ * Now to find a way not to have to allocated 32+12 times 1.5kb worth of
+ * buffers...
+ *
+ * 03-Feb-92 -- sms
+ * Released but still not working. The driver now responds to arp and
+ * ping requests. The board is apparently not returning ring descriptors
+ * to the driver so eventually we run out of buffers. Back to the
+ * drawing board.
+ *
+ * 28-Dec-92 -- sms
+ * Still not released. Hiatus in finding free time and thin-netting
+ * the systems (many thanks Terry!).
+ * Added logic to dynamically allocate a vector and initialize it.
+ *
+ * 23-Oct-92 -- sms
+ * The INIT block must (apparently) be quadword aligned [no thanks to
+ * the manual for not mentioning that fact]. The necessary alignment
+ * is achieved by allocating the INIT block from main memory ('malloc'
+ * guarantees click alignment) and mapping it as needed (which is _very_
+ * infrequently). A check for quadword alignment of the ring descriptors
+ * was added - at present the descriptors are properly aligned, if this
+ * should change then something will have to be done (like do it "right").
+ * Darned alignment restrictions!
+ *
+ * A couple of typos were corrected (missing parentheses, reversed
+ * arguments to printf calls, etc).
+ *
+ * 13-Oct-92 -- sms%wlv.iipo.gtegsc.com@localhost
+ * Created based on the DELQA-PLUS addendum to DELQA User's Guide.
+ * This driver ('qt') is selected at system configuration time. If the
+ * board * is not a DELQA-YM an error message will be printed and the
+ * interface will not be attached.
+*/
+
+#include "qt.h"
+#if NQT > 0
+
+#include "param.h"
+#include "pdp/psl.h"
+#include "pdp/seg.h"
+#include "map.h"
+#include "systm.h"
+#include "mbuf.h"
+#include "buf.h"
+#include "protosw.h"
+#include "socket.h"
+#include "ioctl.h"
+#include "errno.h"
+#include "syslog.h"
+#include "time.h"
+#include "kernel.h"
+
+#include "../net/if.h"
+#include "../net/netisr.h"
+#include "../net/route.h"
+
+#ifdef INET
+#include "domain.h"
+#include "../netinet/in.h"
+#include "../netinet/in_systm.h"
+#include "../netinet/in_var.h"
+#include "../netinet/ip.h"
+#include "../netinet/if_ether.h"
+#endif
+
+#ifdef NS
+#include "../netns/ns.h"
+#include "../netns/ns_if.h"
+#endif
+
+#include "if_qtreg.h"
+#include "if_uba.h"
+#include "../pdpuba/ubavar.h"
+
+#define NRCV 16 /* Receive descriptors (must be <= 32) */
+#define NXMT 6 /* Transmit descriptors (must be <= 12) */
+#if NRCV > 32 || NXMT > 12
+ generate an error
+#endif
+
+ struct qt_uba
+ {
+ struct qt_uba *next; /* link to next buffer in list or
+ * NULL if the last buffer
+ */
+ struct ifuba ubabuf; /* buffer descriptor */
+ };
+
+struct qt_softc {
+ struct arpcom is_ac; /* common part - must be first */
+#define is_if is_ac.ac_if /* network-visible interface */
+#define is_addr is_ac.ac_enaddr /* hardware Ethernet address */
+ struct qt_uba *freelist; /* list of available buffers */
+ struct qt_uba ifrw[NRCV + NXMT];
+ u_short initclick; /* click addr of the INIT block */
+ struct qt_rring *rring; /* Receive ring address */
+ struct qt_tring *tring; /* Transmit ring address */
+ char r_align[QT_MAX_RCV * sizeof (struct qt_rring) + 8];
+ char t_align[QT_MAX_XMT * sizeof (struct qt_tring) + 8];
+ short qt_flags; /* software state */
+#define QTF_RUNNING 0x1
+#define QTF_STARTUP 0x2 /* Waiting for start interrupt */
+ char rindex; /* Receive Completed Index */
+ char nxtrcv; /* Next Receive Index */
+ char nrcv; /* Number of Receives active */
+ char tindex; /* Transmit index */
+ char otindex; /* Old transmit index */
+ char nxmit; /* # of xmits in progress */
+ struct qtdevice *addr; /* device CSR addr */
+} qt_softc[NQT];
+
+struct uba_device *qtinfo[NQT];
+
+int qtattach(), qtintr(), qtinit(), qtoutput(), qtioctl();
+
+extern struct ifnet loif;
+
+u_short qtstd[] = { 0 };
+
+struct uba_driver qtdriver =
+ { 0, 0, qtattach, 0, qtstd, "qe", qtinfo };
+
+/*
+ * Maximum packet size needs to include 4 bytes for the CRC
+ * on received packets.
+*/
+#define MAXPACKETSIZE (ETHERMTU + sizeof (struct ether_header) + 4)
+#define MINPACKETSIZE 64
+
+/*
+ * The C compiler's propensity for prepending '_'s to names is the reason
+ * for the hack below. We need the "handler" address (the code which
+ * sets up the interrupt stack frame) in order to initialize the vector.
+*/
+
+static int qtfoo()
+ {
+ asm("mov $qtintr, r0"); /* return value is in r0 */
+ }
+
+/*
+ * Interface exists. More accurately, something exists at the CSR (see
+ * sys/sys_net.c) -- there's no guarantee it's a DELQA-YM.
+ *
+ * The ring descriptors are initialized, the buffers allocated using first the
+ * DMA region allocated at network load time and then later main memory. The
+ * INIT block is filled in and the device is poked/probed to see if it really
+ * is a DELQA-YM. If the device is not a -YM then a message is printed and
+ * the 'if_attach' call is skipped. For a -YM the START command is issued,
+ * but the device is not marked as running|up - that happens at interrupt level
+ * when the device interrupts to say it has started.
+*/
+
+qtattach(ui)
+ struct uba_device *ui;
+ {
+ register struct qt_softc *sc = &qt_softc[ui->ui_unit];
+ register struct ifnet *ifp = &sc->is_if;
+ register struct qt_init *iniblk = (struct qt_init *)SEG5;
+ segm seg5;
+ long bufaddr;
+ extern int nextiv();
+
+ ifp->if_unit = ui->ui_unit;
+ ifp->if_name = "qe";
+ ifp->if_mtu = ETHERMTU;
+ ifp->if_flags = IFF_BROADCAST;
+
+/*
+ * Fill in most of the INIT block: vector, options (interrupt enable), ring
+ * locations. The physical address is copied from the ROMs as part of the
+ * -YM testing proceedure. The CSR is saved here rather than in qtinit()
+ * because the qtturbo() routine needs it.
+ *
+ * The INIT block must be quadword aligned. Using malloc() guarantees click
+ * (64 byte) alignment. Since the only time the INIT block is referenced is
+ * at 'startup' or 'reset' time there is really no time penalty (and a modest
+ * D space savings) involved.
+*/
+ sc->addr = (struct qtdevice *)ui->ui_addr;
+ sc->initclick = MALLOC(coremap, btoc(sizeof (struct qt_init)));
+ saveseg5(seg5);
+ mapseg5(sc->initclick, 077406);
+ bzero(iniblk, sizeof (struct qt_init));
+ sc->rring = (struct qt_rring *)(((int)sc->r_align + 7) & ~7);
+ sc->tring = (struct qt_tring *)(((int)sc->t_align + 7) & ~7);
+
+/*
+ * Fetch the next available interrupt vector. The routine is in the kernel
+ * (for several reasons) so use SKcall. Then initialize the vector with
+ * the address of our 'handler' and PSW of supervisor, priority 4 and unit
+*/
+ iniblk->vector = SKcall(nextiv, 0);
+ mtkd(iniblk->vector, qtfoo());
+ mtkd(iniblk->vector + 2, PSL_CURSUP | PSL_BR4 | ifp->if_unit);
+
+ iniblk->options = INIT_OPTIONS_INT;
+ bufaddr = startnet + (long)sc->rring;
+ iniblk->rx_lo = loint(bufaddr);
+ iniblk->rx_hi = hiint(bufaddr);
+ bufaddr = startnet + (long)sc->tring;
+ iniblk->tx_lo = loint(bufaddr);
+ iniblk->tx_hi = hiint(bufaddr);
+ restorseg5(seg5);
+
+/*
+ * Now allocate the buffers and initialize the buffers. This should _never_
+ * fail because main memory is allocated after the DMA pool is used up.
+*/
+
+ if (!qbaini(sc, NRCV + NXMT))
+ return; /* XXX */
+
+ ifp->if_init = qtinit;
+ ifp->if_output = qtoutput;
+ ifp->if_ioctl = qtioctl;
+ ifp->if_reset = 0;
+ if (qtturbo(sc))
+ if_attach(ifp);
+ }
+
+qtturbo(sc)
+ register struct qt_softc *sc;
+ {
+ register int i;
+ register struct qtdevice *addr = sc->addr;
+ struct qt_init *iniblk = (struct qt_init *)SEG5;
+ segm seg5;
+
+/*
+ * Issue the software reset. Delay 150us. The board should now be in
+ * DELQA-Normal mode. Set ITB and DEQTA select. If both bits do not
+ * stay turned on then the board is not a DELQA-YM.
+*/
+ addr->arqr = ARQR_SR;
+ addr->arqr = 0;
+ delay(150L);
+
+ addr->srr = 0x8001; /* MS | ITB */
+ i = addr->srr;
+ addr->srr = 0x8000; /* Turn off ITB, set DELQA select */
+ if (i != 0x8001)
+ {
+ printf("qt@%o !-YM\n", addr);
+ return(0);
+ }
+/*
+ * Board is a DELQA-YM. Send the commands to enable Turbo mode. Delay
+ * 1 second, testing the SRR register every millisecond to see if the
Home |
Main Index |
Thread Index |
Old Index