2 * Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
4 * Copyright (c) 2000, 2001 Hellmuth Michaelis. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 *---------------------------------------------------------------------------
29 * i4b_iwic - isdn4bsd Winbond W6692 driver
30 * ----------------------------------------
32 * $FreeBSD: src/sys/i4b/layer1/iwic/i4b_iwic_bchan.c,v 1.7.2.1 2001/08/10 14:08:40 obrien Exp $
34 * last edit-date: [Tue Jan 16 13:21:24 2001]
36 *---------------------------------------------------------------------------*/
42 #if (NIWIC > 0) && (NPCI > 0)
44 #include <sys/param.h>
45 #include <sys/systm.h>
47 #include <sys/socket.h>
52 #include <machine/i4b_debug.h>
53 #include <machine/i4b_ioctl.h>
54 #include <machine/i4b_trace.h>
56 #include <i4b/layer1/i4b_l1.h>
58 #include <i4b/layer1/iwic/i4b_iwic.h>
59 #include <i4b/layer1/iwic/i4b_w6692.h>
61 #include <i4b/include/i4b_global.h>
62 #include <i4b/include/i4b_mbuf.h>
64 static void iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate);
66 /*---------------------------------------------------------------------------*
67 * B-channel interrupt handler
68 *---------------------------------------------------------------------------*/
70 iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
73 struct iwic_bchan *chan;
77 chan = &sc->sc_bchan[chan_no];
79 irq_stat = IWIC_READ(sc, chan->offset + B_EXIR);
81 NDBGL1(L1_H_IRQ, "irq_stat = 0x%x", irq_stat);
83 if((irq_stat & (B_EXIR_RMR | B_EXIR_RME | B_EXIR_RDOV | B_EXIR_XFR | B_EXIR_XDUN)) == 0)
85 NDBGL1(L1_H_XFRERR, "spurious IRQ!");
89 if (irq_stat & B_EXIR_RDOV)
91 NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Receive Data Overflow", sc->sc_unit);
94 if (irq_stat & B_EXIR_XDUN)
96 NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Transmit Data Underrun", sc->sc_unit);
97 cmd |= (B_CMDR_XRST); /*XXX must retransmit frame ! */
100 /* RX message end interrupt */
102 if(irq_stat & B_EXIR_RME)
106 NDBGL1(L1_H_IRQ, "B_EXIR_RME");
108 error = (IWIC_READ(sc,chan->offset+B_STAR) &
109 (B_STAR_RDOV | B_STAR_CRCE | B_STAR_RMB));
113 if(error & B_STAR_RDOV)
114 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel Receive Data Overflow", sc->sc_unit);
115 if(error & B_STAR_CRCE)
116 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel CRC Error", sc->sc_unit);
117 if(error & B_STAR_RMB)
118 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel Receive Message Aborted", sc->sc_unit);
121 /* all error conditions checked, now decide and take action */
125 register int fifo_data_len;
126 fifo_data_len = ((IWIC_READ(sc,chan->offset+B_RBCL)) &
127 ((IWIC_BCHAN_FIFO_LEN)-1));
129 if(fifo_data_len == 0)
130 fifo_data_len = IWIC_BCHAN_FIFO_LEN;
133 if(chan->in_mbuf == NULL)
135 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
136 panic("L1 iwic_bchan_irq: RME, cannot allocate mbuf!\n");
137 chan->in_cbptr = chan->in_mbuf->m_data;
141 if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
143 /* read data from fifo */
145 NDBGL1(L1_H_IRQ, "B_EXIR_RME, rd fifo, len = %d", fifo_data_len);
147 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, fifo_data_len);
149 cmd |= (B_CMDR_RACK | B_CMDR_RACT);
150 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
153 chan->in_len += fifo_data_len;
154 chan->rxcount += fifo_data_len;
156 /* setup mbuf data length */
158 chan->in_mbuf->m_len = chan->in_len;
159 chan->in_mbuf->m_pkthdr.len = chan->in_len;
161 if(sc->sc_trace & TRACE_B_RX)
164 hdr.unit = L0IWICUNIT(sc->sc_unit);
165 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
167 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
169 i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
172 (*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
176 /* mark buffer ptr as unused */
178 chan->in_mbuf = NULL;
179 chan->in_cbptr = NULL;
184 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
185 chan->in_cbptr = chan->in_mbuf->m_data;
187 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
192 if (chan->in_mbuf != NULL)
194 i4b_Bfreembuf(chan->in_mbuf);
195 chan->in_mbuf = NULL;
196 chan->in_cbptr = NULL;
199 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
203 /* RX fifo full interrupt */
205 if(irq_stat & B_EXIR_RMR)
207 NDBGL1(L1_H_IRQ, "B_EXIR_RMR");
209 if(chan->in_mbuf == NULL)
211 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
212 panic("L1 iwic_bchan_irq: RMR, cannot allocate mbuf!\n");
213 chan->in_cbptr = chan->in_mbuf->m_data;
217 chan->rxcount += IWIC_BCHAN_FIFO_LEN;
219 if((chan->in_len + IWIC_BCHAN_FIFO_LEN) <= BCH_MAX_DATALEN)
221 /* read data from fifo */
223 NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo, len = max (64)");
225 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
227 chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
228 chan->in_len += IWIC_BCHAN_FIFO_LEN;
232 if(chan->bprot == BPROT_NONE)
234 /* setup mbuf data length */
236 chan->in_mbuf->m_len = chan->in_len;
237 chan->in_mbuf->m_pkthdr.len = chan->in_len;
239 if(sc->sc_trace & TRACE_B_RX)
242 hdr.unit = L0IWICUNIT(sc->sc_unit);
243 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
245 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
247 i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
250 /* silence detection */
252 if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
255 #if defined (__FreeBSD__) && __FreeBSD__ > 4
256 (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
258 if(!(IF_QFULL(&chan->rx_queue)))
260 IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
264 i4b_Bfreembuf(chan->in_mbuf);
267 /* signal upper driver that data is available */
269 (*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
271 /* alloc new buffer */
273 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
274 panic("L1 iwic_bchan_irq: RMR, cannot allocate new mbuf!\n");
276 /* setup new data ptr */
278 chan->in_cbptr = chan->in_mbuf->m_data;
280 /* read data from fifo */
282 NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo1, len = max (64)");
284 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
286 chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
287 chan->in_len = IWIC_BCHAN_FIFO_LEN;
289 chan->rxcount += IWIC_BCHAN_FIFO_LEN;
293 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
294 chan->in_cbptr = chan->in_mbuf->m_data;
296 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
300 /* command to release fifo space */
307 if (irq_stat & B_EXIR_XFR)
309 /* transmit fifo empty, new data can be written to fifo */
315 NDBGL1(L1_H_IRQ, "B_EXIR_XFR");
317 if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
319 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
321 if(chan->out_mbuf_head == NULL)
323 chan->state &= ~ST_TX_ACTIVE;
324 (*chan->iwic_drvr_linktab->bch_tx_queue_empty)(chan->iwic_drvr_linktab->unit);
328 chan->state |= ST_TX_ACTIVE;
329 chan->out_mbuf_cur = chan->out_mbuf_head;
330 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
331 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
333 if(sc->sc_trace & TRACE_B_TX)
336 hdr.unit = L0IWICUNIT(sc->sc_unit);
337 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
339 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
341 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
344 if(chan->bprot == BPROT_NONE)
346 if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
358 while(chan->out_mbuf_cur && len != IWIC_BCHAN_FIFO_LEN)
360 nextlen = min(chan->out_mbuf_cur_len, IWIC_BCHAN_FIFO_LEN - len);
362 NDBGL1(L1_H_IRQ, "B_EXIR_XFR, wr fifo, len = %d", nextlen);
364 IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, nextlen);
369 chan->txcount += nextlen;
371 chan->out_mbuf_cur_ptr += nextlen;
372 chan->out_mbuf_cur_len -= nextlen;
374 if(chan->out_mbuf_cur_len == 0)
376 if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
378 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
379 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
381 if(sc->sc_trace & TRACE_B_TX)
384 hdr.unit = L0IWICUNIT(sc->sc_unit);
385 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
387 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
389 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
394 if (chan->bprot != BPROT_NONE)
396 i4b_Bfreembuf(chan->out_mbuf_head);
397 chan->out_mbuf_head = NULL;
405 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
409 /*---------------------------------------------------------------------------*
410 * initialize one B channels rx/tx data structures
411 *---------------------------------------------------------------------------*/
413 iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate)
415 struct iwic_softc *sc = &iwic_sc[unit];
416 struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
420 NDBGL1(L1_BCHAN, "unit %d, chan %d, bprot %d, activate %d", unit, chan_no, bprot, activate);
424 chan->bprot = bprot; /* B channel protocol */
425 chan->state = ST_IDLE; /* B channel state */
430 iwic_bchan_init(sc, chan_no, activate);
435 chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
437 #if defined (__FreeBSD__) && __FreeBSD__ > 4
438 mtx_init(&chan->rx_queue.ifq_mtx, "i4b_iwic_rx", MTX_DEF);
441 i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
443 chan->rxcount = 0; /* reset rx counter */
445 i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
447 chan->in_mbuf = NULL; /* reset mbuf ptr */
448 chan->in_cbptr = NULL; /* reset mbuf curr ptr */
449 chan->in_len = 0; /* reset mbuf data len */
451 /* transmitter part */
453 chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
455 #if defined (__FreeBSD__) && __FreeBSD__ > 4
456 mtx_init(&chan->tx_queue.ifq_mtx, "i4b_iwic_tx", MTX_DEF);
459 i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
461 chan->txcount = 0; /* reset tx counter */
463 i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
465 chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
466 chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
467 chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
468 chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
473 iwic_bchan_init(sc, chan_no, activate);
479 /*---------------------------------------------------------------------------*
480 * initalize / deinitialize B-channel hardware
481 *---------------------------------------------------------------------------*/
483 iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate)
485 struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
487 NDBGL1(L1_BCHAN, "chan %d, activate %d", chan_no, activate);
491 if(bchan->bprot == BPROT_NONE)
493 /* Extended transparent mode */
494 IWIC_WRITE(sc, bchan->offset + B_MODE, B_MODE_MMS);
498 /* Transparent mode */
499 IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
500 /* disable address comparation */
501 IWIC_WRITE (sc, bchan->offset+B_ADM1, 0xff);
502 IWIC_WRITE (sc, bchan->offset+B_ADM2, 0xff);
505 /* reset & start receiver */
506 IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST|B_CMDR_RACT);
509 IWIC_WRITE(sc, bchan->offset + B_EXIM, 0);
514 IWIC_WRITE(sc, bchan->offset + B_EXIM, 0xff);
517 IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
519 /* Bring interface down */
520 IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST | B_CMDR_XRST);
522 /* Flush pending interrupts */
523 IWIC_READ(sc, bchan->offset + B_EXIR);
527 /*---------------------------------------------------------------------------*
528 * start transmission on a b channel
529 *---------------------------------------------------------------------------*/
531 iwic_bchannel_start(int unit, int chan_no)
533 struct iwic_softc *sc = &iwic_sc[unit];
534 register struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
535 register int next_len;
542 s = SPLI4B(); /* enter critical section */
544 NDBGL1(L1_BCHAN, "unit %d, channel %d", unit, chan_no);
546 if(chan->state & ST_TX_ACTIVE) /* already running ? */
549 return; /* yes, leave */
552 /* get next mbuf from queue */
554 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
556 if(chan->out_mbuf_head == NULL) /* queue empty ? */
558 splx(s); /* leave critical section */
559 return; /* yes, exit */
562 /* init current mbuf values */
564 chan->out_mbuf_cur = chan->out_mbuf_head;
565 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
566 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
568 /* activity indicator for timeout handling */
570 if(chan->bprot == BPROT_NONE)
572 if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
580 chan->state |= ST_TX_ACTIVE; /* we start transmitting */
582 if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
585 hdr.unit = L0IWICUNIT(unit);
586 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
588 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
590 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
593 len = 0; /* # of chars put into tx fifo this time */
596 * fill the tx fifo with data from the current mbuf. if
597 * current mbuf holds less data than fifo length, try to
598 * get the next mbuf from (a possible) mbuf chain. if there is
599 * not enough data in a single mbuf or in a chain, then this
600 * is the last mbuf and we tell the chip that it has to send
601 * CRC and closing flag
604 while((len < IWIC_BCHAN_FIFO_LEN) && chan->out_mbuf_cur)
607 * put as much data into the fifo as is
608 * available from the current mbuf
611 if((len + chan->out_mbuf_cur_len) >= IWIC_BCHAN_FIFO_LEN)
612 next_len = IWIC_BCHAN_FIFO_LEN - len;
614 next_len = chan->out_mbuf_cur_len;
616 /* write what we have from current mbuf to fifo */
618 IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, next_len);
620 len += next_len; /* update # of bytes written */
621 chan->txcount += next_len; /* statistics */
622 chan->out_mbuf_cur_ptr += next_len; /* data ptr */
623 chan->out_mbuf_cur_len -= next_len; /* data len */
626 * in case the current mbuf (of a possible chain) data
627 * has been put into the fifo, check if there is a next
628 * mbuf in the chain. If there is one, get ptr to it
629 * and update the data ptr and the length
632 if((chan->out_mbuf_cur_len <= 0) &&
633 ((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL))
635 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
636 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
638 if(sc->sc_trace & TRACE_B_TX)
641 hdr.unit = L0IWICUNIT(unit);
642 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
644 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
646 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
652 * if there is either still data in the current mbuf and/or
653 * there is a successor on the chain available issue just
654 * a XTF (transmit) command to the chip. if there is no more
655 * data available from the current mbuf (-chain), issue
656 * an XTF and an XME (message end) command which will then
657 * send the CRC and the closing HDLC flag sequence
660 if(chan->out_mbuf_cur && (chan->out_mbuf_cur_len > 0))
663 * more data available, send current fifo out.
664 * next xfer to tx fifo is done in the
672 /* end of mbuf chain */
674 if(chan->bprot == BPROT_NONE)
677 cmd |= (B_CMDR_XMS | B_CMDR_XME);
679 i4b_Bfreembuf(chan->out_mbuf_head); /* free mbuf chain */
681 chan->out_mbuf_head = NULL;
682 chan->out_mbuf_cur = NULL;
683 chan->out_mbuf_cur_ptr = NULL;
684 chan->out_mbuf_cur_len = 0;
687 /* call timeout handling routine */
689 if(activity == ACT_RX || activity == ACT_TX)
690 (*chan->iwic_drvr_linktab->bch_activity)(chan->iwic_drvr_linktab->unit, activity);
695 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
701 /*---------------------------------------------------------------------------*
702 * return B-channel statistics
703 *---------------------------------------------------------------------------*/
705 iwic_bchannel_stat(int unit, int chan_no, bchan_statistics_t *bsp)
707 struct iwic_softc *sc = iwic_find_sc(unit);
708 struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
712 bsp->outbytes = bchan->txcount;
713 bsp->inbytes = bchan->rxcount;
721 /*---------------------------------------------------------------------------*
722 * initialize our local linktab
723 *---------------------------------------------------------------------------*/
725 iwic_init_linktab(struct iwic_softc *sc)
727 struct iwic_bchan *chan;
730 /* make sure the hardware driver is known to layer 4 */
731 ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab;
732 ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab;
736 chan = &sc->sc_bchan[IWIC_BCH_A];
737 lt = &chan->iwic_isdn_linktab;
739 lt->unit = sc->sc_unit;
740 lt->channel = IWIC_BCH_A;
741 lt->bch_config = iwic_bchannel_setup;
742 lt->bch_tx_start = iwic_bchannel_start;
743 lt->bch_stat = iwic_bchannel_stat;
744 lt->tx_queue = &chan->tx_queue;
746 /* used by non-HDLC data transfers, i.e. telephony drivers */
747 lt->rx_queue = &chan->rx_queue;
749 /* used by HDLC data transfers, i.e. ipr and isp drivers */
750 lt->rx_mbuf = &chan->in_mbuf;
754 chan = &sc->sc_bchan[IWIC_BCH_B];
755 lt = &chan->iwic_isdn_linktab;
757 lt->unit = sc->sc_unit;
758 lt->channel = IWIC_BCH_B;
759 lt->bch_config = iwic_bchannel_setup;
760 lt->bch_tx_start = iwic_bchannel_start;
761 lt->bch_stat = iwic_bchannel_stat;
762 lt->tx_queue = &chan->tx_queue;
764 /* used by non-HDLC data transfers, i.e. telephony drivers */
765 lt->rx_queue = &chan->rx_queue;
767 /* used by HDLC data transfers, i.e. ipr and isp drivers */
768 lt->rx_mbuf = &chan->in_mbuf;
771 #endif /* NIWIC > 0 */