summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhm <hm@FreeBSD.org>2001-01-21 10:12:50 +0000
committerhm <hm@FreeBSD.org>2001-01-21 10:12:50 +0000
commit9c4d942508aa142dc84c8dffc05cafeb76564b71 (patch)
treebd4d0aee922cfac6cb59e45ee3e1384a1c0298bf
parent7e6a9379747e18efa22fdb285658e4641d2718cf (diff)
downloadFreeBSD-src-9c4d942508aa142dc84c8dffc05cafeb76564b71.zip
FreeBSD-src-9c4d942508aa142dc84c8dffc05cafeb76564b71.tar.gz
Update the iwic driver: fix error handling for rx errors on the D-channel
which prevents erroneous packets from being put onto the protocol stack; enhance error detection for B-channel HDLC errors; remove old cvs id´s.
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic.h4
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_bchan.c39
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_dchan.c145
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_ext.h6
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_fsm.c4
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_l1if.c4
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_pci.c8
-rw-r--r--sys/i4b/layer1/iwic/i4b_w6692.h4
8 files changed, 103 insertions, 111 deletions
diff --git a/sys/i4b/layer1/iwic/i4b_iwic.h b/sys/i4b/layer1/iwic/i4b_iwic.h
index 1da90d7..183bee3 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic.h
+++ b/sys/i4b/layer1/iwic/i4b_iwic.h
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_iwic.h,v 1.5 2000/03/13 15:23:43 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Mon Mar 13 16:23:15 2000]
+ * last edit-date: [Sun Jan 21 11:08:44 2001]
*
*---------------------------------------------------------------------------*/
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
index a636f24..5e6948f 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
@@ -31,7 +31,7 @@
*
* $FreeBSD$
*
- * last edit-date: [Fri Jan 12 16:57:01 2001]
+ * last edit-date: [Tue Jan 16 13:21:24 2001]
*
*---------------------------------------------------------------------------*/
@@ -88,33 +88,48 @@ iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
if (irq_stat & B_EXIR_RDOV)
{
- NDBGL1(L1_H_XFRERR, "RDOV");
+ NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Receive Data Overflow", sc->sc_unit);
}
if (irq_stat & B_EXIR_XDUN)
{
- NDBGL1(L1_H_XFRERR, "XDUN");
+ NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Transmit Data Underrun", sc->sc_unit);
+ cmd |= (B_CMDR_XRST); /*XXX must retransmit frame ! */
}
/* RX message end interrupt */
if(irq_stat & B_EXIR_RME)
{
-/* XXXX */ int error = 0;
- register int fifo_data_len;
+ int error;
NDBGL1(L1_H_IRQ, "B_EXIR_RME");
-
- 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;
+
+ 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, "iwic%d: B-channel Receive Data Overflow", sc->sc_unit);
+ if(error & B_STAR_CRCE)
+ NDBGL1(L1_H_XFRERR, "iwic%d: B-channel CRC Error", sc->sc_unit);
+ if(error & B_STAR_RMB)
+ NDBGL1(L1_H_XFRERR, "iwic%d: B-channel Receive Message Aborted", sc->sc_unit);
+ }
/* 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)
@@ -684,7 +699,7 @@ iwic_bchannel_start(int unit, int chan_no)
}
/*---------------------------------------------------------------------------*
- *
+ * return B-channel statistics
*---------------------------------------------------------------------------*/
static void
iwic_bchannel_stat(int unit, int chan_no, bchan_statistics_t *bsp)
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_dchan.c b/sys/i4b/layer1/iwic/i4b_iwic_dchan.c
index e582d6f..d33dc29 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_dchan.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_dchan.c
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_iwic_dchan.c,v 1.5 2000/05/29 15:41:42 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Wed Mar 8 16:17:16 2000]
+ * last edit-date: [Tue Jan 16 13:20:14 2001]
*
*---------------------------------------------------------------------------*/
@@ -66,12 +64,8 @@
static void dchan_receive(struct iwic_softc *sc, int ista);
-#ifdef NOTDEF
-static void output_bytes(char *prefix, u_char * ptr, int len);
-#endif
-
/*---------------------------------------------------------------------------*
- *
+ * initialize D-channel variables and registers
*---------------------------------------------------------------------------*/
void
iwic_dchan_init(struct iwic_softc *sc)
@@ -106,7 +100,7 @@ iwic_dchan_init(struct iwic_softc *sc)
}
/*---------------------------------------------------------------------------*
- *
+ * Extended IRQ handler for the D-channel
*---------------------------------------------------------------------------*/
void
iwic_dchan_xirq(struct iwic_softc *sc)
@@ -119,6 +113,7 @@ iwic_dchan_xirq(struct iwic_softc *sc)
if (irq_stat & D_EXIR_RDOV)
{
NDBGL1(L1_I_ERR, "RDOV in state %s", iwic_printstate(sc));
+ IWIC_WRITE(sc, D_CMDR, D_CMDR_RRST);
}
if (irq_stat & D_EXIR_XDUN)
{
@@ -128,6 +123,7 @@ iwic_dchan_xirq(struct iwic_softc *sc)
if (irq_stat & D_EXIR_XCOL)
{
NDBGL1(L1_I_ERR, "XCOL in state %s", iwic_printstate(sc));
+ IWIC_WRITE(sc, D_CMDR, D_CMDR_XRST);
sc->sc_dchan.tx_ready = 0;
}
if (irq_stat & D_EXIR_TIN2)
@@ -226,7 +222,7 @@ iwic_dchan_xfer_irq(struct iwic_softc *sc, int ista)
}
/*---------------------------------------------------------------------------*
- *
+ * disable D-channel
*---------------------------------------------------------------------------*/
void
iwic_dchan_disable(struct iwic_softc *sc)
@@ -255,7 +251,7 @@ iwic_dchan_disable(struct iwic_softc *sc)
}
/*---------------------------------------------------------------------------*
- *
+ * queue D-channel message for transmission
*---------------------------------------------------------------------------*/
int
iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag)
@@ -297,7 +293,7 @@ iwic_dchan_data_req(struct iwic_softc *sc, struct mbuf *m, int freeflag)
}
/*---------------------------------------------------------------------------*
- *
+ * allocate an mbuf
*---------------------------------------------------------------------------*/
static void
dchan_get_mbuf(struct iwic_softc *sc, int len)
@@ -313,11 +309,13 @@ dchan_get_mbuf(struct iwic_softc *sc, int len)
}
/*---------------------------------------------------------------------------*
- *
+ * D-channel receive data interrupt
*---------------------------------------------------------------------------*/
static void
dchan_receive(struct iwic_softc *sc, int ista)
{
+ int command = D_CMDR_RACK;
+
if (ista & ISTA_D_RMR)
{
/* Got 64 bytes in FIFO */
@@ -330,7 +328,7 @@ dchan_receive(struct iwic_softc *sc, int ista)
else if ((sc->sc_dchan.ibuf_len + MAX_DFRAME_LEN) >
sc->sc_dchan.ibuf_max_len)
{
-/*XXX*/ panic("dchan_receive: not enough space in buffer!\n");
+ panic("dchan_receive: not enough space in buffer!\n");
}
IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, 64);
@@ -342,61 +340,69 @@ dchan_receive(struct iwic_softc *sc, int ista)
if (ista & ISTA_D_RME)
{
/* Got end of frame */
- int hi, lo;
- int total_frame_len;
int status;
- lo = IWIC_READ(sc, D_RBCL);
- hi = IWIC_READ(sc, D_RBCH);
- total_frame_len = D_RBC(hi, lo);
- lo = lo & 0x3f;
-
- if (lo == 0)
- lo = IWIC_DCHAN_FIFO_LEN;
-
- if (!sc->sc_dchan.ibuf)
- {
- dchan_get_mbuf(sc, lo);
- }
- else if ((sc->sc_dchan.ibuf_len + lo) >
- sc->sc_dchan.ibuf_max_len)
- {
- panic("dchan_receive: buffer not long enough");
- }
-
- IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, lo);
- sc->sc_dchan.ibuf_len += lo;
- sc->sc_dchan.rx_count += lo;
-
status = IWIC_READ(sc, D_RSTA);
if (status & (D_RSTA_RDOV | D_RSTA_CRCE | D_RSTA_RMB))
{
- NDBGL1(L1_I_ERR, "bad read status 0x%x", status);
+ if (status & D_RSTA_RDOV)
+ NDBGL1(L1_I_ERR, "iwic%d: D-channel Receive Data Overflow", sc->sc_unit);
+ if (status & D_RSTA_CRCE)
+ NDBGL1(L1_I_ERR, "iwic%d: D-channel CRC Error", sc->sc_unit);
+ if (status & D_RSTA_RMB)
+ NDBGL1(L1_I_ERR, "iwic%d: D-channel Receive Message Aborted", sc->sc_unit);
+ command |= D_CMDR_RRST;
}
-
- sc->sc_dchan.ibuf->m_len = sc->sc_dchan.ibuf_len;
-
- if(sc->sc_trace & TRACE_D_RX)
+ else
{
- i4b_trace_hdr_t hdr;
- hdr.unit = L0IWICUNIT(sc->sc_unit);
- hdr.type = TRC_CH_D;
- hdr.dir = FROM_NT;
- hdr.count = ++sc->sc_dchan.trace_count;
- MICROTIME(hdr.time);
- i4b_l1_trace_ind(&hdr, sc->sc_dchan.ibuf->m_len, sc->sc_dchan.ibuf->m_data);
+ int hi, lo;
+ int total_frame_len;
+
+ lo = IWIC_READ(sc, D_RBCL);
+ hi = IWIC_READ(sc, D_RBCH);
+ total_frame_len = D_RBC(hi, lo);
+ lo = lo & 0x3f;
+
+ if (lo == 0)
+ lo = IWIC_DCHAN_FIFO_LEN;
+
+ if (!sc->sc_dchan.ibuf)
+ {
+ dchan_get_mbuf(sc, lo);
+ }
+ else if ((sc->sc_dchan.ibuf_len + lo) >
+ sc->sc_dchan.ibuf_max_len)
+ {
+ panic("dchan_receive: buffer not long enough");
+ }
+
+ IWIC_RDDFIFO(sc, sc->sc_dchan.ibuf_ptr, lo);
+ sc->sc_dchan.ibuf_len += lo;
+ sc->sc_dchan.rx_count += lo;
+
+ sc->sc_dchan.ibuf->m_len = sc->sc_dchan.ibuf_len;
+
+ if(sc->sc_trace & TRACE_D_RX)
+ {
+ i4b_trace_hdr_t hdr;
+ hdr.unit = L0IWICUNIT(sc->sc_unit);
+ hdr.type = TRC_CH_D;
+ hdr.dir = FROM_NT;
+ hdr.count = ++sc->sc_dchan.trace_count;
+ MICROTIME(hdr.time);
+ i4b_l1_trace_ind(&hdr, sc->sc_dchan.ibuf->m_len, sc->sc_dchan.ibuf->m_data);
+ }
+ i4b_l1_ph_data_ind(L0IWICUNIT(sc->sc_unit), sc->sc_dchan.ibuf);
+
+ sc->sc_dchan.ibuf = NULL;
}
-
- i4b_l1_ph_data_ind(L0IWICUNIT(sc->sc_unit), sc->sc_dchan.ibuf);
-
- sc->sc_dchan.ibuf = NULL;
}
- IWIC_WRITE(sc, D_CMDR, D_CMDR_RACK);
+ IWIC_WRITE(sc, D_CMDR, command);
}
/*---------------------------------------------------------------------------*
- *
+ * transmit D-channel frame
*---------------------------------------------------------------------------*/
void
iwic_dchan_transmit(struct iwic_softc *sc)
@@ -464,29 +470,4 @@ iwic_dchan_transmit(struct iwic_softc *sc)
IWIC_WRITE(sc, D_CMDR, cmd);
}
-#ifdef NOTDEF
-/*---------------------------------------------------------------------------*
- *
- *---------------------------------------------------------------------------*/
-static void
-output_bytes(char *prefix, u_char * ptr, int len)
-{
- char buf[400];
- char tmp[10];
- int i;
-
- sprintf(buf, "%s bytes ", prefix);
- for (i = 0; i < len; i++)
- {
- if (i != (len - 1))
- sprintf(tmp, "0x%x, ", ptr[i] & 0xff);
- else
- sprintf(tmp, "0x%x", ptr[i] & 0xff);
- strcat(buf, tmp);
- }
- strcat(buf, "\n";
- printf(buf);
-}
-#endif
-
-#endif
+#endif /* (NIWIC > 0) && (NPCI > 0) */
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_ext.h b/sys/i4b/layer1/iwic/i4b_iwic_ext.h
index 7f75797..210731e 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_ext.h
+++ b/sys/i4b/layer1/iwic/i4b_iwic_ext.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 Hellmuth Michaelis. 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
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_iwic_ext.h,v 1.4 2000/06/02 16:14:36 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Fri Jun 2 14:52:10 2000]
+ * last edit-date: [Sun Jan 21 11:09:14 2001]
*
*---------------------------------------------------------------------------*/
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_fsm.c b/sys/i4b/layer1/iwic/i4b_iwic_fsm.c
index 5bbf751..b093907 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_fsm.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_fsm.c
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_iwic_fsm.c,v 1.4 2000/05/29 15:41:42 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Thu Apr 27 14:56:54 2000]
+ * last edit-date: [Sun Jan 21 11:09:24 2001]
*
*---------------------------------------------------------------------------*/
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_l1if.c b/sys/i4b/layer1/iwic/i4b_iwic_l1if.c
index ee745c3..2b654e3 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_l1if.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_l1if.c
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_iwic_l1if.c,v 1.3 2000/06/02 16:14:36 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Fri Jun 2 14:52:39 2000]
+ * last edit-date: [Sun Jan 21 11:09:33 2001]
*
*---------------------------------------------------------------------------*/
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_pci.c b/sys/i4b/layer1/iwic/i4b_iwic_pci.c
index b02af71..7f92fdb 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_pci.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_pci.c
@@ -29,7 +29,7 @@
*
* $FreeBSD$
*
- * last edit-date: [Wed Jan 10 14:33:08 2001]
+ * last edit-date: [Tue Jan 16 10:53:03 2001]
*
*---------------------------------------------------------------------------*/
@@ -266,6 +266,12 @@ iwic_pci_attach(device_t dev)
iwic_init_linktab(sc);
+ if(bootverbose)
+ {
+ int ver = IWIC_READ(sc, D_RBCH);
+ printf("iwic%d: W6692 chip version = %d\n", unit, D_RBCH_VN(ver));
+ }
+
i4b_l1_mph_status_ind(L0IWICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &iwic_l1mux_func);
IWIC_READ(sc, ISTA);
diff --git a/sys/i4b/layer1/iwic/i4b_w6692.h b/sys/i4b/layer1/iwic/i4b_w6692.h
index 3fb1d15..ec3112f 100644
--- a/sys/i4b/layer1/iwic/i4b_w6692.h
+++ b/sys/i4b/layer1/iwic/i4b_w6692.h
@@ -27,11 +27,9 @@
* i4b_iwic - isdn4bsd Winbond W6692 driver
* ----------------------------------------
*
- * $Id: i4b_w6692.h,v 1.1 2000/03/07 14:12:26 hm Exp $
- *
* $FreeBSD$
*
- * last edit-date: [Mon Mar 6 12:19:55 2000]
+ * last edit-date: [Sun Jan 21 11:09:46 2001]
*
*---------------------------------------------------------------------------*/
OpenPOWER on IntegriCloud