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