blob: 4a069582fc6b6b1dcfa064739e872529b05448e9 [file] [log] [blame]
Thomas Gleixnerde6cc652019-05-27 08:55:02 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Karsten Keil1700fe12008-07-26 18:55:28 +02002/*
3 *
4 * hfcpci.c low level driver for CCD's hfc-pci based cards
5 *
6 * Author Werner Cornelius (werner@isdn4linux.de)
7 * based on existing driver for CCD hfc ISA cards
8 * type approval valid for HFC-S PCI A based card
9 *
10 * Copyright 1999 by Werner Cornelius (werner@isdn-development.de)
11 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
12 *
Andreas Eversberg87c5fa12008-09-28 13:01:01 +020013 * Module options:
14 *
15 * debug:
16 * NOTE: only one poll value must be given for all cards
17 * See hfc_pci.h for debug flags.
18 *
19 * poll:
20 * NOTE: only one poll value must be given for all cards
21 * Give the number of samples for each fifo process.
22 * By default 128 is used. Decrease to reduce delay, increase to
23 * reduce cpu load. If unsure, don't mess with it!
24 * A value of 128 will use controller's interrupt. Other values will
25 * use kernel timer, because the controller will not allow lower values
26 * than 128.
27 * Also note that the value depends on the kernel timer frequency.
28 * If kernel uses a frequency of 1000 Hz, steps of 8 samples are possible.
29 * If the kernel uses 100 Hz, steps of 80 samples are possible.
30 * If the kernel uses 300 Hz, steps of about 26 samples are possible.
Karsten Keil1700fe12008-07-26 18:55:28 +020031 */
32
Alexey Dobriyana6b7a402011-06-06 10:43:46 +000033#include <linux/interrupt.h>
Karsten Keil1700fe12008-07-26 18:55:28 +020034#include <linux/module.h>
35#include <linux/pci.h>
36#include <linux/delay.h>
37#include <linux/mISDNhw.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090038#include <linux/slab.h>
Karsten Keil1700fe12008-07-26 18:55:28 +020039
40#include "hfc_pci.h"
41
42static const char *hfcpci_revision = "2.0";
43
Karsten Keil1700fe12008-07-26 18:55:28 +020044static int HFC_cnt;
45static uint debug;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +020046static uint poll, tics;
Hannes Eder6c2959a2009-02-12 09:28:40 +000047static struct timer_list hfc_tl;
Hannes Ederaa611f82009-02-14 13:10:33 +000048static unsigned long hfc_jiffies;
Karsten Keil1700fe12008-07-26 18:55:28 +020049
50MODULE_AUTHOR("Karsten Keil");
51MODULE_LICENSE("GPL");
Karsten Keil9785a8f82009-01-11 17:58:13 +010052module_param(debug, uint, S_IRUGO | S_IWUSR);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +020053module_param(poll, uint, S_IRUGO | S_IWUSR);
Karsten Keil1700fe12008-07-26 18:55:28 +020054
Karsten Keil1700fe12008-07-26 18:55:28 +020055enum {
56 HFC_CCD_2BD0,
57 HFC_CCD_B000,
58 HFC_CCD_B006,
59 HFC_CCD_B007,
60 HFC_CCD_B008,
61 HFC_CCD_B009,
62 HFC_CCD_B00A,
63 HFC_CCD_B00B,
64 HFC_CCD_B00C,
65 HFC_CCD_B100,
66 HFC_CCD_B700,
67 HFC_CCD_B701,
68 HFC_ASUS_0675,
69 HFC_BERKOM_A1T,
70 HFC_BERKOM_TCONCEPT,
71 HFC_ANIGMA_MC145575,
72 HFC_ZOLTRIX_2BD0,
73 HFC_DIGI_DF_M_IOM2_E,
74 HFC_DIGI_DF_M_E,
75 HFC_DIGI_DF_M_IOM2_A,
76 HFC_DIGI_DF_M_A,
77 HFC_ABOCOM_2BD1,
78 HFC_SITECOM_DC105V2,
79};
80
81struct hfcPCI_hw {
82 unsigned char cirm;
83 unsigned char ctmt;
84 unsigned char clkdel;
85 unsigned char states;
86 unsigned char conn;
87 unsigned char mst_m;
88 unsigned char int_m1;
89 unsigned char int_m2;
90 unsigned char sctrl;
91 unsigned char sctrl_r;
92 unsigned char sctrl_e;
93 unsigned char trm;
94 unsigned char fifo_en;
95 unsigned char bswapped;
96 unsigned char protocol;
97 int nt_timer;
Joe Perches475be4d2012-02-19 19:52:38 -080098 unsigned char __iomem *pci_io; /* start of PCI IO memory */
Karsten Keil1700fe12008-07-26 18:55:28 +020099 dma_addr_t dmahandle;
100 void *fifos; /* FIFO memory */
101 int last_bfifo_cnt[2];
Joe Perches475be4d2012-02-19 19:52:38 -0800102 /* marker saving last b-fifo frame count */
Karsten Keil1700fe12008-07-26 18:55:28 +0200103 struct timer_list timer;
104};
105
106#define HFC_CFG_MASTER 1
107#define HFC_CFG_SLAVE 2
108#define HFC_CFG_PCM 3
109#define HFC_CFG_2HFC 4
110#define HFC_CFG_SLAVEHFC 5
111#define HFC_CFG_NEG_F0 6
112#define HFC_CFG_SW_DD_DU 7
113
114#define FLG_HFC_TIMER_T1 16
115#define FLG_HFC_TIMER_T3 17
116
117#define NT_T1_COUNT 1120 /* number of 3.125ms interrupts (3.5s) */
118#define NT_T3_COUNT 31 /* number of 3.125ms interrupts (97 ms) */
119#define CLKDEL_TE 0x0e /* CLKDEL in TE mode */
120#define CLKDEL_NT 0x6c /* CLKDEL in NT mode */
121
122
123struct hfc_pci {
Karsten Keil1700fe12008-07-26 18:55:28 +0200124 u_char subtype;
125 u_char chanlimit;
126 u_char initdone;
127 u_long cfg;
128 u_int irq;
129 u_int irqcnt;
130 struct pci_dev *pdev;
131 struct hfcPCI_hw hw;
132 spinlock_t lock; /* card lock */
133 struct dchannel dch;
134 struct bchannel bch[2];
135};
136
137/* Interface functions */
138static void
139enable_hwirq(struct hfc_pci *hc)
140{
141 hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE;
142 Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
143}
144
145static void
146disable_hwirq(struct hfc_pci *hc)
147{
148 hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE);
149 Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
150}
151
152/*
153 * free hardware resources used by driver
154 */
155static void
156release_io_hfcpci(struct hfc_pci *hc)
157{
158 /* disable memory mapped ports + busmaster */
159 pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
160 del_timer(&hc->hw.timer);
161 pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle);
Harvey Harrison1532dcb2008-09-22 19:16:51 -0700162 iounmap(hc->hw.pci_io);
Karsten Keil1700fe12008-07-26 18:55:28 +0200163}
164
165/*
166 * set mode (NT or TE)
167 */
168static void
169hfcpci_setmode(struct hfc_pci *hc)
170{
171 if (hc->hw.protocol == ISDN_P_NT_S0) {
172 hc->hw.clkdel = CLKDEL_NT; /* ST-Bit delay for NT-Mode */
173 hc->hw.sctrl |= SCTRL_MODE_NT; /* NT-MODE */
174 hc->hw.states = 1; /* G1 */
175 } else {
176 hc->hw.clkdel = CLKDEL_TE; /* ST-Bit delay for TE-Mode */
177 hc->hw.sctrl &= ~SCTRL_MODE_NT; /* TE-MODE */
178 hc->hw.states = 2; /* F2 */
179 }
180 Write_hfc(hc, HFCPCI_CLKDEL, hc->hw.clkdel);
181 Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | hc->hw.states);
182 udelay(10);
183 Write_hfc(hc, HFCPCI_STATES, hc->hw.states | 0x40); /* Deactivate */
184 Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
185}
186
187/*
188 * function called to reset the HFC PCI chip. A complete software reset of chip
189 * and fifos is done.
190 */
191static void
192reset_hfcpci(struct hfc_pci *hc)
193{
194 u_char val;
195 int cnt = 0;
196
197 printk(KERN_DEBUG "reset_hfcpci: entered\n");
198 val = Read_hfc(hc, HFCPCI_CHIP_ID);
199 printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val);
200 /* enable memory mapped ports, disable busmaster */
201 pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
202 disable_hwirq(hc);
203 /* enable memory ports + busmaster */
204 pci_write_config_word(hc->pdev, PCI_COMMAND,
Joe Perches475be4d2012-02-19 19:52:38 -0800205 PCI_ENA_MEMIO + PCI_ENA_MASTER);
Karsten Keil1700fe12008-07-26 18:55:28 +0200206 val = Read_hfc(hc, HFCPCI_STATUS);
207 printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val);
208 hc->hw.cirm = HFCPCI_RESET; /* Reset On */
209 Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
210 set_current_state(TASK_UNINTERRUPTIBLE);
211 mdelay(10); /* Timeout 10ms */
212 hc->hw.cirm = 0; /* Reset Off */
213 Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
214 val = Read_hfc(hc, HFCPCI_STATUS);
215 printk(KERN_DEBUG "HFC-PCI status(%x) after reset\n", val);
216 while (cnt < 50000) { /* max 50000 us */
217 udelay(5);
218 cnt += 5;
219 val = Read_hfc(hc, HFCPCI_STATUS);
220 if (!(val & 2))
221 break;
222 }
223 printk(KERN_DEBUG "HFC-PCI status(%x) after %dus\n", val, cnt);
224
225 hc->hw.fifo_en = 0x30; /* only D fifos enabled */
226
227 hc->hw.bswapped = 0; /* no exchange */
228 hc->hw.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER;
229 hc->hw.trm = HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */
230 hc->hw.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */
231 hc->hw.sctrl_r = 0;
232 hc->hw.sctrl_e = HFCPCI_AUTO_AWAKE; /* S/T Auto awake */
233 hc->hw.mst_m = 0;
234 if (test_bit(HFC_CFG_MASTER, &hc->cfg))
235 hc->hw.mst_m |= HFCPCI_MASTER; /* HFC Master Mode */
236 if (test_bit(HFC_CFG_NEG_F0, &hc->cfg))
237 hc->hw.mst_m |= HFCPCI_F0_NEGATIV;
238 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
239 Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
240 Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
241 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
242
243 hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC |
Joe Perches475be4d2012-02-19 19:52:38 -0800244 HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
Karsten Keil1700fe12008-07-26 18:55:28 +0200245 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
246
247 /* Clear already pending ints */
Karsten Keileac74af2009-05-22 11:04:56 +0000248 val = Read_hfc(hc, HFCPCI_INT_S1);
Karsten Keil1700fe12008-07-26 18:55:28 +0200249
250 /* set NT/TE mode */
251 hfcpci_setmode(hc);
252
253 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
254 Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
255
256 /*
257 * Init GCI/IOM2 in master mode
258 * Slots 0 and 1 are set for B-chan 1 and 2
259 * D- and monitor/CI channel are not enabled
260 * STIO1 is used as output for data, B1+B2 from ST->IOM+HFC
261 * STIO2 is used as data input, B1+B2 from IOM->ST
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300262 * ST B-channel send disabled -> continuous 1s
Karsten Keil1700fe12008-07-26 18:55:28 +0200263 * The IOM slots are always enabled
264 */
265 if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
266 /* set data flow directions: connect B1,B2: HFC to/from PCM */
267 hc->hw.conn = 0x09;
268 } else {
269 hc->hw.conn = 0x36; /* set data flow directions */
270 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
271 Write_hfc(hc, HFCPCI_B1_SSL, 0xC0);
272 Write_hfc(hc, HFCPCI_B2_SSL, 0xC1);
273 Write_hfc(hc, HFCPCI_B1_RSL, 0xC0);
274 Write_hfc(hc, HFCPCI_B2_RSL, 0xC1);
275 } else {
276 Write_hfc(hc, HFCPCI_B1_SSL, 0x80);
277 Write_hfc(hc, HFCPCI_B2_SSL, 0x81);
278 Write_hfc(hc, HFCPCI_B1_RSL, 0x80);
279 Write_hfc(hc, HFCPCI_B2_RSL, 0x81);
280 }
281 }
282 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
283 val = Read_hfc(hc, HFCPCI_INT_S2);
284}
285
286/*
287 * Timer function called when kernel timer expires
288 */
289static void
Kees Cook86cb30e2017-10-17 20:21:24 -0700290hfcpci_Timer(struct timer_list *t)
Karsten Keil1700fe12008-07-26 18:55:28 +0200291{
Kees Cook86cb30e2017-10-17 20:21:24 -0700292 struct hfc_pci *hc = from_timer(hc, t, hw.timer);
Karsten Keil1700fe12008-07-26 18:55:28 +0200293 hc->hw.timer.expires = jiffies + 75;
294 /* WD RESET */
295/*
296 * WriteReg(hc, HFCD_DATA, HFCD_CTMT, hc->hw.ctmt | 0x80);
297 * add_timer(&hc->hw.timer);
298 */
299}
300
301
302/*
303 * select a b-channel entry matching and active
304 */
305static struct bchannel *
306Sel_BCS(struct hfc_pci *hc, int channel)
307{
308 if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) &&
Joe Perches475be4d2012-02-19 19:52:38 -0800309 (hc->bch[0].nr & channel))
Karsten Keil1700fe12008-07-26 18:55:28 +0200310 return &hc->bch[0];
311 else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) &&
Joe Perches475be4d2012-02-19 19:52:38 -0800312 (hc->bch[1].nr & channel))
Karsten Keil1700fe12008-07-26 18:55:28 +0200313 return &hc->bch[1];
314 else
315 return NULL;
316}
317
318/*
319 * clear the desired B-channel rx fifo
320 */
321static void
322hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo)
323{
324 u_char fifo_state;
325 struct bzfifo *bzr;
326
327 if (fifo) {
328 bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
329 fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2RX;
330 } else {
331 bzr = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
332 fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1RX;
333 }
334 if (fifo_state)
335 hc->hw.fifo_en ^= fifo_state;
336 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
337 hc->hw.last_bfifo_cnt[fifo] = 0;
338 bzr->f1 = MAX_B_FRAMES;
339 bzr->f2 = bzr->f1; /* init F pointers to remain constant */
340 bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
341 bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16(
Joe Perches475be4d2012-02-19 19:52:38 -0800342 le16_to_cpu(bzr->za[MAX_B_FRAMES].z1));
Karsten Keil1700fe12008-07-26 18:55:28 +0200343 if (fifo_state)
344 hc->hw.fifo_en |= fifo_state;
345 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
346}
347
348/*
349 * clear the desired B-channel tx fifo
350 */
351static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
352{
353 u_char fifo_state;
354 struct bzfifo *bzt;
355
356 if (fifo) {
357 bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
358 fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B2TX;
359 } else {
360 bzt = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
361 fifo_state = hc->hw.fifo_en & HFCPCI_FIFOEN_B1TX;
362 }
363 if (fifo_state)
364 hc->hw.fifo_en ^= fifo_state;
365 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
366 if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
367 printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) "
Joe Perches475be4d2012-02-19 19:52:38 -0800368 "z1(%x) z2(%x) state(%x)\n",
369 fifo, bzt->f1, bzt->f2,
370 le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
371 le16_to_cpu(bzt->za[MAX_B_FRAMES].z2),
372 fifo_state);
Karsten Keil1700fe12008-07-26 18:55:28 +0200373 bzt->f2 = MAX_B_FRAMES;
374 bzt->f1 = bzt->f2; /* init F pointers to remain constant */
375 bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
Harvey Harrisonf11d32d2008-09-22 19:16:20 -0700376 bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2);
Karsten Keil1700fe12008-07-26 18:55:28 +0200377 if (fifo_state)
378 hc->hw.fifo_en |= fifo_state;
379 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
380 if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
381 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800382 "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n",
383 fifo, bzt->f1, bzt->f2,
384 le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
385 le16_to_cpu(bzt->za[MAX_B_FRAMES].z2));
Karsten Keil1700fe12008-07-26 18:55:28 +0200386}
387
388/*
389 * read a complete B-frame out of the buffer
390 */
391static void
392hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
Joe Perches475be4d2012-02-19 19:52:38 -0800393 u_char *bdata, int count)
Karsten Keil1700fe12008-07-26 18:55:28 +0200394{
395 u_char *ptr, *ptr1, new_f2;
David S. Millera719e0a2011-04-17 16:34:50 -0700396 int maxlen, new_z2;
Karsten Keil1700fe12008-07-26 18:55:28 +0200397 struct zt *zp;
398
399 if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
400 printk(KERN_DEBUG "hfcpci_empty_fifo\n");
401 zp = &bz->za[bz->f2]; /* point to Z-Regs */
402 new_z2 = le16_to_cpu(zp->z2) + count; /* new position in fifo */
403 if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
404 new_z2 -= B_FIFO_SIZE; /* buffer wrap */
405 new_f2 = (bz->f2 + 1) & MAX_B_FRAMES;
406 if ((count > MAX_DATA_SIZE + 3) || (count < 4) ||
407 (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) {
408 if (bch->debug & DEBUG_HW)
409 printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet "
Joe Perches475be4d2012-02-19 19:52:38 -0800410 "invalid length %d or crc\n", count);
Karsten Keil1700fe12008-07-26 18:55:28 +0200411#ifdef ERROR_STATISTIC
412 bch->err_inv++;
413#endif
414 bz->za[new_f2].z2 = cpu_to_le16(new_z2);
415 bz->f2 = new_f2; /* next buffer */
416 } else {
417 bch->rx_skb = mI_alloc_skb(count - 3, GFP_ATOMIC);
418 if (!bch->rx_skb) {
419 printk(KERN_WARNING "HFCPCI: receive out of memory\n");
420 return;
421 }
Karsten Keil1700fe12008-07-26 18:55:28 +0200422 count -= 3;
423 ptr = skb_put(bch->rx_skb, count);
424
425 if (le16_to_cpu(zp->z2) + count <= B_FIFO_SIZE + B_SUB_VAL)
426 maxlen = count; /* complete transfer */
427 else
428 maxlen = B_FIFO_SIZE + B_SUB_VAL -
Joe Perches475be4d2012-02-19 19:52:38 -0800429 le16_to_cpu(zp->z2); /* maximum */
Karsten Keil1700fe12008-07-26 18:55:28 +0200430
431 ptr1 = bdata + (le16_to_cpu(zp->z2) - B_SUB_VAL);
Joe Perches475be4d2012-02-19 19:52:38 -0800432 /* start of data */
Karsten Keil1700fe12008-07-26 18:55:28 +0200433 memcpy(ptr, ptr1, maxlen); /* copy data */
434 count -= maxlen;
435
436 if (count) { /* rest remaining */
437 ptr += maxlen;
438 ptr1 = bdata; /* start of buffer */
439 memcpy(ptr, ptr1, count); /* rest */
440 }
441 bz->za[new_f2].z2 = cpu_to_le16(new_z2);
442 bz->f2 = new_f2; /* next buffer */
Karsten Keil034005a2012-05-15 23:51:06 +0000443 recv_Bchannel(bch, MISDN_ID_ANY, false);
Karsten Keil1700fe12008-07-26 18:55:28 +0200444 }
445}
446
447/*
448 * D-channel receive procedure
449 */
450static int
451receive_dmsg(struct hfc_pci *hc)
452{
453 struct dchannel *dch = &hc->dch;
454 int maxlen;
455 int rcnt, total;
456 int count = 5;
457 u_char *ptr, *ptr1;
458 struct dfifo *df;
459 struct zt *zp;
460
461 df = &((union fifo_area *)(hc->hw.fifos))->d_chan.d_rx;
462 while (((df->f1 & D_FREG_MASK) != (df->f2 & D_FREG_MASK)) && count--) {
463 zp = &df->za[df->f2 & D_FREG_MASK];
464 rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
465 if (rcnt < 0)
466 rcnt += D_FIFO_SIZE;
467 rcnt++;
468 if (dch->debug & DEBUG_HW_DCHANNEL)
469 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800470 "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n",
471 df->f1, df->f2,
472 le16_to_cpu(zp->z1),
473 le16_to_cpu(zp->z2),
474 rcnt);
Karsten Keil1700fe12008-07-26 18:55:28 +0200475
476 if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) ||
477 (df->data[le16_to_cpu(zp->z1)])) {
478 if (dch->debug & DEBUG_HW)
479 printk(KERN_DEBUG
Masanari Iida465b1672012-11-09 05:02:49 +0000480 "empty_fifo hfcpci packet inv. len "
Joe Perches475be4d2012-02-19 19:52:38 -0800481 "%d or crc %d\n",
482 rcnt,
483 df->data[le16_to_cpu(zp->z1)]);
Karsten Keil1700fe12008-07-26 18:55:28 +0200484#ifdef ERROR_STATISTIC
485 cs->err_rx++;
486#endif
487 df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
Joe Perches475be4d2012-02-19 19:52:38 -0800488 (MAX_D_FRAMES + 1); /* next buffer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200489 df->za[df->f2 & D_FREG_MASK].z2 =
Joe Perches475be4d2012-02-19 19:52:38 -0800490 cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
491 (D_FIFO_SIZE - 1));
Karsten Keil1700fe12008-07-26 18:55:28 +0200492 } else {
493 dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
494 if (!dch->rx_skb) {
495 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -0800496 "HFC-PCI: D receive out of memory\n");
Karsten Keil1700fe12008-07-26 18:55:28 +0200497 break;
498 }
499 total = rcnt;
500 rcnt -= 3;
501 ptr = skb_put(dch->rx_skb, rcnt);
502
503 if (le16_to_cpu(zp->z2) + rcnt <= D_FIFO_SIZE)
504 maxlen = rcnt; /* complete transfer */
505 else
506 maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2);
Joe Perches475be4d2012-02-19 19:52:38 -0800507 /* maximum */
Karsten Keil1700fe12008-07-26 18:55:28 +0200508
509 ptr1 = df->data + le16_to_cpu(zp->z2);
Joe Perches475be4d2012-02-19 19:52:38 -0800510 /* start of data */
Karsten Keil1700fe12008-07-26 18:55:28 +0200511 memcpy(ptr, ptr1, maxlen); /* copy data */
512 rcnt -= maxlen;
513
514 if (rcnt) { /* rest remaining */
515 ptr += maxlen;
516 ptr1 = df->data; /* start of buffer */
517 memcpy(ptr, ptr1, rcnt); /* rest */
518 }
519 df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
Joe Perches475be4d2012-02-19 19:52:38 -0800520 (MAX_D_FRAMES + 1); /* next buffer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200521 df->za[df->f2 & D_FREG_MASK].z2 = cpu_to_le16((
Joe Perches475be4d2012-02-19 19:52:38 -0800522 le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1));
Karsten Keil1700fe12008-07-26 18:55:28 +0200523 recv_Dchannel(dch);
524 }
525 }
526 return 1;
527}
528
529/*
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200530 * check for transparent receive data and read max one 'poll' size if avail
Karsten Keil1700fe12008-07-26 18:55:28 +0200531 */
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200532static void
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000533hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
Joe Perches475be4d2012-02-19 19:52:38 -0800534 struct bzfifo *txbz, u_char *bdata)
Karsten Keil1700fe12008-07-26 18:55:28 +0200535{
Joe Perches475be4d2012-02-19 19:52:38 -0800536 __le16 *z1r, *z2r, *z1t, *z2t;
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000537 int new_z2, fcnt_rx, fcnt_tx, maxlen;
538 u_char *ptr, *ptr1;
Karsten Keil1700fe12008-07-26 18:55:28 +0200539
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000540 z1r = &rxbz->za[MAX_B_FRAMES].z1; /* pointer to z reg */
Karsten Keil1700fe12008-07-26 18:55:28 +0200541 z2r = z1r + 1;
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000542 z1t = &txbz->za[MAX_B_FRAMES].z1;
543 z2t = z1t + 1;
Karsten Keil1700fe12008-07-26 18:55:28 +0200544
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000545 fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
546 if (!fcnt_rx)
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200547 return; /* no data avail */
Karsten Keil1700fe12008-07-26 18:55:28 +0200548
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000549 if (fcnt_rx <= 0)
550 fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */
551 new_z2 = le16_to_cpu(*z2r) + fcnt_rx; /* new position in fifo */
Karsten Keil1700fe12008-07-26 18:55:28 +0200552 if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
553 new_z2 -= B_FIFO_SIZE; /* buffer wrap */
554
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000555 fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
556 if (fcnt_tx <= 0)
557 fcnt_tx += B_FIFO_SIZE;
Joe Perches475be4d2012-02-19 19:52:38 -0800558 /* fcnt_tx contains available bytes in tx-fifo */
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000559 fcnt_tx = B_FIFO_SIZE - fcnt_tx;
Joe Perches475be4d2012-02-19 19:52:38 -0800560 /* remaining bytes to send (bytes in tx-fifo) */
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000561
Karsten Keilc27b46e2012-05-15 23:51:08 +0000562 if (test_bit(FLG_RX_OFF, &bch->Flags)) {
563 bch->dropcnt += fcnt_rx;
564 *z2r = cpu_to_le16(new_z2);
565 return;
566 }
Karsten Keil7206e652012-05-15 23:51:05 +0000567 maxlen = bchannel_get_rxbuf(bch, fcnt_rx);
568 if (maxlen < 0) {
569 pr_warning("B%d: No bufferspace for %d bytes\n",
570 bch->nr, fcnt_rx);
571 } else {
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000572 ptr = skb_put(bch->rx_skb, fcnt_rx);
573 if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL)
574 maxlen = fcnt_rx; /* complete transfer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200575 else
576 maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
Joe Perches475be4d2012-02-19 19:52:38 -0800577 /* maximum */
Karsten Keil1700fe12008-07-26 18:55:28 +0200578
579 ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
Joe Perches475be4d2012-02-19 19:52:38 -0800580 /* start of data */
Karsten Keil1700fe12008-07-26 18:55:28 +0200581 memcpy(ptr, ptr1, maxlen); /* copy data */
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000582 fcnt_rx -= maxlen;
Karsten Keil1700fe12008-07-26 18:55:28 +0200583
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000584 if (fcnt_rx) { /* rest remaining */
Karsten Keil1700fe12008-07-26 18:55:28 +0200585 ptr += maxlen;
586 ptr1 = bdata; /* start of buffer */
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000587 memcpy(ptr, ptr1, fcnt_rx); /* rest */
Karsten Keil1700fe12008-07-26 18:55:28 +0200588 }
Karsten Keil034005a2012-05-15 23:51:06 +0000589 recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */
Karsten Keil7206e652012-05-15 23:51:05 +0000590 }
Karsten Keil1700fe12008-07-26 18:55:28 +0200591 *z2r = cpu_to_le16(new_z2); /* new position */
Karsten Keil1700fe12008-07-26 18:55:28 +0200592}
593
594/*
595 * B-channel main receive routine
596 */
Harvey Harrison1532dcb2008-09-22 19:16:51 -0700597static void
Karsten Keil1700fe12008-07-26 18:55:28 +0200598main_rec_hfcpci(struct bchannel *bch)
599{
600 struct hfc_pci *hc = bch->hw;
601 int rcnt, real_fifo;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200602 int receive = 0, count = 5;
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000603 struct bzfifo *txbz, *rxbz;
Karsten Keil1700fe12008-07-26 18:55:28 +0200604 u_char *bdata;
605 struct zt *zp;
606
Karsten Keil1700fe12008-07-26 18:55:28 +0200607 if ((bch->nr & 2) && (!hc->hw.bswapped)) {
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000608 rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
609 txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
Karsten Keil1700fe12008-07-26 18:55:28 +0200610 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
611 real_fifo = 1;
612 } else {
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000613 rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
614 txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
Karsten Keil1700fe12008-07-26 18:55:28 +0200615 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
616 real_fifo = 0;
617 }
618Begin:
619 count--;
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000620 if (rxbz->f1 != rxbz->f2) {
Karsten Keil1700fe12008-07-26 18:55:28 +0200621 if (bch->debug & DEBUG_HW_BCHANNEL)
622 printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800623 bch->nr, rxbz->f1, rxbz->f2);
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000624 zp = &rxbz->za[rxbz->f2];
Karsten Keil1700fe12008-07-26 18:55:28 +0200625
626 rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
627 if (rcnt < 0)
628 rcnt += B_FIFO_SIZE;
629 rcnt++;
630 if (bch->debug & DEBUG_HW_BCHANNEL)
631 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800632 "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
633 bch->nr, le16_to_cpu(zp->z1),
634 le16_to_cpu(zp->z2), rcnt);
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000635 hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
636 rcnt = rxbz->f1 - rxbz->f2;
Karsten Keil1700fe12008-07-26 18:55:28 +0200637 if (rcnt < 0)
638 rcnt += MAX_B_FRAMES + 1;
639 if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
640 rcnt = 0;
641 hfcpci_clear_fifo_rx(hc, real_fifo);
642 }
643 hc->hw.last_bfifo_cnt[real_fifo] = rcnt;
644 if (rcnt > 1)
645 receive = 1;
646 else
647 receive = 0;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200648 } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
Andreas Eversberg7cfa1532009-05-22 11:04:46 +0000649 hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200650 return;
651 } else
Karsten Keil1700fe12008-07-26 18:55:28 +0200652 receive = 0;
653 if (count && receive)
654 goto Begin;
655
656}
657
658/*
659 * D-channel send routine
660 */
661static void
662hfcpci_fill_dfifo(struct hfc_pci *hc)
663{
664 struct dchannel *dch = &hc->dch;
665 int fcnt;
666 int count, new_z1, maxlen;
667 struct dfifo *df;
668 u_char *src, *dst, new_f1;
669
670 if ((dch->debug & DEBUG_HW_DCHANNEL) && !(dch->debug & DEBUG_HW_DFIFO))
671 printk(KERN_DEBUG "%s\n", __func__);
672
673 if (!dch->tx_skb)
674 return;
675 count = dch->tx_skb->len - dch->tx_idx;
676 if (count <= 0)
677 return;
678 df = &((union fifo_area *) (hc->hw.fifos))->d_chan.d_tx;
679
680 if (dch->debug & DEBUG_HW_DFIFO)
681 printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__,
Joe Perches475be4d2012-02-19 19:52:38 -0800682 df->f1, df->f2,
683 le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1));
Karsten Keil1700fe12008-07-26 18:55:28 +0200684 fcnt = df->f1 - df->f2; /* frame count actually buffered */
685 if (fcnt < 0)
686 fcnt += (MAX_D_FRAMES + 1); /* if wrap around */
687 if (fcnt > (MAX_D_FRAMES - 1)) {
688 if (dch->debug & DEBUG_HW_DCHANNEL)
689 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800690 "hfcpci_fill_Dfifo more as 14 frames\n");
Karsten Keil1700fe12008-07-26 18:55:28 +0200691#ifdef ERROR_STATISTIC
692 cs->err_tx++;
693#endif
694 return;
695 }
696 /* now determine free bytes in FIFO buffer */
697 maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) -
Joe Perches475be4d2012-02-19 19:52:38 -0800698 le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1;
Karsten Keil1700fe12008-07-26 18:55:28 +0200699 if (maxlen <= 0)
700 maxlen += D_FIFO_SIZE; /* count now contains available bytes */
701
702 if (dch->debug & DEBUG_HW_DCHANNEL)
703 printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800704 count, maxlen);
Karsten Keil1700fe12008-07-26 18:55:28 +0200705 if (count > maxlen) {
706 if (dch->debug & DEBUG_HW_DCHANNEL)
707 printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n");
708 return;
709 }
710 new_z1 = (le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) + count) &
Joe Perches475be4d2012-02-19 19:52:38 -0800711 (D_FIFO_SIZE - 1);
Karsten Keil1700fe12008-07-26 18:55:28 +0200712 new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1);
713 src = dch->tx_skb->data + dch->tx_idx; /* source pointer */
714 dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
715 maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
Joe Perches475be4d2012-02-19 19:52:38 -0800716 /* end fifo */
Karsten Keil1700fe12008-07-26 18:55:28 +0200717 if (maxlen > count)
718 maxlen = count; /* limit size */
719 memcpy(dst, src, maxlen); /* first copy */
720
721 count -= maxlen; /* remaining bytes */
722 if (count) {
723 dst = df->data; /* start of buffer */
724 src += maxlen; /* new position */
725 memcpy(dst, src, count);
726 }
727 df->za[new_f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
Joe Perches475be4d2012-02-19 19:52:38 -0800728 /* for next buffer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200729 df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
Joe Perches475be4d2012-02-19 19:52:38 -0800730 /* new pos actual buffer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200731 df->f1 = new_f1; /* next frame */
732 dch->tx_idx = dch->tx_skb->len;
733}
734
735/*
736 * B-channel send routine
737 */
738static void
739hfcpci_fill_fifo(struct bchannel *bch)
740{
Joe Perches475be4d2012-02-19 19:52:38 -0800741 struct hfc_pci *hc = bch->hw;
Karsten Keil1700fe12008-07-26 18:55:28 +0200742 int maxlen, fcnt;
743 int count, new_z1;
744 struct bzfifo *bz;
745 u_char *bdata;
746 u_char new_f1, *src, *dst;
Harvey Harrisonf11d32d2008-09-22 19:16:20 -0700747 __le16 *z1t, *z2t;
Karsten Keil1700fe12008-07-26 18:55:28 +0200748
749 if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
750 printk(KERN_DEBUG "%s\n", __func__);
Karsten Keil6d1ee482012-05-15 23:51:07 +0000751 if ((!bch->tx_skb) || bch->tx_skb->len == 0) {
752 if (!test_bit(FLG_FILLEMPTY, &bch->Flags) &&
753 !test_bit(FLG_TRANSPARENT, &bch->Flags))
754 return;
755 count = HFCPCI_FILLEMPTY;
756 } else {
757 count = bch->tx_skb->len - bch->tx_idx;
758 }
Karsten Keil1700fe12008-07-26 18:55:28 +0200759 if ((bch->nr & 2) && (!hc->hw.bswapped)) {
760 bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
761 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b2;
762 } else {
763 bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
764 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.txdat_b1;
765 }
766
767 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
768 z1t = &bz->za[MAX_B_FRAMES].z1;
769 z2t = z1t + 1;
770 if (bch->debug & DEBUG_HW_BCHANNEL)
771 printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) "
Joe Perches475be4d2012-02-19 19:52:38 -0800772 "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count,
773 le16_to_cpu(*z1t), le16_to_cpu(*z2t));
Karsten Keil1700fe12008-07-26 18:55:28 +0200774 fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
775 if (fcnt <= 0)
776 fcnt += B_FIFO_SIZE;
Karsten Keil6d1ee482012-05-15 23:51:07 +0000777 if (test_bit(FLG_FILLEMPTY, &bch->Flags)) {
778 /* fcnt contains available bytes in fifo */
779 if (count > fcnt)
780 count = fcnt;
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200781 new_z1 = le16_to_cpu(*z1t) + count;
Joe Perches475be4d2012-02-19 19:52:38 -0800782 /* new buffer Position */
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200783 if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
784 new_z1 -= B_FIFO_SIZE; /* buffer wrap */
785 dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
786 maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
Joe Perches475be4d2012-02-19 19:52:38 -0800787 /* end of fifo */
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200788 if (bch->debug & DEBUG_HW_BFIFO)
789 printk(KERN_DEBUG "hfcpci_FFt fillempty "
Joe Perches475be4d2012-02-19 19:52:38 -0800790 "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
791 fcnt, maxlen, new_z1, dst);
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200792 if (maxlen > count)
Joe Perches475be4d2012-02-19 19:52:38 -0800793 maxlen = count; /* limit size */
Karsten Keil6d1ee482012-05-15 23:51:07 +0000794 memset(dst, bch->fill[0], maxlen); /* first copy */
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200795 count -= maxlen; /* remaining bytes */
796 if (count) {
797 dst = bdata; /* start of buffer */
Karsten Keil6d1ee482012-05-15 23:51:07 +0000798 memset(dst, bch->fill[0], count);
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200799 }
800 *z1t = cpu_to_le16(new_z1); /* now send data */
Karsten Keil6d1ee482012-05-15 23:51:07 +0000801 return;
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200802 }
Karsten Keil6d1ee482012-05-15 23:51:07 +0000803 /* fcnt contains available bytes in fifo */
804 fcnt = B_FIFO_SIZE - fcnt;
805 /* remaining bytes to send (bytes in fifo) */
Andreas Eversberg8dd2f362008-08-02 22:51:52 +0200806
Joe Perches475be4d2012-02-19 19:52:38 -0800807 next_t_frame:
Karsten Keil1700fe12008-07-26 18:55:28 +0200808 count = bch->tx_skb->len - bch->tx_idx;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +0200809 /* maximum fill shall be poll*2 */
810 if (count > (poll << 1) - fcnt)
811 count = (poll << 1) - fcnt;
Karsten Keil1700fe12008-07-26 18:55:28 +0200812 if (count <= 0)
813 return;
814 /* data is suitable for fifo */
815 new_z1 = le16_to_cpu(*z1t) + count;
Joe Perches475be4d2012-02-19 19:52:38 -0800816 /* new buffer Position */
Karsten Keil1700fe12008-07-26 18:55:28 +0200817 if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
818 new_z1 -= B_FIFO_SIZE; /* buffer wrap */
819 src = bch->tx_skb->data + bch->tx_idx;
Joe Perches475be4d2012-02-19 19:52:38 -0800820 /* source pointer */
Karsten Keil1700fe12008-07-26 18:55:28 +0200821 dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
822 maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
Joe Perches475be4d2012-02-19 19:52:38 -0800823 /* end of fifo */
Karsten Keil1700fe12008-07-26 18:55:28 +0200824 if (bch->debug & DEBUG_HW_BFIFO)
825 printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) "
Joe Perches475be4d2012-02-19 19:52:38 -0800826 "maxl(%d) nz1(%x) dst(%p)\n",
827 fcnt, maxlen, new_z1, dst);
Karsten Keil1700fe12008-07-26 18:55:28 +0200828 fcnt += count;
829 bch->tx_idx += count;
830 if (maxlen > count)
831 maxlen = count; /* limit size */
832 memcpy(dst, src, maxlen); /* first copy */
833 count -= maxlen; /* remaining bytes */
834 if (count) {
835 dst = bdata; /* start of buffer */
836 src += maxlen; /* new position */
837 memcpy(dst, src, count);
838 }
839 *z1t = cpu_to_le16(new_z1); /* now send data */
840 if (bch->tx_idx < bch->tx_skb->len)
841 return;
Karsten Keil1700fe12008-07-26 18:55:28 +0200842 dev_kfree_skb(bch->tx_skb);
843 if (get_next_bframe(bch))
844 goto next_t_frame;
845 return;
846 }
847 if (bch->debug & DEBUG_HW_BCHANNEL)
848 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800849 "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n",
850 __func__, bch->nr, bz->f1, bz->f2,
851 bz->za[bz->f1].z1);
Karsten Keil1700fe12008-07-26 18:55:28 +0200852 fcnt = bz->f1 - bz->f2; /* frame count actually buffered */
853 if (fcnt < 0)
854 fcnt += (MAX_B_FRAMES + 1); /* if wrap around */
855 if (fcnt > (MAX_B_FRAMES - 1)) {
856 if (bch->debug & DEBUG_HW_BCHANNEL)
857 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -0800858 "hfcpci_fill_Bfifo more as 14 frames\n");
Karsten Keil1700fe12008-07-26 18:55:28 +0200859 return;
860 }
861 /* now determine free bytes in FIFO buffer */
862 maxlen = le16_to_cpu(bz->za[bz->f2].z2) -
Joe Perches475be4d2012-02-19 19:52:38 -0800863 le16_to_cpu(bz->za[bz->f1].z1) - 1;
Karsten Keil1700fe12008-07-26 18:55:28 +0200864 if (maxlen <= 0)
865 maxlen += B_FIFO_SIZE; /* count now contains available bytes */
866
867 if (bch->debug & DEBUG_HW_BCHANNEL)
868 printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800869 bch->nr, count, maxlen);
Karsten Keil1700fe12008-07-26 18:55:28 +0200870
871 if (maxlen < count) {
872 if (bch->debug & DEBUG_HW_BCHANNEL)
873 printk(KERN_DEBUG "hfcpci_fill_fifo no fifo mem\n");
874 return;
875 }
876 new_z1 = le16_to_cpu(bz->za[bz->f1].z1) + count;
Joe Perches475be4d2012-02-19 19:52:38 -0800877 /* new buffer Position */
Karsten Keil1700fe12008-07-26 18:55:28 +0200878 if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
879 new_z1 -= B_FIFO_SIZE; /* buffer wrap */
880
881 new_f1 = ((bz->f1 + 1) & MAX_B_FRAMES);
882 src = bch->tx_skb->data + bch->tx_idx; /* source pointer */
883 dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL);
884 maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1);
Joe Perches475be4d2012-02-19 19:52:38 -0800885 /* end fifo */
Karsten Keil1700fe12008-07-26 18:55:28 +0200886 if (maxlen > count)
887 maxlen = count; /* limit size */
888 memcpy(dst, src, maxlen); /* first copy */
889
890 count -= maxlen; /* remaining bytes */
891 if (count) {
892 dst = bdata; /* start of buffer */
893 src += maxlen; /* new position */
894 memcpy(dst, src, count);
895 }
896 bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */
897 bz->f1 = new_f1; /* next frame */
898 dev_kfree_skb(bch->tx_skb);
899 get_next_bframe(bch);
900}
901
902
903
904/*
905 * handle L1 state changes TE
906 */
907
908static void
909ph_state_te(struct dchannel *dch)
910{
911 if (dch->debug)
912 printk(KERN_DEBUG "%s: TE newstate %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800913 __func__, dch->state);
Karsten Keil1700fe12008-07-26 18:55:28 +0200914 switch (dch->state) {
915 case 0:
916 l1_event(dch->l1, HW_RESET_IND);
917 break;
918 case 3:
919 l1_event(dch->l1, HW_DEACT_IND);
920 break;
921 case 5:
922 case 8:
923 l1_event(dch->l1, ANYSIGNAL);
924 break;
925 case 6:
926 l1_event(dch->l1, INFO2);
927 break;
928 case 7:
929 l1_event(dch->l1, INFO4_P8);
930 break;
931 }
932}
933
934/*
935 * handle L1 state changes NT
936 */
937
938static void
939handle_nt_timer3(struct dchannel *dch) {
940 struct hfc_pci *hc = dch->hw;
941
942 test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
943 hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
944 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
945 hc->hw.nt_timer = 0;
946 test_and_set_bit(FLG_ACTIVE, &dch->Flags);
947 if (test_bit(HFC_CFG_MASTER, &hc->cfg))
948 hc->hw.mst_m |= HFCPCI_MASTER;
949 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
950 _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
Joe Perches475be4d2012-02-19 19:52:38 -0800951 MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
Karsten Keil1700fe12008-07-26 18:55:28 +0200952}
953
954static void
955ph_state_nt(struct dchannel *dch)
956{
957 struct hfc_pci *hc = dch->hw;
958
959 if (dch->debug)
960 printk(KERN_DEBUG "%s: NT newstate %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800961 __func__, dch->state);
Karsten Keil1700fe12008-07-26 18:55:28 +0200962 switch (dch->state) {
963 case 2:
964 if (hc->hw.nt_timer < 0) {
965 hc->hw.nt_timer = 0;
966 test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
967 test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
968 hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
969 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
970 /* Clear already pending ints */
David S. Millera719e0a2011-04-17 16:34:50 -0700971 (void) Read_hfc(hc, HFCPCI_INT_S1);
Karsten Keil1700fe12008-07-26 18:55:28 +0200972 Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
973 udelay(10);
974 Write_hfc(hc, HFCPCI_STATES, 4);
975 dch->state = 4;
976 } else if (hc->hw.nt_timer == 0) {
977 hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
978 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
979 hc->hw.nt_timer = NT_T1_COUNT;
980 hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
981 hc->hw.ctmt |= HFCPCI_TIM3_125;
982 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
Joe Perches475be4d2012-02-19 19:52:38 -0800983 HFCPCI_CLTIMER);
Karsten Keil1700fe12008-07-26 18:55:28 +0200984 test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
985 test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags);
986 /* allow G2 -> G3 transition */
987 Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
988 } else {
989 Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);
990 }
991 break;
992 case 1:
993 hc->hw.nt_timer = 0;
994 test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
995 test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
996 hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
997 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
998 test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
999 hc->hw.mst_m &= ~HFCPCI_MASTER;
1000 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1001 test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
1002 _queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
Joe Perches475be4d2012-02-19 19:52:38 -08001003 MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001004 break;
1005 case 4:
1006 hc->hw.nt_timer = 0;
1007 test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
1008 test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
1009 hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
1010 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
1011 break;
1012 case 3:
1013 if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) {
1014 if (!test_and_clear_bit(FLG_L2_ACTIVATED,
Joe Perches475be4d2012-02-19 19:52:38 -08001015 &dch->Flags)) {
Karsten Keil1700fe12008-07-26 18:55:28 +02001016 handle_nt_timer3(dch);
1017 break;
1018 }
1019 test_and_clear_bit(FLG_HFC_TIMER_T1, &dch->Flags);
1020 hc->hw.int_m1 |= HFCPCI_INTS_TIMER;
1021 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
1022 hc->hw.nt_timer = NT_T3_COUNT;
1023 hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
1024 hc->hw.ctmt |= HFCPCI_TIM3_125;
1025 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
Joe Perches475be4d2012-02-19 19:52:38 -08001026 HFCPCI_CLTIMER);
Karsten Keil1700fe12008-07-26 18:55:28 +02001027 }
1028 break;
1029 }
1030}
1031
1032static void
1033ph_state(struct dchannel *dch)
1034{
1035 struct hfc_pci *hc = dch->hw;
1036
1037 if (hc->hw.protocol == ISDN_P_NT_S0) {
1038 if (test_bit(FLG_HFC_TIMER_T3, &dch->Flags) &&
1039 hc->hw.nt_timer < 0)
1040 handle_nt_timer3(dch);
1041 else
1042 ph_state_nt(dch);
1043 } else
1044 ph_state_te(dch);
1045}
1046
1047/*
1048 * Layer 1 callback function
1049 */
1050static int
1051hfc_l1callback(struct dchannel *dch, u_int cmd)
1052{
1053 struct hfc_pci *hc = dch->hw;
1054
1055 switch (cmd) {
1056 case INFO3_P8:
1057 case INFO3_P10:
1058 if (test_bit(HFC_CFG_MASTER, &hc->cfg))
1059 hc->hw.mst_m |= HFCPCI_MASTER;
1060 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1061 break;
1062 case HW_RESET_REQ:
1063 Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3);
1064 /* HFC ST 3 */
1065 udelay(6);
1066 Write_hfc(hc, HFCPCI_STATES, 3); /* HFC ST 2 */
1067 if (test_bit(HFC_CFG_MASTER, &hc->cfg))
1068 hc->hw.mst_m |= HFCPCI_MASTER;
1069 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1070 Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
Joe Perches475be4d2012-02-19 19:52:38 -08001071 HFCPCI_DO_ACTION);
Karsten Keil1700fe12008-07-26 18:55:28 +02001072 l1_event(dch->l1, HW_POWERUP_IND);
1073 break;
1074 case HW_DEACT_REQ:
1075 hc->hw.mst_m &= ~HFCPCI_MASTER;
1076 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1077 skb_queue_purge(&dch->squeue);
1078 if (dch->tx_skb) {
1079 dev_kfree_skb(dch->tx_skb);
1080 dch->tx_skb = NULL;
1081 }
1082 dch->tx_idx = 0;
1083 if (dch->rx_skb) {
1084 dev_kfree_skb(dch->rx_skb);
1085 dch->rx_skb = NULL;
1086 }
1087 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
1088 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
1089 del_timer(&dch->timer);
1090 break;
1091 case HW_POWERUP_REQ:
1092 Write_hfc(hc, HFCPCI_STATES, HFCPCI_DO_ACTION);
1093 break;
1094 case PH_ACTIVATE_IND:
1095 test_and_set_bit(FLG_ACTIVE, &dch->Flags);
1096 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
Joe Perches475be4d2012-02-19 19:52:38 -08001097 GFP_ATOMIC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001098 break;
1099 case PH_DEACTIVATE_IND:
1100 test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
1101 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
Joe Perches475be4d2012-02-19 19:52:38 -08001102 GFP_ATOMIC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001103 break;
1104 default:
1105 if (dch->debug & DEBUG_HW)
1106 printk(KERN_DEBUG "%s: unknown command %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001107 __func__, cmd);
Karsten Keil1700fe12008-07-26 18:55:28 +02001108 return -1;
1109 }
1110 return 0;
1111}
1112
1113/*
1114 * Interrupt handler
1115 */
1116static inline void
1117tx_birq(struct bchannel *bch)
1118{
1119 if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
1120 hfcpci_fill_fifo(bch);
1121 else {
1122 if (bch->tx_skb)
1123 dev_kfree_skb(bch->tx_skb);
1124 if (get_next_bframe(bch))
1125 hfcpci_fill_fifo(bch);
1126 }
1127}
1128
1129static inline void
1130tx_dirq(struct dchannel *dch)
1131{
1132 if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len)
1133 hfcpci_fill_dfifo(dch->hw);
1134 else {
1135 if (dch->tx_skb)
1136 dev_kfree_skb(dch->tx_skb);
1137 if (get_next_dframe(dch))
1138 hfcpci_fill_dfifo(dch->hw);
1139 }
1140}
1141
1142static irqreturn_t
1143hfcpci_int(int intno, void *dev_id)
1144{
1145 struct hfc_pci *hc = dev_id;
1146 u_char exval;
1147 struct bchannel *bch;
1148 u_char val, stat;
1149
1150 spin_lock(&hc->lock);
1151 if (!(hc->hw.int_m2 & 0x08)) {
1152 spin_unlock(&hc->lock);
1153 return IRQ_NONE; /* not initialised */
1154 }
1155 stat = Read_hfc(hc, HFCPCI_STATUS);
1156 if (HFCPCI_ANYINT & stat) {
1157 val = Read_hfc(hc, HFCPCI_INT_S1);
1158 if (hc->dch.debug & DEBUG_HW_DCHANNEL)
1159 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -08001160 "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val);
Karsten Keil1700fe12008-07-26 18:55:28 +02001161 } else {
1162 /* shared */
1163 spin_unlock(&hc->lock);
1164 return IRQ_NONE;
1165 }
1166 hc->irqcnt++;
1167
1168 if (hc->dch.debug & DEBUG_HW_DCHANNEL)
1169 printk(KERN_DEBUG "HFC-PCI irq %x\n", val);
1170 val &= hc->hw.int_m1;
1171 if (val & 0x40) { /* state machine irq */
1172 exval = Read_hfc(hc, HFCPCI_STATES) & 0xf;
1173 if (hc->dch.debug & DEBUG_HW_DCHANNEL)
1174 printk(KERN_DEBUG "ph_state chg %d->%d\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001175 hc->dch.state, exval);
Karsten Keil1700fe12008-07-26 18:55:28 +02001176 hc->dch.state = exval;
1177 schedule_event(&hc->dch, FLG_PHCHANGE);
1178 val &= ~0x40;
1179 }
1180 if (val & 0x80) { /* timer irq */
1181 if (hc->hw.protocol == ISDN_P_NT_S0) {
1182 if ((--hc->hw.nt_timer) < 0)
1183 schedule_event(&hc->dch, FLG_PHCHANGE);
1184 }
1185 val &= ~0x80;
1186 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER);
1187 }
Joe Perches475be4d2012-02-19 19:52:38 -08001188 if (val & 0x08) { /* B1 rx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001189 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
1190 if (bch)
1191 main_rec_hfcpci(bch);
1192 else if (hc->dch.debug)
1193 printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n");
1194 }
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001195 if (val & 0x10) { /* B2 rx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001196 bch = Sel_BCS(hc, 2);
1197 if (bch)
1198 main_rec_hfcpci(bch);
1199 else if (hc->dch.debug)
1200 printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n");
1201 }
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001202 if (val & 0x01) { /* B1 tx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001203 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
1204 if (bch)
1205 tx_birq(bch);
1206 else if (hc->dch.debug)
1207 printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n");
1208 }
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001209 if (val & 0x02) { /* B2 tx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001210 bch = Sel_BCS(hc, 2);
1211 if (bch)
1212 tx_birq(bch);
1213 else if (hc->dch.debug)
1214 printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n");
1215 }
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001216 if (val & 0x20) /* D rx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001217 receive_dmsg(hc);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001218 if (val & 0x04) { /* D tx */
Karsten Keil1700fe12008-07-26 18:55:28 +02001219 if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags))
1220 del_timer(&hc->dch.timer);
1221 tx_dirq(&hc->dch);
1222 }
1223 spin_unlock(&hc->lock);
1224 return IRQ_HANDLED;
1225}
1226
1227/*
1228 * timer callback for D-chan busy resolution. Currently no function
1229 */
1230static void
Kees Cooke99e88a2017-10-16 14:43:17 -07001231hfcpci_dbusy_timer(struct timer_list *t)
Karsten Keil1700fe12008-07-26 18:55:28 +02001232{
1233}
1234
1235/*
1236 * activate/deactivate hardware for selected channels and mode
1237 */
1238static int
1239mode_hfcpci(struct bchannel *bch, int bc, int protocol)
1240{
1241 struct hfc_pci *hc = bch->hw;
1242 int fifo2;
1243 u_char rx_slot = 0, tx_slot = 0, pcm_mode;
1244
1245 if (bch->debug & DEBUG_HW_BCHANNEL)
1246 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -08001247 "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n",
1248 bch->state, protocol, bch->nr, bc);
Karsten Keil1700fe12008-07-26 18:55:28 +02001249
1250 fifo2 = bc;
Joe Perches475be4d2012-02-19 19:52:38 -08001251 pcm_mode = (bc >> 24) & 0xff;
Karsten Keil1700fe12008-07-26 18:55:28 +02001252 if (pcm_mode) { /* PCM SLOT USE */
1253 if (!test_bit(HFC_CFG_PCM, &hc->cfg))
1254 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001255 "%s: pcm channel id without HFC_CFG_PCM\n",
1256 __func__);
1257 rx_slot = (bc >> 8) & 0xff;
1258 tx_slot = (bc >> 16) & 0xff;
Karsten Keil1700fe12008-07-26 18:55:28 +02001259 bc = bc & 0xff;
Karsten Keileac74af2009-05-22 11:04:56 +00001260 } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
Karsten Keil1700fe12008-07-26 18:55:28 +02001261 printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001262 __func__);
Karsten Keil1700fe12008-07-26 18:55:28 +02001263 if (hc->chanlimit > 1) {
1264 hc->hw.bswapped = 0; /* B1 and B2 normal mode */
1265 hc->hw.sctrl_e &= ~0x80;
1266 } else {
1267 if (bc & 2) {
1268 if (protocol != ISDN_P_NONE) {
1269 hc->hw.bswapped = 1; /* B1 and B2 exchanged */
1270 hc->hw.sctrl_e |= 0x80;
1271 } else {
1272 hc->hw.bswapped = 0; /* B1 and B2 normal mode */
1273 hc->hw.sctrl_e &= ~0x80;
1274 }
1275 fifo2 = 1;
1276 } else {
1277 hc->hw.bswapped = 0; /* B1 and B2 normal mode */
1278 hc->hw.sctrl_e &= ~0x80;
1279 }
1280 }
1281 switch (protocol) {
1282 case (-1): /* used for init */
1283 bch->state = -1;
1284 bch->nr = bc;
Gustavo A. R. Silvad287c502018-07-03 16:17:31 -05001285 /* fall through */
Karsten Keil1700fe12008-07-26 18:55:28 +02001286 case (ISDN_P_NONE):
1287 if (bch->state == ISDN_P_NONE)
1288 return 0;
1289 if (bc & 2) {
1290 hc->hw.sctrl &= ~SCTRL_B2_ENA;
1291 hc->hw.sctrl_r &= ~SCTRL_B2_ENA;
1292 } else {
1293 hc->hw.sctrl &= ~SCTRL_B1_ENA;
1294 hc->hw.sctrl_r &= ~SCTRL_B1_ENA;
1295 }
1296 if (fifo2 & 2) {
1297 hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2;
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001298 hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001299 HFCPCI_INTS_B2REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001300 } else {
1301 hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1;
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001302 hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001303 HFCPCI_INTS_B1REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001304 }
1305#ifdef REVERSE_BITORDER
1306 if (bch->nr & 2)
1307 hc->hw.cirm &= 0x7f;
1308 else
1309 hc->hw.cirm &= 0xbf;
1310#endif
1311 bch->state = ISDN_P_NONE;
1312 bch->nr = bc;
1313 test_and_clear_bit(FLG_HDLC, &bch->Flags);
1314 test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
1315 break;
1316 case (ISDN_P_B_RAW):
1317 bch->state = protocol;
1318 bch->nr = bc;
Karsten Keileac74af2009-05-22 11:04:56 +00001319 hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
1320 hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02001321 if (bc & 2) {
1322 hc->hw.sctrl |= SCTRL_B2_ENA;
1323 hc->hw.sctrl_r |= SCTRL_B2_ENA;
1324#ifdef REVERSE_BITORDER
1325 hc->hw.cirm |= 0x80;
1326#endif
1327 } else {
1328 hc->hw.sctrl |= SCTRL_B1_ENA;
1329 hc->hw.sctrl_r |= SCTRL_B1_ENA;
1330#ifdef REVERSE_BITORDER
1331 hc->hw.cirm |= 0x40;
1332#endif
1333 }
1334 if (fifo2 & 2) {
1335 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001336 if (!tics)
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001337 hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001338 HFCPCI_INTS_B2REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001339 hc->hw.ctmt |= 2;
1340 hc->hw.conn &= ~0x18;
1341 } else {
1342 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001343 if (!tics)
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001344 hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001345 HFCPCI_INTS_B1REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001346 hc->hw.ctmt |= 1;
1347 hc->hw.conn &= ~0x03;
1348 }
1349 test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
1350 break;
1351 case (ISDN_P_B_HDLC):
1352 bch->state = protocol;
1353 bch->nr = bc;
Karsten Keileac74af2009-05-22 11:04:56 +00001354 hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
1355 hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02001356 if (bc & 2) {
1357 hc->hw.sctrl |= SCTRL_B2_ENA;
1358 hc->hw.sctrl_r |= SCTRL_B2_ENA;
1359 } else {
1360 hc->hw.sctrl |= SCTRL_B1_ENA;
1361 hc->hw.sctrl_r |= SCTRL_B1_ENA;
1362 }
1363 if (fifo2 & 2) {
1364 hc->hw.last_bfifo_cnt[1] = 0;
1365 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001366 hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001367 HFCPCI_INTS_B2REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001368 hc->hw.ctmt &= ~2;
1369 hc->hw.conn &= ~0x18;
1370 } else {
1371 hc->hw.last_bfifo_cnt[0] = 0;
1372 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
Alexandru Juncu6e3d6772013-07-18 14:36:48 +03001373 hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS |
Joe Perches475be4d2012-02-19 19:52:38 -08001374 HFCPCI_INTS_B1REC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001375 hc->hw.ctmt &= ~1;
1376 hc->hw.conn &= ~0x03;
1377 }
1378 test_and_set_bit(FLG_HDLC, &bch->Flags);
1379 break;
1380 default:
1381 printk(KERN_DEBUG "prot not known %x\n", protocol);
1382 return -ENOPROTOOPT;
1383 }
1384 if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
1385 if ((protocol == ISDN_P_NONE) ||
Joe Perches475be4d2012-02-19 19:52:38 -08001386 (protocol == -1)) { /* init case */
Karsten Keil1700fe12008-07-26 18:55:28 +02001387 rx_slot = 0;
1388 tx_slot = 0;
1389 } else {
1390 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg)) {
1391 rx_slot |= 0xC0;
1392 tx_slot |= 0xC0;
1393 } else {
1394 rx_slot |= 0x80;
1395 tx_slot |= 0x80;
1396 }
1397 }
1398 if (bc & 2) {
1399 hc->hw.conn &= 0xc7;
1400 hc->hw.conn |= 0x08;
1401 printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001402 __func__, tx_slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001403 printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001404 __func__, rx_slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001405 Write_hfc(hc, HFCPCI_B2_SSL, tx_slot);
1406 Write_hfc(hc, HFCPCI_B2_RSL, rx_slot);
1407 } else {
1408 hc->hw.conn &= 0xf8;
1409 hc->hw.conn |= 0x01;
1410 printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001411 __func__, tx_slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001412 printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001413 __func__, rx_slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001414 Write_hfc(hc, HFCPCI_B1_SSL, tx_slot);
1415 Write_hfc(hc, HFCPCI_B1_RSL, rx_slot);
1416 }
1417 }
1418 Write_hfc(hc, HFCPCI_SCTRL_E, hc->hw.sctrl_e);
1419 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
1420 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
1421 Write_hfc(hc, HFCPCI_SCTRL, hc->hw.sctrl);
1422 Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
1423 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
1424 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1425#ifdef REVERSE_BITORDER
1426 Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
1427#endif
1428 return 0;
1429}
1430
1431static int
1432set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
1433{
1434 struct hfc_pci *hc = bch->hw;
1435
1436 if (bch->debug & DEBUG_HW_BCHANNEL)
1437 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -08001438 "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n",
1439 bch->state, protocol, bch->nr, chan);
Karsten Keil1700fe12008-07-26 18:55:28 +02001440 if (bch->nr != chan) {
1441 printk(KERN_DEBUG
Joe Perches475be4d2012-02-19 19:52:38 -08001442 "HFCPCI rxtest wrong channel parameter %x/%x\n",
1443 bch->nr, chan);
Karsten Keil1700fe12008-07-26 18:55:28 +02001444 return -EINVAL;
1445 }
1446 switch (protocol) {
1447 case (ISDN_P_B_RAW):
1448 bch->state = protocol;
Karsten Keileac74af2009-05-22 11:04:56 +00001449 hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02001450 if (chan & 2) {
1451 hc->hw.sctrl_r |= SCTRL_B2_ENA;
1452 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001453 if (!tics)
1454 hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
Karsten Keil1700fe12008-07-26 18:55:28 +02001455 hc->hw.ctmt |= 2;
1456 hc->hw.conn &= ~0x18;
1457#ifdef REVERSE_BITORDER
1458 hc->hw.cirm |= 0x80;
1459#endif
1460 } else {
1461 hc->hw.sctrl_r |= SCTRL_B1_ENA;
1462 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02001463 if (!tics)
1464 hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
Karsten Keil1700fe12008-07-26 18:55:28 +02001465 hc->hw.ctmt |= 1;
1466 hc->hw.conn &= ~0x03;
1467#ifdef REVERSE_BITORDER
1468 hc->hw.cirm |= 0x40;
1469#endif
1470 }
1471 break;
1472 case (ISDN_P_B_HDLC):
1473 bch->state = protocol;
Karsten Keileac74af2009-05-22 11:04:56 +00001474 hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02001475 if (chan & 2) {
1476 hc->hw.sctrl_r |= SCTRL_B2_ENA;
1477 hc->hw.last_bfifo_cnt[1] = 0;
1478 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
1479 hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
1480 hc->hw.ctmt &= ~2;
1481 hc->hw.conn &= ~0x18;
1482 } else {
1483 hc->hw.sctrl_r |= SCTRL_B1_ENA;
1484 hc->hw.last_bfifo_cnt[0] = 0;
1485 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
1486 hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
1487 hc->hw.ctmt &= ~1;
1488 hc->hw.conn &= ~0x03;
1489 }
1490 break;
1491 default:
1492 printk(KERN_DEBUG "prot not known %x\n", protocol);
1493 return -ENOPROTOOPT;
1494 }
1495 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
1496 Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
1497 Write_hfc(hc, HFCPCI_SCTRL_R, hc->hw.sctrl_r);
1498 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
1499 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1500#ifdef REVERSE_BITORDER
1501 Write_hfc(hc, HFCPCI_CIRM, hc->hw.cirm);
1502#endif
1503 return 0;
1504}
1505
1506static void
1507deactivate_bchannel(struct bchannel *bch)
1508{
1509 struct hfc_pci *hc = bch->hw;
1510 u_long flags;
1511
1512 spin_lock_irqsave(&hc->lock, flags);
Karsten Keilfb286f02009-07-09 10:02:29 +02001513 mISDN_clear_bchannel(bch);
Karsten Keil1700fe12008-07-26 18:55:28 +02001514 mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
Karsten Keil1700fe12008-07-26 18:55:28 +02001515 spin_unlock_irqrestore(&hc->lock, flags);
1516}
1517
1518/*
1519 * Layer 1 B-channel hardware access
1520 */
1521static int
1522channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1523{
Karsten Keil6d1ee482012-05-15 23:51:07 +00001524 return mISDN_ctrl_bchannel(bch, cq);
Karsten Keil1700fe12008-07-26 18:55:28 +02001525}
1526static int
1527hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1528{
1529 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1530 struct hfc_pci *hc = bch->hw;
1531 int ret = -EINVAL;
1532 u_long flags;
1533
1534 if (bch->debug & DEBUG_HW)
1535 printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg);
1536 switch (cmd) {
1537 case HW_TESTRX_RAW:
1538 spin_lock_irqsave(&hc->lock, flags);
1539 ret = set_hfcpci_rxtest(bch, ISDN_P_B_RAW, (int)(long)arg);
1540 spin_unlock_irqrestore(&hc->lock, flags);
1541 break;
1542 case HW_TESTRX_HDLC:
1543 spin_lock_irqsave(&hc->lock, flags);
1544 ret = set_hfcpci_rxtest(bch, ISDN_P_B_HDLC, (int)(long)arg);
1545 spin_unlock_irqrestore(&hc->lock, flags);
1546 break;
1547 case HW_TESTRX_OFF:
1548 spin_lock_irqsave(&hc->lock, flags);
1549 mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
1550 spin_unlock_irqrestore(&hc->lock, flags);
1551 ret = 0;
1552 break;
1553 case CLOSE_CHANNEL:
1554 test_and_clear_bit(FLG_OPEN, &bch->Flags);
Karsten Keil13681122012-05-15 23:51:01 +00001555 deactivate_bchannel(bch);
Karsten Keil1700fe12008-07-26 18:55:28 +02001556 ch->protocol = ISDN_P_NONE;
1557 ch->peer = NULL;
1558 module_put(THIS_MODULE);
1559 ret = 0;
1560 break;
1561 case CONTROL_CHANNEL:
1562 ret = channel_bctrl(bch, arg);
1563 break;
1564 default:
1565 printk(KERN_WARNING "%s: unknown prim(%x)\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001566 __func__, cmd);
Karsten Keil1700fe12008-07-26 18:55:28 +02001567 }
1568 return ret;
1569}
1570
1571/*
1572 * Layer2 -> Layer 1 Dchannel data
1573 */
1574static int
1575hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
1576{
1577 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1578 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1579 struct hfc_pci *hc = dch->hw;
1580 int ret = -EINVAL;
1581 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1582 unsigned int id;
1583 u_long flags;
1584
1585 switch (hh->prim) {
1586 case PH_DATA_REQ:
1587 spin_lock_irqsave(&hc->lock, flags);
1588 ret = dchannel_senddata(dch, skb);
1589 if (ret > 0) { /* direct TX */
1590 id = hh->id; /* skb can be freed */
1591 hfcpci_fill_dfifo(dch->hw);
1592 ret = 0;
1593 spin_unlock_irqrestore(&hc->lock, flags);
1594 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
1595 } else
1596 spin_unlock_irqrestore(&hc->lock, flags);
1597 return ret;
1598 case PH_ACTIVATE_REQ:
1599 spin_lock_irqsave(&hc->lock, flags);
1600 if (hc->hw.protocol == ISDN_P_NT_S0) {
1601 ret = 0;
1602 if (test_bit(HFC_CFG_MASTER, &hc->cfg))
1603 hc->hw.mst_m |= HFCPCI_MASTER;
1604 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1605 if (test_bit(FLG_ACTIVE, &dch->Flags)) {
1606 spin_unlock_irqrestore(&hc->lock, flags);
1607 _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
Joe Perches475be4d2012-02-19 19:52:38 -08001608 MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
Karsten Keil1700fe12008-07-26 18:55:28 +02001609 break;
1610 }
1611 test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags);
1612 Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
Joe Perches475be4d2012-02-19 19:52:38 -08001613 HFCPCI_DO_ACTION | 1);
Karsten Keil1700fe12008-07-26 18:55:28 +02001614 } else
1615 ret = l1_event(dch->l1, hh->prim);
1616 spin_unlock_irqrestore(&hc->lock, flags);
1617 break;
1618 case PH_DEACTIVATE_REQ:
1619 test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
1620 spin_lock_irqsave(&hc->lock, flags);
1621 if (hc->hw.protocol == ISDN_P_NT_S0) {
1622 /* prepare deactivation */
1623 Write_hfc(hc, HFCPCI_STATES, 0x40);
1624 skb_queue_purge(&dch->squeue);
1625 if (dch->tx_skb) {
1626 dev_kfree_skb(dch->tx_skb);
1627 dch->tx_skb = NULL;
1628 }
1629 dch->tx_idx = 0;
1630 if (dch->rx_skb) {
1631 dev_kfree_skb(dch->rx_skb);
1632 dch->rx_skb = NULL;
1633 }
1634 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
1635 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
1636 del_timer(&dch->timer);
1637#ifdef FIXME
1638 if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
1639 dchannel_sched_event(&hc->dch, D_CLEARBUSY);
1640#endif
1641 hc->hw.mst_m &= ~HFCPCI_MASTER;
1642 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1643 ret = 0;
1644 } else {
1645 ret = l1_event(dch->l1, hh->prim);
1646 }
1647 spin_unlock_irqrestore(&hc->lock, flags);
1648 break;
1649 }
1650 if (!ret)
1651 dev_kfree_skb(skb);
1652 return ret;
1653}
1654
1655/*
1656 * Layer2 -> Layer 1 Bchannel data
1657 */
1658static int
1659hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
1660{
1661 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1662 struct hfc_pci *hc = bch->hw;
1663 int ret = -EINVAL;
1664 struct mISDNhead *hh = mISDN_HEAD_P(skb);
Karsten Keil8bfddfb2012-05-15 23:51:02 +00001665 unsigned long flags;
Karsten Keil1700fe12008-07-26 18:55:28 +02001666
1667 switch (hh->prim) {
1668 case PH_DATA_REQ:
1669 spin_lock_irqsave(&hc->lock, flags);
1670 ret = bchannel_senddata(bch, skb);
1671 if (ret > 0) { /* direct TX */
Karsten Keil1700fe12008-07-26 18:55:28 +02001672 hfcpci_fill_fifo(bch);
1673 ret = 0;
Karsten Keil8bfddfb2012-05-15 23:51:02 +00001674 }
1675 spin_unlock_irqrestore(&hc->lock, flags);
Karsten Keil1700fe12008-07-26 18:55:28 +02001676 return ret;
1677 case PH_ACTIVATE_REQ:
1678 spin_lock_irqsave(&hc->lock, flags);
1679 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1680 ret = mode_hfcpci(bch, bch->nr, ch->protocol);
1681 else
1682 ret = 0;
1683 spin_unlock_irqrestore(&hc->lock, flags);
1684 if (!ret)
1685 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08001686 NULL, GFP_KERNEL);
Karsten Keil1700fe12008-07-26 18:55:28 +02001687 break;
1688 case PH_DEACTIVATE_REQ:
1689 deactivate_bchannel(bch);
1690 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08001691 NULL, GFP_KERNEL);
Karsten Keil1700fe12008-07-26 18:55:28 +02001692 ret = 0;
1693 break;
1694 }
1695 if (!ret)
1696 dev_kfree_skb(skb);
1697 return ret;
1698}
1699
1700/*
1701 * called for card init message
1702 */
1703
Harvey Harrison1532dcb2008-09-22 19:16:51 -07001704static void
Karsten Keil1700fe12008-07-26 18:55:28 +02001705inithfcpci(struct hfc_pci *hc)
1706{
1707 printk(KERN_DEBUG "inithfcpci: entered\n");
Kees Cooke99e88a2017-10-16 14:43:17 -07001708 timer_setup(&hc->dch.timer, hfcpci_dbusy_timer, 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02001709 hc->chanlimit = 2;
1710 mode_hfcpci(&hc->bch[0], 1, -1);
1711 mode_hfcpci(&hc->bch[1], 2, -1);
1712}
1713
1714
1715static int
1716init_card(struct hfc_pci *hc)
1717{
1718 int cnt = 3;
1719 u_long flags;
1720
1721 printk(KERN_DEBUG "init_card: entered\n");
1722
1723
1724 spin_lock_irqsave(&hc->lock, flags);
1725 disable_hwirq(hc);
1726 spin_unlock_irqrestore(&hc->lock, flags);
1727 if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) {
1728 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001729 "mISDN: couldn't get interrupt %d\n", hc->irq);
Karsten Keil1700fe12008-07-26 18:55:28 +02001730 return -EIO;
1731 }
1732 spin_lock_irqsave(&hc->lock, flags);
1733 reset_hfcpci(hc);
1734 while (cnt) {
1735 inithfcpci(hc);
1736 /*
1737 * Finally enable IRQ output
Uwe Kleine-König698f9312010-07-02 20:41:51 +02001738 * this is only allowed, if an IRQ routine is already
Karsten Keil1700fe12008-07-26 18:55:28 +02001739 * established for this HFC, so don't do that earlier
1740 */
1741 enable_hwirq(hc);
1742 spin_unlock_irqrestore(&hc->lock, flags);
1743 /* Timeout 80ms */
Fabian Frederick45cee4f2015-02-20 19:12:52 +01001744 set_current_state(TASK_UNINTERRUPTIBLE);
Joe Perches475be4d2012-02-19 19:52:38 -08001745 schedule_timeout((80 * HZ) / 1000);
Karsten Keil1700fe12008-07-26 18:55:28 +02001746 printk(KERN_INFO "HFC PCI: IRQ %d count %d\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001747 hc->irq, hc->irqcnt);
Karsten Keil1700fe12008-07-26 18:55:28 +02001748 /* now switch timer interrupt off */
1749 spin_lock_irqsave(&hc->lock, flags);
1750 hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
1751 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
1752 /* reinit mode reg */
1753 Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
1754 if (!hc->irqcnt) {
1755 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001756 "HFC PCI: IRQ(%d) getting no interrupts "
1757 "during init %d\n", hc->irq, 4 - cnt);
Andreas Mohrcdae28e12009-06-02 18:15:12 +02001758 if (cnt == 1)
1759 break;
1760 else {
Karsten Keil1700fe12008-07-26 18:55:28 +02001761 reset_hfcpci(hc);
1762 cnt--;
1763 }
1764 } else {
1765 spin_unlock_irqrestore(&hc->lock, flags);
1766 hc->initdone = 1;
1767 return 0;
1768 }
1769 }
1770 disable_hwirq(hc);
1771 spin_unlock_irqrestore(&hc->lock, flags);
1772 free_irq(hc->irq, hc);
1773 return -EIO;
1774}
1775
1776static int
1777channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
1778{
1779 int ret = 0;
1780 u_char slot;
1781
1782 switch (cq->op) {
1783 case MISDN_CTRL_GETOP:
1784 cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
Karsten Keilc626c122012-05-04 04:15:33 +00001785 MISDN_CTRL_DISCONNECT | MISDN_CTRL_L1_TIMER3;
Karsten Keil1700fe12008-07-26 18:55:28 +02001786 break;
1787 case MISDN_CTRL_LOOP:
1788 /* channel 0 disabled loop */
1789 if (cq->channel < 0 || cq->channel > 2) {
1790 ret = -EINVAL;
1791 break;
1792 }
1793 if (cq->channel & 1) {
1794 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
1795 slot = 0xC0;
1796 else
1797 slot = 0x80;
1798 printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001799 __func__, slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001800 Write_hfc(hc, HFCPCI_B1_SSL, slot);
1801 Write_hfc(hc, HFCPCI_B1_RSL, slot);
1802 hc->hw.conn = (hc->hw.conn & ~7) | 6;
1803 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1804 }
1805 if (cq->channel & 2) {
1806 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
1807 slot = 0xC1;
1808 else
1809 slot = 0x81;
1810 printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001811 __func__, slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001812 Write_hfc(hc, HFCPCI_B2_SSL, slot);
1813 Write_hfc(hc, HFCPCI_B2_RSL, slot);
1814 hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30;
1815 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1816 }
1817 if (cq->channel & 3)
1818 hc->hw.trm |= 0x80; /* enable IOM-loop */
1819 else {
1820 hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
1821 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1822 hc->hw.trm &= 0x7f; /* disable IOM-loop */
1823 }
1824 Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
1825 break;
1826 case MISDN_CTRL_CONNECT:
1827 if (cq->channel == cq->p1) {
1828 ret = -EINVAL;
1829 break;
1830 }
1831 if (cq->channel < 1 || cq->channel > 2 ||
1832 cq->p1 < 1 || cq->p1 > 2) {
1833 ret = -EINVAL;
1834 break;
1835 }
1836 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
1837 slot = 0xC0;
1838 else
1839 slot = 0x80;
1840 printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001841 __func__, slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001842 Write_hfc(hc, HFCPCI_B1_SSL, slot);
1843 Write_hfc(hc, HFCPCI_B2_RSL, slot);
1844 if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
1845 slot = 0xC1;
1846 else
1847 slot = 0x81;
1848 printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001849 __func__, slot);
Karsten Keil1700fe12008-07-26 18:55:28 +02001850 Write_hfc(hc, HFCPCI_B2_SSL, slot);
1851 Write_hfc(hc, HFCPCI_B1_RSL, slot);
1852 hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36;
1853 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1854 hc->hw.trm |= 0x80;
1855 Write_hfc(hc, HFCPCI_TRM, hc->hw.trm);
1856 break;
1857 case MISDN_CTRL_DISCONNECT:
1858 hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x09;
1859 Write_hfc(hc, HFCPCI_CONNECT, hc->hw.conn);
1860 hc->hw.trm &= 0x7f; /* disable IOM-loop */
1861 break;
Karsten Keilc626c122012-05-04 04:15:33 +00001862 case MISDN_CTRL_L1_TIMER3:
1863 ret = l1_event(hc->dch.l1, HW_TIMER3_VALUE | (cq->p1 & 0xff));
1864 break;
Karsten Keil1700fe12008-07-26 18:55:28 +02001865 default:
1866 printk(KERN_WARNING "%s: unknown Op %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001867 __func__, cq->op);
Karsten Keil1700fe12008-07-26 18:55:28 +02001868 ret = -EINVAL;
1869 break;
1870 }
1871 return ret;
1872}
1873
1874static int
1875open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch,
Joe Perches475be4d2012-02-19 19:52:38 -08001876 struct channel_req *rq)
Karsten Keil1700fe12008-07-26 18:55:28 +02001877{
1878 int err = 0;
1879
1880 if (debug & DEBUG_HW_OPEN)
1881 printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
Joe Perches475be4d2012-02-19 19:52:38 -08001882 hc->dch.dev.id, __builtin_return_address(0));
Karsten Keil1700fe12008-07-26 18:55:28 +02001883 if (rq->protocol == ISDN_P_NONE)
1884 return -EINVAL;
Martin Bachem55a6af92008-09-04 12:42:39 +02001885 if (rq->adr.channel == 1) {
1886 /* TODO: E-Channel */
1887 return -EINVAL;
1888 }
Karsten Keil1700fe12008-07-26 18:55:28 +02001889 if (!hc->initdone) {
1890 if (rq->protocol == ISDN_P_TE_S0) {
1891 err = create_l1(&hc->dch, hfc_l1callback);
1892 if (err)
1893 return err;
1894 }
1895 hc->hw.protocol = rq->protocol;
1896 ch->protocol = rq->protocol;
1897 err = init_card(hc);
1898 if (err)
1899 return err;
1900 } else {
1901 if (rq->protocol != ch->protocol) {
1902 if (hc->hw.protocol == ISDN_P_TE_S0)
1903 l1_event(hc->dch.l1, CLOSE_CHANNEL);
Andreas Eversbergc3b3cde2008-11-09 10:23:19 +01001904 if (rq->protocol == ISDN_P_TE_S0) {
1905 err = create_l1(&hc->dch, hfc_l1callback);
1906 if (err)
1907 return err;
1908 }
Karsten Keil1700fe12008-07-26 18:55:28 +02001909 hc->hw.protocol = rq->protocol;
1910 ch->protocol = rq->protocol;
1911 hfcpci_setmode(hc);
1912 }
1913 }
1914
1915 if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) ||
1916 ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) {
1917 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
Joe Perches475be4d2012-02-19 19:52:38 -08001918 0, NULL, GFP_KERNEL);
Karsten Keil1700fe12008-07-26 18:55:28 +02001919 }
1920 rq->ch = ch;
1921 if (!try_module_get(THIS_MODULE))
1922 printk(KERN_WARNING "%s:cannot get module\n", __func__);
1923 return 0;
1924}
1925
1926static int
1927open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
1928{
1929 struct bchannel *bch;
1930
Dan Carpenter819a1002012-03-26 21:20:48 +00001931 if (rq->adr.channel == 0 || rq->adr.channel > 2)
Karsten Keil1700fe12008-07-26 18:55:28 +02001932 return -EINVAL;
1933 if (rq->protocol == ISDN_P_NONE)
1934 return -EINVAL;
1935 bch = &hc->bch[rq->adr.channel - 1];
1936 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1937 return -EBUSY; /* b-channel can be only open once */
1938 bch->ch.protocol = rq->protocol;
1939 rq->ch = &bch->ch; /* TODO: E-channel */
1940 if (!try_module_get(THIS_MODULE))
1941 printk(KERN_WARNING "%s:cannot get module\n", __func__);
1942 return 0;
1943}
1944
1945/*
1946 * device control function
1947 */
1948static int
1949hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1950{
1951 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1952 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1953 struct hfc_pci *hc = dch->hw;
1954 struct channel_req *rq;
1955 int err = 0;
1956
1957 if (dch->debug & DEBUG_HW)
1958 printk(KERN_DEBUG "%s: cmd:%x %p\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001959 __func__, cmd, arg);
Karsten Keil1700fe12008-07-26 18:55:28 +02001960 switch (cmd) {
1961 case OPEN_CHANNEL:
1962 rq = arg;
Martin Bachema9b61832008-09-03 18:08:30 +02001963 if ((rq->protocol == ISDN_P_TE_S0) ||
1964 (rq->protocol == ISDN_P_NT_S0))
Karsten Keil1700fe12008-07-26 18:55:28 +02001965 err = open_dchannel(hc, ch, rq);
1966 else
1967 err = open_bchannel(hc, rq);
1968 break;
1969 case CLOSE_CHANNEL:
1970 if (debug & DEBUG_HW_OPEN)
1971 printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001972 __func__, hc->dch.dev.id,
1973 __builtin_return_address(0));
Karsten Keil1700fe12008-07-26 18:55:28 +02001974 module_put(THIS_MODULE);
1975 break;
1976 case CONTROL_CHANNEL:
1977 err = channel_ctrl(hc, arg);
1978 break;
1979 default:
1980 if (dch->debug & DEBUG_HW)
1981 printk(KERN_DEBUG "%s: unknown command %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001982 __func__, cmd);
Karsten Keil1700fe12008-07-26 18:55:28 +02001983 return -EINVAL;
1984 }
1985 return err;
1986}
1987
1988static int
1989setup_hw(struct hfc_pci *hc)
1990{
1991 void *buffer;
1992
1993 printk(KERN_INFO "mISDN: HFC-PCI driver %s\n", hfcpci_revision);
1994 hc->hw.cirm = 0;
1995 hc->dch.state = 0;
1996 pci_set_master(hc->pdev);
1997 if (!hc->irq) {
1998 printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
1999 return 1;
2000 }
Karsten Keileac74af2009-05-22 11:04:56 +00002001 hc->hw.pci_io =
2002 (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
Karsten Keil1700fe12008-07-26 18:55:28 +02002003
2004 if (!hc->hw.pci_io) {
2005 printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
2006 return 1;
2007 }
2008 /* Allocate memory for FIFOS */
2009 /* the memory needs to be on a 32k boundary within the first 4G */
2010 pci_set_dma_mask(hc->pdev, 0xFFFF8000);
2011 buffer = pci_alloc_consistent(hc->pdev, 0x8000, &hc->hw.dmahandle);
2012 /* We silently assume the address is okay if nonzero */
2013 if (!buffer) {
2014 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08002015 "HFC-PCI: Error allocating memory for FIFO!\n");
Karsten Keil1700fe12008-07-26 18:55:28 +02002016 return 1;
2017 }
2018 hc->hw.fifos = buffer;
2019 pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle);
2020 hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256);
Kangjie Lu10010492019-03-12 00:54:55 -05002021 if (unlikely(!hc->hw.pci_io)) {
2022 printk(KERN_WARNING
2023 "HFC-PCI: Error in ioremap for PCI!\n");
2024 pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos,
2025 hc->hw.dmahandle);
2026 return 1;
2027 }
2028
Karsten Keil1700fe12008-07-26 18:55:28 +02002029 printk(KERN_INFO
Fuqian Huang0fa41222019-04-23 10:56:23 +08002030 "HFC-PCI: defined at mem %#lx fifo %p(%pad) IRQ %d HZ %d\n",
2031 (u_long) hc->hw.pci_io, hc->hw.fifos,
2032 &hc->hw.dmahandle, hc->irq, HZ);
Kangjie Lu10010492019-03-12 00:54:55 -05002033
Karsten Keil1700fe12008-07-26 18:55:28 +02002034 /* enable memory mapped ports, disable busmaster */
2035 pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
2036 hc->hw.int_m2 = 0;
2037 disable_hwirq(hc);
2038 hc->hw.int_m1 = 0;
2039 Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
2040 /* At this point the needed PCI config is done */
2041 /* fifos are still not enabled */
Kees Cook86cb30e2017-10-17 20:21:24 -07002042 timer_setup(&hc->hw.timer, hfcpci_Timer, 0);
Karsten Keil1700fe12008-07-26 18:55:28 +02002043 /* default PCM master */
2044 test_and_set_bit(HFC_CFG_MASTER, &hc->cfg);
2045 return 0;
2046}
2047
2048static void
2049release_card(struct hfc_pci *hc) {
2050 u_long flags;
2051
2052 spin_lock_irqsave(&hc->lock, flags);
2053 hc->hw.int_m2 = 0; /* interrupt output off ! */
2054 disable_hwirq(hc);
2055 mode_hfcpci(&hc->bch[0], 1, ISDN_P_NONE);
2056 mode_hfcpci(&hc->bch[1], 2, ISDN_P_NONE);
2057 if (hc->dch.timer.function != NULL) {
2058 del_timer(&hc->dch.timer);
2059 hc->dch.timer.function = NULL;
2060 }
2061 spin_unlock_irqrestore(&hc->lock, flags);
2062 if (hc->hw.protocol == ISDN_P_TE_S0)
2063 l1_event(hc->dch.l1, CLOSE_CHANNEL);
2064 if (hc->initdone)
2065 free_irq(hc->irq, hc);
2066 release_io_hfcpci(hc); /* must release after free_irq! */
2067 mISDN_unregister_device(&hc->dch.dev);
2068 mISDN_freebchannel(&hc->bch[1]);
2069 mISDN_freebchannel(&hc->bch[0]);
2070 mISDN_freedchannel(&hc->dch);
Karsten Keil1700fe12008-07-26 18:55:28 +02002071 pci_set_drvdata(hc->pdev, NULL);
2072 kfree(hc);
2073}
2074
2075static int
2076setup_card(struct hfc_pci *card)
2077{
2078 int err = -EINVAL;
2079 u_int i;
Karsten Keil1700fe12008-07-26 18:55:28 +02002080 char name[MISDN_MAX_IDLEN];
2081
Karsten Keil1700fe12008-07-26 18:55:28 +02002082 card->dch.debug = debug;
2083 spin_lock_init(&card->lock);
2084 mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state);
2085 card->dch.hw = card;
2086 card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
2087 card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
Joe Perches475be4d2012-02-19 19:52:38 -08002088 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
Karsten Keil1700fe12008-07-26 18:55:28 +02002089 card->dch.dev.D.send = hfcpci_l2l1D;
2090 card->dch.dev.D.ctrl = hfc_dctrl;
2091 card->dch.dev.nrbchan = 2;
2092 for (i = 0; i < 2; i++) {
2093 card->bch[i].nr = i + 1;
Karsten Keilff4cc1d2008-07-30 18:26:58 +02002094 set_channelmap(i + 1, card->dch.dev.channelmap);
Karsten Keil1700fe12008-07-26 18:55:28 +02002095 card->bch[i].debug = debug;
Karsten Keil034005a2012-05-15 23:51:06 +00002096 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1);
Karsten Keil1700fe12008-07-26 18:55:28 +02002097 card->bch[i].hw = card;
2098 card->bch[i].ch.send = hfcpci_l2l1B;
2099 card->bch[i].ch.ctrl = hfc_bctrl;
2100 card->bch[i].ch.nr = i + 1;
2101 list_add(&card->bch[i].ch.list, &card->dch.dev.bchannels);
2102 }
2103 err = setup_hw(card);
2104 if (err)
2105 goto error;
2106 snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1);
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002107 err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name);
Karsten Keil1700fe12008-07-26 18:55:28 +02002108 if (err)
2109 goto error;
2110 HFC_cnt++;
Karsten Keil1700fe12008-07-26 18:55:28 +02002111 printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt);
2112 return 0;
2113error:
2114 mISDN_freebchannel(&card->bch[1]);
2115 mISDN_freebchannel(&card->bch[0]);
2116 mISDN_freedchannel(&card->dch);
2117 kfree(card);
2118 return err;
2119}
2120
2121/* private data in the PCI devices list */
2122struct _hfc_map {
2123 u_int subtype;
2124 u_int flag;
2125 char *name;
2126};
2127
2128static const struct _hfc_map hfc_map[] =
2129{
2130 {HFC_CCD_2BD0, 0, "CCD/Billion/Asuscom 2BD0"},
2131 {HFC_CCD_B000, 0, "Billion B000"},
2132 {HFC_CCD_B006, 0, "Billion B006"},
2133 {HFC_CCD_B007, 0, "Billion B007"},
2134 {HFC_CCD_B008, 0, "Billion B008"},
2135 {HFC_CCD_B009, 0, "Billion B009"},
2136 {HFC_CCD_B00A, 0, "Billion B00A"},
2137 {HFC_CCD_B00B, 0, "Billion B00B"},
2138 {HFC_CCD_B00C, 0, "Billion B00C"},
2139 {HFC_CCD_B100, 0, "Seyeon B100"},
2140 {HFC_CCD_B700, 0, "Primux II S0 B700"},
2141 {HFC_CCD_B701, 0, "Primux II S0 NT B701"},
2142 {HFC_ABOCOM_2BD1, 0, "Abocom/Magitek 2BD1"},
2143 {HFC_ASUS_0675, 0, "Asuscom/Askey 675"},
2144 {HFC_BERKOM_TCONCEPT, 0, "German telekom T-Concept"},
2145 {HFC_BERKOM_A1T, 0, "German telekom A1T"},
2146 {HFC_ANIGMA_MC145575, 0, "Motorola MC145575"},
2147 {HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"},
2148 {HFC_DIGI_DF_M_IOM2_E, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08002149 "Digi International DataFire Micro V IOM2 (Europe)"},
Karsten Keil1700fe12008-07-26 18:55:28 +02002150 {HFC_DIGI_DF_M_E, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08002151 "Digi International DataFire Micro V (Europe)"},
Karsten Keil1700fe12008-07-26 18:55:28 +02002152 {HFC_DIGI_DF_M_IOM2_A, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08002153 "Digi International DataFire Micro V IOM2 (North America)"},
Karsten Keil1700fe12008-07-26 18:55:28 +02002154 {HFC_DIGI_DF_M_A, 0,
Joe Perches475be4d2012-02-19 19:52:38 -08002155 "Digi International DataFire Micro V (North America)"},
Karsten Keil1700fe12008-07-26 18:55:28 +02002156 {HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"},
2157 {},
2158};
2159
Arvind Yadaved038e72017-07-15 09:55:50 +05302160static const struct pci_device_id hfc_ids[] =
Karsten Keil1700fe12008-07-26 18:55:28 +02002161{
Peter Hueweb8176a32010-07-15 09:02:36 +00002162 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0),
Joe Perches475be4d2012-02-19 19:52:38 -08002163 (unsigned long) &hfc_map[0] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002164 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000),
Joe Perches475be4d2012-02-19 19:52:38 -08002165 (unsigned long) &hfc_map[1] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002166 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006),
Joe Perches475be4d2012-02-19 19:52:38 -08002167 (unsigned long) &hfc_map[2] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002168 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007),
Joe Perches475be4d2012-02-19 19:52:38 -08002169 (unsigned long) &hfc_map[3] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002170 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008),
Joe Perches475be4d2012-02-19 19:52:38 -08002171 (unsigned long) &hfc_map[4] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002172 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009),
Joe Perches475be4d2012-02-19 19:52:38 -08002173 (unsigned long) &hfc_map[5] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002174 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A),
Joe Perches475be4d2012-02-19 19:52:38 -08002175 (unsigned long) &hfc_map[6] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002176 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B),
Joe Perches475be4d2012-02-19 19:52:38 -08002177 (unsigned long) &hfc_map[7] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002178 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C),
Joe Perches475be4d2012-02-19 19:52:38 -08002179 (unsigned long) &hfc_map[8] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002180 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100),
Joe Perches475be4d2012-02-19 19:52:38 -08002181 (unsigned long) &hfc_map[9] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002182 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700),
Joe Perches475be4d2012-02-19 19:52:38 -08002183 (unsigned long) &hfc_map[10] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002184 { PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701),
Joe Perches475be4d2012-02-19 19:52:38 -08002185 (unsigned long) &hfc_map[11] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002186 { PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1),
Joe Perches475be4d2012-02-19 19:52:38 -08002187 (unsigned long) &hfc_map[12] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002188 { PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675),
Joe Perches475be4d2012-02-19 19:52:38 -08002189 (unsigned long) &hfc_map[13] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002190 { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT),
Joe Perches475be4d2012-02-19 19:52:38 -08002191 (unsigned long) &hfc_map[14] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002192 { PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T),
Joe Perches475be4d2012-02-19 19:52:38 -08002193 (unsigned long) &hfc_map[15] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002194 { PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575),
Joe Perches475be4d2012-02-19 19:52:38 -08002195 (unsigned long) &hfc_map[16] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002196 { PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0),
Joe Perches475be4d2012-02-19 19:52:38 -08002197 (unsigned long) &hfc_map[17] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002198 { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E),
Joe Perches475be4d2012-02-19 19:52:38 -08002199 (unsigned long) &hfc_map[18] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002200 { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E),
Joe Perches475be4d2012-02-19 19:52:38 -08002201 (unsigned long) &hfc_map[19] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002202 { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A),
Joe Perches475be4d2012-02-19 19:52:38 -08002203 (unsigned long) &hfc_map[20] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002204 { PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A),
Joe Perches475be4d2012-02-19 19:52:38 -08002205 (unsigned long) &hfc_map[21] },
Peter Hueweb8176a32010-07-15 09:02:36 +00002206 { PCI_VDEVICE(SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2),
Joe Perches475be4d2012-02-19 19:52:38 -08002207 (unsigned long) &hfc_map[22] },
Karsten Keil1700fe12008-07-26 18:55:28 +02002208 {},
2209};
2210
Greg Kroah-Hartmaned5a84c2012-12-21 13:13:05 -08002211static int
Karsten Keil1700fe12008-07-26 18:55:28 +02002212hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2213{
2214 int err = -ENOMEM;
2215 struct hfc_pci *card;
2216 struct _hfc_map *m = (struct _hfc_map *)ent->driver_data;
2217
Jia-Ju Bai8c957d62018-07-27 10:39:06 +08002218 card = kzalloc(sizeof(struct hfc_pci), GFP_KERNEL);
Karsten Keil1700fe12008-07-26 18:55:28 +02002219 if (!card) {
2220 printk(KERN_ERR "No kmem for HFC card\n");
2221 return err;
2222 }
2223 card->pdev = pdev;
2224 card->subtype = m->subtype;
2225 err = pci_enable_device(pdev);
2226 if (err) {
2227 kfree(card);
2228 return err;
2229 }
2230
2231 printk(KERN_INFO "mISDN_hfcpci: found adapter %s at %s\n",
2232 m->name, pci_name(pdev));
2233
2234 card->irq = pdev->irq;
2235 pci_set_drvdata(pdev, card);
2236 err = setup_card(card);
2237 if (err)
2238 pci_set_drvdata(pdev, NULL);
2239 return err;
2240}
2241
Greg Kroah-Hartmaned5a84c2012-12-21 13:13:05 -08002242static void
Karsten Keil1700fe12008-07-26 18:55:28 +02002243hfc_remove_pci(struct pci_dev *pdev)
2244{
2245 struct hfc_pci *card = pci_get_drvdata(pdev);
Karsten Keil1700fe12008-07-26 18:55:28 +02002246
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002247 if (card)
Karsten Keil1700fe12008-07-26 18:55:28 +02002248 release_card(card);
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002249 else
Karsten Keil1700fe12008-07-26 18:55:28 +02002250 if (debug)
Karsten Keileac74af2009-05-22 11:04:56 +00002251 printk(KERN_DEBUG "%s: drvdata already removed\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002252 __func__);
Karsten Keil1700fe12008-07-26 18:55:28 +02002253}
2254
2255
2256static struct pci_driver hfc_driver = {
2257 .name = "hfcpci",
2258 .probe = hfc_probe,
Greg Kroah-Hartmaned5a84c2012-12-21 13:13:05 -08002259 .remove = hfc_remove_pci,
Karsten Keil1700fe12008-07-26 18:55:28 +02002260 .id_table = hfc_ids,
2261};
2262
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002263static int
Kees Cookc509a822017-11-02 16:18:07 -07002264_hfcpci_softirq(struct device *dev, void *unused)
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002265{
2266 struct hfc_pci *hc = dev_get_drvdata(dev);
2267 struct bchannel *bch;
2268 if (hc == NULL)
2269 return 0;
2270
2271 if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
2272 spin_lock(&hc->lock);
2273 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
2274 if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
2275 main_rec_hfcpci(bch);
2276 tx_birq(bch);
2277 }
2278 bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2);
2279 if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */
2280 main_rec_hfcpci(bch);
2281 tx_birq(bch);
2282 }
2283 spin_unlock(&hc->lock);
2284 }
2285 return 0;
2286}
2287
2288static void
Kees Cookc509a822017-11-02 16:18:07 -07002289hfcpci_softirq(struct timer_list *unused)
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002290{
Kees Cookc509a822017-11-02 16:18:07 -07002291 WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, NULL,
Antonio Alecrim Jrd6d6d1b2013-09-14 14:20:40 -03002292 _hfcpci_softirq) != 0);
Matthias Urlichsb36b6542008-08-16 00:09:24 +02002293
2294 /* if next event would be in the past ... */
2295 if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
2296 hfc_jiffies = jiffies + 1;
2297 else
2298 hfc_jiffies += tics;
2299 hfc_tl.expires = hfc_jiffies;
2300 add_timer(&hfc_tl);
2301}
2302
Karsten Keil1700fe12008-07-26 18:55:28 +02002303static int __init
2304HFC_init(void)
2305{
2306 int err;
2307
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002308 if (!poll)
2309 poll = HFCPCI_BTRANS_THRESHOLD;
2310
2311 if (poll != HFCPCI_BTRANS_THRESHOLD) {
Andreas Eversberg400fd972008-10-11 08:13:29 +02002312 tics = (poll * HZ) / 8000;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002313 if (tics < 1)
2314 tics = 1;
Andreas Eversberg400fd972008-10-11 08:13:29 +02002315 poll = (tics * 8000) / HZ;
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002316 if (poll > 256 || poll < 8) {
2317 printk(KERN_ERR "%s: Wrong poll value %d not in range "
Joe Perches475be4d2012-02-19 19:52:38 -08002318 "of 8..256.\n", __func__, poll);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002319 err = -EINVAL;
2320 return err;
2321 }
2322 }
2323 if (poll != HFCPCI_BTRANS_THRESHOLD) {
2324 printk(KERN_INFO "%s: Using alternative poll value of %d\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002325 __func__, poll);
Kees Cookc509a822017-11-02 16:18:07 -07002326 timer_setup(&hfc_tl, hfcpci_softirq, 0);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002327 hfc_tl.expires = jiffies + tics;
2328 hfc_jiffies = hfc_tl.expires;
2329 add_timer(&hfc_tl);
2330 } else
2331 tics = 0; /* indicate the use of controller's timer */
2332
Karsten Keil1700fe12008-07-26 18:55:28 +02002333 err = pci_register_driver(&hfc_driver);
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002334 if (err) {
2335 if (timer_pending(&hfc_tl))
2336 del_timer(&hfc_tl);
2337 }
2338
Karsten Keil1700fe12008-07-26 18:55:28 +02002339 return err;
2340}
2341
2342static void __exit
2343HFC_cleanup(void)
2344{
Andreas Eversberg87c5fa12008-09-28 13:01:01 +02002345 if (timer_pending(&hfc_tl))
2346 del_timer(&hfc_tl);
2347
Karsten Keil1700fe12008-07-26 18:55:28 +02002348 pci_unregister_driver(&hfc_driver);
2349}
2350
2351module_init(HFC_init);
2352module_exit(HFC_cleanup);
Matthias Urlichse314f892008-10-16 13:58:54 +02002353
2354MODULE_DEVICE_TABLE(pci, hfc_ids);