1/* $NetBSD: ifpci2.c,v 1.18 2009/11/26 15:17:10 njoly Exp $	*/
2/*
3 *   Copyright (c) 1999 Gary Jennejohn. All rights reserved.
4 *
5 *   Redistribution and use in source and binary forms, with or without
6 *   modification, are permitted provided that the following conditions
7 *   are met:
8 *
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.
14 *   3. Neither the name of the author nor the names of any co-contributors
15 *      may be used to endorse or promote products derived from this software
16 *      without specific prior written permission.
17 *   4. Altered versions must be plainly marked as such, and must not be
18 *      misrepresented as being the original software and/or documentation.
19 *
20 *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 *   SUCH DAMAGE.
31 *
32 *---------------------------------------------------------------------------
33 *   a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c
34 *---------------------------------------------------------------------------
35 *
36 *	Fritz!Card PCI driver
37 *	------------------------------------------------
38 *
39 *	$Id: ifpci2.c,v 1.19 2009/12/06 23:14:05 dyoung Exp $
40 *
41 *      last edit-date: [Fri Jan  5 11:38:58 2001]
42 *
43 *---------------------------------------------------------------------------*/
44
45#include <sys/cdefs.h>
46__KERNEL_RCSID(0, "$NetBSD: ifpci2.c,v 1.18 2009/11/26 15:17:10 njoly Exp $");
47
48
49#include <sys/param.h>
50#include <sys/ioctl.h>
51#include <sys/kernel.h>
52#include <sys/systm.h>
53#include <sys/mbuf.h>
54
55#include <sys/bus.h>
56#include <sys/device.h>
57
58#include <sys/socket.h>
59#include <net/if.h>
60
61#include <sys/callout.h>
62
63#include <dev/pci/pcireg.h>
64#include <dev/pci/pcivar.h>
65#include <dev/pci/pcidevs.h>
66#include <netisdn/i4b_debug.h>
67#include <netisdn/i4b_ioctl.h>
68
69#include <netisdn/i4b_global.h>
70#include <netisdn/i4b_l2.h>
71#include <netisdn/i4b_l1l2.h>
72#include <netisdn/i4b_trace.h>
73#include <netisdn/i4b_mbuf.h>
74
75#include <dev/ic/isic_l1.h>
76#include <dev/ic/isacsx.h>
77#include <dev/ic/hscx.h>
78
79#include <dev/pci/isic_pci.h>
80
81/* PCI config map to use (only one in this driver) */
82#define FRITZPCI_PORT0_IO_MAPOFF	PCI_MAPREG_START+4
83#define FRITZPCI_PORT0_MEM_MAPOFF	PCI_MAPREG_START
84
85static isdn_link_t *avma1pp2_ret_linktab(void *token, int channel);
86static void avma1pp2_set_link(void *token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc);
87
88void n_connect_request(struct call_desc *cd);
89void n_connect_response(struct call_desc *cd, int response, int cause);
90void n_disconnect_request(struct call_desc *cd, int cause);
91void n_alert_request(struct call_desc *cd);
92void n_mgmt_command(struct isdn_l3_driver *drv, int cmd, void *parm);
93
94extern const struct isdn_layer1_isdnif_driver isic_std_driver;
95
96const struct isdn_l3_driver_functions
97ifpci2_l3_driver = {
98	avma1pp2_ret_linktab,
99	avma1pp2_set_link,
100	n_connect_request,
101	n_connect_response,
102	n_disconnect_request,
103	n_alert_request,
104	NULL,
105	NULL,
106	n_mgmt_command
107};
108
109struct ifpci_softc {
110	struct isic_softc sc_isic;	/* parent class */
111
112	/* PCI-specific goo */
113	void *sc_ih;				/* interrupt handler */
114	bus_addr_t sc_base;
115	bus_size_t sc_size;
116	pci_chipset_tag_t sc_pc;
117};
118
119/* prototypes */
120static void avma1pp2_disable(struct isic_softc *);
121static int isic_hscx_fifo(l1_bchan_state_t *chan, struct isic_softc *sc);
122
123static int avma1pp2_intr(void*);
124static void avma1pp2_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size);
125static void avma1pp2_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size);
126static void avma1pp2_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data);
127static u_int8_t avma1pp2_read_reg(struct isic_softc *sc, int what, bus_size_t offs);
128static void hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc);
129static void hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc);
130static void hscx_write_reg(int chan, u_int val, struct isic_softc *sc);
131static u_char hscx_read_reg(int chan, struct isic_softc *sc);
132static u_int hscx_read_reg_int(int chan, struct isic_softc *sc);
133static void avma1pp2_bchannel_stat(isdn_layer1token, int h_chan, bchan_statistics_t *bsp);
134static void avma1pp2_map_int(struct ifpci_softc *sc, struct pci_attach_args *pa);
135static void avma1pp2_bchannel_setup(isdn_layer1token, int h_chan, int bprot, int activate);
136static void avma1pp2_init_linktab(struct isic_softc *);
137static int ifpci2_match(device_t parent, cfdata_t match, void *aux);
138static void ifpci2_attach(device_t parent, device_t self, void *aux);
139static int ifpci2_detach(device_t self, int flags);
140static int ifpci2_activate(device_t self, enum devact act);
141
142CFATTACH_DECL(ifritz, sizeof(struct ifpci_softc),
143    ifpci2_match, ifpci2_attach, ifpci2_detach, ifpci2_activate);
144
145/*---------------------------------------------------------------------------*
146 *	AVM PCI Fritz!Card V. 2 special registers
147 *---------------------------------------------------------------------------*/
148
149/*
150 *	AVM PCI Status Latch 0 read only bits
151 */
152#define ASL_IRQ_ISAC            0x01    /* ISAC  interrupt, active high */
153#define ASL_IRQ_HSCX            0x02    /* HSX   interrupt, active high */
154#define ASL_IRQ_TIMER           0x04    /* Timer interrupt, active high */
155#define ASL_IRQ_BCHAN           ASL_IRQ_HSCX
156/* actually active high */
157#define ASL_IRQ_Pending         (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER)
158
159/*
160 *	AVM PCI Status Latch 0 read only bits
161 */
162#define	ASL_RESET		0x01
163#define ASL_TIMERRESET 		0x04
164#define ASL_ENABLE_INT		0x08
165
166/*
167 * "HSCX" status bits
168 */
169#define  HSCX_STAT_RME		0x01
170#define  HSCX_STAT_RDO		0x10
171#define  HSCX_STAT_CRCVFRRAB	0x0E
172#define  HSCX_STAT_CRCVFR	0x06
173#define  HSCX_STAT_RML_MASK	0x3f00
174
175/*
176 * "HSCX" interrupt bits
177 */
178#define  HSCX_INT_XPR		0x80
179#define  HSCX_INT_XDU		0x40
180#define  HSCX_INT_RPR		0x20
181#define  HSCX_INT_MASK		0xE0
182
183/*
184 * "HSCX" command bits
185 */
186#define  HSCX_CMD_XRS		0x80
187#define  HSCX_CMD_XME		0x01
188#define  HSCX_CMD_RRS		0x20
189#define  HSCX_CMD_XML_MASK	0x3f00
190
191/* "HSCX" mode bits */
192#define HSCX_MODE_ITF_FLG 	0x01
193#define HSCX_MODE_TRANS 	0x02
194
195/* offsets to various registers in the ASIC, evidently */
196#define  STAT0_OFFSET   	0x02
197
198#define  HSCX_FIFO1     	0x10
199#define  HSCX_FIFO2     	0x18
200
201#define  HSCX_STAT1     	0x14
202#define  HSCX_STAT2     	0x1c
203
204#define  ISACSX_INDEX   	0x04
205#define  ISACSX_DATA    	0x08
206
207/*
208 * Commands and parameters are sent to the "HSCX" as a long, but the
209 * fields are handled as bytes.
210 *
211 * The long contains:
212 *	(prot << 16)|(txl << 8)|cmd
213 *
214 * where:
215 *	prot = protocol to use
216 *	txl = transmit length
217 *	cmd = the command to be executed
218 *
219 * The fields are defined as u_char in struct l1_softc.
220 *
221 * Macro to coalesce the byte fields into a u_int
222 */
223#define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \
224 					| (sc->avma1pp_prot << 16))
225
226/*
227 * to prevent deactivating the "HSCX" when both channels are active we
228 * define an HSCX_ACTIVE flag which is or'd into the channel's state
229 * flag in avma1pp2_bchannel_setup upon active and cleared upon deactivation.
230 * It is set high to allow room for new flags.
231 */
232#define HSCX_AVMA1PP_ACTIVE	0x1000
233
234static int
235ifpci2_match(device_t parent, cfdata_t match, void *aux)
236{
237	struct pci_attach_args *pa = aux;
238
239	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AVM &&
240	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AVM_FRITZ_PCI_V2_ISDN)
241		return 1;
242	return 0;
243}
244
245static void
246ifpci2_attach(device_t parent, device_t self, void *aux)
247{
248	struct ifpci_softc *psc = device_private(self);
249	struct pci_attach_args *pa = aux;
250	struct isic_softc *sc = &psc->sc_isic;
251	struct isdn_l3_driver *drv;
252	u_int v;
253
254	/* announce */
255	printf(": Fritz!PCI V2 card\n");
256
257	/* initialize sc */
258	callout_init(&sc->sc_T3_callout, 0);
259	callout_init(&sc->sc_T4_callout, 0);
260
261	/* setup io mappings */
262	sc->sc_num_mappings = 1;
263	MALLOC_MAPS(sc);
264	sc->sc_maps[0].size = 0;
265	if (pci_mapreg_map(pa, FRITZPCI_PORT0_IO_MAPOFF, PCI_MAPREG_TYPE_IO, 0,
266	    &sc->sc_maps[0].t, &sc->sc_maps[0].h, &psc->sc_base, &psc->sc_size) != 0) {
267		aprint_error_dev(&sc->sc_dev, "can't map card\n");
268		return;
269	}
270
271	/* setup access routines */
272
273	sc->clearirq = NULL;
274	sc->readreg = avma1pp2_read_reg;
275	sc->writereg = avma1pp2_write_reg;
276
277	sc->readfifo = avma1pp2_read_fifo;
278	sc->writefifo = avma1pp2_write_fifo;
279
280
281	/* setup card type */
282
283	sc->sc_cardtyp = CARD_TYPEP_AVMA1PCIV2;
284
285	/* setup IOM bus type */
286
287	sc->sc_bustyp = BUS_TYPE_IOM2;
288
289	/* this is no IPAC based card */
290	sc->sc_ipac = 0;
291	sc->sc_bfifolen = HSCX_FIFO_LEN;
292
293	/* setup interrupt mapping */
294	avma1pp2_map_int(psc, pa);
295
296	/* init the card */
297
298	v = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, 0);
299	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0);
300	DELAY(SEC_DELAY/20); /* 50 ms */
301	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET);
302	DELAY(SEC_DELAY/20); /* 50 ms */
303	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0);
304	DELAY(SEC_DELAY/20); /* 50 ms */
305
306	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_TIMERRESET);
307	DELAY(SEC_DELAY/100); /* 10 ms */
308	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_ENABLE_INT);
309	DELAY(SEC_DELAY/100); /* 10 ms */
310
311	/* setup i4b infrastructure (have to roll our own here) */
312
313	/* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */
314	printf("%s: ISACSX %s\n", device_xname(&sc->sc_dev), "PSB3186");
315
316	/* init the ISAC */
317	isic_isacsx_init(sc);
318
319	v = ISAC_READ(I_CIR0); /* Leo: reset generates status change */
320
321	/* init the "HSCX" */
322	avma1pp2_bchannel_setup(sc, HSCX_CH_A, BPROT_NONE, 0);
323
324	avma1pp2_bchannel_setup(sc, HSCX_CH_B, BPROT_NONE, 0);
325
326	/* can't use the normal B-Channel stuff */
327	avma1pp2_init_linktab(sc);
328
329	/* set trace level */
330
331	sc->sc_trace = TRACE_OFF;
332
333	sc->sc_state = ISAC_IDLE;
334
335	sc->sc_ibuf = NULL;
336	sc->sc_ib = NULL;
337	sc->sc_ilen = 0;
338
339	sc->sc_obuf = NULL;
340	sc->sc_op = NULL;
341	sc->sc_ol = 0;
342	sc->sc_freeflag = 0;
343
344	sc->sc_obuf2 = NULL;
345	sc->sc_freeflag2 = 0;
346
347	/* init higher protocol layers */
348	drv = isdn_attach_isdnif(device_xname(&sc->sc_dev),
349	    "AVM Fritz!PCI V2", &sc->sc_l2, &ifpci2_l3_driver, NBCH_BRI);
350	sc->sc_l3token = drv;
351	sc->sc_l2.driver = &isic_std_driver;
352	sc->sc_l2.l1_token = sc;
353	sc->sc_l2.drv = drv;
354	isdn_layer2_status_ind(&sc->sc_l2, drv, STI_ATTACH, 1);
355	isdn_isdnif_ready(drv->isdnif);
356}
357
358static int
359ifpci2_detach(device_t self, int flags)
360{
361	struct ifpci_softc *psc = device_private(self);
362
363	bus_space_unmap(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
364	bus_space_free(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
365	pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
366
367	return (0);
368}
369
370int
371ifpci2_activate(device_t self, enum devact act)
372{
373	struct ifpci_softc *psc = device_private(self);
374
375	switch (act) {
376	case DVACT_DEACTIVATE:
377		psc->sc_isic.sc_intr_valid = ISIC_INTR_DYING;
378		isdn_layer2_status_ind(&psc->sc_isic.sc_l2, psc->sc_isic.sc_l3token, STI_ATTACH, 0);
379		isdn_detach_isdnif(psc->sc_isic.sc_l3token);
380		psc->sc_isic.sc_l3token = NULL;
381		return 0;
382	default:
383		return EOPNOTSUPP;
384	}
385}
386
387/*---------------------------------------------------------------------------*
388 *	AVM read fifo routines
389 *---------------------------------------------------------------------------*/
390
391static void
392avma1pp2_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
393{
394	int	i;
395
396	switch (what) {
397		case ISIC_WHAT_ISAC:
398			bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, 0);
399			/* evidently each byte must be read as a long */
400			for (i = 0; i < size; i++)
401				((u_int8_t *)buf)[i] = (u_int8_t)bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h,  ISACSX_DATA);
402			break;
403		case ISIC_WHAT_HSCXA:
404			hscx_read_fifo(0, buf, size, sc);
405			break;
406		case ISIC_WHAT_HSCXB:
407			hscx_read_fifo(1, buf, size, sc);
408			break;
409	}
410}
411
412static void
413hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc)
414{
415	int dataoff;
416
417	dataoff = chan ? HSCX_FIFO2 : HSCX_FIFO1;
418	bus_space_read_multi_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
419	    dataoff, buf, len/4);
420	if (__predict_false((len&3)>0)) {
421		uint32_t tmp;
422
423		buf = ((unsigned char*)buf) + (len & ~3u);
424		len &= 3u;
425		tmp = bus_space_read_stream_4(sc->sc_maps[0].t,
426		    sc->sc_maps[0].h, dataoff);
427		memcpy(buf, &tmp, len);
428	}
429}
430
431/*---------------------------------------------------------------------------*
432 *	AVM write fifo routines
433 *---------------------------------------------------------------------------*/
434
435static void
436avma1pp2_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
437{
438	int	i;
439
440	switch (what) {
441		case ISIC_WHAT_ISAC:
442			bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h,  ISACSX_INDEX, 0);
443			/* evidently each byte must be written as a long */
444			for (i = 0; i < size; i++)
445				bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h,  ISACSX_DATA, ((const unsigned char *)buf)[i]);
446			break;
447		case ISIC_WHAT_HSCXA:
448			hscx_write_fifo(0, buf, size, sc);
449			break;
450		case ISIC_WHAT_HSCXB:
451			hscx_write_fifo(1, buf, size, sc);
452			break;
453	}
454}
455
456static void
457hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc)
458{
459	size_t cnt;
460	int dataoff;
461	l1_bchan_state_t *Bchan = &sc->sc_chan[chan];
462
463	dataoff = chan ? HSCX_FIFO2 : HSCX_FIFO1;
464
465	sc->avma1pp_cmd &= ~HSCX_CMD_XME;
466	sc->avma1pp_txl = 0;
467	if (Bchan->out_mbuf_cur == NULL)
468	{
469	  if (Bchan->bprot != BPROT_NONE)
470		 sc->avma1pp_cmd |= HSCX_CMD_XME;
471	}
472	if (len != sc->sc_bfifolen)
473		sc->avma1pp_txl = len;
474
475	cnt = 0; /* borrow cnt */
476	AVMA1PPSETCMDLONG(cnt);
477	hscx_write_reg(chan, cnt, sc);
478
479	bus_space_write_multi_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
480	    dataoff, buf, (len+3)/4);
481	if (__predict_false((len&3)>0)) {
482		uint32_t tmp;
483
484		buf = (const unsigned char*)buf + (len & ~3u);
485		len &= 3u;
486		memset(&tmp, 0, sizeof(tmp));
487		memcpy(&tmp, buf, len);
488		bus_space_write_stream_4(sc->sc_maps[0].t, sc->sc_maps[0].h,
489		    dataoff, tmp);
490	}
491}
492
493/*---------------------------------------------------------------------------*
494 *	AVM write register routines
495 *---------------------------------------------------------------------------*/
496
497static void
498avma1pp2_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
499{
500	switch (what) {
501		case ISIC_WHAT_ISAC:
502			bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, offs);
503			bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA, data);
504			break;
505		case ISIC_WHAT_HSCXA:
506			hscx_write_reg(0, data, sc);
507			break;
508		case ISIC_WHAT_HSCXB:
509			hscx_write_reg(1, data, sc);
510			break;
511	}
512}
513
514static void
515hscx_write_reg(int chan, u_int val, struct isic_softc *sc)
516{
517	u_int off;
518
519	off = (chan == 0 ? HSCX_STAT1 : HSCX_STAT2);
520	bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, off, val);
521}
522
523/*---------------------------------------------------------------------------*
524 *	AVM read register routines
525 *---------------------------------------------------------------------------*/
526
527static u_int8_t
528avma1pp2_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
529{
530	u_int8_t val;
531
532	switch (what) {
533		case ISIC_WHAT_ISAC:
534			bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_INDEX, offs);
535			val = (u_int8_t)bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISACSX_DATA);
536			return(val);
537		case ISIC_WHAT_HSCXA:
538			return hscx_read_reg(0, sc);
539		case ISIC_WHAT_HSCXB:
540			return hscx_read_reg(1, sc);
541	}
542	return 0;
543}
544
545static u_char
546hscx_read_reg(int chan, struct isic_softc *sc)
547{
548	return(hscx_read_reg_int(chan, sc) & 0xff);
549}
550
551/*
552 * need to be able to return an int because the RBCH is in the 2nd
553 * byte.
554 */
555static u_int
556hscx_read_reg_int(int chan, struct isic_softc *sc)
557{
558	u_int off;
559
560	off = (chan == 0 ? HSCX_STAT1 : HSCX_STAT2);
561	return(bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, off));
562}
563
564/*
565 * this is the real interrupt routine
566 */
567static void
568avma1pp2_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc)
569{
570	register l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
571	int activity = -1;
572	u_int param = 0;
573
574	NDBGL1(L1_H_IRQ, "%#x", stat);
575
576	if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
577	{
578		chan->stat_XDU++;
579		NDBGL1(L1_H_XFRERR, "xmit data underrun");
580		/* abort the transmission */
581		sc->avma1pp_txl = 0;
582		sc->avma1pp_cmd |= HSCX_CMD_XRS;
583		AVMA1PPSETCMDLONG(param);
584		hscx_write_reg(h_chan, param, sc);
585		sc->avma1pp_cmd &= ~HSCX_CMD_XRS;
586		AVMA1PPSETCMDLONG(param);
587		hscx_write_reg(h_chan, param, sc);
588
589		if (chan->out_mbuf_head != NULL)  /* don't continue to transmit this buffer */
590		{
591			i4b_Bfreembuf(chan->out_mbuf_head);
592			chan->out_mbuf_cur = chan->out_mbuf_head = NULL;
593		}
594	}
595
596	/*
597	 * The following is based on examination of the Linux driver.
598	 *
599	 * The logic here is different than with a "real" HSCX; all kinds
600	 * of information (interrupt/status bits) are in stat.
601	 *		HSCX_INT_RPR indicates a receive interrupt
602	 *			HSCX_STAT_RDO indicates an overrun condition, abort -
603	 *			otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8)
604	 *			HSCX_STAT_RME indicates end-of-frame and apparently any
605	 *			CRC/framing errors are only reported in this state.
606	 *				if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR)
607	 *					CRC/framing error
608	 */
609
610	if(stat & HSCX_INT_RPR)
611	{
612		register int fifo_data_len;
613		int error = 0;
614		/* always have to read the FIFO, so use a scratch buffer */
615		u_char scrbuf[HSCX_FIFO_LEN];
616
617		if(stat & HSCX_STAT_RDO)
618		{
619			chan->stat_RDO++;
620			NDBGL1(L1_H_XFRERR, "receive data overflow");
621			error++;
622		}
623
624		/*
625		 * check whether we're receiving data for an inactive B-channel
626		 * and discard it. This appears to happen for telephony when
627		 * both B-channels are active and one is deactivated. Since
628		 * it is not really possible to deactivate the channel in that
629		 * case (the ASIC seems to deactivate _both_ channels), the
630		 * "deactivated" channel keeps receiving data which can lead
631		 * to exhaustion of mbufs and a kernel panic.
632		 *
633		 * This is a hack, but it's the only solution I can think of
634		 * without having the documentation for the ASIC.
635		 * GJ - 28 Nov 1999
636		 */
637		 if (chan->state == HSCX_IDLE)
638		 {
639			NDBGL1(L1_H_XFRERR, "toss data from %d", h_chan);
640			error++;
641		 }
642
643		fifo_data_len = ((stat & HSCX_STAT_RML_MASK) >> 8);
644
645		if(fifo_data_len == 0)
646			fifo_data_len = sc->sc_bfifolen;
647
648		/* ALWAYS read data from HSCX fifo */
649
650		HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len);
651		chan->rxcount += fifo_data_len;
652
653		/* all error conditions checked, now decide and take action */
654
655		if(error == 0)
656		{
657			if(chan->in_mbuf == NULL)
658			{
659				if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
660					panic("L1 avma1pp2_hscx_intr: RME, cannot allocate mbuf!");
661				chan->in_cbptr = chan->in_mbuf->m_data;
662				chan->in_len = 0;
663			}
664
665			if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
666			{
667			   	/* OK to copy the data */
668				memcpy(chan->in_cbptr, scrbuf, fifo_data_len);
669				chan->in_cbptr += fifo_data_len;
670				chan->in_len += fifo_data_len;
671
672				/* setup mbuf data length */
673
674				chan->in_mbuf->m_len = chan->in_len;
675				chan->in_mbuf->m_pkthdr.len = chan->in_len;
676
677				if(sc->sc_trace & TRACE_B_RX)
678				{
679					struct i4b_trace_hdr hdr;
680					hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
681					hdr.dir = FROM_NT;
682					hdr.count = ++sc->sc_trace_bcount;
683					isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
684				}
685
686				if (stat & HSCX_STAT_RME)
687				{
688				  if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR)
689				  {
690					 (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
691					 activity = ACT_RX;
692
693					 /* mark buffer ptr as unused */
694
695					 chan->in_mbuf = NULL;
696					 chan->in_cbptr = NULL;
697					 chan->in_len = 0;
698				  }
699				  else
700				  {
701						chan->stat_CRC++;
702						NDBGL1(L1_H_XFRERR, "CRC/RAB");
703					  if (chan->in_mbuf != NULL)
704					  {
705						  i4b_Bfreembuf(chan->in_mbuf);
706						  chan->in_mbuf = NULL;
707						  chan->in_cbptr = NULL;
708						  chan->in_len = 0;
709					  }
710				  }
711				}
712			} /* END enough space in mbuf */
713			else
714			{
715				 if(chan->bprot == BPROT_NONE)
716				 {
717					  /* setup mbuf data length */
718
719					  chan->in_mbuf->m_len = chan->in_len;
720					  chan->in_mbuf->m_pkthdr.len = chan->in_len;
721
722					  if(sc->sc_trace & TRACE_B_RX)
723					  {
724							struct i4b_trace_hdr hdr;
725							hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
726							hdr.dir = FROM_NT;
727							hdr.count = ++sc->sc_trace_bcount;
728							isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
729						}
730
731					  if(!(isdn_bchan_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
732						 activity = ACT_RX;
733
734					  /* move rx'd data to rx queue */
735
736					  if (!(IF_QFULL(&chan->rx_queue)))
737					  {
738					  	IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
739					  }
740					  else
741				       	  {
742						i4b_Bfreembuf(chan->in_mbuf);
743				          }
744
745					  /* signal upper layer that data are available */
746					  (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
747
748					  /* alloc new buffer */
749
750					  if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
751						 panic("L1 avma1pp2_hscx_intr: RPF, cannot allocate new mbuf!");
752
753					  /* setup new data ptr */
754
755					  chan->in_cbptr = chan->in_mbuf->m_data;
756
757					  /* OK to copy the data */
758					  memcpy(chan->in_cbptr, scrbuf, fifo_data_len);
759
760					  chan->in_cbptr += fifo_data_len;
761					  chan->in_len = fifo_data_len;
762
763					  chan->rxcount += fifo_data_len;
764					}
765				 else
766					{
767					  NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
768					  chan->in_cbptr = chan->in_mbuf->m_data;
769					  chan->in_len = 0;
770					}
771			  }
772		} /* if(error == 0) */
773		else
774		{
775		  	/* land here for RDO */
776			if (chan->in_mbuf != NULL)
777			{
778				i4b_Bfreembuf(chan->in_mbuf);
779				chan->in_mbuf = NULL;
780				chan->in_cbptr = NULL;
781				chan->in_len = 0;
782			}
783			sc->avma1pp_txl = 0;
784			sc->avma1pp_cmd |= HSCX_CMD_RRS;
785			AVMA1PPSETCMDLONG(param);
786			hscx_write_reg(h_chan, param, sc);
787			sc->avma1pp_cmd &= ~HSCX_CMD_RRS;
788			AVMA1PPSETCMDLONG(param);
789			hscx_write_reg(h_chan, param, sc);
790		}
791	}
792
793
794	/* transmit fifo empty, new data can be written to fifo */
795
796	if(stat & HSCX_INT_XPR)
797	{
798		/*
799		 * for a description what is going on here, please have
800		 * a look at isic_bchannel_start() in i4b_bchan.c !
801		 */
802
803		NDBGL1(L1_H_IRQ, "%s: chan %d - XPR, Tx Fifo Empty!", device_xname(&sc->sc_dev), h_chan);
804
805		if(chan->out_mbuf_cur == NULL) 	/* last frame is transmitted */
806		{
807			IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
808
809			if(chan->out_mbuf_head == NULL)
810			{
811				chan->state &= ~HSCX_TX_ACTIVE;
812				(*chan->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
813			}
814			else
815			{
816				chan->state |= HSCX_TX_ACTIVE;
817				chan->out_mbuf_cur = chan->out_mbuf_head;
818				chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
819				chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
820
821				if(sc->sc_trace & TRACE_B_TX)
822				{
823					struct i4b_trace_hdr hdr;
824					hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
825					hdr.dir = FROM_TE;
826					hdr.count = ++sc->sc_trace_bcount;
827					isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
828				}
829
830				if(chan->bprot == BPROT_NONE)
831				{
832					if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
833						activity = ACT_TX;
834				}
835				else
836				{
837					activity = ACT_TX;
838				}
839			}
840		}
841
842		isic_hscx_fifo(chan, sc);
843	}
844
845	/* call timeout handling routine */
846
847	if(activity == ACT_RX || activity == ACT_TX)
848		(*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
849}
850
851/*
852 * this is the main routine which checks each channel and then calls
853 * the real interrupt routine as appropriate
854 */
855static void
856avma1pp2_hscx_int_handler(struct isic_softc *sc)
857{
858	u_int stat;
859
860	/* has to be a u_int because the byte count is in the 2nd byte */
861	stat = hscx_read_reg_int(0, sc);
862	if (stat & HSCX_INT_MASK)
863	  avma1pp2_hscx_intr(0, stat, sc);
864	stat = hscx_read_reg_int(1, sc);
865	if (stat & HSCX_INT_MASK)
866	  avma1pp2_hscx_intr(1, stat, sc);
867}
868
869static void
870avma1pp2_disable(struct isic_softc *sc)
871{
872	/* could be still be wrong, but seems to prevent hangs */
873	bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, 0x00);
874}
875
876static int
877avma1pp2_intr(void *parm)
878{
879	struct isic_softc *sc = parm;
880	int ret = 0;
881#define OURS	ret = 1
882	u_char stat;
883
884	if (sc->sc_intr_valid != ISIC_INTR_VALID)
885		return 0;
886
887	stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET);
888	NDBGL1(L1_H_IRQ, "stat %x", stat);
889	/* was there an interrupt from this card ? */
890	if ((stat & ASL_IRQ_Pending) == 0)
891		return 0; /* no */
892	/* For slow machines loop as long as an interrupt is active */
893	for (; ((stat & ASL_IRQ_Pending) != 0) ;)
894	{
895		/* interrupts are high active */
896		if (stat & ASL_IRQ_TIMER)
897			NDBGL1(L1_H_IRQ, "timer interrupt ???");
898		if (stat & ASL_IRQ_HSCX)
899		{
900			NDBGL1(L1_H_IRQ, "HSCX");
901			avma1pp2_hscx_int_handler(sc);
902		}
903		if (stat & ASL_IRQ_ISAC)
904		{
905		       u_char isacsx_irq_stat;
906
907		       NDBGL1(L1_H_IRQ, "ISAC");
908		       for(;;)
909		       {
910			  /* ISTA tells us whether it was a C/I or HDLC int. */
911			  isacsx_irq_stat = ISAC_READ(I_ISTA);
912
913			  if(isacsx_irq_stat)
914				isic_isacsx_irq(sc, isacsx_irq_stat); /* isac handler */
915			  else
916				break;
917		       }
918
919		       /*
920			* XXX: Leo: Note that Linux doesn't do this mask
921			*           frobbing...
922			*/
923		       ISAC_WRITE(I_MASKD, 0xff);
924		       ISAC_WRITE(I_MASK, 0xff);
925
926		       DELAY(100);
927
928		       ISAC_WRITE(I_MASKD, isacsx_imaskd);
929		       ISAC_WRITE(I_MASK, isacsx_imask);
930
931		}
932		stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET);
933		NDBGL1(L1_H_IRQ, "stat %x", stat);
934		OURS;
935	}
936	return ret;
937}
938
939static void
940avma1pp2_map_int(struct ifpci_softc *psc, struct pci_attach_args *pa)
941{
942	struct isic_softc *sc = &psc->sc_isic;
943	pci_chipset_tag_t pc = pa->pa_pc;
944	pci_intr_handle_t ih;
945	const char *intrstr;
946
947	/* Map and establish the interrupt. */
948	if (pci_intr_map(pa, &ih)) {
949		aprint_error_dev(&sc->sc_dev, "couldn't map interrupt\n");
950		avma1pp2_disable(sc);
951		return;
952	}
953	psc->sc_pc = pc;
954	intrstr = pci_intr_string(pc, ih);
955	psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, avma1pp2_intr, sc);
956	if (psc->sc_ih == NULL) {
957		aprint_error_dev(&sc->sc_dev, "couldn't establish interrupt");
958		if (intrstr != NULL)
959			aprint_error(" at %s", intrstr);
960		aprint_error("\n");
961		avma1pp2_disable(sc);
962		return;
963	}
964	aprint_normal_dev(&sc->sc_dev, "interrupting at %s\n", intrstr);
965}
966
967static void
968avma1pp2_hscx_init(struct isic_softc *sc, int h_chan, int activate)
969{
970	l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
971	u_int param = 0;
972
973	NDBGL1(L1_BCHAN, "%s: channel=%d, %s",
974		device_xname(&sc->sc_dev), h_chan, activate ? "activate" : "deactivate");
975	sc->avma1pp_cmd = sc->avma1pp_prot = sc->avma1pp_txl = 0;
976
977	if (activate == 0)
978	{
979		/* only deactivate if both channels are idle */
980		if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE ||
981			sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE)
982		{
983			return;
984		}
985		sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
986		sc->avma1pp_prot = HSCX_MODE_TRANS;
987		AVMA1PPSETCMDLONG(param);
988		hscx_write_reg(h_chan, param, sc);
989		return;
990	}
991	if(chan->bprot == BPROT_RHDLC)
992	{
993		  NDBGL1(L1_BCHAN, "BPROT_RHDLC");
994
995		/* HDLC Frames, transparent mode 0 */
996		sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
997		sc->avma1pp_prot = HSCX_MODE_ITF_FLG;
998		AVMA1PPSETCMDLONG(param);
999		hscx_write_reg(h_chan, param, sc);
1000		sc->avma1pp_cmd = HSCX_CMD_XRS;
1001		AVMA1PPSETCMDLONG(param);
1002		hscx_write_reg(h_chan, param, sc);
1003		sc->avma1pp_cmd = 0;
1004	}
1005	else
1006	{
1007		  NDBGL1(L1_BCHAN, "BPROT_NONE??");
1008
1009		/* Raw Telephony, extended transparent mode 1 */
1010		sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS;
1011		sc->avma1pp_prot = HSCX_MODE_TRANS;
1012		AVMA1PPSETCMDLONG(param);
1013		hscx_write_reg(h_chan, param, sc);
1014		sc->avma1pp_cmd = HSCX_CMD_XRS;
1015		AVMA1PPSETCMDLONG(param);
1016		hscx_write_reg(h_chan, param, sc);
1017		sc->avma1pp_cmd = 0;
1018	}
1019}
1020
1021static void
1022avma1pp2_bchannel_setup(isdn_layer1token t, int h_chan, int bprot, int activate)
1023{
1024	struct isic_softc *sc = (struct isic_softc*)t;
1025	l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1026
1027	int s = splnet();
1028
1029	if(activate == 0)
1030	{
1031		/* deactivation */
1032		chan->state = HSCX_IDLE;
1033		avma1pp2_hscx_init(sc, h_chan, activate);
1034	}
1035
1036	NDBGL1(L1_BCHAN, "%s: channel=%d, %s",
1037		device_xname(&sc->sc_dev), h_chan, activate ? "activate" : "deactivate");
1038
1039	/* general part */
1040
1041	chan->channel = h_chan;		/* B channel */
1042	chan->bprot = bprot;		/* B channel protocol */
1043	chan->state = HSCX_IDLE;	/* B channel state */
1044
1045	/* receiver part */
1046
1047	i4b_Bcleanifq(&chan->rx_queue);	/* clean rx queue */
1048
1049	chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
1050
1051	chan->rxcount = 0;		/* reset rx counter */
1052
1053	i4b_Bfreembuf(chan->in_mbuf);	/* clean rx mbuf */
1054
1055	chan->in_mbuf = NULL;		/* reset mbuf ptr */
1056	chan->in_cbptr = NULL;		/* reset mbuf curr ptr */
1057	chan->in_len = 0;		/* reset mbuf data len */
1058
1059	/* transmitter part */
1060
1061	i4b_Bcleanifq(&chan->tx_queue);	/* clean tx queue */
1062
1063	chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
1064
1065	chan->txcount = 0;		/* reset tx counter */
1066
1067	i4b_Bfreembuf(chan->out_mbuf_head);	/* clean tx mbuf */
1068
1069	chan->out_mbuf_head = NULL;	/* reset head mbuf ptr */
1070	chan->out_mbuf_cur = NULL;	/* reset current mbuf ptr */
1071	chan->out_mbuf_cur_ptr = NULL;	/* reset current mbuf data ptr */
1072	chan->out_mbuf_cur_len = 0;	/* reset current mbuf data cnt */
1073
1074	if(activate != 0)
1075	{
1076		/* activation */
1077		avma1pp2_hscx_init(sc, h_chan, activate);
1078		chan->state |= HSCX_AVMA1PP_ACTIVE;
1079	}
1080
1081	splx(s);
1082}
1083
1084static void
1085avma1pp2_bchannel_start(isdn_layer1token t, int h_chan)
1086{
1087	struct isic_softc *sc = (struct isic_softc*)t;
1088	register l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1089	int s;
1090	int activity = -1;
1091
1092	s = splnet();				/* enter critical section */
1093	if(chan->state & HSCX_TX_ACTIVE)	/* already running ? */
1094	{
1095		splx(s);
1096		return;				/* yes, leave */
1097	}
1098
1099	/* get next mbuf from queue */
1100
1101	IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
1102
1103	if(chan->out_mbuf_head == NULL)		/* queue empty ? */
1104	{
1105		splx(s);			/* leave critical section */
1106		return;				/* yes, exit */
1107	}
1108
1109	/* init current mbuf values */
1110
1111	chan->out_mbuf_cur = chan->out_mbuf_head;
1112	chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
1113	chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
1114
1115	/* activity indicator for timeout handling */
1116
1117	if(chan->bprot == BPROT_NONE)
1118	{
1119		if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
1120			activity = ACT_TX;
1121	}
1122	else
1123	{
1124		activity = ACT_TX;
1125	}
1126
1127	chan->state |= HSCX_TX_ACTIVE;		/* we start transmitting */
1128
1129	if(sc->sc_trace & TRACE_B_TX)	/* if trace, send mbuf to trace dev */
1130	{
1131		struct i4b_trace_hdr hdr;
1132		hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
1133		hdr.dir = FROM_TE;
1134		hdr.count = ++sc->sc_trace_bcount;
1135		isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
1136	}
1137
1138	isic_hscx_fifo(chan, sc);
1139
1140	/* call timeout handling routine */
1141
1142	if(activity == ACT_RX || activity == ACT_TX)
1143		(*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
1144
1145	splx(s);
1146}
1147
1148/*---------------------------------------------------------------------------*
1149 *	return the address of isic drivers linktab
1150 *---------------------------------------------------------------------------*/
1151static isdn_link_t *
1152avma1pp2_ret_linktab(void *token, int channel)
1153{
1154	struct l2_softc *l2sc = token;
1155	struct isic_softc *sc = l2sc->l1_token;
1156
1157	l1_bchan_state_t *chan = &sc->sc_chan[channel];
1158
1159	return(&chan->isdn_linktab);
1160}
1161
1162/*---------------------------------------------------------------------------*
1163 *	set the driver linktab in the b channel softc
1164 *---------------------------------------------------------------------------*/
1165static void
1166avma1pp2_set_link(void *token, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc)
1167{
1168	struct l2_softc *l2sc = token;
1169	struct isic_softc *sc = l2sc->l1_token;
1170	l1_bchan_state_t *chan = &sc->sc_chan[channel];
1171
1172	chan->l4_driver = l4_driver;
1173	chan->l4_driver_softc = l4_driver_softc;
1174}
1175
1176static const struct isdn_l4_bchannel_functions
1177avma1pp2_l4_bchannel_functions = {
1178	avma1pp2_bchannel_setup,
1179	avma1pp2_bchannel_start,
1180	avma1pp2_bchannel_stat
1181};
1182
1183/*---------------------------------------------------------------------------*
1184 *	initialize our local linktab
1185 *---------------------------------------------------------------------------*/
1186static void
1187avma1pp2_init_linktab(struct isic_softc *sc)
1188{
1189	l1_bchan_state_t *chan = &sc->sc_chan[HSCX_CH_A];
1190	isdn_link_t *lt = &chan->isdn_linktab;
1191
1192	/* local setup */
1193	lt->l1token = sc;
1194	lt->channel = HSCX_CH_A;
1195	lt->bchannel_driver = &avma1pp2_l4_bchannel_functions;
1196	lt->tx_queue = &chan->tx_queue;
1197
1198	/* used by non-HDLC data transfers, i.e. telephony drivers */
1199	lt->rx_queue = &chan->rx_queue;
1200
1201	/* used by HDLC data transfers, i.e. ipr and isp drivers */
1202	lt->rx_mbuf = &chan->in_mbuf;
1203
1204	chan = &sc->sc_chan[HSCX_CH_B];
1205	lt = &chan->isdn_linktab;
1206
1207	lt->l1token = sc;
1208	lt->channel = HSCX_CH_B;
1209	lt->bchannel_driver = &avma1pp2_l4_bchannel_functions;
1210	lt->tx_queue = &chan->tx_queue;
1211
1212	/* used by non-HDLC data transfers, i.e. telephony drivers */
1213	lt->rx_queue = &chan->rx_queue;
1214
1215	/* used by HDLC data transfers, i.e. ipr and isp drivers */
1216	lt->rx_mbuf = &chan->in_mbuf;
1217}
1218
1219/*
1220 * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static
1221 */
1222static void
1223avma1pp2_bchannel_stat(isdn_layer1token t, int h_chan, bchan_statistics_t *bsp)
1224{
1225	struct isic_softc *sc = (struct isic_softc*)t;
1226	l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
1227	int s;
1228
1229	s = splnet();
1230
1231	bsp->outbytes = chan->txcount;
1232	bsp->inbytes = chan->rxcount;
1233
1234	chan->txcount = 0;
1235	chan->rxcount = 0;
1236
1237	splx(s);
1238}
1239
1240/*---------------------------------------------------------------------------*
1241 *	fill HSCX fifo with data from the current mbuf
1242 *	Put this here until it can go into i4b_hscx.c
1243 *---------------------------------------------------------------------------*/
1244static int
1245isic_hscx_fifo(l1_bchan_state_t *chan, struct isic_softc *sc)
1246{
1247	int len;
1248	int nextlen;
1249	int i;
1250	int cmd;
1251	/* using a scratch buffer simplifies writing to the FIFO */
1252	u_char scrbuf[HSCX_FIFO_LEN];
1253
1254	len = 0;
1255	cmd = 0;
1256
1257	/*
1258	 * fill the HSCX tx fifo with data from the current mbuf. if
1259	 * current mbuf holds less data than HSCX fifo length, try to
1260	 * get the next mbuf from (a possible) mbuf chain. if there is
1261	 * not enough data in a single mbuf or in a chain, then this
1262	 * is the last mbuf and we tell the HSCX that it has to send
1263	 * CRC and closing flag
1264	 */
1265
1266	while(chan->out_mbuf_cur && len != sc->sc_bfifolen)
1267	{
1268		nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len);
1269
1270#ifdef NOTDEF
1271		printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ",
1272			chan->out_mbuf_head,
1273			chan->out_mbuf_cur,
1274			chan->out_mbuf_cur_ptr,
1275			chan->out_mbuf_cur_len,
1276			len,
1277			nextlen);
1278#endif
1279
1280		cmd |= HSCX_CMDR_XTF;
1281		/* collect the data in the scratch buffer */
1282		for (i = 0; i < nextlen; i++)
1283			scrbuf[i + len] = chan->out_mbuf_cur_ptr[i];
1284
1285		len += nextlen;
1286		chan->txcount += nextlen;
1287
1288		chan->out_mbuf_cur_ptr += nextlen;
1289		chan->out_mbuf_cur_len -= nextlen;
1290
1291		if(chan->out_mbuf_cur_len == 0)
1292		{
1293			if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
1294			{
1295				chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
1296				chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
1297
1298				if(sc->sc_trace & TRACE_B_TX)
1299				{
1300					struct i4b_trace_hdr hdr;
1301					hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
1302					hdr.dir = FROM_TE;
1303					hdr.count = ++sc->sc_trace_bcount;
1304					isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
1305				}
1306			}
1307			else
1308			{
1309				if (chan->bprot != BPROT_NONE)
1310					cmd |= HSCX_CMDR_XME;
1311				i4b_Bfreembuf(chan->out_mbuf_head);
1312				chan->out_mbuf_head = NULL;
1313			}
1314		}
1315	}
1316	/* write what we have from the scratch buf to the HSCX fifo */
1317	if (len != 0)
1318		HSCX_WRFIFO(chan->channel, scrbuf, len);
1319	return(cmd);
1320}
1321