From 9c4d942508aa142dc84c8dffc05cafeb76564b71 Mon Sep 17 00:00:00 2001 From: hm Date: Sun, 21 Jan 2001 10:12:50 +0000 Subject: =?UTF-8?q?Update=20the=20iwic=20driver:=20fix=20error=20handling?= =?UTF-8?q?=20for=20rx=20errors=20on=20the=20D-channel=20which=20prevents?= =?UTF-8?q?=20erroneous=20packets=20from=20being=20put=20onto=20the=20prot?= =?UTF-8?q?ocol=20stack;=20enhance=20error=20detection=20for=20B-channel?= =?UTF-8?q?=20HDLC=20errors;=20remove=20old=20cvs=20id=C2=B4s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sys/i4b/layer1/iwic/i4b_iwic.h | 4 +- sys/i4b/layer1/iwic/i4b_iwic_bchan.c | 39 +++++++--- sys/i4b/layer1/iwic/i4b_iwic_dchan.c | 145 +++++++++++++++-------------------- sys/i4b/layer1/iwic/i4b_iwic_ext.h | 6 +- sys/i4b/layer1/iwic/i4b_iwic_fsm.c | 4 +- sys/i4b/layer1/iwic/i4b_iwic_l1if.c | 4 +- sys/i4b/layer1/iwic/i4b_iwic_pci.c | 8 +- sys/i4b/layer1/iwic/i4b_w6692.h | 4 +- 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] * *---------------------------------------------------------------------------*/ -- cgit v1.1