1 /* $NetBSD: ifpci2.c,v 1.18 2009/11/26 15:17:10 njoly Exp $ */
3 * Copyright (c) 1999 Gary Jennejohn. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * 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.
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.
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
32 *---------------------------------------------------------------------------
33 * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c
34 *---------------------------------------------------------------------------
36 * Fritz!Card PCI driver
37 * ------------------------------------------------
39 * $Id: ifpci2.c,v 1.19 2009/12/06 23:14:05 dyoung Exp $
41 * last edit-date: [Fri Jan 5 11:38:58 2001]
43 *---------------------------------------------------------------------------*/
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: ifpci2.c,v 1.18 2009/11/26 15:17:10 njoly Exp $");
49 #include <sys/param.h>
50 #include <sys/ioctl.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
56 #include <sys/device.h>
58 #include <sys/socket.h>
61 #include <sys/callout.h>
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>
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>
75 #include <dev/ic/isic_l1.h>
76 #include <dev/ic/isacsx.h>
77 #include <dev/ic/hscx.h>
79 #include <dev/pci/isic_pci.h>
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
85 static isdn_link_t
*avma1pp2_ret_linktab(void *token
, int channel
);
86 static void avma1pp2_set_link(void *token
, int channel
, const struct isdn_l4_driver_functions
*l4_driver
, void *l4_driver_softc
);
88 void n_connect_request(struct call_desc
*cd
);
89 void n_connect_response(struct call_desc
*cd
, int response
, int cause
);
90 void n_disconnect_request(struct call_desc
*cd
, int cause
);
91 void n_alert_request(struct call_desc
*cd
);
92 void n_mgmt_command(struct isdn_l3_driver
*drv
, int cmd
, void *parm
);
94 extern const struct isdn_layer1_isdnif_driver isic_std_driver
;
96 const struct isdn_l3_driver_functions
102 n_disconnect_request
,
110 struct isic_softc sc_isic
; /* parent class */
112 /* PCI-specific goo */
113 void *sc_ih
; /* interrupt handler */
116 pci_chipset_tag_t sc_pc
;
120 static void avma1pp2_disable(struct isic_softc
*);
121 static int isic_hscx_fifo(l1_bchan_state_t
*chan
, struct isic_softc
*sc
);
123 static int avma1pp2_intr(void*);
124 static void avma1pp2_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
);
125 static void avma1pp2_write_fifo(struct isic_softc
*sc
, int what
, const void *buf
, size_t size
);
126 static void avma1pp2_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
);
127 static u_int8_t
avma1pp2_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
);
128 static void hscx_write_fifo(int chan
, const void *buf
, size_t len
, struct isic_softc
*sc
);
129 static void hscx_read_fifo(int chan
, void *buf
, size_t len
, struct isic_softc
*sc
);
130 static void hscx_write_reg(int chan
, u_int val
, struct isic_softc
*sc
);
131 static u_char
hscx_read_reg(int chan
, struct isic_softc
*sc
);
132 static u_int
hscx_read_reg_int(int chan
, struct isic_softc
*sc
);
133 static void avma1pp2_bchannel_stat(isdn_layer1token
, int h_chan
, bchan_statistics_t
*bsp
);
134 static void avma1pp2_map_int(struct ifpci_softc
*sc
, struct pci_attach_args
*pa
);
135 static void avma1pp2_bchannel_setup(isdn_layer1token
, int h_chan
, int bprot
, int activate
);
136 static void avma1pp2_init_linktab(struct isic_softc
*);
137 static int ifpci2_match(device_t parent
, cfdata_t match
, void *aux
);
138 static void ifpci2_attach(device_t parent
, device_t self
, void *aux
);
139 static int ifpci2_detach(device_t self
, int flags
);
140 static int ifpci2_activate(device_t self
, enum devact act
);
142 CFATTACH_DECL(ifritz
, sizeof(struct ifpci_softc
),
143 ifpci2_match
, ifpci2_attach
, ifpci2_detach
, ifpci2_activate
);
145 /*---------------------------------------------------------------------------*
146 * AVM PCI Fritz!Card V. 2 special registers
147 *---------------------------------------------------------------------------*/
150 * AVM PCI Status Latch 0 read only bits
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)
160 * AVM PCI Status Latch 0 read only bits
162 #define ASL_RESET 0x01
163 #define ASL_TIMERRESET 0x04
164 #define ASL_ENABLE_INT 0x08
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
176 * "HSCX" interrupt bits
178 #define HSCX_INT_XPR 0x80
179 #define HSCX_INT_XDU 0x40
180 #define HSCX_INT_RPR 0x20
181 #define HSCX_INT_MASK 0xE0
184 * "HSCX" command bits
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
191 /* "HSCX" mode bits */
192 #define HSCX_MODE_ITF_FLG 0x01
193 #define HSCX_MODE_TRANS 0x02
195 /* offsets to various registers in the ASIC, evidently */
196 #define STAT0_OFFSET 0x02
198 #define HSCX_FIFO1 0x10
199 #define HSCX_FIFO2 0x18
201 #define HSCX_STAT1 0x14
202 #define HSCX_STAT2 0x1c
204 #define ISACSX_INDEX 0x04
205 #define ISACSX_DATA 0x08
208 * Commands and parameters are sent to the "HSCX" as a long, but the
209 * fields are handled as bytes.
212 * (prot << 16)|(txl << 8)|cmd
215 * prot = protocol to use
216 * txl = transmit length
217 * cmd = the command to be executed
219 * The fields are defined as u_char in struct l1_softc.
221 * Macro to coalesce the byte fields into a u_int
223 #define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \
224 | (sc->avma1pp_prot << 16))
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.
232 #define HSCX_AVMA1PP_ACTIVE 0x1000
235 ifpci2_match(device_t parent
, cfdata_t match
, void *aux
)
237 struct pci_attach_args
*pa
= aux
;
239 if (PCI_VENDOR(pa
->pa_id
) == PCI_VENDOR_AVM
&&
240 PCI_PRODUCT(pa
->pa_id
) == PCI_PRODUCT_AVM_FRITZ_PCI_V2_ISDN
)
246 ifpci2_attach(device_t parent
, device_t self
, void *aux
)
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
;
255 printf(": Fritz!PCI V2 card\n");
258 callout_init(&sc
->sc_T3_callout
, 0);
259 callout_init(&sc
->sc_T4_callout
, 0);
261 /* setup io mappings */
262 sc
->sc_num_mappings
= 1;
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");
271 /* setup access routines */
274 sc
->readreg
= avma1pp2_read_reg
;
275 sc
->writereg
= avma1pp2_write_reg
;
277 sc
->readfifo
= avma1pp2_read_fifo
;
278 sc
->writefifo
= avma1pp2_write_fifo
;
281 /* setup card type */
283 sc
->sc_cardtyp
= CARD_TYPEP_AVMA1PCIV2
;
285 /* setup IOM bus type */
287 sc
->sc_bustyp
= BUS_TYPE_IOM2
;
289 /* this is no IPAC based card */
291 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
293 /* setup interrupt mapping */
294 avma1pp2_map_int(psc
, pa
);
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 */
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 */
311 /* setup i4b infrastructure (have to roll our own here) */
313 /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */
314 printf("%s: ISACSX %s\n", device_xname(&sc
->sc_dev
), "PSB3186");
317 isic_isacsx_init(sc
);
319 v
= ISAC_READ(I_CIR0
); /* Leo: reset generates status change */
321 /* init the "HSCX" */
322 avma1pp2_bchannel_setup(sc
, HSCX_CH_A
, BPROT_NONE
, 0);
324 avma1pp2_bchannel_setup(sc
, HSCX_CH_B
, BPROT_NONE
, 0);
326 /* can't use the normal B-Channel stuff */
327 avma1pp2_init_linktab(sc
);
329 /* set trace level */
331 sc
->sc_trace
= TRACE_OFF
;
333 sc
->sc_state
= ISAC_IDLE
;
345 sc
->sc_freeflag2
= 0;
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
;
354 isdn_layer2_status_ind(&sc
->sc_l2
, drv
, STI_ATTACH
, 1);
355 isdn_isdnif_ready(drv
->isdnif
);
359 ifpci2_detach(device_t self
, int flags
)
361 struct ifpci_softc
*psc
= device_private(self
);
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
);
371 ifpci2_activate(device_t self
, enum devact act
)
373 struct ifpci_softc
*psc
= device_private(self
);
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
;
387 /*---------------------------------------------------------------------------*
388 * AVM read fifo routines
389 *---------------------------------------------------------------------------*/
392 avma1pp2_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
)
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
);
403 case ISIC_WHAT_HSCXA
:
404 hscx_read_fifo(0, buf
, size
, sc
);
406 case ISIC_WHAT_HSCXB
:
407 hscx_read_fifo(1, buf
, size
, sc
);
413 hscx_read_fifo(int chan
, void *buf
, size_t len
, struct isic_softc
*sc
)
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)) {
423 buf
= ((unsigned char*)buf
) + (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
);
431 /*---------------------------------------------------------------------------*
432 * AVM write fifo routines
433 *---------------------------------------------------------------------------*/
436 avma1pp2_write_fifo(struct isic_softc
*sc
, int what
, const void *buf
, size_t size
)
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
]);
447 case ISIC_WHAT_HSCXA
:
448 hscx_write_fifo(0, buf
, size
, sc
);
450 case ISIC_WHAT_HSCXB
:
451 hscx_write_fifo(1, buf
, size
, sc
);
457 hscx_write_fifo(int chan
, const void *buf
, size_t len
, struct isic_softc
*sc
)
461 l1_bchan_state_t
*Bchan
= &sc
->sc_chan
[chan
];
463 dataoff
= chan
? HSCX_FIFO2
: HSCX_FIFO1
;
465 sc
->avma1pp_cmd
&= ~HSCX_CMD_XME
;
467 if (Bchan
->out_mbuf_cur
== NULL
)
469 if (Bchan
->bprot
!= BPROT_NONE
)
470 sc
->avma1pp_cmd
|= HSCX_CMD_XME
;
472 if (len
!= sc
->sc_bfifolen
)
473 sc
->avma1pp_txl
= len
;
475 cnt
= 0; /* borrow cnt */
476 AVMA1PPSETCMDLONG(cnt
);
477 hscx_write_reg(chan
, cnt
, sc
);
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)) {
484 buf
= (const unsigned char*)buf
+ (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
,
493 /*---------------------------------------------------------------------------*
494 * AVM write register routines
495 *---------------------------------------------------------------------------*/
498 avma1pp2_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
)
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
);
505 case ISIC_WHAT_HSCXA
:
506 hscx_write_reg(0, data
, sc
);
508 case ISIC_WHAT_HSCXB
:
509 hscx_write_reg(1, data
, sc
);
515 hscx_write_reg(int chan
, u_int val
, struct isic_softc
*sc
)
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
);
523 /*---------------------------------------------------------------------------*
524 * AVM read register routines
525 *---------------------------------------------------------------------------*/
528 avma1pp2_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
)
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
);
537 case ISIC_WHAT_HSCXA
:
538 return hscx_read_reg(0, sc
);
539 case ISIC_WHAT_HSCXB
:
540 return hscx_read_reg(1, sc
);
546 hscx_read_reg(int chan
, struct isic_softc
*sc
)
548 return(hscx_read_reg_int(chan
, sc
) & 0xff);
552 * need to be able to return an int because the RBCH is in the 2nd
556 hscx_read_reg_int(int chan
, struct isic_softc
*sc
)
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
));
565 * this is the real interrupt routine
568 avma1pp2_hscx_intr(int h_chan
, u_int stat
, struct isic_softc
*sc
)
570 register l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
574 NDBGL1(L1_H_IRQ
, "%#x", stat
);
576 if((stat
& HSCX_INT_XDU
) && (chan
->bprot
!= BPROT_NONE
))/* xmit data underrun */
579 NDBGL1(L1_H_XFRERR
, "xmit data underrun");
580 /* abort the transmission */
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
);
589 if (chan
->out_mbuf_head
!= NULL
) /* don't continue to transmit this buffer */
591 i4b_Bfreembuf(chan
->out_mbuf_head
);
592 chan
->out_mbuf_cur
= chan
->out_mbuf_head
= NULL
;
597 * The following is based on examination of the Linux driver.
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)
610 if(stat
& HSCX_INT_RPR
)
612 register int fifo_data_len
;
614 /* always have to read the FIFO, so use a scratch buffer */
615 u_char scrbuf
[HSCX_FIFO_LEN
];
617 if(stat
& HSCX_STAT_RDO
)
620 NDBGL1(L1_H_XFRERR
, "receive data overflow");
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.
633 * This is a hack, but it's the only solution I can think of
634 * without having the documentation for the ASIC.
637 if (chan
->state
== HSCX_IDLE
)
639 NDBGL1(L1_H_XFRERR
, "toss data from %d", h_chan
);
643 fifo_data_len
= ((stat
& HSCX_STAT_RML_MASK
) >> 8);
645 if(fifo_data_len
== 0)
646 fifo_data_len
= sc
->sc_bfifolen
;
648 /* ALWAYS read data from HSCX fifo */
650 HSCX_RDFIFO(h_chan
, scrbuf
, fifo_data_len
);
651 chan
->rxcount
+= fifo_data_len
;
653 /* all error conditions checked, now decide and take action */
657 if(chan
->in_mbuf
== NULL
)
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
;
665 if((chan
->in_len
+ fifo_data_len
) <= BCH_MAX_DATALEN
)
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
;
672 /* setup mbuf data length */
674 chan
->in_mbuf
->m_len
= chan
->in_len
;
675 chan
->in_mbuf
->m_pkthdr
.len
= chan
->in_len
;
677 if(sc
->sc_trace
& TRACE_B_RX
)
679 struct i4b_trace_hdr hdr
;
680 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
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
);
686 if (stat
& HSCX_STAT_RME
)
688 if((stat
& HSCX_STAT_CRCVFRRAB
) == HSCX_STAT_CRCVFR
)
690 (*chan
->l4_driver
->bch_rx_data_ready
)(chan
->l4_driver_softc
);
693 /* mark buffer ptr as unused */
695 chan
->in_mbuf
= NULL
;
696 chan
->in_cbptr
= NULL
;
702 NDBGL1(L1_H_XFRERR
, "CRC/RAB");
703 if (chan
->in_mbuf
!= NULL
)
705 i4b_Bfreembuf(chan
->in_mbuf
);
706 chan
->in_mbuf
= NULL
;
707 chan
->in_cbptr
= NULL
;
712 } /* END enough space in mbuf */
715 if(chan
->bprot
== BPROT_NONE
)
717 /* setup mbuf data length */
719 chan
->in_mbuf
->m_len
= chan
->in_len
;
720 chan
->in_mbuf
->m_pkthdr
.len
= chan
->in_len
;
722 if(sc
->sc_trace
& TRACE_B_RX
)
724 struct i4b_trace_hdr hdr
;
725 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
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
);
731 if(!(isdn_bchan_silence(chan
->in_mbuf
->m_data
, chan
->in_mbuf
->m_len
)))
734 /* move rx'd data to rx queue */
736 if (!(IF_QFULL(&chan
->rx_queue
)))
738 IF_ENQUEUE(&chan
->rx_queue
, chan
->in_mbuf
);
742 i4b_Bfreembuf(chan
->in_mbuf
);
745 /* signal upper layer that data are available */
746 (*chan
->l4_driver
->bch_rx_data_ready
)(chan
->l4_driver_softc
);
748 /* alloc new buffer */
750 if((chan
->in_mbuf
= i4b_Bgetmbuf(BCH_MAX_DATALEN
)) == NULL
)
751 panic("L1 avma1pp2_hscx_intr: RPF, cannot allocate new mbuf!");
753 /* setup new data ptr */
755 chan
->in_cbptr
= chan
->in_mbuf
->m_data
;
757 /* OK to copy the data */
758 memcpy(chan
->in_cbptr
, scrbuf
, fifo_data_len
);
760 chan
->in_cbptr
+= fifo_data_len
;
761 chan
->in_len
= fifo_data_len
;
763 chan
->rxcount
+= fifo_data_len
;
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
;
772 } /* if(error == 0) */
775 /* land here for RDO */
776 if (chan
->in_mbuf
!= NULL
)
778 i4b_Bfreembuf(chan
->in_mbuf
);
779 chan
->in_mbuf
= NULL
;
780 chan
->in_cbptr
= NULL
;
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
);
794 /* transmit fifo empty, new data can be written to fifo */
796 if(stat
& HSCX_INT_XPR
)
799 * for a description what is going on here, please have
800 * a look at isic_bchannel_start() in i4b_bchan.c !
803 NDBGL1(L1_H_IRQ
, "%s: chan %d - XPR, Tx Fifo Empty!", device_xname(&sc
->sc_dev
), h_chan
);
805 if(chan
->out_mbuf_cur
== NULL
) /* last frame is transmitted */
807 IF_DEQUEUE(&chan
->tx_queue
, chan
->out_mbuf_head
);
809 if(chan
->out_mbuf_head
== NULL
)
811 chan
->state
&= ~HSCX_TX_ACTIVE
;
812 (*chan
->l4_driver
->bch_tx_queue_empty
)(chan
->l4_driver_softc
);
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
;
821 if(sc
->sc_trace
& TRACE_B_TX
)
823 struct i4b_trace_hdr hdr
;
824 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
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
);
830 if(chan
->bprot
== BPROT_NONE
)
832 if(!(isdn_bchan_silence(chan
->out_mbuf_cur
->m_data
, chan
->out_mbuf_cur
->m_len
)))
842 isic_hscx_fifo(chan
, sc
);
845 /* call timeout handling routine */
847 if(activity
== ACT_RX
|| activity
== ACT_TX
)
848 (*chan
->l4_driver
->bch_activity
)(chan
->l4_driver_softc
, activity
);
852 * this is the main routine which checks each channel and then calls
853 * the real interrupt routine as appropriate
856 avma1pp2_hscx_int_handler(struct isic_softc
*sc
)
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
);
870 avma1pp2_disable(struct isic_softc
*sc
)
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);
877 avma1pp2_intr(void *parm
)
879 struct isic_softc
*sc
= parm
;
884 if (sc
->sc_intr_valid
!= ISIC_INTR_VALID
)
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)
892 /* For slow machines loop as long as an interrupt is active */
893 for (; ((stat
& ASL_IRQ_Pending
) != 0) ;)
895 /* interrupts are high active */
896 if (stat
& ASL_IRQ_TIMER
)
897 NDBGL1(L1_H_IRQ
, "timer interrupt ???");
898 if (stat
& ASL_IRQ_HSCX
)
900 NDBGL1(L1_H_IRQ
, "HSCX");
901 avma1pp2_hscx_int_handler(sc
);
903 if (stat
& ASL_IRQ_ISAC
)
905 u_char isacsx_irq_stat
;
907 NDBGL1(L1_H_IRQ
, "ISAC");
910 /* ISTA tells us whether it was a C/I or HDLC int. */
911 isacsx_irq_stat
= ISAC_READ(I_ISTA
);
914 isic_isacsx_irq(sc
, isacsx_irq_stat
); /* isac handler */
920 * XXX: Leo: Note that Linux doesn't do this mask
923 ISAC_WRITE(I_MASKD
, 0xff);
924 ISAC_WRITE(I_MASK
, 0xff);
928 ISAC_WRITE(I_MASKD
, isacsx_imaskd
);
929 ISAC_WRITE(I_MASK
, isacsx_imask
);
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
);
940 avma1pp2_map_int(struct ifpci_softc
*psc
, struct pci_attach_args
*pa
)
942 struct isic_softc
*sc
= &psc
->sc_isic
;
943 pci_chipset_tag_t pc
= pa
->pa_pc
;
944 pci_intr_handle_t ih
;
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
);
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");
959 aprint_error(" at %s", intrstr
);
961 avma1pp2_disable(sc
);
964 aprint_normal_dev(&sc
->sc_dev
, "interrupting at %s\n", intrstr
);
968 avma1pp2_hscx_init(struct isic_softc
*sc
, int h_chan
, int activate
)
970 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
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;
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
)
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
);
991 if(chan
->bprot
== BPROT_RHDLC
)
993 NDBGL1(L1_BCHAN
, "BPROT_RHDLC");
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;
1007 NDBGL1(L1_BCHAN
, "BPROT_NONE??");
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;
1022 avma1pp2_bchannel_setup(isdn_layer1token t
, int h_chan
, int bprot
, int activate
)
1024 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1025 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1032 chan
->state
= HSCX_IDLE
;
1033 avma1pp2_hscx_init(sc
, h_chan
, activate
);
1036 NDBGL1(L1_BCHAN
, "%s: channel=%d, %s",
1037 device_xname(&sc
->sc_dev
), h_chan
, activate
? "activate" : "deactivate");
1041 chan
->channel
= h_chan
; /* B channel */
1042 chan
->bprot
= bprot
; /* B channel protocol */
1043 chan
->state
= HSCX_IDLE
; /* B channel state */
1047 i4b_Bcleanifq(&chan
->rx_queue
); /* clean rx queue */
1049 chan
->rx_queue
.ifq_maxlen
= IFQ_MAXLEN
;
1051 chan
->rxcount
= 0; /* reset rx counter */
1053 i4b_Bfreembuf(chan
->in_mbuf
); /* clean rx mbuf */
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 */
1059 /* transmitter part */
1061 i4b_Bcleanifq(&chan
->tx_queue
); /* clean tx queue */
1063 chan
->tx_queue
.ifq_maxlen
= IFQ_MAXLEN
;
1065 chan
->txcount
= 0; /* reset tx counter */
1067 i4b_Bfreembuf(chan
->out_mbuf_head
); /* clean tx mbuf */
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 */
1077 avma1pp2_hscx_init(sc
, h_chan
, activate
);
1078 chan
->state
|= HSCX_AVMA1PP_ACTIVE
;
1085 avma1pp2_bchannel_start(isdn_layer1token t
, int h_chan
)
1087 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1088 register l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1092 s
= splnet(); /* enter critical section */
1093 if(chan
->state
& HSCX_TX_ACTIVE
) /* already running ? */
1096 return; /* yes, leave */
1099 /* get next mbuf from queue */
1101 IF_DEQUEUE(&chan
->tx_queue
, chan
->out_mbuf_head
);
1103 if(chan
->out_mbuf_head
== NULL
) /* queue empty ? */
1105 splx(s
); /* leave critical section */
1106 return; /* yes, exit */
1109 /* init current mbuf values */
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
;
1115 /* activity indicator for timeout handling */
1117 if(chan
->bprot
== BPROT_NONE
)
1119 if(!(isdn_bchan_silence(chan
->out_mbuf_cur
->m_data
, chan
->out_mbuf_cur
->m_len
)))
1127 chan
->state
|= HSCX_TX_ACTIVE
; /* we start transmitting */
1129 if(sc
->sc_trace
& TRACE_B_TX
) /* if trace, send mbuf to trace dev */
1131 struct i4b_trace_hdr hdr
;
1132 hdr
.type
= (h_chan
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
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
);
1138 isic_hscx_fifo(chan
, sc
);
1140 /* call timeout handling routine */
1142 if(activity
== ACT_RX
|| activity
== ACT_TX
)
1143 (*chan
->l4_driver
->bch_activity
)(chan
->l4_driver_softc
, activity
);
1148 /*---------------------------------------------------------------------------*
1149 * return the address of isic drivers linktab
1150 *---------------------------------------------------------------------------*/
1151 static isdn_link_t
*
1152 avma1pp2_ret_linktab(void *token
, int channel
)
1154 struct l2_softc
*l2sc
= token
;
1155 struct isic_softc
*sc
= l2sc
->l1_token
;
1157 l1_bchan_state_t
*chan
= &sc
->sc_chan
[channel
];
1159 return(&chan
->isdn_linktab
);
1162 /*---------------------------------------------------------------------------*
1163 * set the driver linktab in the b channel softc
1164 *---------------------------------------------------------------------------*/
1166 avma1pp2_set_link(void *token
, int channel
, const struct isdn_l4_driver_functions
*l4_driver
, void *l4_driver_softc
)
1168 struct l2_softc
*l2sc
= token
;
1169 struct isic_softc
*sc
= l2sc
->l1_token
;
1170 l1_bchan_state_t
*chan
= &sc
->sc_chan
[channel
];
1172 chan
->l4_driver
= l4_driver
;
1173 chan
->l4_driver_softc
= l4_driver_softc
;
1176 static const struct isdn_l4_bchannel_functions
1177 avma1pp2_l4_bchannel_functions
= {
1178 avma1pp2_bchannel_setup
,
1179 avma1pp2_bchannel_start
,
1180 avma1pp2_bchannel_stat
1183 /*---------------------------------------------------------------------------*
1184 * initialize our local linktab
1185 *---------------------------------------------------------------------------*/
1187 avma1pp2_init_linktab(struct isic_softc
*sc
)
1189 l1_bchan_state_t
*chan
= &sc
->sc_chan
[HSCX_CH_A
];
1190 isdn_link_t
*lt
= &chan
->isdn_linktab
;
1194 lt
->channel
= HSCX_CH_A
;
1195 lt
->bchannel_driver
= &avma1pp2_l4_bchannel_functions
;
1196 lt
->tx_queue
= &chan
->tx_queue
;
1198 /* used by non-HDLC data transfers, i.e. telephony drivers */
1199 lt
->rx_queue
= &chan
->rx_queue
;
1201 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1202 lt
->rx_mbuf
= &chan
->in_mbuf
;
1204 chan
= &sc
->sc_chan
[HSCX_CH_B
];
1205 lt
= &chan
->isdn_linktab
;
1208 lt
->channel
= HSCX_CH_B
;
1209 lt
->bchannel_driver
= &avma1pp2_l4_bchannel_functions
;
1210 lt
->tx_queue
= &chan
->tx_queue
;
1212 /* used by non-HDLC data transfers, i.e. telephony drivers */
1213 lt
->rx_queue
= &chan
->rx_queue
;
1215 /* used by HDLC data transfers, i.e. ipr and isp drivers */
1216 lt
->rx_mbuf
= &chan
->in_mbuf
;
1220 * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static
1223 avma1pp2_bchannel_stat(isdn_layer1token t
, int h_chan
, bchan_statistics_t
*bsp
)
1225 struct isic_softc
*sc
= (struct isic_softc
*)t
;
1226 l1_bchan_state_t
*chan
= &sc
->sc_chan
[h_chan
];
1231 bsp
->outbytes
= chan
->txcount
;
1232 bsp
->inbytes
= chan
->rxcount
;
1240 /*---------------------------------------------------------------------------*
1241 * fill HSCX fifo with data from the current mbuf
1242 * Put this here until it can go into i4b_hscx.c
1243 *---------------------------------------------------------------------------*/
1245 isic_hscx_fifo(l1_bchan_state_t
*chan
, struct isic_softc
*sc
)
1251 /* using a scratch buffer simplifies writing to the FIFO */
1252 u_char scrbuf
[HSCX_FIFO_LEN
];
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
1266 while(chan
->out_mbuf_cur
&& len
!= sc
->sc_bfifolen
)
1268 nextlen
= min(chan
->out_mbuf_cur_len
, sc
->sc_bfifolen
- len
);
1271 printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ",
1272 chan
->out_mbuf_head
,
1274 chan
->out_mbuf_cur_ptr
,
1275 chan
->out_mbuf_cur_len
,
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
];
1286 chan
->txcount
+= nextlen
;
1288 chan
->out_mbuf_cur_ptr
+= nextlen
;
1289 chan
->out_mbuf_cur_len
-= nextlen
;
1291 if(chan
->out_mbuf_cur_len
== 0)
1293 if((chan
->out_mbuf_cur
= chan
->out_mbuf_cur
->m_next
) != NULL
)
1295 chan
->out_mbuf_cur_ptr
= chan
->out_mbuf_cur
->m_data
;
1296 chan
->out_mbuf_cur_len
= chan
->out_mbuf_cur
->m_len
;
1298 if(sc
->sc_trace
& TRACE_B_TX
)
1300 struct i4b_trace_hdr hdr
;
1301 hdr
.type
= (chan
->channel
== HSCX_CH_A
? TRC_CH_B1
: TRC_CH_B2
);
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
);
1309 if (chan
->bprot
!= BPROT_NONE
)
1310 cmd
|= HSCX_CMDR_XME
;
1311 i4b_Bfreembuf(chan
->out_mbuf_head
);
1312 chan
->out_mbuf_head
= NULL
;
1316 /* write what we have from the scratch buf to the HSCX fifo */
1318 HSCX_WRFIFO(chan
->channel
, scrbuf
, len
);