2 * Copyright (c) 1999, 2000 Dave Boyce. All rights reserved.
3 * Copyright (c) 2000, 2001 Hellmuth Michaelis. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 /*---------------------------------------------------------------------------
29 * i4b_iwic - isdn4bsd Winbond W6692 driver
30 * ----------------------------------------
31 * last edit-date: [Tue Jan 16 13:21:24 2001]
33 *---------------------------------------------------------------------------*/
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/socket.h>
48 #include <i4b/include/i4b_debug.h>
49 #include <i4b/include/i4b_ioctl.h>
50 #include <i4b/include/i4b_trace.h>
52 #include <i4b/layer1/i4b_l1.h>
54 #include <i4b/layer1/iwic/i4b_iwic.h>
55 #include <i4b/layer1/iwic/i4b_w6692.h>
57 #include <i4b/include/i4b_global.h>
58 #include <i4b/include/i4b_mbuf.h>
60 static void iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate);
62 /*---------------------------------------------------------------------------*
63 * B-channel interrupt handler
64 *---------------------------------------------------------------------------*/
66 iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
69 struct iwic_bchan *chan;
73 chan = &sc->sc_bchan[chan_no];
75 irq_stat = IWIC_READ(sc, chan->offset + B_EXIR);
77 NDBGL1(L1_H_IRQ, "irq_stat = 0x%x", irq_stat);
79 if((irq_stat & (B_EXIR_RMR | B_EXIR_RME | B_EXIR_RDOV | B_EXIR_XFR | B_EXIR_XDUN)) == 0)
81 NDBGL1(L1_H_XFRERR, "spurious IRQ!");
85 if (irq_stat & B_EXIR_RDOV)
87 NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Receive Data Overflow", sc->sc_unit);
90 if (irq_stat & B_EXIR_XDUN)
92 NDBGL1(L1_H_XFRERR, "iwic%d: EXIR B-channel Transmit Data Underrun", sc->sc_unit);
93 cmd |= (B_CMDR_XRST); /*XXX must retransmit frame ! */
96 /* RX message end interrupt */
98 if(irq_stat & B_EXIR_RME)
102 NDBGL1(L1_H_IRQ, "B_EXIR_RME");
104 error = (IWIC_READ(sc,chan->offset+B_STAR) &
105 (B_STAR_RDOV | B_STAR_CRCE | B_STAR_RMB));
109 if(error & B_STAR_RDOV)
110 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel Receive Data Overflow", sc->sc_unit);
111 if(error & B_STAR_CRCE)
112 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel CRC Error", sc->sc_unit);
113 if(error & B_STAR_RMB)
114 NDBGL1(L1_H_XFRERR, "iwic%d: B-channel Receive Message Aborted", sc->sc_unit);
117 /* all error conditions checked, now decide and take action */
121 register int fifo_data_len;
122 fifo_data_len = ((IWIC_READ(sc,chan->offset+B_RBCL)) &
123 ((IWIC_BCHAN_FIFO_LEN)-1));
125 if(fifo_data_len == 0)
126 fifo_data_len = IWIC_BCHAN_FIFO_LEN;
129 if(chan->in_mbuf == NULL)
131 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
132 panic("L1 iwic_bchan_irq: RME, cannot allocate mbuf!\n");
133 chan->in_cbptr = chan->in_mbuf->m_data;
137 if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
139 /* read data from fifo */
141 NDBGL1(L1_H_IRQ, "B_EXIR_RME, rd fifo, len = %d", fifo_data_len);
143 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, fifo_data_len);
145 cmd |= (B_CMDR_RACK | B_CMDR_RACT);
146 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
149 chan->in_len += fifo_data_len;
150 chan->rxcount += fifo_data_len;
152 /* setup mbuf data length */
154 chan->in_mbuf->m_len = chan->in_len;
155 chan->in_mbuf->m_pkthdr.len = chan->in_len;
157 if(sc->sc_trace & TRACE_B_RX)
160 hdr.unit = L0IWICUNIT(sc->sc_unit);
161 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
163 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
165 i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
168 (*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
172 /* mark buffer ptr as unused */
174 chan->in_mbuf = NULL;
175 chan->in_cbptr = NULL;
180 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
181 chan->in_cbptr = chan->in_mbuf->m_data;
183 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
188 if (chan->in_mbuf != NULL)
190 i4b_Bfreembuf(chan->in_mbuf);
191 chan->in_mbuf = NULL;
192 chan->in_cbptr = NULL;
195 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
199 /* RX fifo full interrupt */
201 if(irq_stat & B_EXIR_RMR)
203 NDBGL1(L1_H_IRQ, "B_EXIR_RMR");
205 if(chan->in_mbuf == NULL)
207 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
208 panic("L1 iwic_bchan_irq: RMR, cannot allocate mbuf!\n");
209 chan->in_cbptr = chan->in_mbuf->m_data;
213 chan->rxcount += IWIC_BCHAN_FIFO_LEN;
215 if((chan->in_len + IWIC_BCHAN_FIFO_LEN) <= BCH_MAX_DATALEN)
217 /* read data from fifo */
219 NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo, len = max (64)");
221 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
223 chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
224 chan->in_len += IWIC_BCHAN_FIFO_LEN;
228 if(chan->bprot == BPROT_NONE)
230 /* setup mbuf data length */
232 chan->in_mbuf->m_len = chan->in_len;
233 chan->in_mbuf->m_pkthdr.len = chan->in_len;
235 if(sc->sc_trace & TRACE_B_RX)
238 hdr.unit = L0IWICUNIT(sc->sc_unit);
239 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
241 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
243 i4b_l1_trace_ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
246 /* silence detection */
248 if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
251 #if defined (__FreeBSD__) && __FreeBSD__ > 4
252 (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
254 if(!(IF_QFULL(&chan->rx_queue)))
256 IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
260 i4b_Bfreembuf(chan->in_mbuf);
263 /* signal upper driver that data is available */
265 (*chan->iwic_drvr_linktab->bch_rx_data_ready)(chan->iwic_drvr_linktab->unit);
267 /* alloc new buffer */
269 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
270 panic("L1 iwic_bchan_irq: RMR, cannot allocate new mbuf!\n");
272 /* setup new data ptr */
274 chan->in_cbptr = chan->in_mbuf->m_data;
276 /* read data from fifo */
278 NDBGL1(L1_H_IRQ, "B_EXIR_RMR, rd fifo1, len = max (64)");
280 IWIC_RDBFIFO(sc, chan, chan->in_cbptr, IWIC_BCHAN_FIFO_LEN);
282 chan->in_cbptr += IWIC_BCHAN_FIFO_LEN;
283 chan->in_len = IWIC_BCHAN_FIFO_LEN;
285 chan->rxcount += IWIC_BCHAN_FIFO_LEN;
289 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
290 chan->in_cbptr = chan->in_mbuf->m_data;
292 cmd |= (B_CMDR_RRST | B_CMDR_RACK);
296 /* command to release fifo space */
303 if (irq_stat & B_EXIR_XFR)
305 /* transmit fifo empty, new data can be written to fifo */
311 NDBGL1(L1_H_IRQ, "B_EXIR_XFR");
313 if(chan->out_mbuf_cur == NULL) /* last frame is transmitted */
315 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
317 if(chan->out_mbuf_head == NULL)
319 chan->state &= ~ST_TX_ACTIVE;
320 (*chan->iwic_drvr_linktab->bch_tx_queue_empty)(chan->iwic_drvr_linktab->unit);
324 chan->state |= ST_TX_ACTIVE;
325 chan->out_mbuf_cur = chan->out_mbuf_head;
326 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
327 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
329 if(sc->sc_trace & TRACE_B_TX)
332 hdr.unit = L0IWICUNIT(sc->sc_unit);
333 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
335 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
337 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
340 if(chan->bprot == BPROT_NONE)
342 if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
354 while(chan->out_mbuf_cur && len != IWIC_BCHAN_FIFO_LEN)
356 nextlen = min(chan->out_mbuf_cur_len, IWIC_BCHAN_FIFO_LEN - len);
358 NDBGL1(L1_H_IRQ, "B_EXIR_XFR, wr fifo, len = %d", nextlen);
360 IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, nextlen);
365 chan->txcount += nextlen;
367 chan->out_mbuf_cur_ptr += nextlen;
368 chan->out_mbuf_cur_len -= nextlen;
370 if(chan->out_mbuf_cur_len == 0)
372 if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
374 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
375 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
377 if(sc->sc_trace & TRACE_B_TX)
380 hdr.unit = L0IWICUNIT(sc->sc_unit);
381 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
383 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
385 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
390 if (chan->bprot != BPROT_NONE)
392 i4b_Bfreembuf(chan->out_mbuf_head);
393 chan->out_mbuf_head = NULL;
401 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
405 /*---------------------------------------------------------------------------*
406 * initialize one B channels rx/tx data structures
407 *---------------------------------------------------------------------------*/
409 iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate)
411 struct iwic_softc *sc = &iwic_sc[unit];
412 struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
416 NDBGL1(L1_BCHAN, "unit %d, chan %d, bprot %d, activate %d", unit, chan_no, bprot, activate);
420 chan->bprot = bprot; /* B channel protocol */
421 chan->state = ST_IDLE; /* B channel state */
426 iwic_bchan_init(sc, chan_no, activate);
431 chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
433 #if defined (__FreeBSD__) && __FreeBSD__ > 4
434 if(!mtx_initialized(&chan->rx_queue.ifq_mtx))
435 mtx_init(&chan->rx_queue.ifq_mtx, "i4b_iwic_rx", NULL, MTX_DEF);
438 i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
440 chan->rxcount = 0; /* reset rx counter */
442 i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */
444 chan->in_mbuf = NULL; /* reset mbuf ptr */
445 chan->in_cbptr = NULL; /* reset mbuf curr ptr */
446 chan->in_len = 0; /* reset mbuf data len */
448 /* transmitter part */
450 chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
452 #if defined (__FreeBSD__) && __FreeBSD__ > 4
453 if(!mtx_initialized(&chan->tx_queue.ifq_mtx))
454 mtx_init(&chan->tx_queue.ifq_mtx, "i4b_iwic_tx", NULL, MTX_DEF);
457 i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
459 chan->txcount = 0; /* reset tx counter */
461 i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
463 chan->out_mbuf_head = NULL; /* reset head mbuf ptr */
464 chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */
465 chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */
466 chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */
471 iwic_bchan_init(sc, chan_no, activate);
477 /*---------------------------------------------------------------------------*
478 * initalize / deinitialize B-channel hardware
479 *---------------------------------------------------------------------------*/
481 iwic_bchan_init(struct iwic_softc *sc, int chan_no, int activate)
483 struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
485 NDBGL1(L1_BCHAN, "chan %d, activate %d", chan_no, activate);
489 if(bchan->bprot == BPROT_NONE)
491 /* Extended transparent mode */
492 IWIC_WRITE(sc, bchan->offset + B_MODE, B_MODE_MMS);
496 /* Transparent mode */
497 IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
498 /* disable address comparation */
499 IWIC_WRITE (sc, bchan->offset+B_ADM1, 0xff);
500 IWIC_WRITE (sc, bchan->offset+B_ADM2, 0xff);
503 /* reset & start receiver */
504 IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST|B_CMDR_RACT);
507 IWIC_WRITE(sc, bchan->offset + B_EXIM, 0);
512 IWIC_WRITE(sc, bchan->offset + B_EXIM, 0xff);
515 IWIC_WRITE(sc, bchan->offset + B_MODE, 0);
517 /* Bring interface down */
518 IWIC_WRITE(sc, bchan->offset + B_CMDR, B_CMDR_RRST | B_CMDR_XRST);
520 /* Flush pending interrupts */
521 IWIC_READ(sc, bchan->offset + B_EXIR);
525 /*---------------------------------------------------------------------------*
526 * start transmission on a b channel
527 *---------------------------------------------------------------------------*/
529 iwic_bchannel_start(int unit, int chan_no)
531 struct iwic_softc *sc = &iwic_sc[unit];
532 register struct iwic_bchan *chan = &sc->sc_bchan[chan_no];
533 register int next_len;
540 s = SPLI4B(); /* enter critical section */
542 NDBGL1(L1_BCHAN, "unit %d, channel %d", unit, chan_no);
544 if(chan->state & ST_TX_ACTIVE) /* already running ? */
547 return; /* yes, leave */
550 /* get next mbuf from queue */
552 IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
554 if(chan->out_mbuf_head == NULL) /* queue empty ? */
556 splx(s); /* leave critical section */
557 return; /* yes, exit */
560 /* init current mbuf values */
562 chan->out_mbuf_cur = chan->out_mbuf_head;
563 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
564 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
566 /* activity indicator for timeout handling */
568 if(chan->bprot == BPROT_NONE)
570 if(!(i4b_l1_bchan_tel_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
578 chan->state |= ST_TX_ACTIVE; /* we start transmitting */
580 if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */
583 hdr.unit = L0IWICUNIT(unit);
584 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
586 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
588 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
591 len = 0; /* # of chars put into tx fifo this time */
594 * fill the tx fifo with data from the current mbuf. if
595 * current mbuf holds less data than fifo length, try to
596 * get the next mbuf from (a possible) mbuf chain. if there is
597 * not enough data in a single mbuf or in a chain, then this
598 * is the last mbuf and we tell the chip that it has to send
599 * CRC and closing flag
602 while((len < IWIC_BCHAN_FIFO_LEN) && chan->out_mbuf_cur)
605 * put as much data into the fifo as is
606 * available from the current mbuf
609 if((len + chan->out_mbuf_cur_len) >= IWIC_BCHAN_FIFO_LEN)
610 next_len = IWIC_BCHAN_FIFO_LEN - len;
612 next_len = chan->out_mbuf_cur_len;
614 /* write what we have from current mbuf to fifo */
616 IWIC_WRBFIFO(sc, chan, chan->out_mbuf_cur_ptr, next_len);
618 len += next_len; /* update # of bytes written */
619 chan->txcount += next_len; /* statistics */
620 chan->out_mbuf_cur_ptr += next_len; /* data ptr */
621 chan->out_mbuf_cur_len -= next_len; /* data len */
624 * in case the current mbuf (of a possible chain) data
625 * has been put into the fifo, check if there is a next
626 * mbuf in the chain. If there is one, get ptr to it
627 * and update the data ptr and the length
630 if((chan->out_mbuf_cur_len <= 0) &&
631 ((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL))
633 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
634 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
636 if(sc->sc_trace & TRACE_B_TX)
639 hdr.unit = L0IWICUNIT(unit);
640 hdr.type = (chan_no == IWIC_BCH_A ? TRC_CH_B1 : TRC_CH_B2);
642 hdr.count = ++sc->sc_bchan[chan_no].sc_trace_bcount;
644 i4b_l1_trace_ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
650 * if there is either still data in the current mbuf and/or
651 * there is a successor on the chain available issue just
652 * a XTF (transmit) command to the chip. if there is no more
653 * data available from the current mbuf (-chain), issue
654 * an XTF and an XME (message end) command which will then
655 * send the CRC and the closing HDLC flag sequence
658 if(chan->out_mbuf_cur && (chan->out_mbuf_cur_len > 0))
661 * more data available, send current fifo out.
662 * next xfer to tx fifo is done in the
670 /* end of mbuf chain */
672 if(chan->bprot == BPROT_NONE)
675 cmd |= (B_CMDR_XMS | B_CMDR_XME);
677 i4b_Bfreembuf(chan->out_mbuf_head); /* free mbuf chain */
679 chan->out_mbuf_head = NULL;
680 chan->out_mbuf_cur = NULL;
681 chan->out_mbuf_cur_ptr = NULL;
682 chan->out_mbuf_cur_len = 0;
685 /* call timeout handling routine */
687 if(activity == ACT_RX || activity == ACT_TX)
688 (*chan->iwic_drvr_linktab->bch_activity)(chan->iwic_drvr_linktab->unit, activity);
693 IWIC_WRITE(sc, chan->offset + B_CMDR, cmd);
699 /*---------------------------------------------------------------------------*
700 * return B-channel statistics
701 *---------------------------------------------------------------------------*/
703 iwic_bchannel_stat(int unit, int chan_no, bchan_statistics_t *bsp)
705 struct iwic_softc *sc = iwic_find_sc(unit);
706 struct iwic_bchan *bchan = &sc->sc_bchan[chan_no];
710 bsp->outbytes = bchan->txcount;
711 bsp->inbytes = bchan->rxcount;
719 /*---------------------------------------------------------------------------*
720 * initialize our local linktab
721 *---------------------------------------------------------------------------*/
723 iwic_init_linktab(struct iwic_softc *sc)
725 struct iwic_bchan *chan;
728 /* make sure the hardware driver is known to layer 4 */
729 ctrl_types[CTRL_PASSIVE].set_linktab = i4b_l1_set_linktab;
730 ctrl_types[CTRL_PASSIVE].get_linktab = i4b_l1_ret_linktab;
734 chan = &sc->sc_bchan[IWIC_BCH_A];
735 lt = &chan->iwic_isdn_linktab;
737 lt->unit = sc->sc_unit;
738 lt->channel = IWIC_BCH_A;
739 lt->bch_config = iwic_bchannel_setup;
740 lt->bch_tx_start = iwic_bchannel_start;
741 lt->bch_stat = iwic_bchannel_stat;
742 lt->tx_queue = &chan->tx_queue;
744 /* used by non-HDLC data transfers, i.e. telephony drivers */
745 lt->rx_queue = &chan->rx_queue;
747 /* used by HDLC data transfers, i.e. ipr and isp drivers */
748 lt->rx_mbuf = &chan->in_mbuf;
752 chan = &sc->sc_bchan[IWIC_BCH_B];
753 lt = &chan->iwic_isdn_linktab;
755 lt->unit = sc->sc_unit;
756 lt->channel = IWIC_BCH_B;
757 lt->bch_config = iwic_bchannel_setup;
758 lt->bch_tx_start = iwic_bchannel_start;
759 lt->bch_stat = iwic_bchannel_stat;
760 lt->tx_queue = &chan->tx_queue;
762 /* used by non-HDLC data transfers, i.e. telephony drivers */
763 lt->rx_queue = &chan->rx_queue;
765 /* used by HDLC data transfers, i.e. ipr and isp drivers */
766 lt->rx_mbuf = &chan->in_mbuf;