Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Driver for Winbond W6692 passive ISDN cards.
details: https://anonhg.NetBSD.org/src/rev/f27f8a050e7d
branches: trunk
changeset: 536964:f27f8a050e7d
user: pooka <pooka%NetBSD.org@localhost>
date: Tue Sep 24 22:05:19 2002 +0000
description:
Driver for Winbond W6692 passive ISDN cards.
Ported from the FreeBSD driver by Ilpo Ruotsalainen <lonewolf%cubical.fi@localhost>,
and reviewed by Martin.
diffstat:
sys/dev/pci/files.pci | 10 +-
sys/dev/pci/iwic_bchan.c | 765 +++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/pci/iwic_dchan.c | 462 ++++++++++++++++++++++++++++
sys/dev/pci/iwic_fsm.c | 226 +++++++++++++
sys/dev/pci/iwic_pci.c | 448 +++++++++++++++++++++++++++
sys/dev/pci/iwicreg.h | 264 ++++++++++++++++
sys/dev/pci/iwicvar.h | 200 ++++++++++++
7 files changed, 2374 insertions(+), 1 deletions(-)
diffs (truncated from 2413 to 300 lines):
diff -r bb15c826560d -r f27f8a050e7d sys/dev/pci/files.pci
--- a/sys/dev/pci/files.pci Tue Sep 24 21:57:20 2002 +0000
+++ b/sys/dev/pci/files.pci Tue Sep 24 22:05:19 2002 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.pci,v 1.177 2002/09/03 18:54:41 augustss Exp $
+# $NetBSD: files.pci,v 1.178 2002/09/24 22:05:19 pooka Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@@ -552,6 +552,14 @@
attach ifpci at pci
file dev/pci/ifpci.c ifpci
+# Winbond W6692
+device iwic: isdndev, passive_isdn
+attach iwic at pci with iwic_pci
+file dev/pci/iwic_pci.c iwic
+file dev/pci/iwic_bchan.c iwic
+file dev/pci/iwic_dchan.c iwic
+file dev/pci/iwic_fsm.c iwic
+
# IrDA devices
# Toshiba Fast Infrared Type O IrDA driver
device oboe: irbus, irdasir
diff -r bb15c826560d -r f27f8a050e7d sys/dev/pci/iwic_bchan.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/iwic_bchan.c Tue Sep 24 22:05:19 2002 +0000
@@ -0,0 +1,765 @@
+/* $NetBSD: iwic_bchan.c,v 1.1 2002/09/24 22:05:19 pooka Exp $ */
+
+/*
+ * Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
+ *
+ * Copyright (c) 2000, 2001 Hellmuth Michaelis. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * i4b_iwic - isdn4bsd Winbond W6692 driver
+ * ----------------------------------------
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Tue Jan 16 13:21:24 2001]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: iwic_bchan.c,v 1.1 2002/09/24 22:05:19 pooka Exp $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/callout.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#include <net/if.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/iwicreg.h>
+#include <dev/pci/iwicvar.h>
+
+#include <netisdn/i4b_debug.h>
+#include <netisdn/i4b_ioctl.h>
+#include <netisdn/i4b_trace.h>
+
+#include <netisdn/i4b_l2.h>
+#include <netisdn/i4b_l1l2.h>
+#include <netisdn/i4b_mbuf.h>
+#include <netisdn/i4b_global.h>
+
+static void iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate);
+
+/*---------------------------------------------------------------------------*
+ * B-channel interrupt handler
+ *---------------------------------------------------------------------------*/
+void
+iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
+{
+ int irq_stat;
+ struct iwic_bchan *chan;
+ int cmd = 0;
+ int activity = 0;
+
+ chan = &sc->sc_bchan[chan_no];
+
+ irq_stat = IWIC_READ(sc, chan->offset + B_EXIR);
+
+ NDBGL1(L1_H_IRQ, "irq_stat = 0x%x", irq_stat);
+
+ if((irq_stat & (B_EXIR_RMR | B_EXIR_RME | B_EXIR_RDOV | B_EXIR_XFR | B_EXIR_XDUN)) == 0)
+ {
+ NDBGL1(L1_H_XFRERR, "spurious IRQ!");
+ return;
+ }
+
+ if (irq_stat & B_EXIR_RDOV)
+ {
+ NDBGL1(L1_H_XFRERR, "%s: EXIR B-channel Receive Data Overflow", sc->sc_dev.dv_xname);
+ }
+
+ if (irq_stat & B_EXIR_XDUN)
+ {
+ NDBGL1(L1_H_XFRERR, "%s: EXIR B-channel Transmit Data Underrun", sc->sc_dev.dv_xname);
+ cmd |= (B_CMDR_XRST); /*XXX must retransmit frame ! */
+ }
+
+/* RX message end interrupt */
+
+ if(irq_stat & B_EXIR_RME)
+ {
+ int error;
+
+ NDBGL1(L1_H_IRQ, "B_EXIR_RME");
+
+ error = (IWIC_READ(sc,chan->offset+B_STAR) &
+ (B_STAR_RDOV | B_STAR_CRCE | B_STAR_RMB));
+
+ if(error)
+ {
+ if(error & B_STAR_RDOV)
+ NDBGL1(L1_H_XFRERR, "%s: B-channel Receive Data Overflow", sc->sc_dev.dv_xname);
+ if(error & B_STAR_CRCE)
+ NDBGL1(L1_H_XFRERR, "%s: B-channel CRC Error", sc->sc_dev.dv_xname);
+ if(error & B_STAR_RMB)
+ NDBGL1(L1_H_XFRERR, "%s: B-channel Receive Message Aborted", sc->sc_dev.dv_xname);
+ }
+
+ /* all error conditions checked, now decide and take action */
+
+ if(error == 0)
+ {
+ register int fifo_data_len;
+ fifo_data_len = ((IWIC_READ(sc,chan->offset+B_RBCL)) &
+ ((IWIC_BCHAN_FIFO_LEN)-1));
+
+ if(fifo_data_len == 0)
+ fifo_data_len = IWIC_BCHAN_FIFO_LEN;
+
+
+ if(chan->in_mbuf == NULL)
+ {
+ if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
+ panic("L1 iwic_bchan_irq: RME, cannot allocate mbuf!\n");
+ chan->in_cbptr = chan->in_mbuf->m_data;
+ chan->in_len = 0;
+ }
+
+ if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
+ {
+ /* read data from fifo */
+
+ NDBGL1(L1_H_IRQ, "B_EXIR_RME, rd fifo, len = %d", fifo_data_len);
+
+ IWIC_RDBFIFO(sc, chan, chan->in_cbptr, fifo_data_len);
+
+ cmd |= (B_CMDR_RACK | B_CMDR_RACT);
+ IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
+ cmd = 0;
+
+ chan->in_len += fifo_data_len;
+ chan->rxcount += fifo_data_len;
+
+ /* setup mbuf data length */
+
+ chan->in_mbuf->m_len = chan->in_len;
+ chan->in_mbuf->m_pkthdr.len = chan->in_len;
+
+ if(sc->sc_trace & TRACE_B_RX)
+ {
+ i4b_trace_hdr hdr;
+ hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_NT;
+ hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
+ isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr,chan->in_mbuf->m_len, chan->in_mbuf->m_data);
+ }
+
+ (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
+
+
+ activity = ACT_RX;
+
+ /* mark buffer ptr as unused */
+
+ chan->in_mbuf = NULL;
+ chan->in_cbptr = NULL;
+ chan->in_len = 0;
+ }
+ else
+ {
+ NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
+ chan->in_cbptr = chan->in_mbuf->m_data;
+ chan->in_len = 0;
+ cmd |= (B_CMDR_RRST | B_CMDR_RACK);
+ }
+ }
+ else
+ {
+ if (chan->in_mbuf != NULL)
+ {
+ i4b_Bfreembuf(chan->in_mbuf);
+ chan->in_mbuf = NULL;
+ chan->in_cbptr = NULL;
+ chan->in_len = 0;
+ }
+ cmd |= (B_CMDR_RRST | B_CMDR_RACK);
+ }
+ }
+
+/* RX fifo full interrupt */
+
+ if(irq_stat & B_EXIR_RMR)
+ {
+ NDBGL1(L1_H_IRQ, "B_EXIR_RMR");
+
+ if(chan->in_mbuf == NULL)
+ {
+ if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
+ panic("L1 iwic_bchan_irq: RMR, cannot allocate mbuf!\n");
+ chan->in_cbptr = chan->in_mbuf->m_data;
+ chan->in_len = 0;
+ }
+
+ chan->rxcount += IWIC_BCHAN_FIFO_LEN;
+
+ if((chan->in_len + IWIC_BCHAN_FIFO_LEN) <= BCH_MAX_DATALEN)
+ {
+ /* read data from fifo */
+
+ NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo, len = max (64)");
+
+ IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
+
+ chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
+ chan->in_len += IWIC_BCHAN_FIFO_LEN;
+ }
+ else
+ {
+ if(chan->bprot == BPROT_NONE)
+ {
+ /* setup mbuf data length */
+
+ chan->in_mbuf->m_len = chan->in_len;
+ chan->in_mbuf->m_pkthdr.len = chan->in_len;
+
+ if(sc->sc_trace & TRACE_B_RX)
+ {
+ i4b_trace_hdr hdr;
+ hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
+ hdr.dir = FROM_NT;
+ hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
+ isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr,chan->in_mbuf->m_len, chan->in_mbuf->m_data);
+ }
+
+ /* silence detection */
+
+ if(!(isdn_bchan_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
+ activity = ACT_RX;
+
+#if defined (__FreeBSD__) && __FreeBSD__ > 4
+ (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
+#else
+ if(!(IF_QFULL(&chan->rx_queue)))
+ {
+ IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
+ }
+ else
+ {
+ i4b_Bfreembuf(chan->in_mbuf);
+ }
+#endif
+ /* signal upper driver that data is available */
+
+ (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
Home |
Main Index |
Thread Index |
Old Index