1 /* $Id: avm_pci.c,v 1.18 2000/08/20 07:34:04 keil Exp $
3 * avm_pci.c low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
4 * Thanks to AVM, Berlin for informations
6 * Author Karsten Keil (keil@isdn4linux.de)
8 * This file is (c) under GNU PUBLIC LICENSE
11 #define __NO_VERSION__
12 #include <linux/config.h>
16 #include <linux/pci.h>
17 #include <linux/interrupt.h>
19 extern const char *CardType
[];
20 static const char *avm_pci_rev
= "$Revision: 1.18 $";
22 #define AVM_FRITZ_PCI 1
23 #define AVM_FRITZ_PNP 2
25 #ifndef PCI_VENDOR_ID_AVM
26 #define PCI_VENDOR_ID_AVM 0x1244
28 #ifndef PCI_DEVICE_ID_AVM_FRITZ
29 #define PCI_DEVICE_ID_AVM_FRITZ 0xa00
33 #define HDLC_STATUS 0x4
35 #define AVM_HDLC_1 0x00
36 #define AVM_HDLC_2 0x01
37 #define AVM_ISAC_FIFO 0x02
38 #define AVM_ISAC_REG_LOW 0x04
39 #define AVM_ISAC_REG_HIGH 0x06
41 #define AVM_STATUS0_IRQ_ISAC 0x01
42 #define AVM_STATUS0_IRQ_HDLC 0x02
43 #define AVM_STATUS0_IRQ_TIMER 0x04
44 #define AVM_STATUS0_IRQ_MASK 0x07
46 #define AVM_STATUS0_RESET 0x01
47 #define AVM_STATUS0_DIS_TIMER 0x02
48 #define AVM_STATUS0_RES_TIMER 0x04
49 #define AVM_STATUS0_ENA_IRQ 0x08
50 #define AVM_STATUS0_TESTBIT 0x10
52 #define AVM_STATUS1_INT_SEL 0x0f
53 #define AVM_STATUS1_ENA_IOM 0x80
55 #define HDLC_MODE_ITF_FLG 0x01
56 #define HDLC_MODE_TRANS 0x02
57 #define HDLC_MODE_CCR_7 0x04
58 #define HDLC_MODE_CCR_16 0x08
59 #define HDLC_MODE_TESTLOOP 0x80
61 #define HDLC_INT_XPR 0x80
62 #define HDLC_INT_XDU 0x40
63 #define HDLC_INT_RPR 0x20
64 #define HDLC_INT_MASK 0xE0
66 #define HDLC_STAT_RME 0x01
67 #define HDLC_STAT_RDO 0x10
68 #define HDLC_STAT_CRCVFRRAB 0x0E
69 #define HDLC_STAT_CRCVFR 0x06
70 #define HDLC_STAT_RML_MASK 0x3f00
72 #define HDLC_CMD_XRS 0x80
73 #define HDLC_CMD_XME 0x01
74 #define HDLC_CMD_RRS 0x20
75 #define HDLC_CMD_XML_MASK 0x3f00
78 /* Interface functions */
81 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
83 register u_char idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
89 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
90 val
= inb(cs
->hw
.avm
.isac
+ (offset
& 0xf));
96 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
98 register u_char idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
103 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
104 outb(value
, cs
->hw
.avm
.isac
+ (offset
& 0xf));
105 restore_flags(flags
);
109 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
111 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
112 insb(cs
->hw
.avm
.isac
, data
, size
);
116 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
118 outb(AVM_ISAC_FIFO
, cs
->hw
.avm
.cfg_reg
+ 4);
119 outsb(cs
->hw
.avm
.isac
, data
, size
);
123 ReadHDLCPCI(struct IsdnCardState
*cs
, int chan
, u_char offset
)
125 register u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
131 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
132 val
= inl(cs
->hw
.avm
.isac
+ offset
);
133 restore_flags(flags
);
138 WriteHDLCPCI(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_int value
)
140 register u_int idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
145 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
146 outl(value
, cs
->hw
.avm
.isac
+ offset
);
147 restore_flags(flags
);
151 ReadHDLCPnP(struct IsdnCardState
*cs
, int chan
, u_char offset
)
153 register u_char idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
159 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
160 val
= inb(cs
->hw
.avm
.isac
+ offset
);
161 restore_flags(flags
);
166 WriteHDLCPnP(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_char value
)
168 register u_char idx
= chan
? AVM_HDLC_2
: AVM_HDLC_1
;
173 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
174 outb(value
, cs
->hw
.avm
.isac
+ offset
);
175 restore_flags(flags
);
179 ReadHDLC_s(struct IsdnCardState
*cs
, int chan
, u_char offset
)
181 return(0xff & ReadHDLCPCI(cs
, chan
, offset
));
185 WriteHDLC_s(struct IsdnCardState
*cs
, int chan
, u_char offset
, u_char value
)
187 WriteHDLCPCI(cs
, chan
, offset
, value
);
191 struct BCState
*Sel_BCS(struct IsdnCardState
*cs
, int channel
)
193 if (cs
->bcs
[0].mode
&& (cs
->bcs
[0].channel
== channel
))
195 else if (cs
->bcs
[1].mode
&& (cs
->bcs
[1].channel
== channel
))
202 hdlc_sched_event(struct BCState
*bcs
, int event
)
204 bcs
->event
|= 1 << event
;
205 queue_task(&bcs
->tqueue
, &tq_immediate
);
206 mark_bh(IMMEDIATE_BH
);
210 write_ctrl(struct BCState
*bcs
, int which
) {
212 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
213 debugl1(bcs
->cs
, "hdlc %c wr%x ctrl %x",
214 'A' + bcs
->channel
, which
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
215 if (bcs
->cs
->subtyp
== AVM_FRITZ_PCI
) {
216 WriteHDLCPCI(bcs
->cs
, bcs
->channel
, HDLC_STATUS
, bcs
->hw
.hdlc
.ctrl
.ctrl
);
219 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 2,
220 bcs
->hw
.hdlc
.ctrl
.sr
.mode
);
222 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
+ 1,
223 bcs
->hw
.hdlc
.ctrl
.sr
.xml
);
225 WriteHDLCPnP(bcs
->cs
, bcs
->channel
, HDLC_STATUS
,
226 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
);
231 modehdlc(struct BCState
*bcs
, int mode
, int bc
)
233 struct IsdnCardState
*cs
= bcs
->cs
;
234 int hdlc
= bcs
->channel
;
236 if (cs
->debug
& L1_DEB_HSCX
)
237 debugl1(cs
, "hdlc %c mode %d --> %d ichan %d --> %d",
238 'A' + hdlc
, bcs
->mode
, mode
, hdlc
, bc
);
239 bcs
->hw
.hdlc
.ctrl
.ctrl
= 0;
241 case (-1): /* used for init */
246 if (bcs
->mode
== L1_MODE_NULL
)
248 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
249 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
251 bcs
->mode
= L1_MODE_NULL
;
254 case (L1_MODE_TRANS
):
257 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
258 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
260 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
262 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
263 hdlc_sched_event(bcs
, B_XMTBUFREADY
);
268 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
269 bcs
->hw
.hdlc
.ctrl
.sr
.mode
= HDLC_MODE_ITF_FLG
;
271 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
273 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
= 0;
274 hdlc_sched_event(bcs
, B_XMTBUFREADY
);
280 hdlc_empty_fifo(struct BCState
*bcs
, int count
)
284 u_char idx
= bcs
->channel
? AVM_HDLC_2
: AVM_HDLC_1
;
286 struct IsdnCardState
*cs
= bcs
->cs
;
288 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
289 debugl1(cs
, "hdlc_empty_fifo %d", count
);
290 if (bcs
->hw
.hdlc
.rcvidx
+ count
> HSCX_BUFMAX
) {
291 if (cs
->debug
& L1_DEB_WARN
)
292 debugl1(cs
, "hdlc_empty_fifo: incoming packet too large");
295 ptr
= (u_int
*) p
= bcs
->hw
.hdlc
.rcvbuf
+ bcs
->hw
.hdlc
.rcvidx
;
296 bcs
->hw
.hdlc
.rcvidx
+= count
;
297 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
298 outl(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
299 while (cnt
< count
) {
302 *ptr
++ = in_le32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
));
304 *ptr
++ = in_be32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
));
305 #endif /* CONFIG_APUS */
307 *ptr
++ = inl(cs
->hw
.avm
.isac
);
308 #endif /* __powerpc__ */
312 outb(idx
, cs
->hw
.avm
.cfg_reg
+ 4);
313 while (cnt
< count
) {
314 *p
++ = inb(cs
->hw
.avm
.isac
);
318 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
321 if (cs
->subtyp
== AVM_FRITZ_PNP
)
323 t
+= sprintf(t
, "hdlc_empty_fifo %c cnt %d",
324 bcs
->channel
? 'B' : 'A', count
);
325 QuickHex(t
, p
, count
);
326 debugl1(cs
, bcs
->blog
);
331 hdlc_fill_fifo(struct BCState
*bcs
)
333 struct IsdnCardState
*cs
= bcs
->cs
;
339 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
340 debugl1(cs
, "hdlc_fill_fifo");
343 if (bcs
->tx_skb
->len
<= 0)
346 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XME
;
347 if (bcs
->tx_skb
->len
> fifo_size
) {
350 count
= bcs
->tx_skb
->len
;
351 if (bcs
->mode
!= L1_MODE_TRANS
)
352 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XME
;
354 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
355 debugl1(cs
, "hdlc_fill_fifo %d/%ld", count
, bcs
->tx_skb
->len
);
356 ptr
= (u_int
*) p
= bcs
->tx_skb
->data
;
357 skb_pull(bcs
->tx_skb
, count
);
358 bcs
->tx_cnt
-= count
;
359 bcs
->hw
.hdlc
.count
+= count
;
360 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= ((count
== fifo_size
) ? 0 : count
);
361 write_ctrl(bcs
, 3); /* sets the correct index too */
362 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
366 out_le32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
), *ptr
++);
368 out_be32((unsigned *)(cs
->hw
.avm
.isac
+_IO_BASE
), *ptr
++);
369 #endif /* CONFIG_APUS */
371 outl(*ptr
++, cs
->hw
.avm
.isac
);
372 #endif /* __powerpc__ */
377 outb(*p
++, cs
->hw
.avm
.isac
);
381 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
384 if (cs
->subtyp
== AVM_FRITZ_PNP
)
386 t
+= sprintf(t
, "hdlc_fill_fifo %c cnt %d",
387 bcs
->channel
? 'B' : 'A', count
);
388 QuickHex(t
, p
, count
);
389 debugl1(cs
, bcs
->blog
);
394 fill_hdlc(struct BCState
*bcs
)
400 restore_flags(flags
);
404 HDLC_irq(struct BCState
*bcs
, u_int stat
) {
408 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
409 debugl1(bcs
->cs
, "ch%d stat %#x", bcs
->channel
, stat
);
410 if (stat
& HDLC_INT_RPR
) {
411 if (stat
& HDLC_STAT_RDO
) {
412 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
413 debugl1(bcs
->cs
, "RDO");
415 debugl1(bcs
->cs
, "ch%d stat %#x", bcs
->channel
, stat
);
416 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= 0;
417 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_RRS
;
419 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_RRS
;
421 bcs
->hw
.hdlc
.rcvidx
= 0;
423 if (!(len
= (stat
& HDLC_STAT_RML_MASK
)>>8))
425 hdlc_empty_fifo(bcs
, len
);
426 if ((stat
& HDLC_STAT_RME
) || (bcs
->mode
== L1_MODE_TRANS
)) {
427 if (((stat
& HDLC_STAT_CRCVFRRAB
)==HDLC_STAT_CRCVFR
) ||
428 (bcs
->mode
== L1_MODE_TRANS
)) {
429 if (!(skb
= dev_alloc_skb(bcs
->hw
.hdlc
.rcvidx
)))
430 printk(KERN_WARNING
"HDLC: receive out of memory\n");
432 memcpy(skb_put(skb
, bcs
->hw
.hdlc
.rcvidx
),
433 bcs
->hw
.hdlc
.rcvbuf
, bcs
->hw
.hdlc
.rcvidx
);
434 skb_queue_tail(&bcs
->rqueue
, skb
);
436 bcs
->hw
.hdlc
.rcvidx
= 0;
437 hdlc_sched_event(bcs
, B_RCVBUFREADY
);
439 if (bcs
->cs
->debug
& L1_DEB_HSCX
)
440 debugl1(bcs
->cs
, "invalid frame");
442 debugl1(bcs
->cs
, "ch%d invalid frame %#x", bcs
->channel
, stat
);
443 bcs
->hw
.hdlc
.rcvidx
= 0;
448 if (stat
& HDLC_INT_XDU
) {
449 /* Here we lost an TX interrupt, so
450 * restart transmitting the whole frame.
453 skb_push(bcs
->tx_skb
, bcs
->hw
.hdlc
.count
);
454 bcs
->tx_cnt
+= bcs
->hw
.hdlc
.count
;
455 bcs
->hw
.hdlc
.count
= 0;
456 // hdlc_sched_event(bcs, B_XMTBUFREADY);
457 if (bcs
->cs
->debug
& L1_DEB_WARN
)
458 debugl1(bcs
->cs
, "ch%d XDU", bcs
->channel
);
459 } else if (bcs
->cs
->debug
& L1_DEB_WARN
)
460 debugl1(bcs
->cs
, "ch%d XDU without skb", bcs
->channel
);
461 bcs
->hw
.hdlc
.ctrl
.sr
.xml
= 0;
462 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
|= HDLC_CMD_XRS
;
464 bcs
->hw
.hdlc
.ctrl
.sr
.cmd
&= ~HDLC_CMD_XRS
;
467 } else if (stat
& HDLC_INT_XPR
) {
469 if (bcs
->tx_skb
->len
) {
473 if (bcs
->st
->lli
.l1writewakeup
&&
474 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
))
475 bcs
->st
->lli
.l1writewakeup(bcs
->st
, bcs
->hw
.hdlc
.count
);
476 dev_kfree_skb_irq(bcs
->tx_skb
);
477 bcs
->hw
.hdlc
.count
= 0;
481 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
482 bcs
->hw
.hdlc
.count
= 0;
483 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
486 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
487 hdlc_sched_event(bcs
, B_XMTBUFREADY
);
493 HDLC_irq_main(struct IsdnCardState
*cs
)
501 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
502 stat
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
504 stat
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
505 if (stat
& HDLC_INT_RPR
)
506 stat
|= (ReadHDLCPnP(cs
, 0, HDLC_STATUS
+1))<<8;
508 if (stat
& HDLC_INT_MASK
) {
509 if (!(bcs
= Sel_BCS(cs
, 0))) {
511 debugl1(cs
, "hdlc spurious channel 0 IRQ");
515 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
516 stat
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
518 stat
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
519 if (stat
& HDLC_INT_RPR
)
520 stat
|= (ReadHDLCPnP(cs
, 1, HDLC_STATUS
+1))<<8;
522 if (stat
& HDLC_INT_MASK
) {
523 if (!(bcs
= Sel_BCS(cs
, 1))) {
525 debugl1(cs
, "hdlc spurious channel 1 IRQ");
529 restore_flags(flags
);
533 hdlc_l2l1(struct PStack
*st
, int pr
, void *arg
)
535 struct sk_buff
*skb
= arg
;
539 case (PH_DATA
| REQUEST
):
542 if (st
->l1
.bcs
->tx_skb
) {
543 skb_queue_tail(&st
->l1
.bcs
->squeue
, skb
);
544 restore_flags(flags
);
546 st
->l1
.bcs
->tx_skb
= skb
;
547 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
548 st
->l1
.bcs
->hw
.hdlc
.count
= 0;
549 restore_flags(flags
);
550 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
553 case (PH_PULL
| INDICATION
):
554 if (st
->l1
.bcs
->tx_skb
) {
555 printk(KERN_WARNING
"hdlc_l2l1: this shouldn't happen\n");
558 test_and_set_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
559 st
->l1
.bcs
->tx_skb
= skb
;
560 st
->l1
.bcs
->hw
.hdlc
.count
= 0;
561 st
->l1
.bcs
->cs
->BC_Send_Data(st
->l1
.bcs
);
563 case (PH_PULL
| REQUEST
):
564 if (!st
->l1
.bcs
->tx_skb
) {
565 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
566 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
568 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
570 case (PH_ACTIVATE
| REQUEST
):
571 test_and_set_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
572 modehdlc(st
->l1
.bcs
, st
->l1
.mode
, st
->l1
.bc
);
573 l1_msg_b(st
, pr
, arg
);
575 case (PH_DEACTIVATE
| REQUEST
):
576 l1_msg_b(st
, pr
, arg
);
578 case (PH_DEACTIVATE
| CONFIRM
):
579 test_and_clear_bit(BC_FLG_ACTIV
, &st
->l1
.bcs
->Flag
);
580 test_and_clear_bit(BC_FLG_BUSY
, &st
->l1
.bcs
->Flag
);
581 modehdlc(st
->l1
.bcs
, 0, st
->l1
.bc
);
582 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
588 close_hdlcstate(struct BCState
*bcs
)
591 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
592 if (bcs
->hw
.hdlc
.rcvbuf
) {
593 kfree(bcs
->hw
.hdlc
.rcvbuf
);
594 bcs
->hw
.hdlc
.rcvbuf
= NULL
;
600 discard_queue(&bcs
->rqueue
);
601 discard_queue(&bcs
->squeue
);
603 dev_kfree_skb_any(bcs
->tx_skb
);
605 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
611 open_hdlcstate(struct IsdnCardState
*cs
, struct BCState
*bcs
)
613 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
614 if (!(bcs
->hw
.hdlc
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
616 "HiSax: No memory for hdlc.rcvbuf\n");
619 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
621 "HiSax: No memory for bcs->blog\n");
622 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
623 kfree(bcs
->hw
.hdlc
.rcvbuf
);
624 bcs
->hw
.hdlc
.rcvbuf
= NULL
;
627 skb_queue_head_init(&bcs
->rqueue
);
628 skb_queue_head_init(&bcs
->squeue
);
631 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
633 bcs
->hw
.hdlc
.rcvidx
= 0;
639 setstack_hdlc(struct PStack
*st
, struct BCState
*bcs
)
641 bcs
->channel
= st
->l1
.bc
;
642 if (open_hdlcstate(st
->l1
.hardware
, bcs
))
645 st
->l2
.l2l1
= hdlc_l2l1
;
646 setstack_manager(st
);
653 clear_pending_hdlc_ints(struct IsdnCardState
*cs
))
657 if (cs
->subtyp
== AVM_FRITZ_PCI
) {
658 val
= ReadHDLCPCI(cs
, 0, HDLC_STATUS
);
659 debugl1(cs
, "HDLC 1 STA %x", val
);
660 val
= ReadHDLCPCI(cs
, 1, HDLC_STATUS
);
661 debugl1(cs
, "HDLC 2 STA %x", val
);
663 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
);
664 debugl1(cs
, "HDLC 1 STA %x", val
);
665 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 1);
666 debugl1(cs
, "HDLC 1 RML %x", val
);
667 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 2);
668 debugl1(cs
, "HDLC 1 MODE %x", val
);
669 val
= ReadHDLCPnP(cs
, 0, HDLC_STATUS
+ 3);
670 debugl1(cs
, "HDLC 1 VIN %x", val
);
671 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
);
672 debugl1(cs
, "HDLC 2 STA %x", val
);
673 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 1);
674 debugl1(cs
, "HDLC 2 RML %x", val
);
675 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 2);
676 debugl1(cs
, "HDLC 2 MODE %x", val
);
677 val
= ReadHDLCPnP(cs
, 1, HDLC_STATUS
+ 3);
678 debugl1(cs
, "HDLC 2 VIN %x", val
);
683 inithdlc(struct IsdnCardState
*cs
))
685 cs
->bcs
[0].BC_SetStack
= setstack_hdlc
;
686 cs
->bcs
[1].BC_SetStack
= setstack_hdlc
;
687 cs
->bcs
[0].BC_Close
= close_hdlcstate
;
688 cs
->bcs
[1].BC_Close
= close_hdlcstate
;
689 modehdlc(cs
->bcs
, -1, 0);
690 modehdlc(cs
->bcs
+ 1, -1, 1);
694 avm_pcipnp_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
696 struct IsdnCardState
*cs
= dev_id
;
701 printk(KERN_WARNING
"AVM PCI: Spurious interrupt!\n");
704 sval
= inb(cs
->hw
.avm
.cfg_reg
+ 2);
705 if ((sval
& AVM_STATUS0_IRQ_MASK
) == AVM_STATUS0_IRQ_MASK
)
706 /* possible a shared IRQ reqest */
708 if (!(sval
& AVM_STATUS0_IRQ_ISAC
)) {
709 val
= ReadISAC(cs
, ISAC_ISTA
);
710 isac_interrupt(cs
, val
);
712 if (!(sval
& AVM_STATUS0_IRQ_HDLC
)) {
715 WriteISAC(cs
, ISAC_MASK
, 0xFF);
716 WriteISAC(cs
, ISAC_MASK
, 0x0);
720 reset_avmpcipnp(struct IsdnCardState
*cs
)
724 printk(KERN_INFO
"AVM PCI/PnP: reset\n");
727 outb(AVM_STATUS0_RESET
| AVM_STATUS0_DIS_TIMER
, cs
->hw
.avm
.cfg_reg
+ 2);
728 set_current_state(TASK_UNINTERRUPTIBLE
);
729 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
730 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
| AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
731 outb(AVM_STATUS1_ENA_IOM
| cs
->irq
, cs
->hw
.avm
.cfg_reg
+ 3);
732 set_current_state(TASK_UNINTERRUPTIBLE
);
733 schedule_timeout((10*HZ
)/1000); /* Timeout 10ms */
734 printk(KERN_INFO
"AVM PCI/PnP: S1 %x\n", inb(cs
->hw
.avm
.cfg_reg
+ 3));
738 AVM_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
745 outb(0, cs
->hw
.avm
.cfg_reg
+ 2);
746 release_region(cs
->hw
.avm
.cfg_reg
, 32);
749 clear_pending_isac_ints(cs
);
751 clear_pending_hdlc_ints(cs
);
753 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
,
754 cs
->hw
.avm
.cfg_reg
+ 2);
755 WriteISAC(cs
, ISAC_MASK
, 0);
756 outb(AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
|
757 AVM_STATUS0_ENA_IRQ
, cs
->hw
.avm
.cfg_reg
+ 2);
758 /* RESET Receiver and Transmitter */
759 WriteISAC(cs
, ISAC_CMDR
, 0x41);
767 static struct pci_dev
*dev_avm __initdata
= NULL
;
770 setup_avm_pcipnp(struct IsdnCard
*card
))
773 struct IsdnCardState
*cs
= card
->cs
;
776 strcpy(tmp
, avm_pci_rev
);
777 printk(KERN_INFO
"HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp
));
778 if (cs
->typ
!= ISDN_CTYPE_FRITZPCI
)
781 cs
->hw
.avm
.cfg_reg
= card
->para
[1];
782 cs
->irq
= card
->para
[0];
783 cs
->subtyp
= AVM_FRITZ_PNP
;
786 if (!pci_present()) {
787 printk(KERN_ERR
"FritzPCI: no PCI bus present\n");
790 if ((dev_avm
= pci_find_device(PCI_VENDOR_ID_AVM
,
791 PCI_DEVICE_ID_AVM_FRITZ
, dev_avm
))) {
792 cs
->irq
= dev_avm
->irq
;
794 printk(KERN_ERR
"FritzPCI: No IRQ for PCI card found\n");
797 if (pci_enable_device(dev_avm
))
799 cs
->hw
.avm
.cfg_reg
= pci_resource_start(dev_avm
, 1);
800 if (!cs
->hw
.avm
.cfg_reg
) {
801 printk(KERN_ERR
"FritzPCI: No IO-Adr for PCI card found\n");
804 cs
->subtyp
= AVM_FRITZ_PCI
;
806 printk(KERN_WARNING
"FritzPCI: No PCI card found\n");
809 cs
->irq_flags
|= SA_SHIRQ
;
811 printk(KERN_WARNING
"FritzPCI: NO_PCI_BIOS\n");
813 #endif /* CONFIG_PCI */
815 cs
->hw
.avm
.isac
= cs
->hw
.avm
.cfg_reg
+ 0x10;
816 if (check_region((cs
->hw
.avm
.cfg_reg
), 32)) {
818 "HiSax: %s config port %x-%x already in use\n",
821 cs
->hw
.avm
.cfg_reg
+ 31);
824 request_region(cs
->hw
.avm
.cfg_reg
, 32,
825 (cs
->subtyp
== AVM_FRITZ_PCI
) ? "avm PCI" : "avm PnP");
827 switch (cs
->subtyp
) {
829 val
= inl(cs
->hw
.avm
.cfg_reg
);
830 printk(KERN_INFO
"AVM PCI: stat %#x\n", val
);
831 printk(KERN_INFO
"AVM PCI: Class %X Rev %d\n",
832 val
& 0xff, (val
>>8) & 0xff);
833 cs
->BC_Read_Reg
= &ReadHDLC_s
;
834 cs
->BC_Write_Reg
= &WriteHDLC_s
;
837 val
= inb(cs
->hw
.avm
.cfg_reg
);
838 ver
= inb(cs
->hw
.avm
.cfg_reg
+ 1);
839 printk(KERN_INFO
"AVM PnP: Class %X Rev %d\n", val
, ver
);
841 cs
->BC_Read_Reg
= &ReadHDLCPnP
;
842 cs
->BC_Write_Reg
= &WriteHDLCPnP
;
845 printk(KERN_WARNING
"AVM unknown subtype %d\n", cs
->subtyp
);
848 printk(KERN_INFO
"HiSax: %s config irq:%d base:0x%X\n",
849 (cs
->subtyp
== AVM_FRITZ_PCI
) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
850 cs
->irq
, cs
->hw
.avm
.cfg_reg
);
852 cs
->readisac
= &ReadISAC
;
853 cs
->writeisac
= &WriteISAC
;
854 cs
->readisacfifo
= &ReadISACfifo
;
855 cs
->writeisacfifo
= &WriteISACfifo
;
856 cs
->BC_Send_Data
= &fill_hdlc
;
857 cs
->cardmsg
= &AVM_card_msg
;
858 cs
->irq_func
= &avm_pcipnp_interrupt
;
859 ISACVersion(cs
, (cs
->subtyp
== AVM_FRITZ_PCI
) ? "AVM PCI:" : "AVM PnP:");