1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * isac.c   ISAC specific routines
4  *
5  * Author       Karsten Keil <keil@isdn4linux.de>
6  *
7  * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
8  */
9 
10 #include <linux/irqreturn.h>
11 #include <linux/slab.h>
12 #include <linux/module.h>
13 #include <linux/mISDNhw.h>
14 #include "ipac.h"
15 
16 
17 #define DBUSY_TIMER_VALUE	80
18 #define ARCOFI_USE		1
19 
20 #define ISAC_REV		"2.0"
21 
22 MODULE_AUTHOR("Karsten Keil");
23 MODULE_VERSION(ISAC_REV);
24 MODULE_LICENSE("GPL v2");
25 
26 #define ReadISAC(is, o)		(is->read_reg(is->dch.hw, o + is->off))
27 #define	WriteISAC(is, o, v)	(is->write_reg(is->dch.hw, o + is->off, v))
28 #define ReadHSCX(h, o)		(h->ip->read_reg(h->ip->hw, h->off + o))
29 #define WriteHSCX(h, o, v)	(h->ip->write_reg(h->ip->hw, h->off + o, v))
30 #define ReadIPAC(ip, o)		(ip->read_reg(ip->hw, o))
31 #define WriteIPAC(ip, o, v)	(ip->write_reg(ip->hw, o, v))
32 
33 static inline void
ph_command(struct isac_hw * isac,u8 command)34 ph_command(struct isac_hw *isac, u8 command)
35 {
36 	pr_debug("%s: ph_command %x\n", isac->name, command);
37 	if (isac->type & IPAC_TYPE_ISACX)
38 		WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
39 	else
40 		WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
41 }
42 
43 static void
isac_ph_state_change(struct isac_hw * isac)44 isac_ph_state_change(struct isac_hw *isac)
45 {
46 	switch (isac->state) {
47 	case (ISAC_IND_RS):
48 	case (ISAC_IND_EI):
49 		ph_command(isac, ISAC_CMD_DUI);
50 	}
51 	schedule_event(&isac->dch, FLG_PHCHANGE);
52 }
53 
54 static void
isac_ph_state_bh(struct dchannel * dch)55 isac_ph_state_bh(struct dchannel *dch)
56 {
57 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
58 
59 	switch (isac->state) {
60 	case ISAC_IND_RS:
61 	case ISAC_IND_EI:
62 		dch->state = 0;
63 		l1_event(dch->l1, HW_RESET_IND);
64 		break;
65 	case ISAC_IND_DID:
66 		dch->state = 3;
67 		l1_event(dch->l1, HW_DEACT_CNF);
68 		break;
69 	case ISAC_IND_DR:
70 	case ISAC_IND_DR6:
71 		dch->state = 3;
72 		l1_event(dch->l1, HW_DEACT_IND);
73 		break;
74 	case ISAC_IND_PU:
75 		dch->state = 4;
76 		l1_event(dch->l1, HW_POWERUP_IND);
77 		break;
78 	case ISAC_IND_RSY:
79 		if (dch->state <= 5) {
80 			dch->state = 5;
81 			l1_event(dch->l1, ANYSIGNAL);
82 		} else {
83 			dch->state = 8;
84 			l1_event(dch->l1, LOSTFRAMING);
85 		}
86 		break;
87 	case ISAC_IND_ARD:
88 		dch->state = 6;
89 		l1_event(dch->l1, INFO2);
90 		break;
91 	case ISAC_IND_AI8:
92 		dch->state = 7;
93 		l1_event(dch->l1, INFO4_P8);
94 		break;
95 	case ISAC_IND_AI10:
96 		dch->state = 7;
97 		l1_event(dch->l1, INFO4_P10);
98 		break;
99 	}
100 	pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
101 }
102 
103 static void
isac_empty_fifo(struct isac_hw * isac,int count)104 isac_empty_fifo(struct isac_hw *isac, int count)
105 {
106 	u8 *ptr;
107 
108 	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
109 
110 	if (!isac->dch.rx_skb) {
111 		isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
112 		if (!isac->dch.rx_skb) {
113 			pr_info("%s: D receive out of memory\n", isac->name);
114 			WriteISAC(isac, ISAC_CMDR, 0x80);
115 			return;
116 		}
117 	}
118 	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
119 		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
120 			 isac->dch.rx_skb->len + count);
121 		WriteISAC(isac, ISAC_CMDR, 0x80);
122 		return;
123 	}
124 	ptr = skb_put(isac->dch.rx_skb, count);
125 	isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
126 	WriteISAC(isac, ISAC_CMDR, 0x80);
127 	if (isac->dch.debug & DEBUG_HW_DFIFO) {
128 		char	pfx[MISDN_MAX_IDLEN + 16];
129 
130 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
131 			 isac->name, count);
132 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
133 	}
134 }
135 
136 static void
isac_fill_fifo(struct isac_hw * isac)137 isac_fill_fifo(struct isac_hw *isac)
138 {
139 	int count, more;
140 	u8 *ptr;
141 
142 	if (!isac->dch.tx_skb)
143 		return;
144 	count = isac->dch.tx_skb->len - isac->dch.tx_idx;
145 	if (count <= 0)
146 		return;
147 
148 	more = 0;
149 	if (count > 32) {
150 		more = !0;
151 		count = 32;
152 	}
153 	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
154 	ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
155 	isac->dch.tx_idx += count;
156 	isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
157 	WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
158 	if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
159 		pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
160 		del_timer(&isac->dch.timer);
161 	}
162 	isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
163 	add_timer(&isac->dch.timer);
164 	if (isac->dch.debug & DEBUG_HW_DFIFO) {
165 		char	pfx[MISDN_MAX_IDLEN + 16];
166 
167 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
168 			 isac->name, count);
169 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
170 	}
171 }
172 
173 static void
isac_rme_irq(struct isac_hw * isac)174 isac_rme_irq(struct isac_hw *isac)
175 {
176 	u8 val, count;
177 
178 	val = ReadISAC(isac, ISAC_RSTA);
179 	if ((val & 0x70) != 0x20) {
180 		if (val & 0x40) {
181 			pr_debug("%s: ISAC RDO\n", isac->name);
182 #ifdef ERROR_STATISTIC
183 			isac->dch.err_rx++;
184 #endif
185 		}
186 		if (!(val & 0x20)) {
187 			pr_debug("%s: ISAC CRC error\n", isac->name);
188 #ifdef ERROR_STATISTIC
189 			isac->dch.err_crc++;
190 #endif
191 		}
192 		WriteISAC(isac, ISAC_CMDR, 0x80);
193 		dev_kfree_skb(isac->dch.rx_skb);
194 		isac->dch.rx_skb = NULL;
195 	} else {
196 		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
197 		if (count == 0)
198 			count = 32;
199 		isac_empty_fifo(isac, count);
200 		recv_Dchannel(&isac->dch);
201 	}
202 }
203 
204 static void
isac_xpr_irq(struct isac_hw * isac)205 isac_xpr_irq(struct isac_hw *isac)
206 {
207 	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
208 		del_timer(&isac->dch.timer);
209 	if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
210 		isac_fill_fifo(isac);
211 	} else {
212 		dev_kfree_skb(isac->dch.tx_skb);
213 		if (get_next_dframe(&isac->dch))
214 			isac_fill_fifo(isac);
215 	}
216 }
217 
218 static void
isac_retransmit(struct isac_hw * isac)219 isac_retransmit(struct isac_hw *isac)
220 {
221 	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
222 		del_timer(&isac->dch.timer);
223 	if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
224 		/* Restart frame */
225 		isac->dch.tx_idx = 0;
226 		isac_fill_fifo(isac);
227 	} else if (isac->dch.tx_skb) { /* should not happen */
228 		pr_info("%s: tx_skb exist but not busy\n", isac->name);
229 		test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
230 		isac->dch.tx_idx = 0;
231 		isac_fill_fifo(isac);
232 	} else {
233 		pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
234 		if (get_next_dframe(&isac->dch))
235 			isac_fill_fifo(isac);
236 	}
237 }
238 
239 static void
isac_mos_irq(struct isac_hw * isac)240 isac_mos_irq(struct isac_hw *isac)
241 {
242 	u8 val;
243 	int ret;
244 
245 	val = ReadISAC(isac, ISAC_MOSR);
246 	pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
247 #if ARCOFI_USE
248 	if (val & 0x08) {
249 		if (!isac->mon_rx) {
250 			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
251 			if (!isac->mon_rx) {
252 				pr_info("%s: ISAC MON RX out of memory!\n",
253 					isac->name);
254 				isac->mocr &= 0xf0;
255 				isac->mocr |= 0x0a;
256 				WriteISAC(isac, ISAC_MOCR, isac->mocr);
257 				goto afterMONR0;
258 			} else
259 				isac->mon_rxp = 0;
260 		}
261 		if (isac->mon_rxp >= MAX_MON_FRAME) {
262 			isac->mocr &= 0xf0;
263 			isac->mocr |= 0x0a;
264 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
265 			isac->mon_rxp = 0;
266 			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
267 			goto afterMONR0;
268 		}
269 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
270 		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
271 			 isac->mon_rx[isac->mon_rxp - 1]);
272 		if (isac->mon_rxp == 1) {
273 			isac->mocr |= 0x04;
274 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
275 		}
276 	}
277 afterMONR0:
278 	if (val & 0x80) {
279 		if (!isac->mon_rx) {
280 			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
281 			if (!isac->mon_rx) {
282 				pr_info("%s: ISAC MON RX out of memory!\n",
283 					isac->name);
284 				isac->mocr &= 0x0f;
285 				isac->mocr |= 0xa0;
286 				WriteISAC(isac, ISAC_MOCR, isac->mocr);
287 				goto afterMONR1;
288 			} else
289 				isac->mon_rxp = 0;
290 		}
291 		if (isac->mon_rxp >= MAX_MON_FRAME) {
292 			isac->mocr &= 0x0f;
293 			isac->mocr |= 0xa0;
294 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
295 			isac->mon_rxp = 0;
296 			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
297 			goto afterMONR1;
298 		}
299 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
300 		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
301 			 isac->mon_rx[isac->mon_rxp - 1]);
302 		isac->mocr |= 0x40;
303 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
304 	}
305 afterMONR1:
306 	if (val & 0x04) {
307 		isac->mocr &= 0xf0;
308 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
309 		isac->mocr |= 0x0a;
310 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
311 		if (isac->monitor) {
312 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
313 					    isac->mon_rx, isac->mon_rxp);
314 			if (ret)
315 				kfree(isac->mon_rx);
316 		} else {
317 			pr_info("%s: MONITOR 0 received %d but no user\n",
318 				isac->name, isac->mon_rxp);
319 			kfree(isac->mon_rx);
320 		}
321 		isac->mon_rx = NULL;
322 		isac->mon_rxp = 0;
323 	}
324 	if (val & 0x40) {
325 		isac->mocr &= 0x0f;
326 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
327 		isac->mocr |= 0xa0;
328 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
329 		if (isac->monitor) {
330 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
331 					    isac->mon_rx, isac->mon_rxp);
332 			if (ret)
333 				kfree(isac->mon_rx);
334 		} else {
335 			pr_info("%s: MONITOR 1 received %d but no user\n",
336 				isac->name, isac->mon_rxp);
337 			kfree(isac->mon_rx);
338 		}
339 		isac->mon_rx = NULL;
340 		isac->mon_rxp = 0;
341 	}
342 	if (val & 0x02) {
343 		if ((!isac->mon_tx) || (isac->mon_txc &&
344 					(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
345 			isac->mocr &= 0xf0;
346 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
347 			isac->mocr |= 0x0a;
348 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
349 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
350 				if (isac->monitor)
351 					isac->monitor(isac->dch.hw,
352 						      MONITOR_TX_0, NULL, 0);
353 			}
354 			kfree(isac->mon_tx);
355 			isac->mon_tx = NULL;
356 			isac->mon_txc = 0;
357 			isac->mon_txp = 0;
358 			goto AfterMOX0;
359 		}
360 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
361 			if (isac->monitor)
362 				isac->monitor(isac->dch.hw,
363 					      MONITOR_TX_0, NULL, 0);
364 			kfree(isac->mon_tx);
365 			isac->mon_tx = NULL;
366 			isac->mon_txc = 0;
367 			isac->mon_txp = 0;
368 			goto AfterMOX0;
369 		}
370 		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
371 		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
372 			 isac->mon_tx[isac->mon_txp - 1]);
373 	}
374 AfterMOX0:
375 	if (val & 0x20) {
376 		if ((!isac->mon_tx) || (isac->mon_txc &&
377 					(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
378 			isac->mocr &= 0x0f;
379 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
380 			isac->mocr |= 0xa0;
381 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
382 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
383 				if (isac->monitor)
384 					isac->monitor(isac->dch.hw,
385 						      MONITOR_TX_1, NULL, 0);
386 			}
387 			kfree(isac->mon_tx);
388 			isac->mon_tx = NULL;
389 			isac->mon_txc = 0;
390 			isac->mon_txp = 0;
391 			goto AfterMOX1;
392 		}
393 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
394 			if (isac->monitor)
395 				isac->monitor(isac->dch.hw,
396 					      MONITOR_TX_1, NULL, 0);
397 			kfree(isac->mon_tx);
398 			isac->mon_tx = NULL;
399 			isac->mon_txc = 0;
400 			isac->mon_txp = 0;
401 			goto AfterMOX1;
402 		}
403 		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
404 		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
405 			 isac->mon_tx[isac->mon_txp - 1]);
406 	}
407 AfterMOX1:
408 	val = 0; /* dummy to avoid warning */
409 #endif
410 }
411 
412 static void
isac_cisq_irq(struct isac_hw * isac)413 isac_cisq_irq(struct isac_hw *isac) {
414 	u8 val;
415 
416 	val = ReadISAC(isac, ISAC_CIR0);
417 	pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
418 	if (val & 2) {
419 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
420 			 isac->state, (val >> 2) & 0xf);
421 		isac->state = (val >> 2) & 0xf;
422 		isac_ph_state_change(isac);
423 	}
424 	if (val & 1) {
425 		val = ReadISAC(isac, ISAC_CIR1);
426 		pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
427 	}
428 }
429 
430 static void
isacsx_cic_irq(struct isac_hw * isac)431 isacsx_cic_irq(struct isac_hw *isac)
432 {
433 	u8 val;
434 
435 	val = ReadISAC(isac, ISACX_CIR0);
436 	pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
437 	if (val & ISACX_CIR0_CIC0) {
438 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
439 			 isac->state, val >> 4);
440 		isac->state = val >> 4;
441 		isac_ph_state_change(isac);
442 	}
443 }
444 
445 static void
isacsx_rme_irq(struct isac_hw * isac)446 isacsx_rme_irq(struct isac_hw *isac)
447 {
448 	int count;
449 	u8 val;
450 
451 	val = ReadISAC(isac, ISACX_RSTAD);
452 	if ((val & (ISACX_RSTAD_VFR |
453 		    ISACX_RSTAD_RDO |
454 		    ISACX_RSTAD_CRC |
455 		    ISACX_RSTAD_RAB))
456 	    != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
457 		pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
458 #ifdef ERROR_STATISTIC
459 		if (val & ISACX_RSTAD_CRC)
460 			isac->dch.err_rx++;
461 		else
462 			isac->dch.err_crc++;
463 #endif
464 		WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
465 		dev_kfree_skb(isac->dch.rx_skb);
466 		isac->dch.rx_skb = NULL;
467 	} else {
468 		count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
469 		if (count == 0)
470 			count = 32;
471 		isac_empty_fifo(isac, count);
472 		if (isac->dch.rx_skb) {
473 			skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
474 			pr_debug("%s: dchannel received %d\n", isac->name,
475 				 isac->dch.rx_skb->len);
476 			recv_Dchannel(&isac->dch);
477 		}
478 	}
479 }
480 
481 irqreturn_t
mISDNisac_irq(struct isac_hw * isac,u8 val)482 mISDNisac_irq(struct isac_hw *isac, u8 val)
483 {
484 	if (unlikely(!val))
485 		return IRQ_NONE;
486 	pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
487 	if (isac->type & IPAC_TYPE_ISACX) {
488 		if (val & ISACX__CIC)
489 			isacsx_cic_irq(isac);
490 		if (val & ISACX__ICD) {
491 			val = ReadISAC(isac, ISACX_ISTAD);
492 			pr_debug("%s: ISTAD %02x\n", isac->name, val);
493 			if (val & ISACX_D_XDU) {
494 				pr_debug("%s: ISAC XDU\n", isac->name);
495 #ifdef ERROR_STATISTIC
496 				isac->dch.err_tx++;
497 #endif
498 				isac_retransmit(isac);
499 			}
500 			if (val & ISACX_D_XMR) {
501 				pr_debug("%s: ISAC XMR\n", isac->name);
502 #ifdef ERROR_STATISTIC
503 				isac->dch.err_tx++;
504 #endif
505 				isac_retransmit(isac);
506 			}
507 			if (val & ISACX_D_XPR)
508 				isac_xpr_irq(isac);
509 			if (val & ISACX_D_RFO) {
510 				pr_debug("%s: ISAC RFO\n", isac->name);
511 				WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
512 			}
513 			if (val & ISACX_D_RME)
514 				isacsx_rme_irq(isac);
515 			if (val & ISACX_D_RPF)
516 				isac_empty_fifo(isac, 0x20);
517 		}
518 	} else {
519 		if (val & 0x80)	/* RME */
520 			isac_rme_irq(isac);
521 		if (val & 0x40)	/* RPF */
522 			isac_empty_fifo(isac, 32);
523 		if (val & 0x10)	/* XPR */
524 			isac_xpr_irq(isac);
525 		if (val & 0x04)	/* CISQ */
526 			isac_cisq_irq(isac);
527 		if (val & 0x20)	/* RSC - never */
528 			pr_debug("%s: ISAC RSC interrupt\n", isac->name);
529 		if (val & 0x02)	/* SIN - never */
530 			pr_debug("%s: ISAC SIN interrupt\n", isac->name);
531 		if (val & 0x01) {	/* EXI */
532 			val = ReadISAC(isac, ISAC_EXIR);
533 			pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
534 			if (val & 0x80)	/* XMR */
535 				pr_debug("%s: ISAC XMR\n", isac->name);
536 			if (val & 0x40) { /* XDU */
537 				pr_debug("%s: ISAC XDU\n", isac->name);
538 #ifdef ERROR_STATISTIC
539 				isac->dch.err_tx++;
540 #endif
541 				isac_retransmit(isac);
542 			}
543 			if (val & 0x04)	/* MOS */
544 				isac_mos_irq(isac);
545 		}
546 	}
547 	return IRQ_HANDLED;
548 }
549 EXPORT_SYMBOL(mISDNisac_irq);
550 
551 static int
isac_l1hw(struct mISDNchannel * ch,struct sk_buff * skb)552 isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
553 {
554 	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
555 	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
556 	struct isac_hw		*isac = container_of(dch, struct isac_hw, dch);
557 	int			ret = -EINVAL;
558 	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
559 	u32			id;
560 	u_long			flags;
561 
562 	switch (hh->prim) {
563 	case PH_DATA_REQ:
564 		spin_lock_irqsave(isac->hwlock, flags);
565 		ret = dchannel_senddata(dch, skb);
566 		if (ret > 0) { /* direct TX */
567 			id = hh->id; /* skb can be freed */
568 			isac_fill_fifo(isac);
569 			ret = 0;
570 			spin_unlock_irqrestore(isac->hwlock, flags);
571 			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
572 		} else
573 			spin_unlock_irqrestore(isac->hwlock, flags);
574 		return ret;
575 	case PH_ACTIVATE_REQ:
576 		ret = l1_event(dch->l1, hh->prim);
577 		break;
578 	case PH_DEACTIVATE_REQ:
579 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
580 		ret = l1_event(dch->l1, hh->prim);
581 		break;
582 	}
583 
584 	if (!ret)
585 		dev_kfree_skb(skb);
586 	return ret;
587 }
588 
589 static int
isac_ctrl(struct isac_hw * isac,u32 cmd,unsigned long para)590 isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para)
591 {
592 	u8 tl = 0;
593 	unsigned long flags;
594 	int ret = 0;
595 
596 	switch (cmd) {
597 	case HW_TESTLOOP:
598 		spin_lock_irqsave(isac->hwlock, flags);
599 		if (!(isac->type & IPAC_TYPE_ISACX)) {
600 			/* TODO: implement for IPAC_TYPE_ISACX */
601 			if (para & 1) /* B1 */
602 				tl |= 0x0c;
603 			else if (para & 2) /* B2 */
604 				tl |= 0x3;
605 			/* we only support IOM2 mode */
606 			WriteISAC(isac, ISAC_SPCR, tl);
607 			if (tl)
608 				WriteISAC(isac, ISAC_ADF1, 0x8);
609 			else
610 				WriteISAC(isac, ISAC_ADF1, 0x0);
611 		}
612 		spin_unlock_irqrestore(isac->hwlock, flags);
613 		break;
614 	case HW_TIMER3_VALUE:
615 		ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff));
616 		break;
617 	default:
618 		pr_debug("%s: %s unknown command %x %lx\n", isac->name,
619 			 __func__, cmd, para);
620 		ret = -1;
621 	}
622 	return ret;
623 }
624 
625 static int
isac_l1cmd(struct dchannel * dch,u32 cmd)626 isac_l1cmd(struct dchannel *dch, u32 cmd)
627 {
628 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
629 	u_long flags;
630 
631 	pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
632 	switch (cmd) {
633 	case INFO3_P8:
634 		spin_lock_irqsave(isac->hwlock, flags);
635 		ph_command(isac, ISAC_CMD_AR8);
636 		spin_unlock_irqrestore(isac->hwlock, flags);
637 		break;
638 	case INFO3_P10:
639 		spin_lock_irqsave(isac->hwlock, flags);
640 		ph_command(isac, ISAC_CMD_AR10);
641 		spin_unlock_irqrestore(isac->hwlock, flags);
642 		break;
643 	case HW_RESET_REQ:
644 		spin_lock_irqsave(isac->hwlock, flags);
645 		if ((isac->state == ISAC_IND_EI) ||
646 		    (isac->state == ISAC_IND_DR) ||
647 		    (isac->state == ISAC_IND_DR6) ||
648 		    (isac->state == ISAC_IND_RS))
649 			ph_command(isac, ISAC_CMD_TIM);
650 		else
651 			ph_command(isac, ISAC_CMD_RS);
652 		spin_unlock_irqrestore(isac->hwlock, flags);
653 		break;
654 	case HW_DEACT_REQ:
655 		skb_queue_purge(&dch->squeue);
656 		if (dch->tx_skb) {
657 			dev_kfree_skb(dch->tx_skb);
658 			dch->tx_skb = NULL;
659 		}
660 		dch->tx_idx = 0;
661 		if (dch->rx_skb) {
662 			dev_kfree_skb(dch->rx_skb);
663 			dch->rx_skb = NULL;
664 		}
665 		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
666 		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
667 			del_timer(&dch->timer);
668 		break;
669 	case HW_POWERUP_REQ:
670 		spin_lock_irqsave(isac->hwlock, flags);
671 		ph_command(isac, ISAC_CMD_TIM);
672 		spin_unlock_irqrestore(isac->hwlock, flags);
673 		break;
674 	case PH_ACTIVATE_IND:
675 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
676 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
677 			    GFP_ATOMIC);
678 		break;
679 	case PH_DEACTIVATE_IND:
680 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
681 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
682 			    GFP_ATOMIC);
683 		break;
684 	default:
685 		pr_debug("%s: %s unknown command %x\n", isac->name,
686 			 __func__, cmd);
687 		return -1;
688 	}
689 	return 0;
690 }
691 
692 static void
isac_release(struct isac_hw * isac)693 isac_release(struct isac_hw *isac)
694 {
695 	if (isac->type & IPAC_TYPE_ISACX)
696 		WriteISAC(isac, ISACX_MASK, 0xff);
697 	else if (isac->type != 0)
698 		WriteISAC(isac, ISAC_MASK, 0xff);
699 	if (isac->dch.timer.function != NULL) {
700 		del_timer(&isac->dch.timer);
701 		isac->dch.timer.function = NULL;
702 	}
703 	kfree(isac->mon_rx);
704 	isac->mon_rx = NULL;
705 	kfree(isac->mon_tx);
706 	isac->mon_tx = NULL;
707 	if (isac->dch.l1)
708 		l1_event(isac->dch.l1, CLOSE_CHANNEL);
709 	mISDN_freedchannel(&isac->dch);
710 }
711 
712 static void
dbusy_timer_handler(struct timer_list * t)713 dbusy_timer_handler(struct timer_list *t)
714 {
715 	struct isac_hw *isac = from_timer(isac, t, dch.timer);
716 	int rbch, star;
717 	u_long flags;
718 
719 	if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
720 		spin_lock_irqsave(isac->hwlock, flags);
721 		rbch = ReadISAC(isac, ISAC_RBCH);
722 		star = ReadISAC(isac, ISAC_STAR);
723 		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
724 			 isac->name, rbch, star);
725 		if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
726 			test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
727 		else {
728 			/* discard frame; reset transceiver */
729 			test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
730 			if (isac->dch.tx_idx)
731 				isac->dch.tx_idx = 0;
732 			else
733 				pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
734 					isac->name);
735 			/* Transmitter reset */
736 			WriteISAC(isac, ISAC_CMDR, 0x01);
737 		}
738 		spin_unlock_irqrestore(isac->hwlock, flags);
739 	}
740 }
741 
742 static int
open_dchannel_caller(struct isac_hw * isac,struct channel_req * rq,void * caller)743 open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
744 {
745 	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
746 		 isac->dch.dev.id, caller);
747 	if (rq->protocol != ISDN_P_TE_S0)
748 		return -EINVAL;
749 	if (rq->adr.channel == 1)
750 		/* E-Channel not supported */
751 		return -EINVAL;
752 	rq->ch = &isac->dch.dev.D;
753 	rq->ch->protocol = rq->protocol;
754 	if (isac->dch.state == 7)
755 		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
756 			    0, NULL, GFP_KERNEL);
757 	return 0;
758 }
759 
760 static int
open_dchannel(struct isac_hw * isac,struct channel_req * rq)761 open_dchannel(struct isac_hw *isac, struct channel_req *rq)
762 {
763 	return open_dchannel_caller(isac, rq, __builtin_return_address(0));
764 }
765 
766 static const char *ISACVer[] =
767 {"2086/2186 V1.1", "2085 B1", "2085 B2",
768  "2085 V2.3"};
769 
770 static int
isac_init(struct isac_hw * isac)771 isac_init(struct isac_hw *isac)
772 {
773 	u8 val;
774 	int err = 0;
775 
776 	if (!isac->dch.l1) {
777 		err = create_l1(&isac->dch, isac_l1cmd);
778 		if (err)
779 			return err;
780 	}
781 	isac->mon_tx = NULL;
782 	isac->mon_rx = NULL;
783 	timer_setup(&isac->dch.timer, dbusy_timer_handler, 0);
784 	isac->mocr = 0xaa;
785 	if (isac->type & IPAC_TYPE_ISACX) {
786 		/* Disable all IRQ */
787 		WriteISAC(isac, ISACX_MASK, 0xff);
788 		val = ReadISAC(isac, ISACX_STARD);
789 		pr_debug("%s: ISACX STARD %x\n", isac->name, val);
790 		val = ReadISAC(isac, ISACX_ISTAD);
791 		pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
792 		val = ReadISAC(isac, ISACX_ISTA);
793 		pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
794 		/* clear LDD */
795 		WriteISAC(isac, ISACX_TR_CONF0, 0x00);
796 		/* enable transmitter */
797 		WriteISAC(isac, ISACX_TR_CONF2, 0x00);
798 		/* transparent mode 0, RAC, stop/go */
799 		WriteISAC(isac, ISACX_MODED, 0xc9);
800 		/* all HDLC IRQ unmasked */
801 		val = ReadISAC(isac, ISACX_ID);
802 		if (isac->dch.debug & DEBUG_HW)
803 			pr_notice("%s: ISACX Design ID %x\n",
804 				  isac->name, val & 0x3f);
805 		val = ReadISAC(isac, ISACX_CIR0);
806 		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
807 		isac->state = val >> 4;
808 		isac_ph_state_change(isac);
809 		ph_command(isac, ISAC_CMD_RS);
810 		WriteISAC(isac, ISACX_MASK, IPACX__ON);
811 		WriteISAC(isac, ISACX_MASKD, 0x00);
812 	} else { /* old isac */
813 		WriteISAC(isac, ISAC_MASK, 0xff);
814 		val = ReadISAC(isac, ISAC_STAR);
815 		pr_debug("%s: ISAC STAR %x\n", isac->name, val);
816 		val = ReadISAC(isac, ISAC_MODE);
817 		pr_debug("%s: ISAC MODE %x\n", isac->name, val);
818 		val = ReadISAC(isac, ISAC_ADF2);
819 		pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
820 		val = ReadISAC(isac, ISAC_ISTA);
821 		pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
822 		if (val & 0x01) {
823 			val = ReadISAC(isac, ISAC_EXIR);
824 			pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
825 		}
826 		val = ReadISAC(isac, ISAC_RBCH);
827 		if (isac->dch.debug & DEBUG_HW)
828 			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
829 				  val, ISACVer[(val >> 5) & 3]);
830 		isac->type |= ((val >> 5) & 3);
831 		if (!isac->adf2)
832 			isac->adf2 = 0x80;
833 		if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
834 			pr_info("%s: only support IOM2 mode but adf2=%02x\n",
835 				isac->name, isac->adf2);
836 			isac_release(isac);
837 			return -EINVAL;
838 		}
839 		WriteISAC(isac, ISAC_ADF2, isac->adf2);
840 		WriteISAC(isac, ISAC_SQXR, 0x2f);
841 		WriteISAC(isac, ISAC_SPCR, 0x00);
842 		WriteISAC(isac, ISAC_STCR, 0x70);
843 		WriteISAC(isac, ISAC_MODE, 0xc9);
844 		WriteISAC(isac, ISAC_TIMR, 0x00);
845 		WriteISAC(isac, ISAC_ADF1, 0x00);
846 		val = ReadISAC(isac, ISAC_CIR0);
847 		pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
848 		isac->state = (val >> 2) & 0xf;
849 		isac_ph_state_change(isac);
850 		ph_command(isac, ISAC_CMD_RS);
851 		WriteISAC(isac, ISAC_MASK, 0);
852 	}
853 	return err;
854 }
855 
856 int
mISDNisac_init(struct isac_hw * isac,void * hw)857 mISDNisac_init(struct isac_hw *isac, void *hw)
858 {
859 	mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
860 	isac->dch.hw = hw;
861 	isac->dch.dev.D.send = isac_l1hw;
862 	isac->init = isac_init;
863 	isac->release = isac_release;
864 	isac->ctrl = isac_ctrl;
865 	isac->open = open_dchannel;
866 	isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
867 	isac->dch.dev.nrbchan = 2;
868 	return 0;
869 }
870 EXPORT_SYMBOL(mISDNisac_init);
871 
872 static void
waitforCEC(struct hscx_hw * hx)873 waitforCEC(struct hscx_hw *hx)
874 {
875 	u8 starb, to = 50;
876 
877 	while (to) {
878 		starb = ReadHSCX(hx, IPAC_STARB);
879 		if (!(starb & 0x04))
880 			break;
881 		udelay(1);
882 		to--;
883 	}
884 	if (to < 50)
885 		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
886 			 50 - to);
887 	if (!to)
888 		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
889 }
890 
891 
892 static void
waitforXFW(struct hscx_hw * hx)893 waitforXFW(struct hscx_hw *hx)
894 {
895 	u8 starb, to = 50;
896 
897 	while (to) {
898 		starb = ReadHSCX(hx, IPAC_STARB);
899 		if ((starb & 0x44) == 0x40)
900 			break;
901 		udelay(1);
902 		to--;
903 	}
904 	if (to < 50)
905 		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
906 			 50 - to);
907 	if (!to)
908 		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
909 }
910 
911 static void
hscx_cmdr(struct hscx_hw * hx,u8 cmd)912 hscx_cmdr(struct hscx_hw *hx, u8 cmd)
913 {
914 	if (hx->ip->type & IPAC_TYPE_IPACX)
915 		WriteHSCX(hx, IPACX_CMDRB, cmd);
916 	else {
917 		waitforCEC(hx);
918 		WriteHSCX(hx, IPAC_CMDRB, cmd);
919 	}
920 }
921 
922 static void
hscx_empty_fifo(struct hscx_hw * hscx,u8 count)923 hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
924 {
925 	u8 *p;
926 	int maxlen;
927 
928 	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
929 	if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
930 		hscx->bch.dropcnt += count;
931 		hscx_cmdr(hscx, 0x80); /* RMC */
932 		return;
933 	}
934 	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
935 	if (maxlen < 0) {
936 		hscx_cmdr(hscx, 0x80); /* RMC */
937 		if (hscx->bch.rx_skb)
938 			skb_trim(hscx->bch.rx_skb, 0);
939 		pr_warn("%s.B%d: No bufferspace for %d bytes\n",
940 			hscx->ip->name, hscx->bch.nr, count);
941 		return;
942 	}
943 	p = skb_put(hscx->bch.rx_skb, count);
944 
945 	if (hscx->ip->type & IPAC_TYPE_IPACX)
946 		hscx->ip->read_fifo(hscx->ip->hw,
947 				    hscx->off + IPACX_RFIFOB, p, count);
948 	else
949 		hscx->ip->read_fifo(hscx->ip->hw,
950 				    hscx->off, p, count);
951 
952 	hscx_cmdr(hscx, 0x80); /* RMC */
953 
954 	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
955 		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
956 			 hscx->bch.nr, hscx->ip->name, count);
957 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
958 	}
959 }
960 
961 static void
hscx_fill_fifo(struct hscx_hw * hscx)962 hscx_fill_fifo(struct hscx_hw *hscx)
963 {
964 	int count, more;
965 	u8 *p;
966 
967 	if (!hscx->bch.tx_skb) {
968 		if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
969 			return;
970 		count = hscx->fifo_size;
971 		more = 1;
972 		p = hscx->log;
973 		memset(p, hscx->bch.fill[0], count);
974 	} else {
975 		count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
976 		if (count <= 0)
977 			return;
978 		p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
979 
980 		more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
981 		if (count > hscx->fifo_size) {
982 			count = hscx->fifo_size;
983 			more = 1;
984 		}
985 		pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
986 			 count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
987 		hscx->bch.tx_idx += count;
988 	}
989 	if (hscx->ip->type & IPAC_TYPE_IPACX)
990 		hscx->ip->write_fifo(hscx->ip->hw,
991 				     hscx->off + IPACX_XFIFOB, p, count);
992 	else {
993 		waitforXFW(hscx);
994 		hscx->ip->write_fifo(hscx->ip->hw,
995 				     hscx->off, p, count);
996 	}
997 	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
998 
999 	if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
1000 		snprintf(hscx->log, 64, "B%1d-send %s %d ",
1001 			 hscx->bch.nr, hscx->ip->name, count);
1002 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
1003 	}
1004 }
1005 
1006 static void
hscx_xpr(struct hscx_hw * hx)1007 hscx_xpr(struct hscx_hw *hx)
1008 {
1009 	if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
1010 		hscx_fill_fifo(hx);
1011 	} else {
1012 		dev_kfree_skb(hx->bch.tx_skb);
1013 		if (get_next_bframe(&hx->bch)) {
1014 			hscx_fill_fifo(hx);
1015 			test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1016 		} else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
1017 			hscx_fill_fifo(hx);
1018 		}
1019 	}
1020 }
1021 
1022 static void
ipac_rme(struct hscx_hw * hx)1023 ipac_rme(struct hscx_hw *hx)
1024 {
1025 	int count;
1026 	u8 rstab;
1027 
1028 	if (hx->ip->type & IPAC_TYPE_IPACX)
1029 		rstab = ReadHSCX(hx, IPACX_RSTAB);
1030 	else
1031 		rstab = ReadHSCX(hx, IPAC_RSTAB);
1032 	pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
1033 	if ((rstab & 0xf0) != 0xa0) {
1034 		/* !(VFR && !RDO && CRC && !RAB) */
1035 		if (!(rstab & 0x80)) {
1036 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1037 				pr_notice("%s: B%1d invalid frame\n",
1038 					  hx->ip->name, hx->bch.nr);
1039 		}
1040 		if (rstab & 0x40) {
1041 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1042 				pr_notice("%s: B%1d RDO proto=%x\n",
1043 					  hx->ip->name, hx->bch.nr,
1044 					  hx->bch.state);
1045 		}
1046 		if (!(rstab & 0x20)) {
1047 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1048 				pr_notice("%s: B%1d CRC error\n",
1049 					  hx->ip->name, hx->bch.nr);
1050 		}
1051 		hscx_cmdr(hx, 0x80); /* Do RMC */
1052 		return;
1053 	}
1054 	if (hx->ip->type & IPAC_TYPE_IPACX)
1055 		count = ReadHSCX(hx, IPACX_RBCLB);
1056 	else
1057 		count = ReadHSCX(hx, IPAC_RBCLB);
1058 	count &= (hx->fifo_size - 1);
1059 	if (count == 0)
1060 		count = hx->fifo_size;
1061 	hscx_empty_fifo(hx, count);
1062 	if (!hx->bch.rx_skb)
1063 		return;
1064 	if (hx->bch.rx_skb->len < 2) {
1065 		pr_debug("%s: B%1d frame too short %d\n",
1066 			 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
1067 		skb_trim(hx->bch.rx_skb, 0);
1068 	} else {
1069 		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1070 		recv_Bchannel(&hx->bch, 0, false);
1071 	}
1072 }
1073 
1074 static void
ipac_irq(struct hscx_hw * hx,u8 ista)1075 ipac_irq(struct hscx_hw *hx, u8 ista)
1076 {
1077 	u8 istab, m, exirb = 0;
1078 
1079 	if (hx->ip->type & IPAC_TYPE_IPACX)
1080 		istab = ReadHSCX(hx, IPACX_ISTAB);
1081 	else if (hx->ip->type & IPAC_TYPE_IPAC) {
1082 		istab = ReadHSCX(hx, IPAC_ISTAB);
1083 		m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
1084 		if (m & ista) {
1085 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1086 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1087 				 hx->bch.nr, exirb);
1088 		}
1089 	} else if (hx->bch.nr & 2) { /* HSCX B */
1090 		if (ista & (HSCX__EXA | HSCX__ICA))
1091 			ipac_irq(&hx->ip->hscx[0], ista);
1092 		if (ista & HSCX__EXB) {
1093 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1094 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1095 				 hx->bch.nr, exirb);
1096 		}
1097 		istab = ista & 0xF8;
1098 	} else { /* HSCX A */
1099 		istab = ReadHSCX(hx, IPAC_ISTAB);
1100 		if (ista & HSCX__EXA) {
1101 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1102 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1103 				 hx->bch.nr, exirb);
1104 		}
1105 		istab = istab & 0xF8;
1106 	}
1107 	if (exirb & IPAC_B_XDU)
1108 		istab |= IPACX_B_XDU;
1109 	if (exirb & IPAC_B_RFO)
1110 		istab |= IPACX_B_RFO;
1111 	pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
1112 
1113 	if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
1114 		return;
1115 
1116 	if (istab & IPACX_B_RME)
1117 		ipac_rme(hx);
1118 
1119 	if (istab & IPACX_B_RPF) {
1120 		hscx_empty_fifo(hx, hx->fifo_size);
1121 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1122 			recv_Bchannel(&hx->bch, 0, false);
1123 	}
1124 
1125 	if (istab & IPACX_B_RFO) {
1126 		pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
1127 		hscx_cmdr(hx, 0x40);	/* RRES */
1128 	}
1129 
1130 	if (istab & IPACX_B_XPR)
1131 		hscx_xpr(hx);
1132 
1133 	if (istab & IPACX_B_XDU) {
1134 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1135 			if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
1136 				test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1137 			hscx_xpr(hx);
1138 			return;
1139 		}
1140 		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
1141 			 hx->bch.nr, hx->bch.tx_idx);
1142 		hx->bch.tx_idx = 0;
1143 		hscx_cmdr(hx, 0x01);	/* XRES */
1144 	}
1145 }
1146 
1147 irqreturn_t
mISDNipac_irq(struct ipac_hw * ipac,int maxloop)1148 mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
1149 {
1150 	int cnt = maxloop + 1;
1151 	u8 ista, istad;
1152 	struct isac_hw  *isac = &ipac->isac;
1153 
1154 	if (ipac->type & IPAC_TYPE_IPACX) {
1155 		ista = ReadIPAC(ipac, ISACX_ISTA);
1156 		while (ista && --cnt) {
1157 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1158 			if (ista & IPACX__ICA)
1159 				ipac_irq(&ipac->hscx[0], ista);
1160 			if (ista & IPACX__ICB)
1161 				ipac_irq(&ipac->hscx[1], ista);
1162 			if (ista & (ISACX__ICD | ISACX__CIC))
1163 				mISDNisac_irq(&ipac->isac, ista);
1164 			ista = ReadIPAC(ipac, ISACX_ISTA);
1165 		}
1166 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1167 		ista = ReadIPAC(ipac, IPAC_ISTA);
1168 		while (ista && --cnt) {
1169 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1170 			if (ista & (IPAC__ICD | IPAC__EXD)) {
1171 				istad = ReadISAC(isac, ISAC_ISTA);
1172 				pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1173 				if (istad & IPAC_D_TIN2)
1174 					pr_debug("%s TIN2 irq\n", ipac->name);
1175 				if (ista & IPAC__EXD)
1176 					istad |= 1; /* ISAC EXI */
1177 				mISDNisac_irq(isac, istad);
1178 			}
1179 			if (ista & (IPAC__ICA | IPAC__EXA))
1180 				ipac_irq(&ipac->hscx[0], ista);
1181 			if (ista & (IPAC__ICB | IPAC__EXB))
1182 				ipac_irq(&ipac->hscx[1], ista);
1183 			ista = ReadIPAC(ipac, IPAC_ISTA);
1184 		}
1185 	} else if (ipac->type & IPAC_TYPE_HSCX) {
1186 		while (--cnt) {
1187 			ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
1188 			pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
1189 			if (ista)
1190 				ipac_irq(&ipac->hscx[1], ista);
1191 			istad = ReadISAC(isac, ISAC_ISTA);
1192 			pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1193 			if (istad)
1194 				mISDNisac_irq(isac, istad);
1195 			if (0 == (ista | istad))
1196 				break;
1197 		}
1198 	}
1199 	if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
1200 		return IRQ_NONE;
1201 	if (cnt < maxloop)
1202 		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
1203 			 maxloop - cnt, smp_processor_id());
1204 	if (maxloop && !cnt)
1205 		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
1206 			  maxloop, smp_processor_id());
1207 	return IRQ_HANDLED;
1208 }
1209 EXPORT_SYMBOL(mISDNipac_irq);
1210 
1211 static int
hscx_mode(struct hscx_hw * hscx,u32 bprotocol)1212 hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
1213 {
1214 	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
1215 		 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
1216 	if (hscx->ip->type & IPAC_TYPE_IPACX) {
1217 		if (hscx->bch.nr & 1) { /* B1 and ICA */
1218 			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
1219 			WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
1220 		} else { /* B2 and ICB */
1221 			WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
1222 			WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
1223 		}
1224 		switch (bprotocol) {
1225 		case ISDN_P_NONE: /* init */
1226 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* rec off */
1227 			WriteHSCX(hscx, IPACX_EXMB,  0x30);	/* std adj. */
1228 			WriteHSCX(hscx, IPACX_MASKB, 0xFF);	/* ints off */
1229 			hscx_cmdr(hscx, 0x41);
1230 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1231 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1232 			break;
1233 		case ISDN_P_B_RAW:
1234 			WriteHSCX(hscx, IPACX_MODEB, 0x88);	/* ex trans */
1235 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* trans */
1236 			hscx_cmdr(hscx, 0x41);
1237 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1238 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1239 			break;
1240 		case ISDN_P_B_HDLC:
1241 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* trans */
1242 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* hdlc,crc */
1243 			hscx_cmdr(hscx, 0x41);
1244 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1245 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1246 			break;
1247 		default:
1248 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1249 				bprotocol);
1250 			return -ENOPROTOOPT;
1251 		}
1252 	} else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
1253 		WriteHSCX(hscx, IPAC_CCR1, 0x82);
1254 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1255 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1256 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1257 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1258 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1259 		switch (bprotocol) {
1260 		case ISDN_P_NONE:
1261 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1262 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1263 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1264 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1265 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1266 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1267 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1268 			break;
1269 		case ISDN_P_B_RAW:
1270 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1271 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1272 			hscx_cmdr(hscx, 0x41);
1273 			WriteHSCX(hscx, IPAC_MASKB, 0);
1274 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1275 			break;
1276 		case ISDN_P_B_HDLC:
1277 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1278 			WriteHSCX(hscx, IPAC_CCR1, 0x8a);
1279 			hscx_cmdr(hscx, 0x41);
1280 			WriteHSCX(hscx, IPAC_MASKB, 0);
1281 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1282 			break;
1283 		default:
1284 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1285 				bprotocol);
1286 			return -ENOPROTOOPT;
1287 		}
1288 	} else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
1289 		WriteHSCX(hscx, IPAC_CCR1, 0x85);
1290 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1291 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1292 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1293 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1294 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1295 		switch (bprotocol) {
1296 		case ISDN_P_NONE:
1297 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1298 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1299 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1300 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1301 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1302 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1303 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1304 			break;
1305 		case ISDN_P_B_RAW:
1306 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1307 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1308 			hscx_cmdr(hscx, 0x41);
1309 			WriteHSCX(hscx, IPAC_MASKB, 0);
1310 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1311 			break;
1312 		case ISDN_P_B_HDLC:
1313 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1314 			WriteHSCX(hscx, IPAC_CCR1, 0x8d);
1315 			hscx_cmdr(hscx, 0x41);
1316 			WriteHSCX(hscx, IPAC_MASKB, 0);
1317 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1318 			break;
1319 		default:
1320 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1321 				bprotocol);
1322 			return -ENOPROTOOPT;
1323 		}
1324 	} else
1325 		return -EINVAL;
1326 	hscx->bch.state = bprotocol;
1327 	return 0;
1328 }
1329 
1330 static int
hscx_l2l1(struct mISDNchannel * ch,struct sk_buff * skb)1331 hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1332 {
1333 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1334 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1335 	int ret = -EINVAL;
1336 	struct mISDNhead *hh = mISDN_HEAD_P(skb);
1337 	unsigned long flags;
1338 
1339 	switch (hh->prim) {
1340 	case PH_DATA_REQ:
1341 		spin_lock_irqsave(hx->ip->hwlock, flags);
1342 		ret = bchannel_senddata(bch, skb);
1343 		if (ret > 0) { /* direct TX */
1344 			ret = 0;
1345 			hscx_fill_fifo(hx);
1346 		}
1347 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1348 		return ret;
1349 	case PH_ACTIVATE_REQ:
1350 		spin_lock_irqsave(hx->ip->hwlock, flags);
1351 		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1352 			ret = hscx_mode(hx, ch->protocol);
1353 		else
1354 			ret = 0;
1355 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1356 		if (!ret)
1357 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1358 				    NULL, GFP_KERNEL);
1359 		break;
1360 	case PH_DEACTIVATE_REQ:
1361 		spin_lock_irqsave(hx->ip->hwlock, flags);
1362 		mISDN_clear_bchannel(bch);
1363 		hscx_mode(hx, ISDN_P_NONE);
1364 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1365 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1366 			    NULL, GFP_KERNEL);
1367 		ret = 0;
1368 		break;
1369 	default:
1370 		pr_info("%s: %s unknown prim(%x,%x)\n",
1371 			hx->ip->name, __func__, hh->prim, hh->id);
1372 		ret = -EINVAL;
1373 	}
1374 	if (!ret)
1375 		dev_kfree_skb(skb);
1376 	return ret;
1377 }
1378 
1379 static int
channel_bctrl(struct bchannel * bch,struct mISDN_ctrl_req * cq)1380 channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1381 {
1382 	return mISDN_ctrl_bchannel(bch, cq);
1383 }
1384 
1385 static int
hscx_bctrl(struct mISDNchannel * ch,u32 cmd,void * arg)1386 hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1387 {
1388 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1389 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1390 	int ret = -EINVAL;
1391 	u_long flags;
1392 
1393 	pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
1394 	switch (cmd) {
1395 	case CLOSE_CHANNEL:
1396 		test_and_clear_bit(FLG_OPEN, &bch->Flags);
1397 		cancel_work_sync(&bch->workq);
1398 		spin_lock_irqsave(hx->ip->hwlock, flags);
1399 		mISDN_clear_bchannel(bch);
1400 		hscx_mode(hx, ISDN_P_NONE);
1401 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1402 		ch->protocol = ISDN_P_NONE;
1403 		ch->peer = NULL;
1404 		module_put(hx->ip->owner);
1405 		ret = 0;
1406 		break;
1407 	case CONTROL_CHANNEL:
1408 		ret = channel_bctrl(bch, arg);
1409 		break;
1410 	default:
1411 		pr_info("%s: %s unknown prim(%x)\n",
1412 			hx->ip->name, __func__, cmd);
1413 	}
1414 	return ret;
1415 }
1416 
1417 static void
free_ipac(struct ipac_hw * ipac)1418 free_ipac(struct ipac_hw *ipac)
1419 {
1420 	isac_release(&ipac->isac);
1421 }
1422 
1423 static const char *HSCXVer[] =
1424 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1425  "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1426 
1427 
1428 
1429 static void
hscx_init(struct hscx_hw * hx)1430 hscx_init(struct hscx_hw *hx)
1431 {
1432 	u8 val;
1433 
1434 	WriteHSCX(hx, IPAC_RAH2, 0xFF);
1435 	WriteHSCX(hx, IPAC_XBCH, 0x00);
1436 	WriteHSCX(hx, IPAC_RLCR, 0x00);
1437 
1438 	if (hx->ip->type & IPAC_TYPE_HSCX) {
1439 		WriteHSCX(hx, IPAC_CCR1, 0x85);
1440 		val = ReadHSCX(hx, HSCX_VSTR);
1441 		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
1442 		if (hx->bch.debug & DEBUG_HW)
1443 			pr_notice("%s: HSCX version %s\n", hx->ip->name,
1444 				  HSCXVer[val & 0x0f]);
1445 	} else
1446 		WriteHSCX(hx, IPAC_CCR1, 0x82);
1447 	WriteHSCX(hx, IPAC_CCR2, 0x30);
1448 	WriteHSCX(hx, IPAC_XCCR, 0x07);
1449 	WriteHSCX(hx, IPAC_RCCR, 0x07);
1450 }
1451 
1452 static int
ipac_init(struct ipac_hw * ipac)1453 ipac_init(struct ipac_hw *ipac)
1454 {
1455 	u8 val;
1456 
1457 	if (ipac->type & IPAC_TYPE_HSCX) {
1458 		hscx_init(&ipac->hscx[0]);
1459 		hscx_init(&ipac->hscx[1]);
1460 		val = ReadIPAC(ipac, IPAC_ID);
1461 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1462 		hscx_init(&ipac->hscx[0]);
1463 		hscx_init(&ipac->hscx[1]);
1464 		WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
1465 		val = ReadIPAC(ipac, IPAC_CONF);
1466 		/* conf is default 0, but can be overwritten by card setup */
1467 		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
1468 			 val, ipac->conf);
1469 		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
1470 		val = ReadIPAC(ipac, IPAC_ID);
1471 		if (ipac->hscx[0].bch.debug & DEBUG_HW)
1472 			pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
1473 	}
1474 	/* nothing special for IPACX to do here */
1475 	return isac_init(&ipac->isac);
1476 }
1477 
1478 static int
open_bchannel(struct ipac_hw * ipac,struct channel_req * rq)1479 open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
1480 {
1481 	struct bchannel		*bch;
1482 
1483 	if (rq->adr.channel == 0 || rq->adr.channel > 2)
1484 		return -EINVAL;
1485 	if (rq->protocol == ISDN_P_NONE)
1486 		return -EINVAL;
1487 	bch = &ipac->hscx[rq->adr.channel - 1].bch;
1488 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1489 		return -EBUSY; /* b-channel can be only open once */
1490 	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1491 	bch->ch.protocol = rq->protocol;
1492 	rq->ch = &bch->ch;
1493 	return 0;
1494 }
1495 
1496 static int
channel_ctrl(struct ipac_hw * ipac,struct mISDN_ctrl_req * cq)1497 channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
1498 {
1499 	int	ret = 0;
1500 
1501 	switch (cq->op) {
1502 	case MISDN_CTRL_GETOP:
1503 		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
1504 		break;
1505 	case MISDN_CTRL_LOOP:
1506 		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1507 		if (cq->channel < 0 || cq->channel > 3) {
1508 			ret = -EINVAL;
1509 			break;
1510 		}
1511 		ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
1512 		break;
1513 	case MISDN_CTRL_L1_TIMER3:
1514 		ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
1515 		break;
1516 	default:
1517 		pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
1518 		ret = -EINVAL;
1519 		break;
1520 	}
1521 	return ret;
1522 }
1523 
1524 static int
ipac_dctrl(struct mISDNchannel * ch,u32 cmd,void * arg)1525 ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1526 {
1527 	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1528 	struct dchannel *dch = container_of(dev, struct dchannel, dev);
1529 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
1530 	struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
1531 	struct channel_req *rq;
1532 	int err = 0;
1533 
1534 	pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
1535 	switch (cmd) {
1536 	case OPEN_CHANNEL:
1537 		rq = arg;
1538 		if (rq->protocol == ISDN_P_TE_S0)
1539 			err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
1540 		else
1541 			err = open_bchannel(ipac, rq);
1542 		if (err)
1543 			break;
1544 		if (!try_module_get(ipac->owner))
1545 			pr_info("%s: cannot get module\n", ipac->name);
1546 		break;
1547 	case CLOSE_CHANNEL:
1548 		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
1549 			 dch->dev.id, __builtin_return_address(0));
1550 		module_put(ipac->owner);
1551 		break;
1552 	case CONTROL_CHANNEL:
1553 		err = channel_ctrl(ipac, arg);
1554 		break;
1555 	default:
1556 		pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
1557 		return -EINVAL;
1558 	}
1559 	return err;
1560 }
1561 
1562 u32
mISDNipac_init(struct ipac_hw * ipac,void * hw)1563 mISDNipac_init(struct ipac_hw *ipac, void *hw)
1564 {
1565 	u32 ret;
1566 	u8 i;
1567 
1568 	ipac->hw = hw;
1569 	if (ipac->isac.dch.debug & DEBUG_HW)
1570 		pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
1571 	if (ipac->type & IPAC_TYPE_HSCX) {
1572 		ipac->isac.type = IPAC_TYPE_ISAC;
1573 		ipac->hscx[0].off = 0;
1574 		ipac->hscx[1].off = 0x40;
1575 		ipac->hscx[0].fifo_size = 32;
1576 		ipac->hscx[1].fifo_size = 32;
1577 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1578 		ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
1579 		ipac->hscx[0].off = 0;
1580 		ipac->hscx[1].off = 0x40;
1581 		ipac->hscx[0].fifo_size = 64;
1582 		ipac->hscx[1].fifo_size = 64;
1583 	} else if (ipac->type & IPAC_TYPE_IPACX) {
1584 		ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
1585 		ipac->hscx[0].off = IPACX_OFF_ICA;
1586 		ipac->hscx[1].off = IPACX_OFF_ICB;
1587 		ipac->hscx[0].fifo_size = 64;
1588 		ipac->hscx[1].fifo_size = 64;
1589 	} else
1590 		return 0;
1591 
1592 	mISDNisac_init(&ipac->isac, hw);
1593 
1594 	ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
1595 
1596 	for (i = 0; i < 2; i++) {
1597 		ipac->hscx[i].bch.nr = i + 1;
1598 		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1599 		list_add(&ipac->hscx[i].bch.ch.list,
1600 			 &ipac->isac.dch.dev.bchannels);
1601 		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
1602 				   ipac->hscx[i].fifo_size);
1603 		ipac->hscx[i].bch.ch.nr = i + 1;
1604 		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1605 		ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
1606 		ipac->hscx[i].bch.hw = hw;
1607 		ipac->hscx[i].ip = ipac;
1608 		/* default values for IOM time slots
1609 		 * can be overwritten by card */
1610 		ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
1611 	}
1612 
1613 	ipac->init = ipac_init;
1614 	ipac->release = free_ipac;
1615 
1616 	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1617 		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1618 	return ret;
1619 }
1620 EXPORT_SYMBOL(mISDNipac_init);
1621 
1622 static int __init
isac_mod_init(void)1623 isac_mod_init(void)
1624 {
1625 	pr_notice("mISDNipac module version %s\n", ISAC_REV);
1626 	return 0;
1627 }
1628 
1629 static void __exit
isac_mod_cleanup(void)1630 isac_mod_cleanup(void)
1631 {
1632 	pr_notice("mISDNipac module unloaded\n");
1633 }
1634 module_init(isac_mod_init);
1635 module_exit(isac_mod_cleanup);
1636