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.
This commit is contained in:
parent
7e6a937974
commit
9c4d942508
@ -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]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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) */
|
||||
|
@ -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]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -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]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -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]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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]
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user