2 * avm_fritz.c low level stuff for AVM FRITZ!CARD PCI ISDN cards
3 * Thanks to AVM, Berlin for informations
5 * Author Karsten Keil <keil@isdn4linux.de>
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <linux/module.h>
24 #include <linux/pci.h>
25 #include <linux/delay.h>
26 #include <linux/mISDNhw.h>
27 #include <linux/slab.h>
28 #include <asm/unaligned.h>
32 #define AVMFRITZ_REV "2.1"
43 #define HDLC_STATUS 0x4
44 #define CHIP_WINDOW 0x10
46 #define CHIP_INDEX 0x4
47 #define AVM_HDLC_1 0x00
48 #define AVM_HDLC_2 0x01
49 #define AVM_ISAC_FIFO 0x02
50 #define AVM_ISAC_REG_LOW 0x04
51 #define AVM_ISAC_REG_HIGH 0x06
53 #define AVM_STATUS0_IRQ_ISAC 0x01
54 #define AVM_STATUS0_IRQ_HDLC 0x02
55 #define AVM_STATUS0_IRQ_TIMER 0x04
56 #define AVM_STATUS0_IRQ_MASK 0x07
58 #define AVM_STATUS0_RESET 0x01
59 #define AVM_STATUS0_DIS_TIMER 0x02
60 #define AVM_STATUS0_RES_TIMER 0x04
61 #define AVM_STATUS0_ENA_IRQ 0x08
62 #define AVM_STATUS0_TESTBIT 0x10
64 #define AVM_STATUS1_INT_SEL 0x0f
65 #define AVM_STATUS1_ENA_IOM 0x80
67 #define HDLC_MODE_ITF_FLG 0x01
68 #define HDLC_MODE_TRANS 0x02
69 #define HDLC_MODE_CCR_7 0x04
70 #define HDLC_MODE_CCR_16 0x08
71 #define HDLC_MODE_TESTLOOP 0x80
73 #define HDLC_INT_XPR 0x80
74 #define HDLC_INT_XDU 0x40
75 #define HDLC_INT_RPR 0x20
76 #define HDLC_INT_MASK 0xE0
78 #define HDLC_STAT_RME 0x01
79 #define HDLC_STAT_RDO 0x10
80 #define HDLC_STAT_CRCVFRRAB 0x0E
81 #define HDLC_STAT_CRCVFR 0x06
82 #define HDLC_STAT_RML_MASK 0x3f00
84 #define HDLC_CMD_XRS 0x80
85 #define HDLC_CMD_XME 0x01
86 #define HDLC_CMD_RRS 0x20
87 #define HDLC_CMD_XML_MASK 0x3f00
88 #define HDLC_FIFO_SIZE 32
92 #define AVM_HDLC_FIFO_1 0x10
93 #define AVM_HDLC_FIFO_2 0x18
95 #define AVM_HDLC_STATUS_1 0x14
96 #define AVM_HDLC_STATUS_2 0x1c
98 #define AVM_ISACX_INDEX 0x04
99 #define AVM_ISACX_DATA 0x08
104 struct hdlc_stat_reg
{
116 } __attribute__((packed
));
121 struct hdlc_stat_reg sr
;
127 struct list_head list
;
128 struct pci_dev
*pdev
;
129 char name
[MISDN_MAX_IDLEN
];
135 spinlock_t lock
; /* hw lock */
137 struct hdlc_hw hdlc
[2];
138 struct bchannel bch
[2];
139 char log
[LOG_SIZE
+ 1];
142 static LIST_HEAD(Cards
);
143 static DEFINE_RWLOCK(card_lock
); /* protect Cards */
146 _set_debug(struct fritzcard
*card
)
148 card
->isac
.dch
.debug
= debug
;
149 card
->bch
[0].debug
= debug
;
150 card
->bch
[1].debug
= debug
;
154 set_debug(const char *val
, struct kernel_param
*kp
)
157 struct fritzcard
*card
;
159 ret
= param_set_uint(val
, kp
);
161 read_lock(&card_lock
);
162 list_for_each_entry(card
, &Cards
, list
)
164 read_unlock(&card_lock
);
169 MODULE_AUTHOR("Karsten Keil");
170 MODULE_LICENSE("GPL v2");
171 MODULE_VERSION(AVMFRITZ_REV
);
172 module_param_call(debug
, set_debug
, param_get_uint
, &debug
, S_IRUGO
| S_IWUSR
);
173 MODULE_PARM_DESC(debug
, "avmfritz debug mask");
175 /* Interface functions */
178 ReadISAC_V1(void *p
, u8 offset
)
180 struct fritzcard
*fc
= p
;
181 u8 idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
183 outb(idx
, fc
->addr
+ CHIP_INDEX
);
184 return inb(fc
->addr
+ CHIP_WINDOW
+ (offset
& 0xf));
188 WriteISAC_V1(void *p
, u8 offset
, u8 value
)
190 struct fritzcard
*fc
= p
;
191 u8 idx
= (offset
> 0x2f) ? AVM_ISAC_REG_HIGH
: AVM_ISAC_REG_LOW
;
193 outb(idx
, fc
->addr
+ CHIP_INDEX
);
194 outb(value
, fc
->addr
+ CHIP_WINDOW
+ (offset
& 0xf));
198 ReadFiFoISAC_V1(void *p
, u8 off
, u8
*data
, int size
)
200 struct fritzcard
*fc
= p
;
202 outb(AVM_ISAC_FIFO
, fc
->addr
+ CHIP_INDEX
);
203 insb(fc
->addr
+ CHIP_WINDOW
, data
, size
);
207 WriteFiFoISAC_V1(void *p
, u8 off
, u8
*data
, int size
)
209 struct fritzcard
*fc
= p
;
211 outb(AVM_ISAC_FIFO
, fc
->addr
+ CHIP_INDEX
);
212 outsb(fc
->addr
+ CHIP_WINDOW
, data
, size
);
216 ReadISAC_V2(void *p
, u8 offset
)
218 struct fritzcard
*fc
= p
;
220 outl(offset
, fc
->addr
+ AVM_ISACX_INDEX
);
221 return 0xff & inl(fc
->addr
+ AVM_ISACX_DATA
);
225 WriteISAC_V2(void *p
, u8 offset
, u8 value
)
227 struct fritzcard
*fc
= p
;
229 outl(offset
, fc
->addr
+ AVM_ISACX_INDEX
);
230 outl(value
, fc
->addr
+ AVM_ISACX_DATA
);
234 ReadFiFoISAC_V2(void *p
, u8 off
, u8
*data
, int size
)
236 struct fritzcard
*fc
= p
;
239 outl(off
, fc
->addr
+ AVM_ISACX_INDEX
);
240 for (i
= 0; i
< size
; i
++)
241 data
[i
] = 0xff & inl(fc
->addr
+ AVM_ISACX_DATA
);
245 WriteFiFoISAC_V2(void *p
, u8 off
, u8
*data
, int size
)
247 struct fritzcard
*fc
= p
;
250 outl(off
, fc
->addr
+ AVM_ISACX_INDEX
);
251 for (i
= 0; i
< size
; i
++)
252 outl(data
[i
], fc
->addr
+ AVM_ISACX_DATA
);
255 static struct bchannel
*
256 Sel_BCS(struct fritzcard
*fc
, u32 channel
)
258 if (test_bit(FLG_ACTIVE
, &fc
->bch
[0].Flags
) &&
259 (fc
->bch
[0].nr
& channel
))
261 else if (test_bit(FLG_ACTIVE
, &fc
->bch
[1].Flags
) &&
262 (fc
->bch
[1].nr
& channel
))
269 __write_ctrl_pci(struct fritzcard
*fc
, struct hdlc_hw
*hdlc
, u32 channel
) {
270 u32 idx
= channel
== 2 ? AVM_HDLC_2
: AVM_HDLC_1
;
272 outl(idx
, fc
->addr
+ CHIP_INDEX
);
273 outl(hdlc
->ctrl
.ctrl
, fc
->addr
+ CHIP_WINDOW
+ HDLC_STATUS
);
277 __write_ctrl_pciv2(struct fritzcard
*fc
, struct hdlc_hw
*hdlc
, u32 channel
) {
278 outl(hdlc
->ctrl
.ctrl
, fc
->addr
+ (channel
== 2 ? AVM_HDLC_STATUS_2
:
283 write_ctrl(struct bchannel
*bch
, int which
) {
284 struct fritzcard
*fc
= bch
->hw
;
285 struct hdlc_hw
*hdlc
;
287 hdlc
= &fc
->hdlc
[(bch
->nr
- 1) & 1];
288 pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc
->name
, '@' + bch
->nr
,
289 which
, hdlc
->ctrl
.ctrl
);
291 case AVM_FRITZ_PCIV2
:
292 __write_ctrl_pciv2(fc
, hdlc
, bch
->nr
);
295 __write_ctrl_pci(fc
, hdlc
, bch
->nr
);
302 __read_status_pci(u_long addr
, u32 channel
)
304 outl(channel
== 2 ? AVM_HDLC_2
: AVM_HDLC_1
, addr
+ CHIP_INDEX
);
305 return inl(addr
+ CHIP_WINDOW
+ HDLC_STATUS
);
309 __read_status_pciv2(u_long addr
, u32 channel
)
311 return inl(addr
+ (channel
== 2 ? AVM_HDLC_STATUS_2
:
317 read_status(struct fritzcard
*fc
, u32 channel
)
320 case AVM_FRITZ_PCIV2
:
321 return __read_status_pciv2(fc
->addr
, channel
);
323 return __read_status_pci(fc
->addr
, channel
);
330 enable_hwirq(struct fritzcard
*fc
)
332 fc
->ctrlreg
|= AVM_STATUS0_ENA_IRQ
;
333 outb(fc
->ctrlreg
, fc
->addr
+ 2);
337 disable_hwirq(struct fritzcard
*fc
)
339 fc
->ctrlreg
&= ~AVM_STATUS0_ENA_IRQ
;
340 outb(fc
->ctrlreg
, fc
->addr
+ 2);
344 modehdlc(struct bchannel
*bch
, int protocol
)
346 struct fritzcard
*fc
= bch
->hw
;
347 struct hdlc_hw
*hdlc
;
349 hdlc
= &fc
->hdlc
[(bch
->nr
- 1) & 1];
350 pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc
->name
,
351 '@' + bch
->nr
, bch
->state
, protocol
, bch
->nr
);
354 case -1: /* used for init */
357 if (bch
->state
== ISDN_P_NONE
)
359 hdlc
->ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
360 hdlc
->ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
362 bch
->state
= ISDN_P_NONE
;
363 test_and_clear_bit(FLG_HDLC
, &bch
->Flags
);
364 test_and_clear_bit(FLG_TRANSPARENT
, &bch
->Flags
);
367 bch
->state
= protocol
;
368 hdlc
->ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
369 hdlc
->ctrl
.sr
.mode
= HDLC_MODE_TRANS
;
371 hdlc
->ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
373 hdlc
->ctrl
.sr
.cmd
= 0;
374 test_and_set_bit(FLG_TRANSPARENT
, &bch
->Flags
);
377 bch
->state
= protocol
;
378 hdlc
->ctrl
.sr
.cmd
= HDLC_CMD_XRS
| HDLC_CMD_RRS
;
379 hdlc
->ctrl
.sr
.mode
= HDLC_MODE_ITF_FLG
;
381 hdlc
->ctrl
.sr
.cmd
= HDLC_CMD_XRS
;
383 hdlc
->ctrl
.sr
.cmd
= 0;
384 test_and_set_bit(FLG_HDLC
, &bch
->Flags
);
387 pr_info("%s: protocol not known %x\n", fc
->name
, protocol
);
394 hdlc_empty_fifo(struct bchannel
*bch
, int count
)
400 struct fritzcard
*fc
= bch
->hw
;
402 pr_debug("%s: %s %d\n", fc
->name
, __func__
, count
);
404 bch
->rx_skb
= mI_alloc_skb(bch
->maxlen
, GFP_ATOMIC
);
406 pr_info("%s: B receive out of memory\n",
411 if ((bch
->rx_skb
->len
+ count
) > bch
->maxlen
) {
412 pr_debug("%s: overrun %d\n", fc
->name
,
413 bch
->rx_skb
->len
+ count
);
416 p
= skb_put(bch
->rx_skb
, count
);
418 if (AVM_FRITZ_PCIV2
== fc
->type
)
419 addr
= fc
->addr
+ (bch
->nr
== 2 ?
420 AVM_HDLC_FIFO_2
: AVM_HDLC_FIFO_1
);
422 addr
= fc
->addr
+ CHIP_WINDOW
;
423 outl(bch
->nr
== 2 ? AVM_HDLC_2
: AVM_HDLC_1
, fc
->addr
);
425 while (cnt
< count
) {
426 val
= le32_to_cpu(inl(addr
));
427 put_unaligned(val
, ptr
);
431 if (debug
& DEBUG_HW_BFIFO
) {
432 snprintf(fc
->log
, LOG_SIZE
, "B%1d-recv %s %d ",
433 bch
->nr
, fc
->name
, count
);
434 print_hex_dump_bytes(fc
->log
, DUMP_PREFIX_OFFSET
, p
, count
);
439 hdlc_fill_fifo(struct bchannel
*bch
)
441 struct fritzcard
*fc
= bch
->hw
;
442 struct hdlc_hw
*hdlc
;
447 hdlc
= &fc
->hdlc
[(bch
->nr
- 1) & 1];
450 count
= bch
->tx_skb
->len
- bch
->tx_idx
;
453 p
= bch
->tx_skb
->data
+ bch
->tx_idx
;
454 hdlc
->ctrl
.sr
.cmd
&= ~HDLC_CMD_XME
;
455 if (count
> HDLC_FIFO_SIZE
) {
456 count
= HDLC_FIFO_SIZE
;
458 if (test_bit(FLG_HDLC
, &bch
->Flags
))
459 hdlc
->ctrl
.sr
.cmd
|= HDLC_CMD_XME
;
461 pr_debug("%s: %s %d/%d/%d", fc
->name
, __func__
, count
,
462 bch
->tx_idx
, bch
->tx_skb
->len
);
464 bch
->tx_idx
+= count
;
465 hdlc
->ctrl
.sr
.xml
= ((count
== HDLC_FIFO_SIZE
) ? 0 : count
);
466 if (AVM_FRITZ_PCIV2
== fc
->type
) {
467 __write_ctrl_pciv2(fc
, hdlc
, bch
->nr
);
468 addr
= fc
->addr
+ (bch
->nr
== 2 ?
469 AVM_HDLC_FIFO_2
: AVM_HDLC_FIFO_1
);
471 __write_ctrl_pci(fc
, hdlc
, bch
->nr
);
472 addr
= fc
->addr
+ CHIP_WINDOW
;
474 while (cnt
< count
) {
475 val
= get_unaligned(ptr
);
476 outl(cpu_to_le32(val
), addr
);
480 if (debug
& DEBUG_HW_BFIFO
) {
481 snprintf(fc
->log
, LOG_SIZE
, "B%1d-send %s %d ",
482 bch
->nr
, fc
->name
, count
);
483 print_hex_dump_bytes(fc
->log
, DUMP_PREFIX_OFFSET
, p
, count
);
488 HDLC_irq_xpr(struct bchannel
*bch
)
490 if (bch
->tx_skb
&& bch
->tx_idx
< bch
->tx_skb
->len
)
494 /* send confirm, on trans, free on hdlc. */
495 if (test_bit(FLG_TRANSPARENT
, &bch
->Flags
))
497 dev_kfree_skb(bch
->tx_skb
);
499 if (get_next_bframe(bch
))
505 HDLC_irq(struct bchannel
*bch
, u32 stat
)
507 struct fritzcard
*fc
= bch
->hw
;
509 struct hdlc_hw
*hdlc
;
511 hdlc
= &fc
->hdlc
[(bch
->nr
- 1) & 1];
512 pr_debug("%s: ch%d stat %#x\n", fc
->name
, bch
->nr
, stat
);
513 if (stat
& HDLC_INT_RPR
) {
514 if (stat
& HDLC_STAT_RDO
) {
515 hdlc
->ctrl
.sr
.xml
= 0;
516 hdlc
->ctrl
.sr
.cmd
|= HDLC_CMD_RRS
;
518 hdlc
->ctrl
.sr
.cmd
&= ~HDLC_CMD_RRS
;
521 skb_trim(bch
->rx_skb
, 0);
523 len
= (stat
& HDLC_STAT_RML_MASK
) >> 8;
526 hdlc_empty_fifo(bch
, len
);
529 if ((stat
& HDLC_STAT_RME
) || test_bit(FLG_TRANSPARENT
,
531 if (((stat
& HDLC_STAT_CRCVFRRAB
) ==
533 test_bit(FLG_TRANSPARENT
, &bch
->Flags
)) {
534 recv_Bchannel(bch
, 0);
536 pr_debug("%s: got invalid frame\n",
538 skb_trim(bch
->rx_skb
, 0);
544 if (stat
& HDLC_INT_XDU
) {
545 /* Here we lost an TX interrupt, so
546 * restart transmitting the whole frame on HDLC
547 * in transparent mode we send the next data
550 pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n",
551 fc
->name
, bch
->nr
, bch
->tx_skb
->len
,
552 bch
->tx_idx
, bch
->Flags
);
554 pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n",
555 fc
->name
, bch
->nr
, bch
->Flags
);
556 if (bch
->tx_skb
&& bch
->tx_skb
->len
) {
557 if (!test_bit(FLG_TRANSPARENT
, &bch
->Flags
))
560 hdlc
->ctrl
.sr
.xml
= 0;
561 hdlc
->ctrl
.sr
.cmd
|= HDLC_CMD_XRS
;
563 hdlc
->ctrl
.sr
.cmd
&= ~HDLC_CMD_XRS
;
566 } else if (stat
& HDLC_INT_XPR
)
571 HDLC_irq_main(struct fritzcard
*fc
)
574 struct bchannel
*bch
;
576 stat
= read_status(fc
, 1);
577 if (stat
& HDLC_INT_MASK
) {
578 bch
= Sel_BCS(fc
, 1);
582 pr_debug("%s: spurious ch1 IRQ\n", fc
->name
);
584 stat
= read_status(fc
, 2);
585 if (stat
& HDLC_INT_MASK
) {
586 bch
= Sel_BCS(fc
, 2);
590 pr_debug("%s: spurious ch2 IRQ\n", fc
->name
);
595 avm_fritz_interrupt(int intno
, void *dev_id
)
597 struct fritzcard
*fc
= dev_id
;
601 spin_lock(&fc
->lock
);
602 sval
= inb(fc
->addr
+ 2);
603 pr_debug("%s: irq stat0 %x\n", fc
->name
, sval
);
604 if ((sval
& AVM_STATUS0_IRQ_MASK
) == AVM_STATUS0_IRQ_MASK
) {
605 /* shared IRQ from other HW */
606 spin_unlock(&fc
->lock
);
611 if (!(sval
& AVM_STATUS0_IRQ_ISAC
)) {
612 val
= ReadISAC_V1(fc
, ISAC_ISTA
);
613 mISDNisac_irq(&fc
->isac
, val
);
615 if (!(sval
& AVM_STATUS0_IRQ_HDLC
))
617 spin_unlock(&fc
->lock
);
622 avm_fritzv2_interrupt(int intno
, void *dev_id
)
624 struct fritzcard
*fc
= dev_id
;
628 spin_lock(&fc
->lock
);
629 sval
= inb(fc
->addr
+ 2);
630 pr_debug("%s: irq stat0 %x\n", fc
->name
, sval
);
631 if (!(sval
& AVM_STATUS0_IRQ_MASK
)) {
632 /* shared IRQ from other HW */
633 spin_unlock(&fc
->lock
);
638 if (sval
& AVM_STATUS0_IRQ_HDLC
)
640 if (sval
& AVM_STATUS0_IRQ_ISAC
) {
641 val
= ReadISAC_V2(fc
, ISACX_ISTA
);
642 mISDNisac_irq(&fc
->isac
, val
);
644 if (sval
& AVM_STATUS0_IRQ_TIMER
) {
645 pr_debug("%s: timer irq\n", fc
->name
);
646 outb(fc
->ctrlreg
| AVM_STATUS0_RES_TIMER
, fc
->addr
+ 2);
648 outb(fc
->ctrlreg
, fc
->addr
+ 2);
650 spin_unlock(&fc
->lock
);
655 avm_l2l1B(struct mISDNchannel
*ch
, struct sk_buff
*skb
)
657 struct bchannel
*bch
= container_of(ch
, struct bchannel
, ch
);
658 struct fritzcard
*fc
= bch
->hw
;
660 struct mISDNhead
*hh
= mISDN_HEAD_P(skb
);
666 spin_lock_irqsave(&fc
->lock
, flags
);
667 ret
= bchannel_senddata(bch
, skb
);
668 if (ret
> 0) { /* direct TX */
669 id
= hh
->id
; /* skb can be freed */
672 spin_unlock_irqrestore(&fc
->lock
, flags
);
673 if (!test_bit(FLG_TRANSPARENT
, &bch
->Flags
))
674 queue_ch_frame(ch
, PH_DATA_CNF
, id
, NULL
);
676 spin_unlock_irqrestore(&fc
->lock
, flags
);
678 case PH_ACTIVATE_REQ
:
679 spin_lock_irqsave(&fc
->lock
, flags
);
680 if (!test_and_set_bit(FLG_ACTIVE
, &bch
->Flags
))
681 ret
= modehdlc(bch
, ch
->protocol
);
684 spin_unlock_irqrestore(&fc
->lock
, flags
);
686 _queue_data(ch
, PH_ACTIVATE_IND
, MISDN_ID_ANY
, 0,
689 case PH_DEACTIVATE_REQ
:
690 spin_lock_irqsave(&fc
->lock
, flags
);
691 mISDN_clear_bchannel(bch
);
692 modehdlc(bch
, ISDN_P_NONE
);
693 spin_unlock_irqrestore(&fc
->lock
, flags
);
694 _queue_data(ch
, PH_DEACTIVATE_IND
, MISDN_ID_ANY
, 0,
705 inithdlc(struct fritzcard
*fc
)
707 modehdlc(&fc
->bch
[0], -1);
708 modehdlc(&fc
->bch
[1], -1);
712 clear_pending_hdlc_ints(struct fritzcard
*fc
)
716 val
= read_status(fc
, 1);
717 pr_debug("%s: HDLC 1 STA %x\n", fc
->name
, val
);
718 val
= read_status(fc
, 2);
719 pr_debug("%s: HDLC 2 STA %x\n", fc
->name
, val
);
723 reset_avm(struct fritzcard
*fc
)
727 fc
->ctrlreg
= AVM_STATUS0_RESET
| AVM_STATUS0_DIS_TIMER
;
729 case AVM_FRITZ_PCIV2
:
730 fc
->ctrlreg
= AVM_STATUS0_RESET
;
733 if (debug
& DEBUG_HW
)
734 pr_notice("%s: reset\n", fc
->name
);
739 fc
->ctrlreg
= AVM_STATUS0_DIS_TIMER
| AVM_STATUS0_RES_TIMER
;
741 outb(AVM_STATUS1_ENA_IOM
, fc
->addr
+ 3);
743 case AVM_FRITZ_PCIV2
:
749 if (debug
& DEBUG_HW
)
750 pr_notice("%s: S0/S1 %x/%x\n", fc
->name
,
751 inb(fc
->addr
+ 2), inb(fc
->addr
+ 3));
755 init_card(struct fritzcard
*fc
)
760 reset_avm(fc
); /* disable IRQ */
761 if (fc
->type
== AVM_FRITZ_PCIV2
)
762 ret
= request_irq(fc
->irq
, avm_fritzv2_interrupt
,
763 IRQF_SHARED
, fc
->name
, fc
);
765 ret
= request_irq(fc
->irq
, avm_fritz_interrupt
,
766 IRQF_SHARED
, fc
->name
, fc
);
768 pr_info("%s: couldn't get interrupt %d\n",
773 spin_lock_irqsave(&fc
->lock
, flags
);
774 ret
= fc
->isac
.init(&fc
->isac
);
776 spin_unlock_irqrestore(&fc
->lock
, flags
);
777 pr_info("%s: ISAC init failed with %d\n",
781 clear_pending_hdlc_ints(fc
);
784 /* RESET Receiver and Transmitter */
785 if (AVM_FRITZ_PCIV2
== fc
->type
) {
786 WriteISAC_V2(fc
, ISACX_MASK
, 0);
787 WriteISAC_V2(fc
, ISACX_CMDRD
, 0x41);
789 WriteISAC_V1(fc
, ISAC_MASK
, 0);
790 WriteISAC_V1(fc
, ISAC_CMDR
, 0x41);
792 spin_unlock_irqrestore(&fc
->lock
, flags
);
794 msleep_interruptible(10);
795 if (debug
& DEBUG_HW
)
796 pr_notice("%s: IRQ %d count %d\n", fc
->name
,
797 fc
->irq
, fc
->irqcnt
);
799 pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
800 fc
->name
, fc
->irq
, 3 - cnt
);
805 free_irq(fc
->irq
, fc
);
810 channel_bctrl(struct bchannel
*bch
, struct mISDN_ctrl_req
*cq
)
813 struct fritzcard
*fc
= bch
->hw
;
816 case MISDN_CTRL_GETOP
:
819 /* Nothing implemented yet */
820 case MISDN_CTRL_FILL_EMPTY
:
822 pr_info("%s: %s unknown Op %x\n", fc
->name
, __func__
, cq
->op
);
830 avm_bctrl(struct mISDNchannel
*ch
, u32 cmd
, void *arg
)
832 struct bchannel
*bch
= container_of(ch
, struct bchannel
, ch
);
833 struct fritzcard
*fc
= bch
->hw
;
837 pr_debug("%s: %s cmd:%x %p\n", fc
->name
, __func__
, cmd
, arg
);
840 test_and_clear_bit(FLG_OPEN
, &bch
->Flags
);
841 if (test_bit(FLG_ACTIVE
, &bch
->Flags
)) {
842 spin_lock_irqsave(&fc
->lock
, flags
);
843 mISDN_freebchannel(bch
);
844 test_and_clear_bit(FLG_TX_BUSY
, &bch
->Flags
);
845 test_and_clear_bit(FLG_ACTIVE
, &bch
->Flags
);
846 modehdlc(bch
, ISDN_P_NONE
);
847 spin_unlock_irqrestore(&fc
->lock
, flags
);
849 ch
->protocol
= ISDN_P_NONE
;
851 module_put(THIS_MODULE
);
854 case CONTROL_CHANNEL
:
855 ret
= channel_bctrl(bch
, arg
);
858 pr_info("%s: %s unknown prim(%x)\n", fc
->name
, __func__
, cmd
);
864 channel_ctrl(struct fritzcard
*fc
, struct mISDN_ctrl_req
*cq
)
869 case MISDN_CTRL_GETOP
:
870 cq
->op
= MISDN_CTRL_LOOP
;
872 case MISDN_CTRL_LOOP
:
873 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
874 if (cq
->channel
< 0 || cq
->channel
> 3) {
878 ret
= fc
->isac
.ctrl(&fc
->isac
, HW_TESTLOOP
, cq
->channel
);
881 pr_info("%s: %s unknown Op %x\n", fc
->name
, __func__
, cq
->op
);
889 open_bchannel(struct fritzcard
*fc
, struct channel_req
*rq
)
891 struct bchannel
*bch
;
893 if (rq
->adr
.channel
> 2)
895 if (rq
->protocol
== ISDN_P_NONE
)
897 bch
= &fc
->bch
[rq
->adr
.channel
- 1];
898 if (test_and_set_bit(FLG_OPEN
, &bch
->Flags
))
899 return -EBUSY
; /* b-channel can be only open once */
900 test_and_clear_bit(FLG_FILLEMPTY
, &bch
->Flags
);
901 bch
->ch
.protocol
= rq
->protocol
;
907 * device control function
910 avm_dctrl(struct mISDNchannel
*ch
, u32 cmd
, void *arg
)
912 struct mISDNdevice
*dev
= container_of(ch
, struct mISDNdevice
, D
);
913 struct dchannel
*dch
= container_of(dev
, struct dchannel
, dev
);
914 struct fritzcard
*fc
= dch
->hw
;
915 struct channel_req
*rq
;
918 pr_debug("%s: %s cmd:%x %p\n", fc
->name
, __func__
, cmd
, arg
);
922 if (rq
->protocol
== ISDN_P_TE_S0
)
923 err
= fc
->isac
.open(&fc
->isac
, rq
);
925 err
= open_bchannel(fc
, rq
);
928 if (!try_module_get(THIS_MODULE
))
929 pr_info("%s: cannot get module\n", fc
->name
);
932 pr_debug("%s: dev(%d) close from %p\n", fc
->name
, dch
->dev
.id
,
933 __builtin_return_address(0));
934 module_put(THIS_MODULE
);
936 case CONTROL_CHANNEL
:
937 err
= channel_ctrl(fc
, arg
);
940 pr_debug("%s: %s unknown command %x\n",
941 fc
->name
, __func__
, cmd
);
948 setup_fritz(struct fritzcard
*fc
)
952 if (!request_region(fc
->addr
, 32, fc
->name
)) {
953 pr_info("%s: AVM config port %x-%x already in use\n",
954 fc
->name
, fc
->addr
, fc
->addr
+ 31);
960 outl(AVM_HDLC_1
, fc
->addr
+ CHIP_INDEX
);
961 ver
= inl(fc
->addr
+ CHIP_WINDOW
+ HDLC_STATUS
) >> 24;
962 if (debug
& DEBUG_HW
) {
963 pr_notice("%s: PCI stat %#x\n", fc
->name
, val
);
964 pr_notice("%s: PCI Class %X Rev %d\n", fc
->name
,
965 val
& 0xff, (val
>> 8) & 0xff);
966 pr_notice("%s: HDLC version %x\n", fc
->name
, ver
& 0xf);
968 ASSIGN_FUNC(V1
, ISAC
, fc
->isac
);
969 fc
->isac
.type
= IPAC_TYPE_ISAC
;
971 case AVM_FRITZ_PCIV2
:
973 ver
= inl(fc
->addr
+ AVM_HDLC_STATUS_1
) >> 24;
974 if (debug
& DEBUG_HW
) {
975 pr_notice("%s: PCI V2 stat %#x\n", fc
->name
, val
);
976 pr_notice("%s: PCI V2 Class %X Rev %d\n", fc
->name
,
977 val
& 0xff, (val
>>8) & 0xff);
978 pr_notice("%s: HDLC version %x\n", fc
->name
, ver
& 0xf);
980 ASSIGN_FUNC(V2
, ISAC
, fc
->isac
);
981 fc
->isac
.type
= IPAC_TYPE_ISACX
;
984 release_region(fc
->addr
, 32);
985 pr_info("%s: AVM unknown type %d\n", fc
->name
, fc
->type
);
988 pr_notice("%s: %s config irq:%d base:0x%X\n", fc
->name
,
989 (fc
->type
== AVM_FRITZ_PCI
) ? "AVM Fritz!CARD PCI" :
990 "AVM Fritz!CARD PCIv2", fc
->irq
, fc
->addr
);
995 release_card(struct fritzcard
*card
)
1000 spin_lock_irqsave(&card
->lock
, flags
);
1001 modehdlc(&card
->bch
[0], ISDN_P_NONE
);
1002 modehdlc(&card
->bch
[1], ISDN_P_NONE
);
1003 spin_unlock_irqrestore(&card
->lock
, flags
);
1004 card
->isac
.release(&card
->isac
);
1005 free_irq(card
->irq
, card
);
1006 mISDN_freebchannel(&card
->bch
[1]);
1007 mISDN_freebchannel(&card
->bch
[0]);
1008 mISDN_unregister_device(&card
->isac
.dch
.dev
);
1009 release_region(card
->addr
, 32);
1010 pci_disable_device(card
->pdev
);
1011 pci_set_drvdata(card
->pdev
, NULL
);
1012 write_lock_irqsave(&card_lock
, flags
);
1013 list_del(&card
->list
);
1014 write_unlock_irqrestore(&card_lock
, flags
);
1019 static int __devinit
1020 setup_instance(struct fritzcard
*card
)
1025 snprintf(card
->name
, MISDN_MAX_IDLEN
- 1, "AVM.%d", AVM_cnt
+ 1);
1026 write_lock_irqsave(&card_lock
, flags
);
1027 list_add_tail(&card
->list
, &Cards
);
1028 write_unlock_irqrestore(&card_lock
, flags
);
1031 card
->isac
.name
= card
->name
;
1032 spin_lock_init(&card
->lock
);
1033 card
->isac
.hwlock
= &card
->lock
;
1034 mISDNisac_init(&card
->isac
, card
);
1036 card
->isac
.dch
.dev
.Bprotocols
= (1 << (ISDN_P_B_RAW
& ISDN_P_B_MASK
)) |
1037 (1 << (ISDN_P_B_HDLC
& ISDN_P_B_MASK
));
1038 card
->isac
.dch
.dev
.D
.ctrl
= avm_dctrl
;
1039 for (i
= 0; i
< 2; i
++) {
1040 card
->bch
[i
].nr
= i
+ 1;
1041 set_channelmap(i
+ 1, card
->isac
.dch
.dev
.channelmap
);
1042 mISDN_initbchannel(&card
->bch
[i
], MAX_DATA_MEM
);
1043 card
->bch
[i
].hw
= card
;
1044 card
->bch
[i
].ch
.send
= avm_l2l1B
;
1045 card
->bch
[i
].ch
.ctrl
= avm_bctrl
;
1046 card
->bch
[i
].ch
.nr
= i
+ 1;
1047 list_add(&card
->bch
[i
].ch
.list
, &card
->isac
.dch
.dev
.bchannels
);
1049 err
= setup_fritz(card
);
1052 err
= mISDN_register_device(&card
->isac
.dch
.dev
, &card
->pdev
->dev
,
1056 err
= init_card(card
);
1059 pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt
);
1062 mISDN_unregister_device(&card
->isac
.dch
.dev
);
1064 release_region(card
->addr
, 32);
1066 card
->isac
.release(&card
->isac
);
1067 mISDN_freebchannel(&card
->bch
[1]);
1068 mISDN_freebchannel(&card
->bch
[0]);
1069 write_lock_irqsave(&card_lock
, flags
);
1070 list_del(&card
->list
);
1071 write_unlock_irqrestore(&card_lock
, flags
);
1076 static int __devinit
1077 fritzpci_probe(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1080 struct fritzcard
*card
;
1082 card
= kzalloc(sizeof(struct fritzcard
), GFP_KERNEL
);
1084 pr_info("No kmem for fritzcard\n");
1087 if (pdev
->device
== PCI_DEVICE_ID_AVM_A1_V2
)
1088 card
->type
= AVM_FRITZ_PCIV2
;
1090 card
->type
= AVM_FRITZ_PCI
;
1092 err
= pci_enable_device(pdev
);
1098 pr_notice("mISDN: found adapter %s at %s\n",
1099 (char *) ent
->driver_data
, pci_name(pdev
));
1101 card
->addr
= pci_resource_start(pdev
, 1);
1102 card
->irq
= pdev
->irq
;
1103 pci_set_drvdata(pdev
, card
);
1104 err
= setup_instance(card
);
1106 pci_set_drvdata(pdev
, NULL
);
1110 static void __devexit
1111 fritz_remove_pci(struct pci_dev
*pdev
)
1113 struct fritzcard
*card
= pci_get_drvdata(pdev
);
1119 pr_info("%s: drvdata already removed\n", __func__
);
1122 static struct pci_device_id fcpci_ids
[] __devinitdata
= {
1123 { PCI_VENDOR_ID_AVM
, PCI_DEVICE_ID_AVM_A1
, PCI_ANY_ID
, PCI_ANY_ID
,
1124 0, 0, (unsigned long) "Fritz!Card PCI"},
1125 { PCI_VENDOR_ID_AVM
, PCI_DEVICE_ID_AVM_A1_V2
, PCI_ANY_ID
, PCI_ANY_ID
,
1126 0, 0, (unsigned long) "Fritz!Card PCI v2" },
1129 MODULE_DEVICE_TABLE(pci
, fcpci_ids
);
1131 static struct pci_driver fcpci_driver
= {
1133 .probe
= fritzpci_probe
,
1134 .remove
= __devexit_p(fritz_remove_pci
),
1135 .id_table
= fcpci_ids
,
1138 static int __init
AVM_init(void)
1142 pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV
);
1143 err
= pci_register_driver(&fcpci_driver
);
1147 static void __exit
AVM_cleanup(void)
1149 pci_unregister_driver(&fcpci_driver
);
1152 module_init(AVM_init
);
1153 module_exit(AVM_cleanup
);