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