Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* $Id: avmcard.h,v 1.1.4.1.2.1 2001/12/21 15:00:17 kai Exp $ |
2 | * | |
3 | * Copyright 1999 by Carsten Paeth <calle@calle.de> | |
4 | * | |
5 | * This software may be used and distributed according to the terms | |
6 | * of the GNU General Public License, incorporated herein by reference. | |
7 | * | |
8 | */ | |
9 | ||
10 | #ifndef _AVMCARD_H_ | |
11 | #define _AVMCARD_H_ | |
12 | ||
13 | #include <linux/spinlock.h> | |
14 | #include <linux/list.h> | |
15 | #include <linux/interrupt.h> | |
16 | ||
17 | #define AVMB1_PORTLEN 0x1f | |
18 | #define AVM_MAXVERSION 8 | |
19 | #define AVM_NCCI_PER_CHANNEL 4 | |
20 | ||
21 | /* | |
22 | * Versions | |
23 | */ | |
24 | ||
25 | #define VER_DRIVER 0 | |
26 | #define VER_CARDTYPE 1 | |
27 | #define VER_HWID 2 | |
28 | #define VER_SERIAL 3 | |
29 | #define VER_OPTION 4 | |
30 | #define VER_PROTO 5 | |
31 | #define VER_PROFILE 6 | |
32 | #define VER_CAPI 7 | |
33 | ||
34 | enum avmcardtype { | |
35 | avm_b1isa, | |
36 | avm_b1pci, | |
37 | avm_b1pcmcia, | |
38 | avm_m1, | |
39 | avm_m2, | |
40 | avm_t1isa, | |
41 | avm_t1pci, | |
42 | avm_c4, | |
43 | avm_c2 | |
44 | }; | |
45 | ||
46 | typedef struct avmcard_dmabuf { | |
47 | long size; | |
48 | u8 *dmabuf; | |
49 | dma_addr_t dmaaddr; | |
50 | } avmcard_dmabuf; | |
51 | ||
52 | typedef struct avmcard_dmainfo { | |
53 | u32 recvlen; | |
54 | avmcard_dmabuf recvbuf; | |
55 | ||
56 | avmcard_dmabuf sendbuf; | |
57 | struct sk_buff_head send_queue; | |
58 | ||
59 | struct pci_dev *pcidev; | |
60 | } avmcard_dmainfo; | |
61 | ||
62 | typedef struct avmctrl_info { | |
63 | char cardname[32]; | |
64 | ||
65 | int versionlen; | |
66 | char versionbuf[1024]; | |
67 | char *version[AVM_MAXVERSION]; | |
68 | ||
69 | char infobuf[128]; /* for function procinfo */ | |
70 | ||
71 | struct avmcard *card; | |
72 | struct capi_ctr capi_ctrl; | |
73 | ||
74 | struct list_head ncci_head; | |
75 | } avmctrl_info; | |
76 | ||
77 | typedef struct avmcard { | |
78 | char name[32]; | |
79 | ||
80 | spinlock_t lock; | |
81 | unsigned int port; | |
82 | unsigned irq; | |
83 | unsigned long membase; | |
84 | enum avmcardtype cardtype; | |
85 | unsigned char revision; | |
86 | unsigned char class; | |
87 | int cardnr; /* for t1isa */ | |
88 | ||
89 | char msgbuf[128]; /* capimsg msg part */ | |
90 | char databuf[2048]; /* capimsg data part */ | |
91 | ||
92 | void __iomem *mbase; | |
93 | volatile u32 csr; | |
94 | avmcard_dmainfo *dma; | |
95 | ||
96 | struct avmctrl_info *ctrlinfo; | |
97 | ||
98 | u_int nr_controllers; | |
99 | u_int nlogcontr; | |
100 | struct list_head list; | |
101 | } avmcard; | |
102 | ||
103 | extern int b1_irq_table[16]; | |
104 | ||
105 | /* | |
106 | * LLI Messages to the ISDN-ControllerISDN Controller | |
107 | */ | |
108 | ||
109 | #define SEND_POLL 0x72 /* | |
110 | * after load <- RECEIVE_POLL | |
111 | */ | |
112 | #define SEND_INIT 0x11 /* | |
113 | * first message <- RECEIVE_INIT | |
114 | * int32 NumApplications int32 | |
115 | * NumNCCIs int32 BoardNumber | |
116 | */ | |
117 | #define SEND_REGISTER 0x12 /* | |
118 | * register an application int32 | |
119 | * ApplIDId int32 NumMessages | |
120 | * int32 NumB3Connections int32 | |
121 | * NumB3Blocks int32 B3Size | |
122 | * | |
123 | * AnzB3Connection != 0 && | |
124 | * AnzB3Blocks >= 1 && B3Size >= 1 | |
125 | */ | |
126 | #define SEND_RELEASE 0x14 /* | |
127 | * deregister an application int32 | |
128 | * ApplID | |
129 | */ | |
130 | #define SEND_MESSAGE 0x15 /* | |
131 | * send capi-message int32 length | |
132 | * capi-data ... | |
133 | */ | |
134 | #define SEND_DATA_B3_REQ 0x13 /* | |
135 | * send capi-data-message int32 | |
136 | * MsgLength capi-data ... int32 | |
137 | * B3Length data .... | |
138 | */ | |
139 | ||
140 | #define SEND_CONFIG 0x21 /* | |
141 | */ | |
142 | ||
143 | #define SEND_POLLACK 0x73 /* T1 Watchdog */ | |
144 | ||
145 | /* | |
146 | * LLI Messages from the ISDN-ControllerISDN Controller | |
147 | */ | |
148 | ||
149 | #define RECEIVE_POLL 0x32 /* | |
150 | * <- after SEND_POLL | |
151 | */ | |
152 | #define RECEIVE_INIT 0x27 /* | |
153 | * <- after SEND_INIT int32 length | |
154 | * byte total length b1struct board | |
155 | * driver revision b1struct card | |
156 | * type b1struct reserved b1struct | |
157 | * serial number b1struct driver | |
158 | * capability b1struct d-channel | |
159 | * protocol b1struct CAPI-2.0 | |
160 | * profile b1struct capi version | |
161 | */ | |
162 | #define RECEIVE_MESSAGE 0x21 /* | |
163 | * <- after SEND_MESSAGE int32 | |
164 | * AppllID int32 Length capi-data | |
165 | * .... | |
166 | */ | |
167 | #define RECEIVE_DATA_B3_IND 0x22 /* | |
168 | * received data int32 AppllID | |
169 | * int32 Length capi-data ... | |
170 | * int32 B3Length data ... | |
171 | */ | |
172 | #define RECEIVE_START 0x23 /* | |
173 | * Handshake | |
174 | */ | |
175 | #define RECEIVE_STOP 0x24 /* | |
176 | * Handshake | |
177 | */ | |
178 | #define RECEIVE_NEW_NCCI 0x25 /* | |
179 | * int32 AppllID int32 NCCI int32 | |
180 | * WindowSize | |
181 | */ | |
182 | #define RECEIVE_FREE_NCCI 0x26 /* | |
183 | * int32 AppllID int32 NCCI | |
184 | */ | |
185 | #define RECEIVE_RELEASE 0x26 /* | |
186 | * int32 AppllID int32 0xffffffff | |
187 | */ | |
188 | #define RECEIVE_TASK_READY 0x31 /* | |
189 | * int32 tasknr | |
190 | * int32 Length Taskname ... | |
191 | */ | |
192 | #define RECEIVE_DEBUGMSG 0x71 /* | |
193 | * int32 Length message | |
194 | * | |
195 | */ | |
196 | #define RECEIVE_POLLDWORD 0x75 /* t1pci in dword mode */ | |
197 | ||
198 | #define WRITE_REGISTER 0x00 | |
199 | #define READ_REGISTER 0x01 | |
200 | ||
201 | /* | |
202 | * port offsets | |
203 | */ | |
204 | ||
205 | #define B1_READ 0x00 | |
206 | #define B1_WRITE 0x01 | |
207 | #define B1_INSTAT 0x02 | |
208 | #define B1_OUTSTAT 0x03 | |
209 | #define B1_ANALYSE 0x04 | |
210 | #define B1_REVISION 0x05 | |
211 | #define B1_RESET 0x10 | |
212 | ||
213 | ||
214 | #define B1_STAT0(cardtype) ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l) | |
215 | #define B1_STAT1(cardtype) (0x80E00000l) | |
216 | ||
217 | /* ---------------------------------------------------------------- */ | |
218 | ||
219 | static inline unsigned char b1outp(unsigned int base, | |
220 | unsigned short offset, | |
221 | unsigned char value) | |
222 | { | |
223 | outb(value, base + offset); | |
224 | return inb(base + B1_ANALYSE); | |
225 | } | |
226 | ||
227 | ||
228 | static inline int b1_rx_full(unsigned int base) | |
229 | { | |
230 | return inb(base + B1_INSTAT) & 0x1; | |
231 | } | |
232 | ||
233 | static inline unsigned char b1_get_byte(unsigned int base) | |
234 | { | |
235 | unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ | |
236 | while (!b1_rx_full(base) && time_before(jiffies, stop)); | |
237 | if (b1_rx_full(base)) | |
238 | return inb(base + B1_READ); | |
239 | printk(KERN_CRIT "b1lli(0x%x): rx not full after 1 second\n", base); | |
240 | return 0; | |
241 | } | |
242 | ||
243 | static inline unsigned int b1_get_word(unsigned int base) | |
244 | { | |
245 | unsigned int val = 0; | |
246 | val |= b1_get_byte(base); | |
247 | val |= (b1_get_byte(base) << 8); | |
248 | val |= (b1_get_byte(base) << 16); | |
249 | val |= (b1_get_byte(base) << 24); | |
250 | return val; | |
251 | } | |
252 | ||
253 | static inline int b1_tx_empty(unsigned int base) | |
254 | { | |
255 | return inb(base + B1_OUTSTAT) & 0x1; | |
256 | } | |
257 | ||
258 | static inline void b1_put_byte(unsigned int base, unsigned char val) | |
259 | { | |
260 | while (!b1_tx_empty(base)); | |
261 | b1outp(base, B1_WRITE, val); | |
262 | } | |
263 | ||
264 | static inline int b1_save_put_byte(unsigned int base, unsigned char val) | |
265 | { | |
266 | unsigned long stop = jiffies + 2 * HZ; | |
267 | while (!b1_tx_empty(base) && time_before(jiffies,stop)); | |
268 | if (!b1_tx_empty(base)) return -1; | |
269 | b1outp(base, B1_WRITE, val); | |
270 | return 0; | |
271 | } | |
272 | ||
273 | static inline void b1_put_word(unsigned int base, unsigned int val) | |
274 | { | |
275 | b1_put_byte(base, val & 0xff); | |
276 | b1_put_byte(base, (val >> 8) & 0xff); | |
277 | b1_put_byte(base, (val >> 16) & 0xff); | |
278 | b1_put_byte(base, (val >> 24) & 0xff); | |
279 | } | |
280 | ||
281 | static inline unsigned int b1_get_slice(unsigned int base, | |
282 | unsigned char *dp) | |
283 | { | |
284 | unsigned int len, i; | |
285 | ||
286 | len = i = b1_get_word(base); | |
287 | while (i-- > 0) *dp++ = b1_get_byte(base); | |
288 | return len; | |
289 | } | |
290 | ||
291 | static inline void b1_put_slice(unsigned int base, | |
292 | unsigned char *dp, unsigned int len) | |
293 | { | |
294 | unsigned i = len; | |
295 | b1_put_word(base, i); | |
296 | while (i-- > 0) | |
297 | b1_put_byte(base, *dp++); | |
298 | } | |
299 | ||
300 | static void b1_wr_reg(unsigned int base, | |
301 | unsigned int reg, | |
302 | unsigned int value) | |
303 | { | |
304 | b1_put_byte(base, WRITE_REGISTER); | |
305 | b1_put_word(base, reg); | |
306 | b1_put_word(base, value); | |
307 | } | |
308 | ||
309 | static inline unsigned int b1_rd_reg(unsigned int base, | |
310 | unsigned int reg) | |
311 | { | |
312 | b1_put_byte(base, READ_REGISTER); | |
313 | b1_put_word(base, reg); | |
314 | return b1_get_word(base); | |
315 | ||
316 | } | |
317 | ||
318 | static inline void b1_reset(unsigned int base) | |
319 | { | |
320 | b1outp(base, B1_RESET, 0); | |
321 | mdelay(55 * 2); /* 2 TIC's */ | |
322 | ||
323 | b1outp(base, B1_RESET, 1); | |
324 | mdelay(55 * 2); /* 2 TIC's */ | |
325 | ||
326 | b1outp(base, B1_RESET, 0); | |
327 | mdelay(55 * 2); /* 2 TIC's */ | |
328 | } | |
329 | ||
330 | static inline unsigned char b1_disable_irq(unsigned int base) | |
331 | { | |
332 | return b1outp(base, B1_INSTAT, 0x00); | |
333 | } | |
334 | ||
335 | /* ---------------------------------------------------------------- */ | |
336 | ||
337 | static inline void b1_set_test_bit(unsigned int base, | |
338 | enum avmcardtype cardtype, | |
339 | int onoff) | |
340 | { | |
341 | b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20); | |
342 | } | |
343 | ||
344 | static inline int b1_get_test_bit(unsigned int base, | |
345 | enum avmcardtype cardtype) | |
346 | { | |
347 | return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0; | |
348 | } | |
349 | ||
350 | /* ---------------------------------------------------------------- */ | |
351 | ||
352 | #define T1_FASTLINK 0x00 | |
353 | #define T1_SLOWLINK 0x08 | |
354 | ||
355 | #define T1_READ B1_READ | |
356 | #define T1_WRITE B1_WRITE | |
357 | #define T1_INSTAT B1_INSTAT | |
358 | #define T1_OUTSTAT B1_OUTSTAT | |
359 | #define T1_IRQENABLE 0x05 | |
360 | #define T1_FIFOSTAT 0x06 | |
361 | #define T1_RESETLINK 0x10 | |
362 | #define T1_ANALYSE 0x11 | |
363 | #define T1_IRQMASTER 0x12 | |
364 | #define T1_IDENT 0x17 | |
365 | #define T1_RESETBOARD 0x1f | |
366 | ||
367 | #define T1F_IREADY 0x01 | |
368 | #define T1F_IHALF 0x02 | |
369 | #define T1F_IFULL 0x04 | |
370 | #define T1F_IEMPTY 0x08 | |
371 | #define T1F_IFLAGS 0xF0 | |
372 | ||
373 | #define T1F_OREADY 0x10 | |
374 | #define T1F_OHALF 0x20 | |
375 | #define T1F_OEMPTY 0x40 | |
376 | #define T1F_OFULL 0x80 | |
377 | #define T1F_OFLAGS 0xF0 | |
378 | ||
379 | /* there are HEMA cards with 1k and 4k FIFO out */ | |
380 | #define FIFO_OUTBSIZE 256 | |
381 | #define FIFO_INPBSIZE 512 | |
382 | ||
383 | #define HEMA_VERSION_ID 0 | |
384 | #define HEMA_PAL_ID 0 | |
385 | ||
386 | static inline void t1outp(unsigned int base, | |
387 | unsigned short offset, | |
388 | unsigned char value) | |
389 | { | |
390 | outb(value, base + offset); | |
391 | } | |
392 | ||
393 | static inline unsigned char t1inp(unsigned int base, | |
394 | unsigned short offset) | |
395 | { | |
396 | return inb(base + offset); | |
397 | } | |
398 | ||
399 | static inline int t1_isfastlink(unsigned int base) | |
400 | { | |
401 | return (inb(base + T1_IDENT) & ~0x82) == 1; | |
402 | } | |
403 | ||
404 | static inline unsigned char t1_fifostatus(unsigned int base) | |
405 | { | |
406 | return inb(base + T1_FIFOSTAT); | |
407 | } | |
408 | ||
409 | static inline unsigned int t1_get_slice(unsigned int base, | |
410 | unsigned char *dp) | |
411 | { | |
412 | unsigned int len, i; | |
413 | #ifdef FASTLINK_DEBUG | |
414 | unsigned wcnt = 0, bcnt = 0; | |
415 | #endif | |
416 | ||
417 | len = i = b1_get_word(base); | |
418 | if (t1_isfastlink(base)) { | |
419 | int status; | |
420 | while (i > 0) { | |
421 | status = t1_fifostatus(base) & (T1F_IREADY|T1F_IHALF); | |
422 | if (i >= FIFO_INPBSIZE) status |= T1F_IFULL; | |
423 | ||
424 | switch (status) { | |
425 | case T1F_IREADY|T1F_IHALF|T1F_IFULL: | |
426 | insb(base+B1_READ, dp, FIFO_INPBSIZE); | |
427 | dp += FIFO_INPBSIZE; | |
428 | i -= FIFO_INPBSIZE; | |
429 | #ifdef FASTLINK_DEBUG | |
430 | wcnt += FIFO_INPBSIZE; | |
431 | #endif | |
432 | break; | |
433 | case T1F_IREADY|T1F_IHALF: | |
434 | insb(base+B1_READ,dp, i); | |
435 | #ifdef FASTLINK_DEBUG | |
436 | wcnt += i; | |
437 | #endif | |
438 | dp += i; | |
439 | i = 0; | |
dac5bafa | 440 | break; |
1da177e4 LT |
441 | default: |
442 | *dp++ = b1_get_byte(base); | |
443 | i--; | |
444 | #ifdef FASTLINK_DEBUG | |
445 | bcnt++; | |
446 | #endif | |
447 | break; | |
448 | } | |
449 | } | |
450 | #ifdef FASTLINK_DEBUG | |
451 | if (wcnt) | |
452 | printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n", | |
453 | base, len, wcnt, bcnt); | |
454 | #endif | |
455 | } else { | |
456 | while (i-- > 0) | |
457 | *dp++ = b1_get_byte(base); | |
458 | } | |
459 | return len; | |
460 | } | |
461 | ||
462 | static inline void t1_put_slice(unsigned int base, | |
463 | unsigned char *dp, unsigned int len) | |
464 | { | |
465 | unsigned i = len; | |
466 | b1_put_word(base, i); | |
467 | if (t1_isfastlink(base)) { | |
468 | int status; | |
469 | while (i > 0) { | |
470 | status = t1_fifostatus(base) & (T1F_OREADY|T1F_OHALF); | |
471 | if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY; | |
472 | switch (status) { | |
473 | case T1F_OREADY|T1F_OHALF|T1F_OEMPTY: | |
474 | outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE); | |
475 | dp += FIFO_OUTBSIZE; | |
476 | i -= FIFO_OUTBSIZE; | |
477 | break; | |
478 | case T1F_OREADY|T1F_OHALF: | |
479 | outsb(base+B1_WRITE, dp, i); | |
480 | dp += i; | |
481 | i = 0; | |
482 | break; | |
483 | default: | |
484 | b1_put_byte(base, *dp++); | |
485 | i--; | |
486 | break; | |
487 | } | |
488 | } | |
489 | } else { | |
490 | while (i-- > 0) | |
491 | b1_put_byte(base, *dp++); | |
492 | } | |
493 | } | |
494 | ||
495 | static inline void t1_disable_irq(unsigned int base) | |
496 | { | |
497 | t1outp(base, T1_IRQMASTER, 0x00); | |
498 | } | |
499 | ||
500 | static inline void t1_reset(unsigned int base) | |
501 | { | |
502 | /* reset T1 Controller */ | |
503 | b1_reset(base); | |
504 | /* disable irq on HEMA */ | |
505 | t1outp(base, B1_INSTAT, 0x00); | |
506 | t1outp(base, B1_OUTSTAT, 0x00); | |
507 | t1outp(base, T1_IRQMASTER, 0x00); | |
508 | /* reset HEMA board configuration */ | |
509 | t1outp(base, T1_RESETBOARD, 0xf); | |
510 | } | |
511 | ||
512 | static inline void b1_setinterrupt(unsigned int base, unsigned irq, | |
513 | enum avmcardtype cardtype) | |
514 | { | |
515 | switch (cardtype) { | |
516 | case avm_t1isa: | |
517 | t1outp(base, B1_INSTAT, 0x00); | |
518 | t1outp(base, B1_INSTAT, 0x02); | |
519 | t1outp(base, T1_IRQMASTER, 0x08); | |
520 | break; | |
521 | case avm_b1isa: | |
522 | b1outp(base, B1_INSTAT, 0x00); | |
523 | b1outp(base, B1_RESET, b1_irq_table[irq]); | |
524 | b1outp(base, B1_INSTAT, 0x02); | |
525 | break; | |
526 | default: | |
527 | case avm_m1: | |
528 | case avm_m2: | |
529 | case avm_b1pci: | |
530 | b1outp(base, B1_INSTAT, 0x00); | |
531 | b1outp(base, B1_RESET, 0xf0); | |
532 | b1outp(base, B1_INSTAT, 0x02); | |
533 | break; | |
534 | case avm_c4: | |
535 | case avm_t1pci: | |
536 | b1outp(base, B1_RESET, 0xf0); | |
537 | break; | |
538 | } | |
539 | } | |
540 | ||
541 | /* b1.c */ | |
542 | avmcard *b1_alloc_card(int nr_controllers); | |
543 | void b1_free_card(avmcard *card); | |
544 | int b1_detect(unsigned int base, enum avmcardtype cardtype); | |
545 | void b1_getrevision(avmcard *card); | |
546 | int b1_load_t4file(avmcard *card, capiloaddatapart * t4file); | |
547 | int b1_load_config(avmcard *card, capiloaddatapart * config); | |
548 | int b1_loaded(avmcard *card); | |
549 | ||
550 | int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); | |
551 | void b1_reset_ctr(struct capi_ctr *ctrl); | |
552 | void b1_register_appl(struct capi_ctr *ctrl, u16 appl, | |
553 | capi_register_params *rp); | |
554 | void b1_release_appl(struct capi_ctr *ctrl, u16 appl); | |
555 | u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); | |
556 | void b1_parse_version(avmctrl_info *card); | |
7d12e780 | 557 | irqreturn_t b1_interrupt(int interrupt, void *devptr); |
1da177e4 LT |
558 | |
559 | int b1ctl_read_proc(char *page, char **start, off_t off, | |
560 | int count, int *eof, struct capi_ctr *ctrl); | |
561 | ||
562 | avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, | |
563 | long rsize, long ssize); | |
564 | void avmcard_dma_free(avmcard_dmainfo *); | |
565 | ||
566 | /* b1dma.c */ | |
567 | int b1pciv4_detect(avmcard *card); | |
568 | int t1pci_detect(avmcard *card); | |
569 | void b1dma_reset(avmcard *card); | |
7d12e780 | 570 | irqreturn_t b1dma_interrupt(int interrupt, void *devptr); |
1da177e4 LT |
571 | |
572 | int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); | |
573 | void b1dma_reset_ctr(struct capi_ctr *ctrl); | |
574 | void b1dma_remove_ctr(struct capi_ctr *ctrl); | |
575 | void b1dma_register_appl(struct capi_ctr *ctrl, | |
576 | u16 appl, | |
577 | capi_register_params *rp); | |
578 | void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); | |
579 | u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); | |
580 | int b1dmactl_read_proc(char *page, char **start, off_t off, | |
581 | int count, int *eof, struct capi_ctr *ctrl); | |
582 | ||
583 | #endif /* _AVMCARD_H_ */ |