12 #include <linux/module.h>
13 #include <linux/kernel.h>
21 #include <linux/pci.h>
23 #include <linux/kernelcapi.h>
27 #include <asm/uaccess.h>
28 #include <linux/netdevice.h>
35 #undef AVM_C4_POLLDEBUG
39 static char *
revision =
"$Revision: 1.1.2.2 $";
43 static bool suppress_pollack;
63 #define DC21285_DRAM_A0MR 0x40000000
64 #define DC21285_DRAM_A1MR 0x40004000
65 #define DC21285_DRAM_A2MR 0x40008000
66 #define DC21285_DRAM_A3MR 0x4000C000
68 #define CAS_OFFSET 0x88
70 #define DC21285_ARMCSR_BASE 0x42000000
72 #define PCI_OUT_INT_STATUS 0x30
73 #define PCI_OUT_INT_MASK 0x34
74 #define MAILBOX_0 0x50
75 #define MAILBOX_1 0x54
76 #define MAILBOX_2 0x58
77 #define MAILBOX_3 0x5C
79 #define DOORBELL_SETUP 0x64
81 #define CHAN_1_CONTROL 0x90
82 #define CHAN_2_CONTROL 0xB0
83 #define DRAM_TIMING 0x10C
84 #define DRAM_ADDR_SIZE_0 0x110
85 #define DRAM_ADDR_SIZE_1 0x114
86 #define DRAM_ADDR_SIZE_2 0x118
87 #define DRAM_ADDR_SIZE_3 0x11C
88 #define SA_CONTROL 0x13C
89 #define XBUS_CYCLE 0x148
90 #define XBUS_STROBE 0x14C
91 #define DBELL_PCI_MASK 0x150
92 #define DBELL_SA_MASK 0x154
94 #define SDRAM_SIZE 0x1000000
98 #define MBOX_PEEK_POKE MAILBOX_0
100 #define DBELL_ADDR 0x01
101 #define DBELL_DATA 0x02
102 #define DBELL_RNWR 0x40
103 #define DBELL_INIT 0x80
107 #define MBOX_UP_ADDR MAILBOX_0
108 #define MBOX_UP_LEN MAILBOX_1
109 #define MBOX_DOWN_ADDR MAILBOX_2
110 #define MBOX_DOWN_LEN MAILBOX_3
112 #define DBELL_UP_HOST 0x00000100
113 #define DBELL_UP_ARM 0x00000200
114 #define DBELL_DOWN_HOST 0x00000400
115 #define DBELL_DOWN_ARM 0x00000800
116 #define DBELL_RESET_HOST 0x40000000
117 #define DBELL_RESET_ARM 0x80000000
121 #define DRAM_TIMING_DEF 0x001A01A5
122 #define DRAM_AD_SZ_DEF0 0x00000045
123 #define DRAM_AD_SZ_NULL 0x00000000
125 #define SA_CTL_ALLRIGHT 0x64AA0271
127 #define INIT_XBUS_CYCLE 0x100016DB
128 #define INIT_XBUS_STROBE 0xF1F1F1F1
132 #define RESET_TIMEOUT (15 * HZ)
133 #define PEEK_POKE_TIMEOUT (HZ / 10)
137 #define c4outmeml(addr, value) writel(value, addr)
138 #define c4inmeml(addr) readl(addr)
139 #define c4outmemw(addr, value) writew(value, addr)
140 #define c4inmemw(addr) readw(addr)
141 #define c4outmemb(addr, value) writeb(value, addr)
142 #define c4inmemb(addr) readb(addr)
146 static inline int wait_for_doorbell(
avmcard *
card,
unsigned long t)
162 if (wait_for_doorbell(card,
HZ / 10) < 0)
168 if (wait_for_doorbell(card,
HZ / 10) < 0)
177 static int c4_peek(
avmcard *card,
unsigned long off,
unsigned long *valuep)
179 if (wait_for_doorbell(card,
HZ / 10) < 0)
185 if (wait_for_doorbell(card,
HZ / 10) < 0)
204 while (left >=
sizeof(
u32)) {
209 memcpy(&val, dp,
sizeof(val));
211 if (c4_poke(card, loadoff, val)) {
218 loadoff +=
sizeof(
u32);
228 if (c4_poke(card, loadoff, val)) {
239 static inline void _put_byte(
void **
pp,
u8 val)
246 static inline void _put_word(
void **
pp,
u32 val)
250 *s++ = (val >> 8) & 0xff;
251 *s++ = (val >> 16) & 0xff;
252 *s++ = (val >> 24) & 0xff;
256 static inline void _put_slice(
void **
pp,
unsigned char *dp,
unsigned int len)
261 _put_byte(pp, *dp++);
264 static inline u8 _get_byte(
void **pp)
273 static inline u32 _get_word(
void **pp)
285 static inline u32 _get_slice(
void **pp,
unsigned char *dp)
289 len = i = _get_word(pp);
290 while (i-- > 0) *dp++ = _get_byte(pp);
296 static void c4_reset(
avmcard *card)
316 static int c4_detect(
avmcard *card)
381 if (c4_poke(card, 0x000000, 0x11111111)
382 || c4_poke(card, 0x400000, 0x22222222)
383 || c4_poke(card, 0x800000, 0x33333333)
384 || c4_poke(card, 0xC00000, 0x44444444))
387 if (c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111
388 || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222
389 || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333
390 || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)
393 if (c4_poke(card, 0x000000, 0x55555555)
394 || c4_poke(card, 0x400000, 0x66666666)
395 || c4_poke(card, 0x800000, 0x77777777)
396 || c4_poke(card, 0xC00000, 0x88888888))
399 if (c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555
400 || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666
401 || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777
402 || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)
410 static void c4_dispatch_tx(
avmcard *card)
443 _put_slice(&p, skb->
data, len);
444 _put_slice(&p, skb->
data + len, dlen);
447 _put_slice(&p, skb->
data, len);
454 txlen = skb->
len - 2;
455 #ifdef AVM_C4_POLLDEBUG
463 skb_copy_from_linear_data_offset(skb, 2, dma->
sendbuf.
dmabuf,
466 txlen = (txlen + 3) & ~3;
480 static void queue_pollack(
avmcard *card)
498 c4_dispatch_tx(card);
503 static void c4_handle_rx(
avmcard *card)
510 u32 ApplId, MsgLen, DataB3Len,
NCCI, WindowSize;
511 u8 b1cmd = _get_byte(&p);
517 b1cmd, (
unsigned long)dma->
recvlen);
523 ApplId = (unsigned) _get_word(&p);
524 MsgLen = _get_slice(&p, card->
msgbuf);
525 DataB3Len = _get_slice(&p, card->
databuf);
528 ctrl = &card->
ctrlinfo[cidx].capi_ctrl;
535 if (!(skb = alloc_skb(DataB3Len + MsgLen,
GFP_ATOMIC))) {
547 ApplId = (unsigned) _get_word(&p);
548 MsgLen = _get_slice(&p, card->
msgbuf);
552 ctrl = &card->
ctrlinfo[cidx].capi_ctrl;
570 ApplId = _get_word(&p);
571 NCCI = _get_word(&p);
572 WindowSize = _get_word(&p);
573 cidx = (NCCI & 0x7f) - card->
cardnr;
582 ApplId = _get_word(&p);
583 NCCI = _get_word(&p);
585 if (NCCI != 0xffffffff) {
586 cidx = (NCCI & 0x7f) - card->
cardnr;
593 #ifdef AVM_C4_POLLDEBUG
596 if (!suppress_pollack)
599 ctrl = &card->
ctrlinfo[cidx].capi_ctrl;
606 ctrl = &card->
ctrlinfo[cidx].capi_ctrl;
616 card->
name, cidx + 1);
632 ApplId = (unsigned) _get_word(&p);
633 MsgLen = _get_slice(&p, card->
msgbuf);
636 && (card->
msgbuf[MsgLen - 1] ==
'\n'
637 || card->
msgbuf[MsgLen - 1] ==
'\r')) {
638 card->
msgbuf[MsgLen - 1] = 0;
646 MsgLen = _get_slice(&p, card->
msgbuf);
649 && (card->
msgbuf[MsgLen - 1] ==
'\n'
650 || card->
msgbuf[MsgLen - 1] ==
'\r')) {
651 card->
msgbuf[MsgLen - 1] = 0;
677 spin_unlock_irqrestore(&card->
lock, flags);
686 spin_unlock_irqrestore(&card->
lock, flags);
695 spin_unlock_irqrestore(&card->
lock, flags);
711 c4_dispatch_tx(card);
712 }
else if (card->
csr & DBELL_DOWN_HOST) {
715 c4_dispatch_tx(card);
718 spin_unlock_irqrestore(&card->
lock, flags);
726 return c4_handle_interrupt(card);
731 static void c4_send_init(
avmcard *card)
749 _put_word(&p, card->
cardnr - 1);
754 c4_dispatch_tx(card);
755 spin_unlock_irqrestore(&card->
lock, flags);
758 static int queue_sendconfigword(
avmcard *card,
u32 val)
779 c4_dispatch_tx(card);
780 spin_unlock_irqrestore(&card->
lock, flags);
784 static int queue_sendconfig(
avmcard *card,
char cval[4])
800 _put_byte(&p, cval[0]);
801 _put_byte(&p, cval[1]);
802 _put_byte(&p, cval[2]);
803 _put_byte(&p, cval[3]);
809 c4_dispatch_tx(card);
810 spin_unlock_irqrestore(&card->
lock, flags);
821 if ((retval = queue_sendconfigword(card, 1)) != 0)
823 if ((retval = queue_sendconfigword(card, config->
len)) != 0)
828 while (left >=
sizeof(
u32)) {
833 memcpy(val, dp,
sizeof(val));
835 if ((retval = queue_sendconfig(card, val)) != 0)
841 memset(val, 0,
sizeof(val));
848 if ((retval = queue_sendconfig(card, val)) != 0)
861 if ((retval = c4_load_t4file(card, &data->
firmware))) {
874 DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);
899 static void c4_reset_ctr(
struct capi_ctr *ctrl)
910 spin_unlock_irqrestore(&card->
lock, flags);
920 static void c4_remove(
struct pci_dev *pdev)
922 avmcard *card = pci_get_drvdata(pdev);
940 pci_set_drvdata(pdev,
NULL);
947 static void c4_register_appl(
struct capi_ctr *ctrl,
961 if (want > 0) nconn = want;
976 _put_word(&p, 1024 * (nconn + 1));
977 _put_word(&p, nconn);
985 c4_dispatch_tx(card);
986 spin_unlock_irqrestore(&card->
lock, flags);
992 static void c4_release_appl(
struct capi_ctr *ctrl,
u16 appl)
1002 spin_unlock_irqrestore(&card->
lock, flags);
1015 _put_word(&p, appl);
1020 c4_dispatch_tx(card);
1021 spin_unlock_irqrestore(&card->
lock, flags);
1033 unsigned long flags;
1044 c4_dispatch_tx(card);
1046 spin_unlock_irqrestore(&card->
lock, flags);
1052 static char *c4_procinfo(
struct capi_ctr *ctrl)
1061 cinfo->
card ? cinfo->
card->port : 0x0,
1062 cinfo->
card ? cinfo->
card->irq : 0,
1063 cinfo->
card ? cinfo->
card->membase : 0
1068 static int c4_proc_show(
struct seq_file *
m,
void *
v)
1084 case avm_m1: s =
"M1";
break;
1085 case avm_m2: s =
"M2";
break;
1086 case avm_t1isa: s =
"T1 ISA (HEMA)";
break;
1088 case avm_c4: s =
"C4";
break;
1089 case avm_c2: s =
"C2";
break;
1090 default: s =
"???";
break;
1094 seq_printf(m,
"%-16s %s\n",
"ver_driver", s);
1096 seq_printf(m,
"%-16s %s\n",
"ver_cardtype", s);
1098 seq_printf(m,
"%-16s %s\n",
"ver_serial", s);
1105 (flag & 0x01) ?
" DSS1" :
"",
1106 (flag & 0x02) ?
" CT1" :
"",
1107 (flag & 0x04) ?
" VN3" :
"",
1108 (flag & 0x08) ?
" NI1" :
"",
1109 (flag & 0x10) ?
" AUSTEL" :
"",
1110 (flag & 0x20) ?
" ESS" :
"",
1111 (flag & 0x40) ?
" 1TR6" :
""
1119 (flag & 0x01) ?
" point to point" :
"",
1120 (flag & 0x02) ?
" point to multipoint" :
"",
1121 (flag & 0x08) ?
" leased line without D-channel" :
"",
1122 (flag & 0x04) ?
" leased line with D-channel" :
""
1132 return single_open(file, c4_proc_show, PDE(inode)->data);
1137 .open = c4_proc_open,
1184 goto err_release_region;
1187 retval = c4_detect(card);
1190 card->
port, retval);
1203 for (i = 0; i < nr_controllers; i++) {
1208 cinfo->
capi_ctrl.register_appl = c4_register_appl;
1209 cinfo->
capi_ctrl.release_appl = c4_release_appl;
1210 cinfo->
capi_ctrl.send_message = c4_send_message;
1211 cinfo->
capi_ctrl.load_firmware = c4_load_firmware;
1212 cinfo->
capi_ctrl.reset_ctr = c4_reset_ctr;
1213 cinfo->
capi_ctrl.procinfo = c4_procinfo;
1214 cinfo->
capi_ctrl.proc_fops = &c4_proc_fops;
1220 for (i--; i >= 0; i--) {
1231 nr_controllers, card->
port, card->
irq,
1233 pci_set_drvdata(dev, card);
1269 printk(
KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n",
1272 retval = c4_add_card(&
param, dev, nr);
1274 printk(
KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n",
1284 .id_table = c4_pci_tbl,
1286 .remove = c4_remove,
1299 static int __init c4_init(
void)
1307 if ((p =
strchr(rev,
'$')) !=
NULL && p > rev)
1312 err = pci_register_driver(&c4_pci_driver);
1323 static void __exit c4_exit(
void)