4e40f9495f71801563cb2827435293c586454707
[feed/telephony.git] / libs / dahdi-linux / patches / 100-add-support-for-hfc-s-pci.patch
1 --- a/drivers/dahdi/Kbuild
2 +++ b/drivers/dahdi/Kbuild
3 @@ -12,6 +12,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT
4 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
5 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
6 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE13XP) += wcte13xp.o
7 +obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_HFCS) += hfcs/
8
9 wcte13xp-objs := wcte13xp-base.o wcxb_spi.o wcxb.o wcxb_flash.o
10 CFLAGS_wcte13xp-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
11 --- a/drivers/dahdi/Kconfig
12 +++ b/drivers/dahdi/Kconfig
13 @@ -223,4 +223,14 @@ config DAHDI_DYNAMIC_LOC
14 If unsure, say Y.
15
16
17 +config DAHDI_HFCS
18 + tristate "Support for various HFC-S PCI BRI adapters"
19 + depends on DAHDI && PCI
20 + default DAHDI
21 + ---help---
22 + To compile this driver as a module, choose M here: the
23 + module will be called dahdi_hfcs.
24 +
25 + If unsure, say Y.
26 +
27 source "drivers/dahdi/xpp/Kconfig"
28 --- /dev/null
29 +++ b/drivers/dahdi/hfcs/base.c
30 @@ -0,0 +1,1742 @@
31 +/*
32 + * dahdi_hfcs.c - Dahdi driver for HFC-S PCI A based ISDN BRI cards
33 + *
34 + * Dahdi rewrite in hardhdlc mode
35 + * Jose A. Deniz <odicha@hotmail.com>
36 + *
37 + * Copyright (C) 2011, Raoul Bönisch
38 + * Copyright (C) 2009, Jose A. Deniz
39 + * Copyright (C) 2006, headissue GmbH; Jens Wilke
40 + * Copyright (C) 2004 Daniele Orlandi
41 + * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
42 + *
43 + * Jens Wilke <jw_vzaphfc@headissue.com>
44 + *
45 + * Original author of this code is
46 + * Daniele "Vihai" Orlandi <daniele@orlandi.com>
47 + *
48 + * Major rewrite of the driver made by
49 + * Klaus-Peter Junghanns <kpj@junghanns.net>
50 + *
51 + * This program is free software and may be modified and
52 + * distributed under the terms of the GNU Public License.
53 + *
54 + * Please read the README file for important infos.
55 + */
56 +
57 +#include <linux/spinlock.h>
58 +#include <linux/init.h>
59 +#include <linux/pci.h>
60 +#include <linux/interrupt.h>
61 +#include <linux/module.h>
62 +#include <linux/moduleparam.h>
63 +#include <linux/version.h>
64 +#include <linux/kernel.h>
65 +#include <linux/delay.h>
66 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32))
67 +#include <linux/sched.h>
68 +#endif
69 +#include <linux/proc_fs.h>
70 +#include <linux/if_arp.h>
71 +
72 +#include <dahdi/kernel.h>
73 +
74 +#include "dahdi_hfcs.h"
75 +#include "fifo.h"
76 +
77 +#if CONFIG_PCI
78 +
79 +#define DAHDI_B1 0
80 +#define DAHDI_B2 1
81 +#define DAHDI_D 2
82 +
83 +#define D 0
84 +#define B1 1
85 +#define B2 2
86 +
87 +/*
88 + * Mode Te for all
89 + */
90 +static int modes;
91 +static int nt_modes[hfc_MAX_BOARDS];
92 +static int nt_modes_count;
93 +static int force_l1_up;
94 +static struct proc_dir_entry *hfc_proc_dahdi_hfcs_dir;
95 +
96 +#define DEBUG
97 +#ifdef DEBUG
98 +int debug_level;
99 +#endif
100 +
101 +#ifndef FALSE
102 +#define FALSE 0
103 +#endif
104 +#ifndef TRUE
105 +#define TRUE (!FALSE)
106 +#endif
107 +
108 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
109 +#define SET_PROC_DIRENTRY_OWNER(p) do { (p)->owner = THIS_MODULE; } while(0);
110 +#else
111 +#define SET_PROC_DIRENTRY_OWNER(p) do { } while(0);
112 +#endif
113 +
114 +static DEFINE_PCI_DEVICE_TABLE(hfc_pci_ids) = {
115 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0,
116 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
117 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000,
118 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
119 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006,
120 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
121 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007,
122 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
123 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008,
124 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
125 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009,
126 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
127 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A,
128 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
129 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B,
130 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
131 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C,
132 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
133 + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100,
134 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
135 + {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1,
136 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
137 + {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675,
138 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
139 + {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT,
140 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
141 + {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T,
142 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
143 + {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575,
144 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
145 + {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0,
146 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
147 + {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,
148 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
149 + {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,
150 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
151 + {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,
152 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
153 + {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,
154 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
155 + {PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_3069,
156 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
157 + {0,}
158 +};
159 +
160 +MODULE_DEVICE_TABLE(pci, hfc_pci_ids);
161 +
162 +static int __devinit hfc_probe(struct pci_dev *dev
163 + , const struct pci_device_id *ent);
164 +static void __devexit hfc_remove(struct pci_dev *dev);
165 +
166 +static struct pci_driver hfc_driver = {
167 + .name = hfc_DRIVER_NAME,
168 + .id_table = hfc_pci_ids,
169 + .probe = hfc_probe,
170 + .remove = __devexit_p(hfc_remove),
171 +};
172 +
173 +/******************************************
174 + * HW routines
175 + ******************************************/
176 +
177 +static void hfc_softreset(struct hfc_card *card)
178 +{
179 + printk(KERN_INFO hfc_DRIVER_PREFIX
180 + "card %d: "
181 + "resetting\n",
182 + card->cardnum);
183 +
184 +/*
185 + * Softreset procedure. Put it on, wait and off again
186 + */
187 + hfc_outb(card, hfc_CIRM, hfc_CIRM_RESET);
188 + udelay(6);
189 + hfc_outb(card, hfc_CIRM, 0);
190 +
191 + set_current_state(TASK_UNINTERRUPTIBLE);
192 + schedule_timeout((hfc_RESET_DELAY * HZ) / 1000);
193 +}
194 +
195 +static void hfc_resetCard(struct hfc_card *card)
196 +{
197 + card->regs.m1 = 0;
198 + hfc_outb(card, hfc_INT_M1, card->regs.m1);
199 +
200 + card->regs.m2 = 0;
201 + hfc_outb(card, hfc_INT_M2, card->regs.m2);
202 +
203 + hfc_softreset(card);
204 +
205 + card->regs.trm = 0;
206 + hfc_outb(card, hfc_TRM, card->regs.trm);
207 +
208 + /*
209 + * Select the non-capacitive line mode for the S/T interface
210 + */
211 + card->regs.sctrl = hfc_SCTRL_NONE_CAP;
212 +
213 + if (card->nt_mode) {
214 + /*
215 + * ST-Bit delay for NT-Mode
216 + */
217 + hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_NT);
218 +
219 + card->regs.sctrl |= hfc_SCTRL_MODE_NT;
220 + } else {
221 + /*
222 + * ST-Bit delay for TE-Mode
223 + */
224 + hfc_outb(card, hfc_CLKDEL, hfc_CLKDEL_TE);
225 +
226 + card->regs.sctrl |= hfc_SCTRL_MODE_TE;
227 + }
228 +
229 + hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
230 +
231 + /*
232 + * S/T Auto awake
233 + */
234 + card->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
235 + hfc_outb(card, hfc_SCTRL_E, card->regs.sctrl_e);
236 +
237 + /*
238 + * No B-channel enabled at startup
239 + */
240 + card->regs.sctrl_r = 0;
241 + hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
242 +
243 + /*
244 + * HFC Master Mode
245 + */
246 + hfc_outb(card, hfc_MST_MODE, hfc_MST_MODE_MASTER);
247 +
248 + /*
249 + * Connect internal blocks
250 + */
251 + card->regs.connect =
252 + hfc_CONNECT_B1_HFC_from_ST |
253 + hfc_CONNECT_B1_ST_from_HFC |
254 + hfc_CONNECT_B1_GCI_from_HFC |
255 + hfc_CONNECT_B2_HFC_from_ST |
256 + hfc_CONNECT_B2_ST_from_HFC |
257 + hfc_CONNECT_B2_GCI_from_HFC;
258 + hfc_outb(card, hfc_CONNECT, card->regs.connect);
259 +
260 + /*
261 + * All bchans are HDLC by default, not useful, actually
262 + * since mode is set during open()
263 + */
264 + hfc_outb(card, hfc_CTMT, 0);
265 +
266 + /*
267 + * bit order
268 + */
269 + hfc_outb(card, hfc_CIRM, 0);
270 +
271 + /*
272 + * Enable D-rx FIFO. At least one FIFO must be enabled (by specs)
273 + */
274 + card->regs.fifo_en = hfc_FIFOEN_DRX;
275 + hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
276 +
277 + card->late_irqs = 0;
278 +
279 + /*
280 + * Clear already pending ints
281 + */
282 + hfc_inb(card, hfc_INT_S1);
283 + hfc_inb(card, hfc_INT_S2);
284 +
285 + /*
286 + * Enable IRQ output
287 + */
288 + card->regs.m1 = hfc_INTS_DREC | hfc_INTS_L1STATE | hfc_INTS_TIMER;
289 + hfc_outb(card, hfc_INT_M1, card->regs.m1);
290 +
291 + card->regs.m2 = hfc_M2_IRQ_ENABLE;
292 + hfc_outb(card, hfc_INT_M2, card->regs.m2);
293 +
294 + /*
295 + * Unlocks the states machine
296 + */
297 + hfc_outb(card, hfc_STATES, 0);
298 +
299 + /*
300 + * There's no need to explicitly activate L1 now.
301 + * Activation is managed inside the interrupt routine.
302 + */
303 +}
304 +
305 +static void hfc_update_fifo_state(struct hfc_card *card)
306 +{
307 + /*
308 + * I'm not sure if irqsave is needed but there could be a race
309 + * condition since hfc_update_fifo_state could be called from
310 + * both the IRQ handler and the *_(open|close) functions
311 + */
312 +
313 + unsigned long flags;
314 + spin_lock_irqsave(&card->chans[B1].lock, flags);
315 + if (!card->fifo_suspended &&
316 + (card->chans[B1].status == open_framed ||
317 + card->chans[B1].status == open_voice)) {
318 +
319 + if (!(card->regs.fifo_en & hfc_FIFOEN_B1RX)) {
320 + card->regs.fifo_en |= hfc_FIFOEN_B1RX;
321 + hfc_clear_fifo_rx(&card->chans[B1].rx);
322 + }
323 +
324 + if (!(card->regs.fifo_en & hfc_FIFOEN_B1TX)) {
325 + card->regs.fifo_en |= hfc_FIFOEN_B1TX;
326 + hfc_clear_fifo_tx(&card->chans[B1].tx);
327 + }
328 + } else {
329 + if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
330 + card->regs.fifo_en &= ~hfc_FIFOEN_B1RX;
331 + if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
332 + card->regs.fifo_en &= ~hfc_FIFOEN_B1TX;
333 + }
334 + spin_unlock_irqrestore(&card->chans[B1].lock, flags);
335 +
336 + spin_lock_irqsave(&card->chans[B2].lock, flags);
337 + if (!card->fifo_suspended &&
338 + (card->chans[B2].status == open_framed ||
339 + card->chans[B2].status == open_voice ||
340 + card->chans[B2].status == sniff_aux)) {
341 +
342 + if (!(card->regs.fifo_en & hfc_FIFOEN_B2RX)) {
343 + card->regs.fifo_en |= hfc_FIFOEN_B2RX;
344 + hfc_clear_fifo_rx(&card->chans[B2].rx);
345 + }
346 +
347 + if (!(card->regs.fifo_en & hfc_FIFOEN_B2TX)) {
348 + card->regs.fifo_en |= hfc_FIFOEN_B2TX;
349 + hfc_clear_fifo_tx(&card->chans[B2].tx);
350 + }
351 + } else {
352 + if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
353 + card->regs.fifo_en &= ~hfc_FIFOEN_B2RX;
354 + if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
355 + card->regs.fifo_en &= ~hfc_FIFOEN_B2TX;
356 + }
357 + spin_unlock_irqrestore(&card->chans[B2].lock, flags);
358 +
359 + spin_lock_irqsave(&card->chans[D].lock, flags);
360 + if (!card->fifo_suspended &&
361 + card->chans[D].status == open_framed) {
362 +
363 + if (!(card->regs.fifo_en & hfc_FIFOEN_DTX)) {
364 + card->regs.fifo_en |= hfc_FIFOEN_DTX;
365 +
366 + card->chans[D].tx.ugly_framebuf_size = 0;
367 + card->chans[D].tx.ugly_framebuf_off = 0;
368 + }
369 + } else {
370 + if (card->regs.fifo_en & hfc_FIFOEN_DTX)
371 + card->regs.fifo_en &= ~hfc_FIFOEN_DTX;
372 + }
373 + spin_unlock_irqrestore(&card->chans[D].lock, flags);
374 +
375 + hfc_outb(card, hfc_FIFO_EN, card->regs.fifo_en);
376 +}
377 +
378 +static inline void hfc_suspend_fifo(struct hfc_card *card)
379 +{
380 + card->fifo_suspended = TRUE;
381 +
382 + hfc_update_fifo_state(card);
383 +
384 + /*
385 + * When L1 goes down D rx receives garbage; it is nice to
386 + * clear it to avoid a CRC error on reactivation
387 + * udelay is needed because the FIFO deactivation happens
388 + * in 250us
389 + */
390 + udelay(250);
391 + hfc_clear_fifo_rx(&card->chans[D].rx);
392 +
393 +#ifdef DEBUG
394 + if (debug_level >= 3) {
395 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
396 + "card %d: "
397 + "FIFOs suspended\n",
398 + card->cardnum);
399 + }
400 +#endif
401 +}
402 +
403 +static inline void hfc_resume_fifo(struct hfc_card *card)
404 +{
405 + card->fifo_suspended = FALSE;
406 +
407 + hfc_update_fifo_state(card);
408 +
409 +#ifdef DEBUG
410 + if (debug_level >= 3) {
411 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
412 + "card %d: "
413 + "FIFOs resumed\n",
414 + card->cardnum);
415 + }
416 +#endif
417 +}
418 +
419 +static void hfc_check_l1_up(struct hfc_card *card)
420 +{
421 + if ((!card->nt_mode && card->l1_state != 7)
422 + || (card->nt_mode && card->l1_state != 3)) {
423 +
424 + hfc_outb(card, hfc_STATES, hfc_STATES_DO_ACTION |
425 + hfc_STATES_ACTIVATE|
426 + hfc_STATES_NT_G2_G3);
427 +
428 + /*
429 + * 0 because this is quite verbose when an inferface is unconnected, jaw
430 + */
431 +#if 0
432 + if (debug_level >= 1) {
433 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
434 + "card %d: "
435 + "L1 is down, bringing up L1.\n",
436 + card->cardnum);
437 + }
438 +#endif
439 + }
440 +}
441 +
442 +
443 +/*******************
444 + * Dahdi interface *
445 + *******************/
446 +
447 +static int hfc_dahdi_open(struct dahdi_chan *dahdi_chan)
448 +{
449 + struct hfc_chan_duplex *chan = dahdi_chan->pvt;
450 + struct hfc_card *card = chan->card;
451 +
452 + spin_lock(&chan->lock);
453 +
454 + switch (chan->number) {
455 + case D:
456 + if (chan->status != free &&
457 + chan->status != open_framed) {
458 + spin_unlock(&chan->lock);
459 + return -EBUSY;
460 + }
461 + chan->status = open_framed;
462 + break;
463 +
464 + case B1:
465 + case B2:
466 + if (chan->status != free) {
467 + spin_unlock(&chan->lock);
468 + return -EBUSY;
469 + }
470 + chan->status = open_voice;
471 + break;
472 + }
473 +
474 + chan->open_by_dahdi = TRUE;
475 + try_module_get(THIS_MODULE);
476 + spin_unlock(&chan->lock);
477 +
478 + switch (chan->number) {
479 + case D:
480 + break;
481 +
482 + case B1:
483 + card->regs.m2 |= hfc_M2_PROC_TRANS;
484 + /*
485 + * Enable transparent mode
486 + */
487 + card->regs.ctmt |= hfc_CTMT_TRANSB1;
488 + /*
489 + * Reversed bit order
490 + */
491 + card->regs.cirm |= hfc_CIRM_B1_REV;
492 + /*
493 + * Enable transmission
494 + */
495 + card->regs.sctrl |= hfc_SCTRL_B1_ENA;
496 + /*
497 + * Enable reception
498 + */
499 + card->regs.sctrl_r |= hfc_SCTRL_R_B1_ENA;
500 + break;
501 +
502 + case B2:
503 + card->regs.m2 |= hfc_M2_PROC_TRANS;
504 + card->regs.ctmt |= hfc_CTMT_TRANSB2;
505 + card->regs.cirm |= hfc_CIRM_B2_REV;
506 + card->regs.sctrl |= hfc_SCTRL_B2_ENA;
507 + card->regs.sctrl_r |= hfc_SCTRL_R_B2_ENA;
508 + break;
509 +
510 + }
511 +
512 + /*
513 + * If not already enabled, enable processing transition (8KHz)
514 + * interrupt
515 + */
516 + hfc_outb(card, hfc_INT_M2, card->regs.m2);
517 + hfc_outb(card, hfc_CTMT, card->regs.ctmt);
518 + hfc_outb(card, hfc_CIRM, card->regs.cirm);
519 + hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
520 + hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
521 +
522 + hfc_update_fifo_state(card);
523 +
524 + printk(KERN_INFO hfc_DRIVER_PREFIX
525 + "card %d: "
526 + "chan %s opened as %s.\n",
527 + card->cardnum,
528 + chan->name,
529 + dahdi_chan->name);
530 +
531 + return 0;
532 +}
533 +
534 +static int hfc_dahdi_close(struct dahdi_chan *dahdi_chan)
535 +{
536 + struct hfc_chan_duplex *chan = dahdi_chan->pvt;
537 + struct hfc_card *card = chan->card;
538 +
539 + if (!card) {
540 + printk(KERN_CRIT hfc_DRIVER_PREFIX
541 + "hfc_dahdi_close called with NULL card\n");
542 + return -1;
543 + }
544 +
545 + spin_lock(&chan->lock);
546 +
547 + if (chan->status == free) {
548 + spin_unlock(&chan->lock);
549 + return -EINVAL;
550 + }
551 +
552 + chan->status = free;
553 + chan->open_by_dahdi = FALSE;
554 +
555 + spin_unlock(&chan->lock);
556 +
557 + switch (chan->number) {
558 + case D:
559 + break;
560 +
561 + case B1:
562 + card->regs.ctmt &= ~hfc_CTMT_TRANSB1;
563 + card->regs.cirm &= ~hfc_CIRM_B1_REV;
564 + card->regs.sctrl &= ~hfc_SCTRL_B1_ENA;
565 + card->regs.sctrl_r &= ~hfc_SCTRL_R_B1_ENA;
566 + break;
567 +
568 + case B2:
569 + card->regs.ctmt &= ~hfc_CTMT_TRANSB2;
570 + card->regs.cirm &= ~hfc_CIRM_B2_REV;
571 + card->regs.sctrl &= ~hfc_SCTRL_B2_ENA;
572 + card->regs.sctrl_r &= ~hfc_SCTRL_R_B2_ENA;
573 + break;
574 + }
575 +
576 + if (card->chans[B1].status == free &&
577 + card->chans[B2].status == free)
578 + card->regs.m2 &= ~hfc_M2_PROC_TRANS;
579 +
580 + hfc_outb(card, hfc_INT_M2, card->regs.m2);
581 + hfc_outb(card, hfc_CTMT, card->regs.ctmt);
582 + hfc_outb(card, hfc_CIRM, card->regs.cirm);
583 + hfc_outb(card, hfc_SCTRL, card->regs.sctrl);
584 + hfc_outb(card, hfc_SCTRL_R, card->regs.sctrl_r);
585 +
586 + hfc_update_fifo_state(card);
587 +
588 + module_put(THIS_MODULE);
589 +
590 + printk(KERN_INFO hfc_DRIVER_PREFIX
591 + "card %d: "
592 + "chan %s closed as %s.\n",
593 + card->cardnum,
594 + chan->name,
595 + dahdi_chan->name);
596 +
597 + return 0;
598 +}
599 +
600 +static int hfc_dahdi_rbsbits(struct dahdi_chan *chan, int bits)
601 +{
602 + return 0;
603 +}
604 +
605 +static int hfc_dahdi_ioctl(struct dahdi_chan *chan,
606 + unsigned int cmd, unsigned long data)
607 +{
608 + switch (cmd) {
609 +
610 + default:
611 + return -ENOTTY;
612 + }
613 +
614 + return 0;
615 +}
616 +
617 +static void hfc_hdlc_hard_xmit(struct dahdi_chan *d_chan)
618 +{
619 + struct hfc_chan_duplex *chan = d_chan->pvt;
620 + struct hfc_card *card = chan->card;
621 + struct dahdi_hfc *hfccard = card->dahdi_dev;
622 +
623 + atomic_inc(&hfccard->hdlc_pending);
624 +
625 +}
626 +
627 +static int hfc_dahdi_startup(struct file *file, struct dahdi_span *span)
628 +{
629 + struct dahdi_hfc *dahdi_hfcs = dahdi_hfc_from_span(span);
630 + struct hfc_card *hfctmp = dahdi_hfcs->card;
631 + int alreadyrunning;
632 +
633 + if (!hfctmp) {
634 + printk(KERN_INFO hfc_DRIVER_PREFIX
635 + "card %d: "
636 + "no card for span at startup!\n",
637 + hfctmp->cardnum);
638 + }
639 +
640 + alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
641 +
642 + if (!alreadyrunning)
643 + span->flags |= DAHDI_FLAG_RUNNING;
644 +
645 + return 0;
646 +}
647 +
648 +static int hfc_dahdi_shutdown(struct dahdi_span *span)
649 +{
650 + return 0;
651 +}
652 +
653 +static int hfc_dahdi_maint(struct dahdi_span *span, int cmd)
654 +{
655 + return 0;
656 +}
657 +
658 +static int hfc_dahdi_chanconfig(struct file *file, struct dahdi_chan *d_chan, int sigtype)
659 +{
660 + struct hfc_chan_duplex *chan = d_chan->pvt;
661 + struct hfc_card *card = chan->card;
662 + struct dahdi_hfc *hfccard = card->dahdi_dev;
663 +
664 + if ((sigtype == DAHDI_SIG_HARDHDLC) && (hfccard->sigchan == d_chan)) {
665 + hfccard->sigactive = 0;
666 + atomic_set(&hfccard->hdlc_pending, 0);
667 + }
668 +
669 + return 0;
670 +}
671 +
672 +static int hfc_dahdi_spanconfig(struct file *file, struct dahdi_span *span,
673 + struct dahdi_lineconfig *lc)
674 +{
675 + span->lineconfig = lc->lineconfig;
676 +
677 + return 0;
678 +}
679 +
680 +static const struct dahdi_span_ops hfc_dahdi_span_ops = {
681 + .owner = THIS_MODULE,
682 + .chanconfig = hfc_dahdi_chanconfig,
683 + .spanconfig = hfc_dahdi_spanconfig,
684 + .startup = hfc_dahdi_startup,
685 + .shutdown = hfc_dahdi_shutdown,
686 + .maint = hfc_dahdi_maint,
687 + .rbsbits = hfc_dahdi_rbsbits,
688 + .open = hfc_dahdi_open,
689 + .close = hfc_dahdi_close,
690 + .ioctl = hfc_dahdi_ioctl,
691 + .hdlc_hard_xmit = hfc_hdlc_hard_xmit
692 +};
693 +
694 +static int hfc_dahdi_initialize(struct dahdi_hfc *hfccard)
695 +{
696 + struct hfc_card *hfctmp = hfccard->card;
697 + int i;
698 +
699 + hfccard->ddev = dahdi_create_device();
700 + if (!hfccard->ddev)
701 + return -ENOMEM;
702 +
703 + memset(&hfccard->span, 0x0, sizeof(struct dahdi_span));
704 +
705 + /*
706 + * ZTHFC
707 + *
708 + * Cards' and channels' names shall contain "ZTHFC"
709 + * as the dahdi-tools look for this string to guess framing.
710 + * We don't want to modify dahdi-tools only in order to change this.
711 + *
712 + * So we choose for a span name: DAHDI HFC-S formerly known as ZTHFC. :-)
713 + */
714 +
715 + sprintf(hfccard->span.name, "DAHDI_HFCS_FKA_ZTHFC%d", hfctmp->cardnum + 1);
716 + sprintf(hfccard->span.desc,
717 + "HFC-S PCI A ISDN card %d [%s] ",
718 + hfctmp->cardnum,
719 + hfctmp->nt_mode ? "NT" : "TE");
720 + hfccard->span.spantype = hfctmp->nt_mode ? SPANTYPE_DIGITAL_BRI_NT :
721 + SPANTYPE_DIGITAL_BRI_TE;
722 + hfccard->ddev->manufacturer = "Cologne Chips";
723 + hfccard->span.flags = 0;
724 + hfccard->span.ops = &hfc_dahdi_span_ops;
725 + hfccard->ddev->devicetype = kasprintf(GFP_KERNEL, "HFC-S PCI-A ISDN");
726 + hfccard->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
727 + hfctmp->pcidev->bus->number,
728 + PCI_SLOT(hfctmp->pcidev->devfn) + 1);
729 + hfccard->span.chans = hfccard->_chans;
730 + hfccard->span.channels = 3;
731 + for (i = 0; i < hfccard->span.channels; i++)
732 + hfccard->_chans[i] = &hfccard->chans[i];
733 + hfccard->span.deflaw = DAHDI_LAW_ALAW;
734 + hfccard->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_CCS;
735 + hfccard->span.offset = 0;
736 +
737 + for (i = 0; i < hfccard->span.channels; i++) {
738 + memset(&hfccard->chans[i], 0x0, sizeof(struct dahdi_chan));
739 +
740 + sprintf(hfccard->chans[i].name,
741 + "DAHDI_HFCS_FKA_ZTHFC%d/%d/%d",
742 + hfctmp->cardnum + 1, 0, i + 1);
743 +
744 + printk(KERN_INFO hfc_DRIVER_PREFIX
745 + "card %d: "
746 + "registered %s\n",
747 + hfctmp->cardnum,
748 + hfccard->chans[i].name);
749 +
750 + if (i == hfccard->span.channels - 1) {
751 + hfccard->chans[i].sigcap = DAHDI_SIG_HARDHDLC;
752 + hfccard->sigchan = &hfccard->chans[DAHDI_D];
753 + hfccard->sigactive = 0;
754 + atomic_set(&hfccard->hdlc_pending, 0);
755 + } else {
756 + hfccard->chans[i].sigcap =
757 + DAHDI_SIG_CLEAR | DAHDI_SIG_DACS;
758 + }
759 +
760 + hfccard->chans[i].chanpos = i + 1;
761 + }
762 +
763 + hfccard->chans[DAHDI_D].readchunk =
764 + hfctmp->chans[D].rx.dahdi_buffer;
765 +
766 + hfccard->chans[DAHDI_D].writechunk =
767 + hfctmp->chans[D].tx.dahdi_buffer;
768 +
769 + hfccard->chans[DAHDI_D].pvt = &hfctmp->chans[D];
770 +
771 + hfccard->chans[DAHDI_B1].readchunk =
772 + hfctmp->chans[B1].rx.dahdi_buffer;
773 +
774 + hfccard->chans[DAHDI_B1].writechunk =
775 + hfctmp->chans[B1].tx.dahdi_buffer;
776 +
777 + hfccard->chans[DAHDI_B1].pvt = &hfctmp->chans[B1];
778 +
779 + hfccard->chans[DAHDI_B2].readchunk =
780 + hfctmp->chans[B2].rx.dahdi_buffer;
781 +
782 + hfccard->chans[DAHDI_B2].writechunk =
783 + hfctmp->chans[B2].tx.dahdi_buffer;
784 +
785 + hfccard->chans[DAHDI_B2].pvt = &hfctmp->chans[B2];
786 +
787 + list_add_tail(&hfccard->span.device_node, &hfccard->ddev->spans);
788 + if (dahdi_register_device(hfccard->ddev, &hfccard->card->pcidev->dev)) {
789 + printk(KERN_NOTICE "Unable to register device with DAHDI\n");
790 + return -1;
791 + }
792 +
793 + return 0;
794 +}
795 +
796 +static void hfc_dahdi_transmit(struct hfc_chan_simplex *chan)
797 +{
798 + hfc_fifo_put(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE);
799 +}
800 +
801 +static void hfc_dahdi_receive(struct hfc_chan_simplex *chan)
802 +{
803 + hfc_fifo_get(chan, chan->dahdi_buffer, DAHDI_CHUNKSIZE);
804 +}
805 +
806 +/******************************************
807 + * Interrupt Handler
808 + ******************************************/
809 +
810 +static void hfc_handle_timer_interrupt(struct hfc_card *card);
811 +static void hfc_handle_state_interrupt(struct hfc_card *card);
812 +static void hfc_handle_processing_interrupt(struct hfc_card *card);
813 +static void hfc_frame_arrived(struct hfc_chan_duplex *chan);
814 +static void hfc_handle_voice(struct hfc_card *card);
815 +
816 +#if (KERNEL_VERSION(2, 6, 24) < LINUX_VERSION_CODE)
817 +static irqreturn_t hfc_interrupt(int irq, void *dev_id)
818 +#else
819 +static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
820 +#endif
821 +{
822 + struct hfc_card *card = dev_id;
823 + unsigned long flags;
824 + u8 status, s1, s2;
825 +
826 + if (!card) {
827 + printk(KERN_CRIT hfc_DRIVER_PREFIX
828 + "spurious interrupt (IRQ %d)\n",
829 + irq);
830 + return IRQ_NONE;
831 + }
832 +
833 + spin_lock_irqsave(&card->lock, flags);
834 + status = hfc_inb(card, hfc_STATUS);
835 + if (!(status & hfc_STATUS_ANYINT)) {
836 + /*
837 + * maybe we are sharing the irq
838 + */
839 + spin_unlock_irqrestore(&card->lock, flags);
840 + return IRQ_NONE;
841 + }
842 +
843 + /* We used to ingore the IRQ when the card was in processing
844 + * state but apparently there is no restriction to access the
845 + * card in such state:
846 + *
847 + * Joerg Ciesielski wrote:
848 + * > There is no restriction for the IRQ handler to access
849 + * > HFC-S PCI during processing phase. A IRQ latency of 375 us
850 + * > is also no problem since there are no interrupt sources in
851 + * > HFC-S PCI which must be handled very fast.
852 + * > Due to its deep fifos the IRQ latency can be several ms with
853 + * > out the risk of loosing data. Even the S/T state interrupts
854 + * > must not be handled with a latency less than <5ms.
855 + * >
856 + * > The processing phase only indicates that HFC-S PCI is
857 + * > processing the Fifos as PCI master so that data is read and
858 + * > written in the 32k memory window. But there is no restriction
859 + * > to access data in the memory window during this time.
860 + *
861 + * // if (status & hfc_STATUS_PCI_PROC) {
862 + * // return IRQ_HANDLED;
863 + * // }
864 + */
865 +
866 + s1 = hfc_inb(card, hfc_INT_S1);
867 + s2 = hfc_inb(card, hfc_INT_S2);
868 +
869 + if (s1 != 0) {
870 + if (s1 & hfc_INTS_TIMER) {
871 + /*
872 + * timer (bit 7)
873 + */
874 + hfc_handle_timer_interrupt(card);
875 + }
876 +
877 + if (s1 & hfc_INTS_L1STATE) {
878 + /*
879 + * state machine (bit 6)
880 + */
881 + hfc_handle_state_interrupt(card);
882 + }
883 +
884 + if (s1 & hfc_INTS_DREC) {
885 + /*
886 + * D chan RX (bit 5)
887 + */
888 + hfc_frame_arrived(&card->chans[D]);
889 + }
890 +
891 + if (s1 & hfc_INTS_B1REC) {
892 + /*
893 + * B1 chan RX (bit 3)
894 + */
895 + hfc_frame_arrived(&card->chans[B1]);
896 + }
897 +
898 + if (s1 & hfc_INTS_B2REC) {
899 + /*
900 + * B2 chan RX (bit 4)
901 + */
902 + hfc_frame_arrived(&card->chans[B2]);
903 + }
904 +
905 + if (s1 & hfc_INTS_DTRANS) {
906 + /*
907 + * D chan TX (bit 2)
908 + */
909 + }
910 +
911 + if (s1 & hfc_INTS_B1TRANS) {
912 + /*
913 + * B1 chan TX (bit 0)
914 + */
915 + }
916 +
917 + if (s1 & hfc_INTS_B2TRANS) {
918 + /*
919 + * B2 chan TX (bit 1)
920 + */
921 + }
922 +
923 + }
924 +
925 + if (s2 != 0) {
926 + if (s2 & hfc_M2_PMESEL) {
927 + /*
928 + * kaboom irq (bit 7)
929 + *
930 + * CologneChip says:
931 + *
932 + * the meaning of this fatal error bit is that HFC-S
933 + * PCI as PCI master could not access the PCI bus
934 + * within 125us to finish its data processing. If this
935 + * happens only very seldom it does not cause big
936 + * problems but of course some B-channel or D-channel
937 + * data will be corrupted due to this event.
938 + *
939 + * Unfortunately this bit is only set once after the
940 + * problem occurs and can only be reseted by a
941 + * software reset. That means it is not easily
942 + * possible to check how often this fatal error
943 + * happens.
944 + *
945 + */
946 +
947 + if (!card->sync_loss_reported) {
948 + printk(KERN_CRIT hfc_DRIVER_PREFIX
949 + "card %d: "
950 + "sync lost, pci performance too low!\n",
951 + card->cardnum);
952 +
953 + card->sync_loss_reported = TRUE;
954 + }
955 + }
956 +
957 + if (s2 & hfc_M2_GCI_MON_REC) {
958 + /*
959 + * RxR monitor channel (bit 2)
960 + */
961 + }
962 +
963 + if (s2 & hfc_M2_GCI_I_CHG) {
964 + /*
965 + * GCI I-change (bit 1)
966 + */
967 + }
968 +
969 + if (s2 & hfc_M2_PROC_TRANS) {
970 + /*
971 + * processing/non-processing transition (bit 0)
972 + */
973 + hfc_handle_processing_interrupt(card);
974 + }
975 +
976 + }
977 +
978 + spin_unlock_irqrestore(&card->lock, flags);
979 +
980 + return IRQ_HANDLED;
981 +}
982 +
983 +static void hfc_handle_timer_interrupt(struct hfc_card *card)
984 +{
985 + if (card->ignore_first_timer_interrupt) {
986 + card->ignore_first_timer_interrupt = FALSE;
987 + return;
988 + }
989 +
990 + if ((card->nt_mode && card->l1_state == 3) ||
991 + (!card->nt_mode && card->l1_state == 7)) {
992 +
993 + card->regs.ctmt &= ~hfc_CTMT_TIMER_MASK;
994 + hfc_outb(card, hfc_CTMT, card->regs.ctmt);
995 +
996 + hfc_resume_fifo(card);
997 + }
998 +}
999 +
1000 +static void hfc_handle_state_interrupt(struct hfc_card *card)
1001 +{
1002 + u8 new_state = hfc_inb(card, hfc_STATES) & hfc_STATES_STATE_MASK;
1003 +
1004 +#ifdef DEBUG
1005 + if (debug_level >= 1) {
1006 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
1007 + "card %d: "
1008 + "layer 1 state = %c%d\n",
1009 + card->cardnum,
1010 + card->nt_mode ? 'G' : 'F',
1011 + new_state);
1012 + }
1013 +#endif
1014 +
1015 + if (card->nt_mode) {
1016 + /*
1017 + * NT mode
1018 + */
1019 +
1020 + if (new_state == 3) {
1021 + /*
1022 + * fix to G3 state (see specs)
1023 + */
1024 + hfc_outb(card, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
1025 + }
1026 +
1027 + if (new_state == 3 && card->l1_state != 3)
1028 + hfc_resume_fifo(card);
1029 +
1030 + if (new_state != 3 && card->l1_state == 3)
1031 + hfc_suspend_fifo(card);
1032 +
1033 + } else {
1034 + if (new_state == 3) {
1035 + /*
1036 + * Keep L1 up... zaptel & libpri expects
1037 + * a always up L1...
1038 + * Enable only when using an unpatched libpri
1039 + *
1040 + * Are we still using unpatched libpri? Is this tested at runtime???
1041 + * Does it only affect zaptel or DAHDI, too?
1042 + */
1043 +
1044 + if (force_l1_up) {
1045 + hfc_outb(card, hfc_STATES,
1046 + hfc_STATES_DO_ACTION |
1047 + hfc_STATES_ACTIVATE|
1048 + hfc_STATES_NT_G2_G3);
1049 + }
1050 + }
1051 +
1052 + if (new_state == 7 && card->l1_state != 7) {
1053 + /*
1054 + * TE is now active, schedule FIFO activation after
1055 + * some time, otherwise the first frames are lost
1056 + */
1057 +
1058 + card->regs.ctmt |= hfc_CTMT_TIMER_50 |
1059 + hfc_CTMT_TIMER_CLEAR;
1060 + hfc_outb(card, hfc_CTMT, card->regs.ctmt);
1061 +
1062 + /*
1063 + * Activating the timer firest an
1064 + * interrupt immediately, we
1065 + * obviously need to ignore it
1066 + */
1067 + card->ignore_first_timer_interrupt = TRUE;
1068 + }
1069 +
1070 + if (new_state != 7 && card->l1_state == 7) {
1071 + /*
1072 + * TE has become inactive, disable FIFO
1073 + */
1074 + hfc_suspend_fifo(card);
1075 + }
1076 + }
1077 +
1078 + card->l1_state = new_state;
1079 +}
1080 +
1081 +static void hfc_handle_processing_interrupt(struct hfc_card *card)
1082 +{
1083 + int available_bytes = 0;
1084 +
1085 + /*
1086 + * Synchronize with the first enabled channel
1087 + */
1088 + if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1089 + available_bytes = hfc_fifo_used_rx(&card->chans[B1].rx);
1090 + if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1091 + available_bytes = hfc_fifo_used_rx(&card->chans[B2].rx);
1092 + else
1093 + available_bytes = -1;
1094 +
1095 + if ((available_bytes == -1 && card->ticks == 8) ||
1096 + available_bytes >= DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD) {
1097 + card->ticks = 0;
1098 +
1099 + if (available_bytes > DAHDI_CHUNKSIZE*2 + hfc_RX_FIFO_PRELOAD) {
1100 + card->late_irqs++;
1101 + /*
1102 + * we are out of sync, clear fifos, jaw
1103 + */
1104 + hfc_clear_fifo_rx(&card->chans[B1].rx);
1105 + hfc_clear_fifo_tx(&card->chans[B1].tx);
1106 + hfc_clear_fifo_rx(&card->chans[B2].rx);
1107 + hfc_clear_fifo_tx(&card->chans[B2].tx);
1108 +
1109 +#ifdef DEBUG
1110 + if (debug_level >= 4) {
1111 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
1112 + "card %d: "
1113 + "late IRQ, %d bytes late\n",
1114 + card->cardnum,
1115 + available_bytes -
1116 + (DAHDI_CHUNKSIZE +
1117 + hfc_RX_FIFO_PRELOAD));
1118 + }
1119 +#endif
1120 + } else {
1121 + hfc_handle_voice(card);
1122 + }
1123 + }
1124 +
1125 + card->ticks++;
1126 +}
1127 +
1128 +
1129 +static void hfc_handle_voice(struct hfc_card *card)
1130 +{
1131 + struct dahdi_hfc *hfccard = card->dahdi_dev;
1132 + int frame_left, res;
1133 + unsigned char buf[hfc_HDLC_BUF_LEN];
1134 + unsigned int size = sizeof(buf) / sizeof(buf[0]);
1135 +
1136 +
1137 + if (card->chans[B1].status != open_voice &&
1138 + card->chans[B2].status != open_voice)
1139 + return;
1140 +
1141 + dahdi_transmit(&hfccard->span);
1142 +
1143 + if (card->regs.fifo_en & hfc_FIFOEN_B1TX)
1144 + hfc_dahdi_transmit(&card->chans[B1].tx);
1145 + if (card->regs.fifo_en & hfc_FIFOEN_B2TX)
1146 + hfc_dahdi_transmit(&card->chans[B2].tx);
1147 +
1148 + /*
1149 + * dahdi hdlc frame tx
1150 + */
1151 +
1152 + if (atomic_read(&hfccard->hdlc_pending)) {
1153 + hfc_check_l1_up(card);
1154 + res = dahdi_hdlc_getbuf(hfccard->sigchan, buf, &size);
1155 + if (size > 0) {
1156 + hfccard->sigactive = 1;
1157 + memcpy(card->chans[D].tx.ugly_framebuf +
1158 + card->chans[D].tx.ugly_framebuf_size,
1159 + buf, size);
1160 + card->chans[D].tx.ugly_framebuf_size += size;
1161 + if (res != 0) {
1162 + hfc_fifo_put_frame(&card->chans[D].tx,
1163 + card->chans[D].tx.ugly_framebuf,
1164 + card->chans[D].tx.ugly_framebuf_size);
1165 + ++hfccard->frames_out;
1166 + hfccard->sigactive = 0;
1167 + card->chans[D].tx.ugly_framebuf_size
1168 + = 0;
1169 + atomic_dec(&hfccard->hdlc_pending);
1170 + }
1171 + }
1172 + }
1173 + /*
1174 + * dahdi hdlc frame tx done
1175 + */
1176 +
1177 + if (card->regs.fifo_en & hfc_FIFOEN_B1RX)
1178 + hfc_dahdi_receive(&card->chans[B1].rx);
1179 + else
1180 + memset(&card->chans[B1].rx.dahdi_buffer, 0x7f,
1181 + sizeof(card->chans[B1].rx.dahdi_buffer));
1182 +
1183 + if (card->regs.fifo_en & hfc_FIFOEN_B2RX)
1184 + hfc_dahdi_receive(&card->chans[B2].rx);
1185 + else
1186 + memset(&card->chans[B2].rx.dahdi_buffer, 0x7f,
1187 + sizeof(card->chans[B1].rx.dahdi_buffer));
1188 +
1189 + /*
1190 + * Echo cancellation
1191 + */
1192 + dahdi_ec_chunk(&hfccard->chans[DAHDI_B1],
1193 + card->chans[B1].rx.dahdi_buffer,
1194 + card->chans[B1].tx.dahdi_buffer);
1195 + dahdi_ec_chunk(&hfccard->chans[DAHDI_B2],
1196 + card->chans[B2].rx.dahdi_buffer,
1197 + card->chans[B2].tx.dahdi_buffer);
1198 +
1199 + /*
1200 + * dahdi hdlc frame rx
1201 + */
1202 + if (hfc_fifo_has_frames(&card->chans[D].rx))
1203 + hfc_frame_arrived(&card->chans[D]);
1204 +
1205 + if (card->chans[D].rx.ugly_framebuf_size) {
1206 + frame_left = card->chans[D].rx.ugly_framebuf_size -
1207 + card->chans[D].rx.ugly_framebuf_off ;
1208 + if (frame_left > hfc_HDLC_BUF_LEN) {
1209 + dahdi_hdlc_putbuf(hfccard->sigchan,
1210 + card->chans[D].rx.ugly_framebuf +
1211 + card->chans[D].rx.ugly_framebuf_off,
1212 + hfc_HDLC_BUF_LEN);
1213 + card->chans[D].rx.ugly_framebuf_off +=
1214 + hfc_HDLC_BUF_LEN;
1215 + } else {
1216 + dahdi_hdlc_putbuf(hfccard->sigchan,
1217 + card->chans[D].rx.ugly_framebuf +
1218 + card->chans[D].rx.ugly_framebuf_off,
1219 + frame_left);
1220 + dahdi_hdlc_finish(hfccard->sigchan);
1221 + card->chans[D].rx.ugly_framebuf_size = 0;
1222 + card->chans[D].rx.ugly_framebuf_off = 0;
1223 + }
1224 + }
1225 + /*
1226 + * dahdi hdlc frame rx done
1227 + */
1228 +
1229 + if (hfccard->span.flags & DAHDI_FLAG_RUNNING)
1230 + dahdi_receive(&hfccard->span);
1231 +
1232 +}
1233 +
1234 +static void hfc_frame_arrived(struct hfc_chan_duplex *chan)
1235 +{
1236 + struct hfc_card *card = chan->card;
1237 + int antiloop = 16;
1238 + struct sk_buff *skb;
1239 +
1240 + while (hfc_fifo_has_frames(&chan->rx) && --antiloop) {
1241 + int frame_size = hfc_fifo_get_frame_size(&chan->rx);
1242 +
1243 + if (frame_size < 3) {
1244 +#ifdef DEBUG
1245 + if (debug_level >= 2)
1246 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
1247 + "card %d: "
1248 + "chan %s: "
1249 + "invalid frame received, "
1250 + "just %d bytes\n",
1251 + card->cardnum,
1252 + chan->name,
1253 + frame_size);
1254 +#endif
1255 +
1256 + hfc_fifo_drop_frame(&chan->rx);
1257 +
1258 +
1259 + continue;
1260 + } else if (frame_size == 3) {
1261 +#ifdef DEBUG
1262 + if (debug_level >= 2)
1263 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
1264 + "card %d: "
1265 + "chan %s: "
1266 + "empty frame received\n",
1267 + card->cardnum,
1268 + chan->name);
1269 +#endif
1270 +
1271 + hfc_fifo_drop_frame(&chan->rx);
1272 +
1273 +
1274 + continue;
1275 + }
1276 +
1277 + if (chan->open_by_dahdi &&
1278 + card->chans[D].rx.ugly_framebuf_size) {
1279 +
1280 + /*
1281 + * We have to wait for Dahdi to transmit the
1282 + * frame... wait for next time
1283 + */
1284 +
1285 + break;
1286 + }
1287 +
1288 + skb = dev_alloc_skb(frame_size - 3);
1289 +
1290 + if (!skb) {
1291 + printk(KERN_ERR hfc_DRIVER_PREFIX
1292 + "card %d: "
1293 + "chan %s: "
1294 + "cannot allocate skb: frame dropped\n",
1295 + card->cardnum,
1296 + chan->name);
1297 +
1298 + hfc_fifo_drop_frame(&chan->rx);
1299 +
1300 +
1301 + continue;
1302 + }
1303 +
1304 +
1305 + /*
1306 + * HFC does the checksum
1307 + */
1308 +#ifndef CHECKSUM_HW
1309 + skb->ip_summed = CHECKSUM_COMPLETE;
1310 +#else
1311 + skb->ip_summed = CHECKSUM_HW;
1312 +#endif
1313 +
1314 + if (chan->open_by_dahdi) {
1315 + card->chans[D].rx.ugly_framebuf_size = frame_size - 1;
1316 +
1317 + if (hfc_fifo_get_frame(&card->chans[D].rx,
1318 + card->chans[D].rx.ugly_framebuf,
1319 + frame_size - 1) == -1) {
1320 + dev_kfree_skb(skb);
1321 + continue;
1322 + }
1323 +
1324 + memcpy(skb_put(skb, frame_size - 3),
1325 + card->chans[D].rx.ugly_framebuf,
1326 + frame_size - 3);
1327 + } else {
1328 + if (hfc_fifo_get_frame(&chan->rx,
1329 + skb_put(skb, frame_size - 3),
1330 + frame_size - 3) == -1) {
1331 + dev_kfree_skb(skb);
1332 + continue;
1333 + }
1334 + }
1335 + }
1336 +
1337 + if (!antiloop)
1338 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1339 + "card %d: "
1340 + "Infinite loop detected\n",
1341 + card->cardnum);
1342 +}
1343 +
1344 +/******************************************
1345 + * Module initialization and cleanup
1346 + ******************************************/
1347 +
1348 +static int __devinit hfc_probe(struct pci_dev *pci_dev,
1349 + const struct pci_device_id *ent)
1350 +{
1351 + static int cardnum;
1352 + int err;
1353 + int i;
1354 +
1355 + struct hfc_card *card = NULL;
1356 + struct dahdi_hfc *dahdi_hfcs = NULL;
1357 + card = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
1358 + if (!card) {
1359 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1360 + "unable to kmalloc!\n");
1361 + err = -ENOMEM;
1362 + goto err_alloc_hfccard;
1363 + }
1364 +
1365 + memset(card, 0x00, sizeof(struct hfc_card));
1366 + card->cardnum = cardnum;
1367 + card->pcidev = pci_dev;
1368 + spin_lock_init(&card->lock);
1369 +
1370 + pci_set_drvdata(pci_dev, card);
1371 +
1372 + err = pci_enable_device(pci_dev);
1373 + if (err)
1374 + goto err_pci_enable_device;
1375 +
1376 + err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
1377 + if (err) {
1378 + printk(KERN_ERR hfc_DRIVER_PREFIX
1379 + "card %d: "
1380 + "No suitable DMA configuration available.\n",
1381 + card->cardnum);
1382 + goto err_pci_set_dma_mask;
1383 + }
1384 +
1385 + pci_write_config_word(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
1386 + err = pci_request_regions(pci_dev, hfc_DRIVER_NAME);
1387 + if (err) {
1388 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1389 + "card %d: "
1390 + "cannot request I/O memory region\n",
1391 + card->cardnum);
1392 + goto err_pci_request_regions;
1393 + }
1394 +
1395 + pci_set_master(pci_dev);
1396 +
1397 + if (!pci_dev->irq) {
1398 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1399 + "card %d: "
1400 + "no irq!\n",
1401 + card->cardnum);
1402 + err = -ENODEV;
1403 + goto err_noirq;
1404 + }
1405 +
1406 + card->io_bus_mem = pci_resource_start(pci_dev, 1);
1407 + if (!card->io_bus_mem) {
1408 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1409 + "card %d: "
1410 + "no iomem!\n",
1411 + card->cardnum);
1412 + err = -ENODEV;
1413 + goto err_noiobase;
1414 + }
1415 +
1416 + card->io_mem = ioremap(card->io_bus_mem, hfc_PCI_MEM_SIZE);
1417 + if (!(card->io_mem)) {
1418 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1419 + "card %d: "
1420 + "cannot ioremap I/O memory\n",
1421 + card->cardnum);
1422 + err = -ENODEV;
1423 + goto err_ioremap;
1424 + }
1425 +
1426 + /*
1427 + * pci_alloc_consistent guarantees alignment
1428 + * (Documentation/DMA-mapping.txt)
1429 + */
1430 + card->fifo_mem = pci_alloc_consistent(pci_dev,
1431 + hfc_FIFO_SIZE, &card->fifo_bus_mem);
1432 + if (!card->fifo_mem) {
1433 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1434 + "card %d: "
1435 + "unable to allocate FIFO DMA memory!\n",
1436 + card->cardnum);
1437 + err = -ENOMEM;
1438 + goto err_alloc_fifo;
1439 + }
1440 +
1441 + memset(card->fifo_mem, 0x00, hfc_FIFO_SIZE);
1442 +
1443 + card->fifos = card->fifo_mem;
1444 +
1445 + pci_write_config_dword(card->pcidev, hfc_PCI_MWBA, card->fifo_bus_mem);
1446 +
1447 + err = request_irq(card->pcidev->irq, &hfc_interrupt,
1448 +
1449 +#if (KERNEL_VERSION(2, 6, 23) < LINUX_VERSION_CODE)
1450 + IRQF_SHARED, hfc_DRIVER_NAME, card);
1451 +#else
1452 + SA_SHIRQ, hfc_DRIVER_NAME, card);
1453 +#endif
1454 +
1455 + if (err) {
1456 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1457 + "card %d: "
1458 + "unable to register irq\n",
1459 + card->cardnum);
1460 + goto err_request_irq;
1461 + }
1462 +
1463 + card->nt_mode = FALSE;
1464 +
1465 + if (modes & (1 << card->cardnum))
1466 + card->nt_mode = TRUE;
1467 +
1468 + for (i = 0; i < nt_modes_count; i++) {
1469 + if (nt_modes[i] == card->cardnum)
1470 + card->nt_mode = TRUE;
1471 + }
1472 +
1473 + /*
1474 + * D Channel
1475 + */
1476 + card->chans[D].card = card;
1477 + card->chans[D].name = "D";
1478 + card->chans[D].status = free;
1479 + card->chans[D].number = D;
1480 + spin_lock_init(&card->chans[D].lock);
1481 +
1482 + card->chans[D].rx.chan = &card->chans[D];
1483 + card->chans[D].rx.fifo_base = card->fifos + 0x4000;
1484 + card->chans[D].rx.z_base = card->fifos + 0x4000;
1485 + card->chans[D].rx.z1_base = card->fifos + 0x6080;
1486 + card->chans[D].rx.z2_base = card->fifos + 0x6082;
1487 + card->chans[D].rx.z_min = 0x0000;
1488 + card->chans[D].rx.z_max = 0x01FF;
1489 + card->chans[D].rx.f_min = 0x10;
1490 + card->chans[D].rx.f_max = 0x1F;
1491 + card->chans[D].rx.f1 = card->fifos + 0x60a0;
1492 + card->chans[D].rx.f2 = card->fifos + 0x60a1;
1493 + card->chans[D].rx.fifo_size = card->chans[D].rx.z_max
1494 + - card->chans[D].rx.z_min + 1;
1495 + card->chans[D].rx.f_num = card->chans[D].rx.f_max
1496 + - card->chans[D].rx.f_min + 1;
1497 +
1498 + card->chans[D].tx.chan = &card->chans[D];
1499 + card->chans[D].tx.fifo_base = card->fifos + 0x0000;
1500 + card->chans[D].tx.z_base = card->fifos + 0x0000;
1501 + card->chans[D].tx.z1_base = card->fifos + 0x2080;
1502 + card->chans[D].tx.z2_base = card->fifos + 0x2082;
1503 + card->chans[D].tx.z_min = 0x0000;
1504 + card->chans[D].tx.z_max = 0x01FF;
1505 + card->chans[D].tx.f_min = 0x10;
1506 + card->chans[D].tx.f_max = 0x1F;
1507 + card->chans[D].tx.f1 = card->fifos + 0x20a0;
1508 + card->chans[D].tx.f2 = card->fifos + 0x20a1;
1509 + card->chans[D].tx.fifo_size = card->chans[D].tx.z_max -
1510 + card->chans[D].tx.z_min + 1;
1511 + card->chans[D].tx.f_num = card->chans[D].tx.f_max -
1512 + card->chans[D].tx.f_min + 1;
1513 +
1514 + /*
1515 + * B1 Channel
1516 + */
1517 + card->chans[B1].card = card;
1518 + card->chans[B1].name = "B1";
1519 + card->chans[B1].status = free;
1520 + card->chans[B1].number = B1;
1521 + card->chans[B1].protocol = 0;
1522 + spin_lock_init(&card->chans[B1].lock);
1523 +
1524 + card->chans[B1].rx.chan = &card->chans[B1];
1525 + card->chans[B1].rx.fifo_base = card->fifos + 0x4200;
1526 + card->chans[B1].rx.z_base = card->fifos + 0x4000;
1527 + card->chans[B1].rx.z1_base = card->fifos + 0x6000;
1528 + card->chans[B1].rx.z2_base = card->fifos + 0x6002;
1529 + card->chans[B1].rx.z_min = 0x0200;
1530 + card->chans[B1].rx.z_max = 0x1FFF;
1531 + card->chans[B1].rx.f_min = 0x00;
1532 + card->chans[B1].rx.f_max = 0x1F;
1533 + card->chans[B1].rx.f1 = card->fifos + 0x6080;
1534 + card->chans[B1].rx.f2 = card->fifos + 0x6081;
1535 + card->chans[B1].rx.fifo_size = card->chans[B1].rx.z_max -
1536 + card->chans[B1].rx.z_min + 1;
1537 + card->chans[B1].rx.f_num = card->chans[B1].rx.f_max -
1538 + card->chans[B1].rx.f_min + 1;
1539 +
1540 + card->chans[B1].tx.chan = &card->chans[B1];
1541 + card->chans[B1].tx.fifo_base = card->fifos + 0x0200;
1542 + card->chans[B1].tx.z_base = card->fifos + 0x0000;
1543 + card->chans[B1].tx.z1_base = card->fifos + 0x2000;
1544 + card->chans[B1].tx.z2_base = card->fifos + 0x2002;
1545 + card->chans[B1].tx.z_min = 0x0200;
1546 + card->chans[B1].tx.z_max = 0x1FFF;
1547 + card->chans[B1].tx.f_min = 0x00;
1548 + card->chans[B1].tx.f_max = 0x1F;
1549 + card->chans[B1].tx.f1 = card->fifos + 0x2080;
1550 + card->chans[B1].tx.f2 = card->fifos + 0x2081;
1551 + card->chans[B1].tx.fifo_size = card->chans[B1].tx.z_max -
1552 + card->chans[B1].tx.z_min + 1;
1553 + card->chans[B1].tx.f_num = card->chans[B1].tx.f_max -
1554 + card->chans[B1].tx.f_min + 1;
1555 +
1556 + /*
1557 + * B2 Channel
1558 + */
1559 + card->chans[B2].card = card;
1560 + card->chans[B2].name = "B2";
1561 + card->chans[B2].status = free;
1562 + card->chans[B2].number = B2;
1563 + card->chans[B2].protocol = 0;
1564 + spin_lock_init(&card->chans[B2].lock);
1565 +
1566 + card->chans[B2].rx.chan = &card->chans[B2];
1567 + card->chans[B2].rx.fifo_base = card->fifos + 0x6200,
1568 + card->chans[B2].rx.z_base = card->fifos + 0x6000;
1569 + card->chans[B2].rx.z1_base = card->fifos + 0x6100;
1570 + card->chans[B2].rx.z2_base = card->fifos + 0x6102;
1571 + card->chans[B2].rx.z_min = 0x0200;
1572 + card->chans[B2].rx.z_max = 0x1FFF;
1573 + card->chans[B2].rx.f_min = 0x00;
1574 + card->chans[B2].rx.f_max = 0x1F;
1575 + card->chans[B2].rx.f1 = card->fifos + 0x6180;
1576 + card->chans[B2].rx.f2 = card->fifos + 0x6181;
1577 + card->chans[B2].rx.fifo_size = card->chans[B2].rx.z_max -
1578 + card->chans[B2].rx.z_min + 1;
1579 + card->chans[B2].rx.f_num = card->chans[B2].rx.f_max -
1580 + card->chans[B2].rx.f_min + 1;
1581 +
1582 + card->chans[B2].tx.chan = &card->chans[B2];
1583 + card->chans[B2].tx.fifo_base = card->fifos + 0x2200;
1584 + card->chans[B2].tx.z_base = card->fifos + 0x2000;
1585 + card->chans[B2].tx.z1_base = card->fifos + 0x2100;
1586 + card->chans[B2].tx.z2_base = card->fifos + 0x2102;
1587 + card->chans[B2].tx.z_min = 0x0200;
1588 + card->chans[B2].tx.z_max = 0x1FFF;
1589 + card->chans[B2].tx.f_min = 0x00;
1590 + card->chans[B2].tx.f_max = 0x1F;
1591 + card->chans[B2].tx.f1 = card->fifos + 0x2180;
1592 + card->chans[B2].tx.f2 = card->fifos + 0x2181;
1593 + card->chans[B2].tx.fifo_size = card->chans[B2].tx.z_max -
1594 + card->chans[B2].tx.z_min + 1;
1595 + card->chans[B2].tx.f_num = card->chans[B2].tx.f_max -
1596 + card->chans[B2].tx.f_min + 1;
1597 +
1598 + /*
1599 + * All done
1600 + */
1601 +
1602 + dahdi_hfcs = kmalloc(sizeof(struct dahdi_hfc), GFP_KERNEL);
1603 + if (!dahdi_hfcs) {
1604 + printk(KERN_CRIT hfc_DRIVER_PREFIX
1605 + "unable to kmalloc!\n");
1606 + goto err_request_irq;
1607 + }
1608 + memset(dahdi_hfcs, 0x0, sizeof(struct dahdi_hfc));
1609 +
1610 + dahdi_hfcs->card = card;
1611 + hfc_dahdi_initialize(dahdi_hfcs);
1612 + card->dahdi_dev = dahdi_hfcs;
1613 +
1614 + snprintf(card->proc_dir_name,
1615 + sizeof(card->proc_dir_name),
1616 + "%d", card->cardnum);
1617 + card->proc_dir = proc_mkdir(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir);
1618 + SET_PROC_DIRENTRY_OWNER(card->proc_dir);
1619 +
1620 + hfc_resetCard(card);
1621 +
1622 + printk(KERN_INFO hfc_DRIVER_PREFIX
1623 + "card %d configured for %s mode at mem %#lx (0x%p) IRQ %u\n",
1624 + card->cardnum,
1625 + card->nt_mode ? "NT" : "TE",
1626 + card->io_bus_mem,
1627 + card->io_mem,
1628 + card->pcidev->irq);
1629 +
1630 + cardnum++;
1631 +
1632 + return 0;
1633 +
1634 +err_request_irq:
1635 + pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1636 + card->fifo_mem, card->fifo_bus_mem);
1637 +err_alloc_fifo:
1638 + iounmap(card->io_mem);
1639 +err_ioremap:
1640 +err_noiobase:
1641 +err_noirq:
1642 + pci_release_regions(pci_dev);
1643 +err_pci_request_regions:
1644 +err_pci_set_dma_mask:
1645 +err_pci_enable_device:
1646 + kfree(card);
1647 +err_alloc_hfccard:
1648 + return err;
1649 +}
1650 +
1651 +static void __devexit hfc_remove(struct pci_dev *pci_dev)
1652 +{
1653 + struct hfc_card *card = pci_get_drvdata(pci_dev);
1654 +
1655 +
1656 + printk(KERN_INFO hfc_DRIVER_PREFIX
1657 + "card %d: "
1658 + "shutting down card at %p.\n",
1659 + card->cardnum,
1660 + card->io_mem);
1661 +
1662 + if (!card) {
1663 + return;
1664 + }
1665 +
1666 + hfc_softreset(card);
1667 +
1668 + dahdi_unregister_device(card->dahdi_dev->ddev);
1669 +
1670 +
1671 + /*
1672 + * disable memio and bustmaster
1673 + */
1674 + pci_write_config_word(pci_dev, PCI_COMMAND, 0);
1675 +
1676 +/*
1677 +BUG: these proc entries just cause Call traces, so removed.
1678 + remove_proc_entry("bufs", card->proc_dir);
1679 + remove_proc_entry("fifos", card->proc_dir);
1680 + remove_proc_entry("info", card->proc_dir);
1681 +*/
1682 + remove_proc_entry(card->proc_dir_name, hfc_proc_dahdi_hfcs_dir);
1683 +
1684 + free_irq(pci_dev->irq, card);
1685 +
1686 + pci_free_consistent(pci_dev, hfc_FIFO_SIZE,
1687 + card->fifo_mem, card->fifo_bus_mem);
1688 +
1689 + iounmap(card->io_mem);
1690 +
1691 + pci_release_regions(pci_dev);
1692 +
1693 + pci_disable_device(pci_dev);
1694 +
1695 + kfree(card);
1696 +}
1697 +
1698 +/******************************************
1699 + * Module stuff
1700 + ******************************************/
1701 +
1702 +static int __init hfc_init_module(void)
1703 +{
1704 + int ret;
1705 +
1706 + printk(KERN_INFO hfc_DRIVER_PREFIX
1707 + hfc_DRIVER_STRING " loading\n");
1708 +#ifdef DEBUG
1709 +printk(KERN_INFO hfc_DRIVER_PREFIX "Check /var/log/kern-debug.log for debugging output level %d.", debug_level);
1710 +printk(KERN_DEBUG hfc_DRIVER_PREFIX "base.c is debugging.");
1711 +#endif
1712 +
1713 +#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1714 + hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, NULL);
1715 +#else
1716 + hfc_proc_dahdi_hfcs_dir = proc_mkdir(hfc_DRIVER_NAME, proc_root_driver);
1717 +#endif
1718 +
1719 + ret = pci_register_driver(&hfc_driver);
1720 + return ret;
1721 +}
1722 +
1723 +module_init(hfc_init_module);
1724 +
1725 +static void __exit hfc_module_exit(void)
1726 +{
1727 + pci_unregister_driver(&hfc_driver);
1728 +
1729 +#if (KERNEL_VERSION(2, 6, 26) <= LINUX_VERSION_CODE)
1730 + remove_proc_entry(hfc_DRIVER_NAME, NULL);
1731 +#else
1732 + remove_proc_entry(hfc_DRIVER_NAME, proc_root_driver);
1733 +#endif
1734 +
1735 + printk(KERN_INFO hfc_DRIVER_PREFIX
1736 + hfc_DRIVER_STRING " unloaded\n");
1737 +}
1738 +
1739 +module_exit(hfc_module_exit);
1740 +
1741 +#endif
1742 +
1743 +MODULE_DESCRIPTION(hfc_DRIVER_DESCR);
1744 +MODULE_AUTHOR("Jens Wilke <jw_vzaphfc@headissue.com>, "
1745 + "Daniele (Vihai) Orlandi <daniele@orlandi.com>, "
1746 + "Jose A. Deniz <odicha@hotmail.com>");
1747 +MODULE_ALIAS("dahdi_hfcs");
1748 +#ifdef MODULE_LICENSE
1749 +MODULE_LICENSE("GPL");
1750 +#endif
1751 +
1752 +
1753 +module_param(modes, int, 0444);
1754 +
1755 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
1756 +module_param_array(nt_modes, int, &nt_modes_count, 0444);
1757 +#else
1758 +module_param_array(nt_modes, int, nt_modes_count, 0444);
1759 +#endif
1760 +
1761 +module_param(force_l1_up, int, 0444);
1762 +#ifdef DEBUG
1763 +module_param(debug_level, int, 0444);
1764 +#endif
1765 +
1766 +MODULE_PARM_DESC(modes, "[Deprecated] bit-mask to configure NT mode");
1767 +MODULE_PARM_DESC(nt_modes,
1768 + "Comma-separated list of card IDs to configure in NT mode");
1769 +MODULE_PARM_DESC(force_l1_up, "Don't allow L1 to go down");
1770 +#ifdef DEBUG
1771 +MODULE_PARM_DESC(debug_level, "Debug verbosity level");
1772 +#endif
1773 --- /dev/null
1774 +++ b/drivers/dahdi/hfcs/dahdi_hfcs.h
1775 @@ -0,0 +1,419 @@
1776 +/*
1777 + * dahdi_hfcs.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
1778 + *
1779 + * Dahdi port by Jose A. Deniz <odicha@hotmail.com>
1780 + *
1781 + * Copyright (C) 2009 Jose A. Deniz
1782 + * Copyright (C) 2006 headissue GmbH; Jens Wilke
1783 + * Copyright (C) 2004 Daniele Orlandi
1784 + * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
1785 + *
1786 + * Jens Wilke <jw_vzaphfc@headissue.com>
1787 + *
1788 + * Orginal author of this code is
1789 + * Daniele "Vihai" Orlandi <daniele@orlandi.com>
1790 + *
1791 + * Major rewrite of the driver made by
1792 + * Klaus-Peter Junghanns <kpj@junghanns.net>
1793 + *
1794 + * This program is free software and may be modified and
1795 + * distributed under the terms of the GNU Public License.
1796 + *
1797 + */
1798 +
1799 +#ifndef _HFC_ZAPHFC_H
1800 +#define _HFC_ZAPHFC_H
1801 +
1802 +#include <asm/io.h>
1803 +
1804 +#define hfc_DRIVER_NAME "dahdi_hfcs"
1805 +#define hfc_DRIVER_PREFIX hfc_DRIVER_NAME ": "
1806 +#define hfc_DRIVER_DESCR "HFC-S PCI A ISDN"
1807 +#define hfc_DRIVER_VERSION "1.42"
1808 +#define hfc_DRIVER_STRING hfc_DRIVER_DESCR " (V" hfc_DRIVER_VERSION ")"
1809 +
1810 +#define hfc_MAX_BOARDS 32
1811 +
1812 +#ifndef PCI_DMA_32BIT
1813 +#define PCI_DMA_32BIT 0x00000000ffffffffULL
1814 +#endif
1815 +
1816 +#ifndef PCI_VENDOR_ID_SITECOM
1817 +#define PCI_VENDOR_ID_SITECOM 0x182D
1818 +#endif
1819 +
1820 +#ifndef PCI_DEVICE_ID_SITECOM_3069
1821 +#define PCI_DEVICE_ID_SITECOM_3069 0x3069
1822 +#endif
1823 +
1824 +#define hfc_RESET_DELAY 20
1825 +
1826 +#define hfc_CLKDEL_TE 0x0f /* CLKDEL in TE mode */
1827 +#define hfc_CLKDEL_NT 0x6c /* CLKDEL in NT mode */
1828 +
1829 +/* PCI memory mapped I/O */
1830 +
1831 +#define hfc_PCI_MEM_SIZE 0x0100
1832 +#define hfc_PCI_MWBA 0x80
1833 +
1834 +/* GCI/IOM bus monitor registers */
1835 +
1836 +#define hfc_C_I 0x08
1837 +#define hfc_TRxR 0x0C
1838 +#define hfc_MON1_D 0x28
1839 +#define hfc_MON2_D 0x2C
1840 +
1841 +
1842 +/* GCI/IOM bus timeslot registers */
1843 +
1844 +#define hfc_B1_SSL 0x80
1845 +#define hfc_B2_SSL 0x84
1846 +#define hfc_AUX1_SSL 0x88
1847 +#define hfc_AUX2_SSL 0x8C
1848 +#define hfc_B1_RSL 0x90
1849 +#define hfc_B2_RSL 0x94
1850 +#define hfc_AUX1_RSL 0x98
1851 +#define hfc_AUX2_RSL 0x9C
1852 +
1853 +/* GCI/IOM bus data registers */
1854 +
1855 +#define hfc_B1_D 0xA0
1856 +#define hfc_B2_D 0xA4
1857 +#define hfc_AUX1_D 0xA8
1858 +#define hfc_AUX2_D 0xAC
1859 +
1860 +/* GCI/IOM bus configuration registers */
1861 +
1862 +#define hfc_MST_EMOD 0xB4
1863 +#define hfc_MST_MODE 0xB8
1864 +#define hfc_CONNECT 0xBC
1865 +
1866 +
1867 +/* Interrupt and status registers */
1868 +
1869 +#define hfc_FIFO_EN 0x44
1870 +#define hfc_TRM 0x48
1871 +#define hfc_B_MODE 0x4C
1872 +#define hfc_CHIP_ID 0x58
1873 +#define hfc_CIRM 0x60
1874 +#define hfc_CTMT 0x64
1875 +#define hfc_INT_M1 0x68
1876 +#define hfc_INT_M2 0x6C
1877 +#define hfc_INT_S1 0x78
1878 +#define hfc_INT_S2 0x7C
1879 +#define hfc_STATUS 0x70
1880 +
1881 +/* S/T section registers */
1882 +
1883 +#define hfc_STATES 0xC0
1884 +#define hfc_SCTRL 0xC4
1885 +#define hfc_SCTRL_E 0xC8
1886 +#define hfc_SCTRL_R 0xCC
1887 +#define hfc_SQ 0xD0
1888 +#define hfc_CLKDEL 0xDC
1889 +#define hfc_B1_REC 0xF0
1890 +#define hfc_B1_SEND 0xF0
1891 +#define hfc_B2_REC 0xF4
1892 +#define hfc_B2_SEND 0xF4
1893 +#define hfc_D_REC 0xF8
1894 +#define hfc_D_SEND 0xF8
1895 +#define hfc_E_REC 0xFC
1896 +
1897 +/* Bits and values in various HFC PCI registers */
1898 +
1899 +/* bits in status register (READ) */
1900 +#define hfc_STATUS_PCI_PROC 0x02
1901 +#define hfc_STATUS_NBUSY 0x04
1902 +#define hfc_STATUS_TIMER_ELAP 0x10
1903 +#define hfc_STATUS_STATINT 0x20
1904 +#define hfc_STATUS_FRAMEINT 0x40
1905 +#define hfc_STATUS_ANYINT 0x80
1906 +
1907 +/* bits in CTMT (Write) */
1908 +#define hfc_CTMT_TRANSB1 0x01
1909 +#define hfc_CTMT_TRANSB2 0x02
1910 +#define hfc_CTMT_TIMER_CLEAR 0x80
1911 +#define hfc_CTMT_TIMER_MASK 0x1C
1912 +#define hfc_CTMT_TIMER_3_125 (0x01 << 2)
1913 +#define hfc_CTMT_TIMER_6_25 (0x02 << 2)
1914 +#define hfc_CTMT_TIMER_12_5 (0x03 << 2)
1915 +#define hfc_CTMT_TIMER_25 (0x04 << 2)
1916 +#define hfc_CTMT_TIMER_50 (0x05 << 2)
1917 +#define hfc_CTMT_TIMER_400 (0x06 << 2)
1918 +#define hfc_CTMT_TIMER_800 (0x07 << 2)
1919 +#define hfc_CTMT_AUTO_TIMER 0x20
1920 +
1921 +/* bits in CIRM (Write) */
1922 +#define hfc_CIRM_AUX_MSK 0x07
1923 +#define hfc_CIRM_RESET 0x08
1924 +#define hfc_CIRM_B1_REV 0x40
1925 +#define hfc_CIRM_B2_REV 0x80
1926 +
1927 +/* bits in INT_M1 and INT_S1 */
1928 +#define hfc_INTS_B1TRANS 0x01
1929 +#define hfc_INTS_B2TRANS 0x02
1930 +#define hfc_INTS_DTRANS 0x04
1931 +#define hfc_INTS_B1REC 0x08
1932 +#define hfc_INTS_B2REC 0x10
1933 +#define hfc_INTS_DREC 0x20
1934 +#define hfc_INTS_L1STATE 0x40
1935 +#define hfc_INTS_TIMER 0x80
1936 +
1937 +/* bits in INT_M2 */
1938 +#define hfc_M2_PROC_TRANS 0x01
1939 +#define hfc_M2_GCI_I_CHG 0x02
1940 +#define hfc_M2_GCI_MON_REC 0x04
1941 +#define hfc_M2_IRQ_ENABLE 0x08
1942 +#define hfc_M2_PMESEL 0x80
1943 +
1944 +/* bits in STATES */
1945 +#define hfc_STATES_STATE_MASK 0x0F
1946 +#define hfc_STATES_LOAD_STATE 0x10
1947 +#define hfc_STATES_ACTIVATE 0x20
1948 +#define hfc_STATES_DO_ACTION 0x40
1949 +#define hfc_STATES_NT_G2_G3 0x80
1950 +
1951 +/* bits in HFCD_MST_MODE */
1952 +#define hfc_MST_MODE_MASTER 0x01
1953 +#define hfc_MST_MODE_SLAVE 0x00
1954 +/* remaining bits are for codecs control */
1955 +
1956 +/* bits in HFCD_SCTRL */
1957 +#define hfc_SCTRL_B1_ENA 0x01
1958 +#define hfc_SCTRL_B2_ENA 0x02
1959 +#define hfc_SCTRL_MODE_TE 0x00
1960 +#define hfc_SCTRL_MODE_NT 0x04
1961 +#define hfc_SCTRL_LOW_PRIO 0x08
1962 +#define hfc_SCTRL_SQ_ENA 0x10
1963 +#define hfc_SCTRL_TEST 0x20
1964 +#define hfc_SCTRL_NONE_CAP 0x40
1965 +#define hfc_SCTRL_PWR_DOWN 0x80
1966 +
1967 +/* bits in SCTRL_E */
1968 +#define hfc_SCTRL_E_AUTO_AWAKE 0x01
1969 +#define hfc_SCTRL_E_DBIT_1 0x04
1970 +#define hfc_SCTRL_E_IGNORE_COL 0x08
1971 +#define hfc_SCTRL_E_CHG_B1_B2 0x80
1972 +
1973 +/* bits in SCTRL_R */
1974 +#define hfc_SCTRL_R_B1_ENA 0x01
1975 +#define hfc_SCTRL_R_B2_ENA 0x02
1976 +
1977 +/* bits in FIFO_EN register */
1978 +#define hfc_FIFOEN_B1TX 0x01
1979 +#define hfc_FIFOEN_B1RX 0x02
1980 +#define hfc_FIFOEN_B2TX 0x04
1981 +#define hfc_FIFOEN_B2RX 0x08
1982 +#define hfc_FIFOEN_DTX 0x10
1983 +#define hfc_FIFOEN_DRX 0x20
1984 +
1985 +#define hfc_FIFOEN_B1 (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
1986 +#define hfc_FIFOEN_B2 (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
1987 +#define hfc_FIFOEN_D (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
1988 +
1989 +/* bits in the CONNECT register */
1990 +#define hfc_CONNECT_B1_HFC_from_ST 0x00
1991 +#define hfc_CONNECT_B1_HFC_from_GCI 0x01
1992 +#define hfc_CONNECT_B1_ST_from_HFC 0x00
1993 +#define hfc_CONNECT_B1_ST_from_GCI 0x02
1994 +#define hfc_CONNECT_B1_GCI_from_HFC 0x00
1995 +#define hfc_CONNECT_B1_GCI_from_ST 0x04
1996 +
1997 +#define hfc_CONNECT_B2_HFC_from_ST 0x00
1998 +#define hfc_CONNECT_B2_HFC_from_GCI 0x08
1999 +#define hfc_CONNECT_B2_ST_from_HFC 0x00
2000 +#define hfc_CONNECT_B2_ST_from_GCI 0x10
2001 +#define hfc_CONNECT_B2_GCI_from_HFC 0x00
2002 +#define hfc_CONNECT_B2_GCI_from_ST 0x20
2003 +
2004 +/* bits in the TRM register */
2005 +#define hfc_TRM_TRANS_INT_00 0x00
2006 +#define hfc_TRM_TRANS_INT_01 0x01
2007 +#define hfc_TRM_TRANS_INT_10 0x02
2008 +#define hfc_TRM_TRANS_INT_11 0x04
2009 +#define hfc_TRM_ECHO 0x20
2010 +#define hfc_TRM_B1_PLUS_B2 0x40
2011 +#define hfc_TRM_IOM_TEST_LOOP 0x80
2012 +
2013 +/* bits in the __SSL and __RSL registers */
2014 +#define hfc_SRSL_STIO 0x40
2015 +#define hfc_SRSL_ENABLE 0x80
2016 +#define hfc_SRCL_SLOT_MASK 0x1f
2017 +
2018 +/* FIFO memory definitions */
2019 +
2020 +#define hfc_FIFO_SIZE 0x8000
2021 +
2022 +#define hfc_UGLY_FRAMEBUF 0x2000
2023 +
2024 +#define hfc_TX_FIFO_PRELOAD (DAHDI_CHUNKSIZE + 2)
2025 +#define hfc_RX_FIFO_PRELOAD 4
2026 +
2027 +/* HDLC STUFF */
2028 +#define hfc_HDLC_BUF_LEN 32
2029 +/* arbitrary, just the max # of byts we will send to DAHDI per call */
2030 +
2031 +
2032 +/* NOTE: FIFO pointers are not declared volatile because accesses to the
2033 + * FIFOs are inherently safe.
2034 + */
2035 +
2036 +#ifdef DEBUG
2037 +extern int debug_level;
2038 +#endif
2039 +
2040 +struct hfc_chan;
2041 +
2042 +struct hfc_chan_simplex {
2043 + struct hfc_chan_duplex *chan;
2044 +
2045 + u8 dahdi_buffer[DAHDI_CHUNKSIZE];
2046 +
2047 + u8 ugly_framebuf[hfc_UGLY_FRAMEBUF];
2048 + int ugly_framebuf_size;
2049 + u16 ugly_framebuf_off;
2050 +
2051 + void *z1_base, *z2_base;
2052 + void *fifo_base;
2053 + void *z_base;
2054 + u16 z_min;
2055 + u16 z_max;
2056 + u16 fifo_size;
2057 +
2058 + u8 *f1, *f2;
2059 + u8 f_min;
2060 + u8 f_max;
2061 + u8 f_num;
2062 +
2063 + unsigned long long frames;
2064 + unsigned long long bytes;
2065 + unsigned long long fifo_full;
2066 + unsigned long long crc;
2067 + unsigned long long fifo_underrun;
2068 +};
2069 +
2070 +enum hfc_chan_status {
2071 + free,
2072 + open_framed,
2073 + open_voice,
2074 + sniff_aux,
2075 + loopback,
2076 +};
2077 +
2078 +struct hfc_chan_duplex {
2079 + struct hfc_card *card;
2080 +
2081 + char *name;
2082 + int number;
2083 +
2084 + enum hfc_chan_status status;
2085 + int open_by_netdev;
2086 + int open_by_dahdi;
2087 +
2088 + unsigned short protocol;
2089 +
2090 + spinlock_t lock;
2091 +
2092 + struct hfc_chan_simplex rx;
2093 + struct hfc_chan_simplex tx;
2094 +
2095 +};
2096 +
2097 +typedef struct hfc_card {
2098 + int cardnum;
2099 + struct pci_dev *pcidev;
2100 + struct dahdi_hfc *dahdi_dev;
2101 + struct proc_dir_entry *proc_dir;
2102 + char proc_dir_name[32];
2103 +
2104 + struct proc_dir_entry *proc_info;
2105 + struct proc_dir_entry *proc_fifos;
2106 + struct proc_dir_entry *proc_bufs;
2107 +
2108 + unsigned long io_bus_mem;
2109 + void __iomem *io_mem;
2110 +
2111 + dma_addr_t fifo_bus_mem;
2112 + void *fifo_mem;
2113 + void *fifos;
2114 +
2115 + int nt_mode;
2116 + int sync_loss_reported;
2117 + int late_irqs;
2118 +
2119 + u8 l1_state;
2120 + int fifo_suspended;
2121 + int ignore_first_timer_interrupt;
2122 +
2123 + struct {
2124 + u8 m1;
2125 + u8 m2;
2126 + u8 fifo_en;
2127 + u8 trm;
2128 + u8 connect;
2129 + u8 sctrl;
2130 + u8 sctrl_r;
2131 + u8 sctrl_e;
2132 + u8 ctmt;
2133 + u8 cirm;
2134 + } regs;
2135 +
2136 + struct hfc_chan_duplex chans[3];
2137 + int echo_enabled;
2138 +
2139 +
2140 +
2141 + int debug_event;
2142 +
2143 + spinlock_t lock;
2144 + unsigned int irq;
2145 + unsigned int iomem;
2146 + int ticks;
2147 + int clicks;
2148 + unsigned char *pci_io;
2149 + void *fifomem; /* start of the shared mem */
2150 +
2151 + unsigned int pcibus;
2152 + unsigned int pcidevfn;
2153 +
2154 + int drecinframe;
2155 +
2156 + unsigned char cardno;
2157 + struct hfc_card *next;
2158 +
2159 +} hfc_card;
2160 +
2161 +typedef struct dahdi_hfc {
2162 + unsigned int usecount;
2163 + struct dahdi_device *ddev;
2164 + struct dahdi_span span;
2165 + struct dahdi_chan chans[3];
2166 + struct dahdi_chan *_chans[3];
2167 + struct hfc_card *card;
2168 +
2169 + /* pointer to the signalling channel for this span */
2170 + struct dahdi_chan *sigchan;
2171 + /* nonzero means we're in the middle of sending an HDLC frame */
2172 + int sigactive;
2173 + /* hdlc_hard_xmit() increments, hdlc_tx_frame() decrements */
2174 + atomic_t hdlc_pending;
2175 + int frames_out;
2176 + int frames_in;
2177 +
2178 +} dahdi_hfc;
2179 +
2180 +static inline struct dahdi_hfc* dahdi_hfc_from_span(struct dahdi_span *span) {
2181 + return container_of(span, struct dahdi_hfc, span);
2182 +}
2183 +
2184 +static inline u8 hfc_inb(struct hfc_card *card, int offset)
2185 +{
2186 + return readb(card->io_mem + offset);
2187 +}
2188 +
2189 +static inline void hfc_outb(struct hfc_card *card, int offset, u8 value)
2190 +{
2191 + writeb(value, card->io_mem + offset);
2192 +}
2193 +
2194 +#endif
2195 --- /dev/null
2196 +++ b/drivers/dahdi/hfcs/fifo.c
2197 @@ -0,0 +1,380 @@
2198 +/*
2199 + * fifo.c - HFC FIFO management routines
2200 + *
2201 + * Copyright (C) 2006 headissue GmbH; Jens Wilke
2202 + * Copyright (C) 2004 Daniele Orlandi
2203 + * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
2204 + *
2205 + * Original author of this code is
2206 + * Daniele "Vihai" Orlandi <daniele@orlandi.com>
2207 + *
2208 + * This program is free software and may be modified and
2209 + * distributed under the terms of the GNU Public License.
2210 + *
2211 + */
2212 +
2213 +#define DEBUG
2214 +#ifdef DEBUG
2215 +extern int debug_level;
2216 +#endif
2217 +
2218 +#include <linux/kernel.h>
2219 +
2220 +#include <dahdi/kernel.h>
2221 +
2222 +#include "fifo.h"
2223 +
2224 +static void hfc_fifo_mem_read(struct hfc_chan_simplex *chan,
2225 + int z_start,
2226 + void *data, int size)
2227 +{
2228 + int bytes_to_boundary = chan->z_max - z_start + 1;
2229 + if (bytes_to_boundary >= size) {
2230 + memcpy(data,
2231 + chan->z_base + z_start,
2232 + size);
2233 + } else {
2234 + /*
2235 + * Buffer wrap
2236 + */
2237 + memcpy(data,
2238 + chan->z_base + z_start,
2239 + bytes_to_boundary);
2240 +
2241 + memcpy(data + bytes_to_boundary,
2242 + chan->fifo_base,
2243 + size - bytes_to_boundary);
2244 + }
2245 +}
2246 +
2247 +static void hfc_fifo_mem_write(struct hfc_chan_simplex *chan,
2248 + void *data, int size)
2249 +{
2250 + int bytes_to_boundary = chan->z_max - *Z1_F1(chan) + 1;
2251 + if (bytes_to_boundary >= size) {
2252 + memcpy(chan->z_base + *Z1_F1(chan),
2253 + data,
2254 + size);
2255 + } else {
2256 + /*
2257 + * FIFO wrap
2258 + */
2259 +
2260 + memcpy(chan->z_base + *Z1_F1(chan),
2261 + data,
2262 + bytes_to_boundary);
2263 +
2264 + memcpy(chan->fifo_base,
2265 + data + bytes_to_boundary,
2266 + size - bytes_to_boundary);
2267 + }
2268 +}
2269 +
2270 +int hfc_fifo_get(struct hfc_chan_simplex *chan,
2271 + void *data, int size)
2272 +{
2273 + int available_bytes;
2274 +
2275 + /*
2276 + * Some useless statistic
2277 + */
2278 + chan->bytes += size;
2279 +
2280 + available_bytes = hfc_fifo_used_rx(chan);
2281 +
2282 + if (available_bytes < size && !chan->fifo_underrun++) {
2283 + /*
2284 + * print the warning only once
2285 + */
2286 + printk(KERN_WARNING hfc_DRIVER_PREFIX
2287 + "card %d: "
2288 + "chan %s: "
2289 + "RX FIFO not enough (%d) bytes to receive!\n",
2290 + chan->chan->card->cardnum,
2291 + chan->chan->name,
2292 + available_bytes);
2293 + return -1;
2294 + }
2295 +
2296 + hfc_fifo_mem_read(chan, *Z2_F2(chan), data, size);
2297 + *Z2_F2(chan) = Z_inc(chan, *Z2_F2(chan), size);
2298 + return available_bytes - size;
2299 +}
2300 +
2301 +void hfc_fifo_put(struct hfc_chan_simplex *chan,
2302 + void *data, int size)
2303 +{
2304 + struct hfc_card *card = chan->chan->card;
2305 + int used_bytes = hfc_fifo_used_tx(chan);
2306 + int free_bytes = hfc_fifo_free_tx(chan);
2307 +
2308 + if (!used_bytes && !chan->fifo_underrun++) {
2309 + /*
2310 + * print warning only once, to make timing not worse
2311 + */
2312 + printk(KERN_WARNING hfc_DRIVER_PREFIX
2313 + "card %d: "
2314 + "chan %s: "
2315 + "TX FIFO has become empty\n",
2316 + card->cardnum,
2317 + chan->chan->name);
2318 + }
2319 + if (free_bytes < size) {
2320 + printk(KERN_CRIT hfc_DRIVER_PREFIX
2321 + "card %d: "
2322 + "chan %s: "
2323 + "TX FIFO full!\n",
2324 + chan->chan->card->cardnum,
2325 + chan->chan->name);
2326 + chan->fifo_full++;
2327 + hfc_clear_fifo_tx(chan);
2328 + }
2329 +
2330 + hfc_fifo_mem_write(chan, data, size);
2331 + chan->bytes += size;
2332 + *Z1_F1(chan) = Z_inc(chan, *Z1_F1(chan), size);
2333 +}
2334 +
2335 +int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size)
2336 +{
2337 + int frame_size;
2338 + u16 newz2 ;
2339 +
2340 + if (*chan->f1 == *chan->f2) {
2341 + /*
2342 + * nothing received, strange uh?
2343 + */
2344 + printk(KERN_WARNING hfc_DRIVER_PREFIX
2345 + "card %d: "
2346 + "chan %s: "
2347 + "get_frame called with no frame in FIFO.\n",
2348 + chan->chan->card->cardnum,
2349 + chan->chan->name);
2350 +
2351 + return -1;
2352 + }
2353 +
2354 + /*
2355 + * frame_size includes CRC+CRC+STAT
2356 + */
2357 + frame_size = hfc_fifo_get_frame_size(chan);
2358 +
2359 +#ifdef DEBUG
2360 + if (debug_level == 3) {
2361 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
2362 + "card %d: "
2363 + "chan %s: "
2364 + "RX len %2d: ",
2365 + chan->chan->card->cardnum,
2366 + chan->chan->name,
2367 + frame_size);
2368 + } else if (debug_level >= 4) {
2369 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
2370 + "card %d: "
2371 + "chan %s: "
2372 + "RX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
2373 + chan->chan->card->cardnum,
2374 + chan->chan->name,
2375 + *chan->f1, *chan->f2, *Z1_F2(chan), *Z2_F2(chan),
2376 + frame_size);
2377 + }
2378 +
2379 + if (debug_level >= 3) {
2380 + int i;
2381 + for (i = 0; i < frame_size; i++) {
2382 + printk("%02x", hfc_fifo_u8(chan,
2383 + Z_inc(chan, *Z2_F2(chan), i)));
2384 + }
2385 +
2386 + printk("\n");
2387 + }
2388 +#endif
2389 +
2390 + if (frame_size <= 0) {
2391 +#ifdef DEBUG
2392 + if (debug_level >= 2) {
2393 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
2394 + "card %d: "
2395 + "chan %s: "
2396 + "invalid (empty) frame received.\n",
2397 + chan->chan->card->cardnum,
2398 + chan->chan->name);
2399 + }
2400 +#endif
2401 +
2402 + hfc_fifo_drop_frame(chan);
2403 + return -1;
2404 + }
2405 +
2406 + /*
2407 + * STAT is not really received
2408 + */
2409 + chan->bytes += frame_size - 1;
2410 +
2411 + /*
2412 + * Calculate beginning of the next frame
2413 + */
2414 + newz2 = Z_inc(chan, *Z2_F2(chan), frame_size);
2415 +
2416 + /*
2417 + * We cannot use hfc_fifo_get because of different semantic of
2418 + * "available bytes" and to avoid useless increment of Z2
2419 + */
2420 + hfc_fifo_mem_read(chan, *Z2_F2(chan), data,
2421 + frame_size < max_size ? frame_size : max_size);
2422 +
2423 + if (hfc_fifo_u8(chan, Z_inc(chan, *Z2_F2(chan),
2424 + frame_size - 1)) != 0x00) {
2425 + /*
2426 + * CRC not ok, frame broken, skipping
2427 + */
2428 +#ifdef DEBUG
2429 + if (debug_level >= 2) {
2430 + printk(KERN_WARNING hfc_DRIVER_PREFIX
2431 + "card %d: "
2432 + "chan %s: "
2433 + "Received frame with wrong CRC\n",
2434 + chan->chan->card->cardnum,
2435 + chan->chan->name);
2436 + }
2437 +#endif
2438 +
2439 + chan->crc++;
2440 +
2441 + hfc_fifo_drop_frame(chan);
2442 + return -1;
2443 + }
2444 +
2445 + chan->frames++;
2446 +
2447 + *chan->f2 = F_inc(chan, *chan->f2, 1);
2448 +
2449 + /*
2450 + * Set Z2 for the next frame we're going to receive
2451 + */
2452 + *Z2_F2(chan) = newz2;
2453 +
2454 + return frame_size;
2455 +}
2456 +
2457 +void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan)
2458 +{
2459 + int available_bytes;
2460 + u16 newz2;
2461 +
2462 + if (*chan->f1 == *chan->f2) {
2463 + /*
2464 + * nothing received, strange eh?
2465 + */
2466 + printk(KERN_WARNING hfc_DRIVER_PREFIX
2467 + "card %d: "
2468 + "chan %s: "
2469 + "skip_frame called with no frame in FIFO.\n",
2470 + chan->chan->card->cardnum,
2471 + chan->chan->name);
2472 +
2473 + return;
2474 + }
2475 +
2476 + available_bytes = hfc_fifo_used_rx(chan) + 1;
2477 +
2478 + /*
2479 + * Calculate beginning of the next frame
2480 + */
2481 + newz2 = Z_inc(chan, *Z2_F2(chan), available_bytes);
2482 +
2483 + *chan->f2 = F_inc(chan, *chan->f2, 1);
2484 +
2485 + /*
2486 + * Set Z2 for the next frame we're going to receive
2487 + */
2488 + *Z2_F2(chan) = newz2;
2489 +}
2490 +
2491 +void hfc_fifo_put_frame(struct hfc_chan_simplex *chan,
2492 + void *data, int size)
2493 +{
2494 + u16 newz1;
2495 + int available_frames;
2496 +
2497 +#ifdef DEBUG
2498 + if (debug_level == 3) {
2499 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
2500 + "card %d: "
2501 + "chan %s: "
2502 + "TX len %2d: ",
2503 + chan->chan->card->cardnum,
2504 + chan->chan->name,
2505 + size);
2506 + } else if (debug_level >= 4) {
2507 + printk(KERN_DEBUG hfc_DRIVER_PREFIX
2508 + "card %d: "
2509 + "chan %s: "
2510 + "TX (f1=%02x, f2=%02x, z1=%04x, z2=%04x) len %2d: ",
2511 + chan->chan->card->cardnum,
2512 + chan->chan->name,
2513 + *chan->f1, *chan->f2, *Z1_F1(chan), *Z2_F1(chan),
2514 + size);
2515 + }
2516 +
2517 + if (debug_level >= 3) {
2518 + int i;
2519 + for (i = 0; i < size; i++)
2520 + printk("%02x", ((u8 *)data)[i]);
2521 +
2522 + printk("\n");
2523 + }
2524 +#endif
2525 +
2526 + available_frames = hfc_fifo_free_frames(chan);
2527 +
2528 + if (available_frames >= chan->f_num) {
2529 + printk(KERN_CRIT hfc_DRIVER_PREFIX
2530 + "card %d: "
2531 + "chan %s: "
2532 + "TX FIFO total number of frames exceeded!\n",
2533 + chan->chan->card->cardnum,
2534 + chan->chan->name);
2535 +
2536 + chan->fifo_full++;
2537 +
2538 + return;
2539 + }
2540 +
2541 + hfc_fifo_put(chan, data, size);
2542 +
2543 + newz1 = *Z1_F1(chan);
2544 +
2545 + *chan->f1 = F_inc(chan, *chan->f1, 1);
2546 +
2547 + *Z1_F1(chan) = newz1;
2548 +
2549 + chan->frames++;
2550 +}
2551 +
2552 +void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan)
2553 +{
2554 + *chan->f2 = *chan->f1;
2555 + *Z2_F2(chan) = *Z1_F2(chan);
2556 +}
2557 +
2558 +void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan)
2559 +{
2560 + *chan->f1 = *chan->f2;
2561 + *Z1_F1(chan) = *Z2_F1(chan);
2562 +
2563 + if (chan->chan->status == open_voice) {
2564 + /*
2565 + * Make sure that at least hfc_TX_FIFO_PRELOAD bytes are
2566 + * present in the TX FIFOs
2567 + * Create hfc_TX_FIFO_PRELOAD bytes of empty data
2568 + * (0x7f is mute audio)
2569 + */
2570 + u8 empty_fifo[hfc_TX_FIFO_PRELOAD +
2571 + DAHDI_CHUNKSIZE + hfc_RX_FIFO_PRELOAD];
2572 + memset(empty_fifo, 0x7f, sizeof(empty_fifo));
2573 +
2574 + hfc_fifo_put(chan, empty_fifo, sizeof(empty_fifo));
2575 + }
2576 +}
2577 +
2578 --- /dev/null
2579 +++ b/drivers/dahdi/hfcs/fifo.h
2580 @@ -0,0 +1,139 @@
2581 +/*
2582 + * fifo.h - Dahdi driver for HFC-S PCI A based ISDN BRI cards
2583 + *
2584 + * Copyright (C) 2004 Daniele Orlandi
2585 + * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
2586 + *
2587 + * Daniele "Vihai" Orlandi <daniele@orlandi.com>
2588 + *
2589 + * Major rewrite of the driver made by
2590 + * Klaus-Peter Junghanns <kpj@junghanns.net>
2591 + *
2592 + * This program is free software and may be modified and
2593 + * distributed under the terms of the GNU Public License.
2594 + *
2595 + */
2596 +
2597 +#ifndef _HFC_FIFO_H
2598 +#define _HFC_FIFO_H
2599 +
2600 +#include "dahdi_hfcs.h"
2601 +
2602 +static inline u16 *Z1_F1(struct hfc_chan_simplex *chan)
2603 +{
2604 + return chan->z1_base + (*chan->f1 * 4);
2605 +}
2606 +
2607 +static inline u16 *Z2_F1(struct hfc_chan_simplex *chan)
2608 +{
2609 + return chan->z2_base + (*chan->f1 * 4);
2610 +}
2611 +
2612 +static inline u16 *Z1_F2(struct hfc_chan_simplex *chan)
2613 +{
2614 + return chan->z1_base + (*chan->f2 * 4);
2615 +}
2616 +
2617 +static inline u16 *Z2_F2(struct hfc_chan_simplex *chan)
2618 +{
2619 + return chan->z2_base + (*chan->f2 * 4);
2620 +}
2621 +
2622 +static inline u16 Z_inc(struct hfc_chan_simplex *chan, u16 z, u16 inc)
2623 +{
2624 + /*
2625 + * declared as u32 in order to manage overflows
2626 + */
2627 + u32 newz = z + inc;
2628 + if (newz > chan->z_max)
2629 + newz -= chan->fifo_size;
2630 +
2631 + return newz;
2632 +}
2633 +
2634 +static inline u8 F_inc(struct hfc_chan_simplex *chan, u8 f, u8 inc)
2635 +{
2636 + /*
2637 + * declared as u16 in order to manage overflows
2638 + */
2639 + u16 newf = f + inc;
2640 + if (newf > chan->f_max)
2641 + newf -= chan->f_num;
2642 +
2643 + return newf;
2644 +}
2645 +
2646 +static inline u16 hfc_fifo_used_rx(struct hfc_chan_simplex *chan)
2647 +{
2648 + return (*Z1_F2(chan) - *Z2_F2(chan) +
2649 + chan->fifo_size) % chan->fifo_size;
2650 +}
2651 +
2652 +static inline u16 hfc_fifo_get_frame_size(struct hfc_chan_simplex *chan)
2653 +{
2654 + /*
2655 + * This +1 is needed because in frame mode the available bytes are Z2-Z1+1
2656 + * while in transparent mode I wouldn't consider the byte pointed by Z2 to
2657 + * be available, otherwise, the FIFO would always contain one byte, even
2658 + * when Z1==Z2
2659 + */
2660 +
2661 + return hfc_fifo_used_rx(chan) + 1;
2662 +}
2663 +
2664 +static inline u8 hfc_fifo_u8(struct hfc_chan_simplex *chan, u16 z)
2665 +{
2666 + return *((u8 *)(chan->z_base + z));
2667 +}
2668 +
2669 +static inline u16 hfc_fifo_used_tx(struct hfc_chan_simplex *chan)
2670 +{
2671 + return (*Z1_F1(chan) - *Z2_F1(chan) +
2672 + chan->fifo_size) % chan->fifo_size;
2673 +}
2674 +
2675 +static inline u16 hfc_fifo_free_rx(struct hfc_chan_simplex *chan)
2676 +{
2677 + u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
2678 +
2679 + if (free_bytes > 0)
2680 + return free_bytes;
2681 + else
2682 + return free_bytes + chan->fifo_size;
2683 +}
2684 +
2685 +static inline u16 hfc_fifo_free_tx(struct hfc_chan_simplex *chan)
2686 +{
2687 + u16 free_bytes = *Z2_F1(chan) - *Z1_F1(chan);
2688 +
2689 + if (free_bytes > 0)
2690 + return free_bytes;
2691 + else
2692 + return free_bytes + chan->fifo_size;
2693 +}
2694 +
2695 +static inline int hfc_fifo_has_frames(struct hfc_chan_simplex *chan)
2696 +{
2697 + return *chan->f1 != *chan->f2;
2698 +}
2699 +
2700 +static inline u8 hfc_fifo_used_frames(struct hfc_chan_simplex *chan)
2701 +{
2702 + return (*chan->f1 - *chan->f2 + chan->f_num) % chan->f_num;
2703 +}
2704 +
2705 +static inline u8 hfc_fifo_free_frames(struct hfc_chan_simplex *chan)
2706 +{
2707 + return (*chan->f2 - *chan->f1 + chan->f_num) % chan->f_num;
2708 +}
2709 +
2710 +int hfc_fifo_get(struct hfc_chan_simplex *chan, void *data, int size);
2711 +void hfc_fifo_put(struct hfc_chan_simplex *chan, void *data, int size);
2712 +void hfc_fifo_drop(struct hfc_chan_simplex *chan, int size);
2713 +int hfc_fifo_get_frame(struct hfc_chan_simplex *chan, void *data, int max_size);
2714 +void hfc_fifo_drop_frame(struct hfc_chan_simplex *chan);
2715 +void hfc_fifo_put_frame(struct hfc_chan_simplex *chan, void *data, int size);
2716 +void hfc_clear_fifo_rx(struct hfc_chan_simplex *chan);
2717 +void hfc_clear_fifo_tx(struct hfc_chan_simplex *chan);
2718 +
2719 +#endif
2720 --- /dev/null
2721 +++ b/drivers/dahdi/hfcs/Kbuild
2722 @@ -0,0 +1,10 @@
2723 +obj-m += dahdi_hfcs.o
2724 +
2725 +EXTRA_CFLAGS := -I$(src)/.. -Wno-undef
2726 +
2727 +dahdi_hfcs-objs := base.o fifo.o
2728 +
2729 +$(obj)/base.o: $(src)/dahdi_hfcs.h
2730 +$(obj)/fifo.o: $(src)/fifo.h
2731 +
2732 +