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
22MODULE_AUTHOR("Karsten Keil");
23MODULE_VERSION(ISAC_REV);
24MODULE_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
33static inline void
34ph_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
43static void
44isac_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
54static void
55isac_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
103static void
104isac_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
136static void
137isac_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
173static void
174isac_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
204static void
205isac_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
218static void
219isac_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
239static void
240isac_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	}
277afterMONR0:
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	}
305afterMONR1:
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	}
374AfterMOX0:
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	}
407AfterMOX1:
408	val = 0; /* dummy to avoid warning */
409#endif
410}
411
412static void
413isac_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
430static void
431isacsx_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
445static void
446isacsx_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
481irqreturn_t
482mISDNisac_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}
549EXPORT_SYMBOL(mISDNisac_irq);
550
551static int
552isac_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
589static int
590isac_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
625static int
626isac_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
692static void
693isac_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
712static void
713dbusy_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
742static int
743open_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
760static int
761open_dchannel(struct isac_hw *isac, struct channel_req *rq)
762{
763	return open_dchannel_caller(isac, rq, __builtin_return_address(0));
764}
765
766static const char *ISACVer[] =
767{"2086/2186 V1.1", "2085 B1", "2085 B2",
768 "2085 V2.3"};
769
770static int
771isac_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
856int
857mISDNisac_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}
870EXPORT_SYMBOL(mISDNisac_init);
871
872static void
873waitforCEC(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
892static void
893waitforXFW(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
911static void
912hscx_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
922static void
923hscx_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
961static void
962hscx_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
1006static void
1007hscx_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
1022static void
1023ipac_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
1074static void
1075ipac_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
1147irqreturn_t
1148mISDNipac_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}
1209EXPORT_SYMBOL(mISDNipac_irq);
1210
1211static int
1212hscx_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
1330static int
1331hscx_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
1379static int
1380channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1381{
1382	return mISDN_ctrl_bchannel(bch, cq);
1383}
1384
1385static int
1386hscx_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
1417static void
1418free_ipac(struct ipac_hw *ipac)
1419{
1420	isac_release(&ipac->isac);
1421}
1422
1423static const char *HSCXVer[] =
1424{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1425 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1426
1427
1428
1429static void
1430hscx_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
1452static int
1453ipac_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
1478static int
1479open_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
1496static int
1497channel_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
1524static int
1525ipac_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
1562u32
1563mISDNipac_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}
1620EXPORT_SYMBOL(mISDNipac_init);
1621
1622static int __init
1623isac_mod_init(void)
1624{
1625	pr_notice("mISDNipac module version %s\n", ISAC_REV);
1626	return 0;
1627}
1628
1629static void __exit
1630isac_mod_cleanup(void)
1631{
1632	pr_notice("mISDNipac module unloaded\n");
1633}
1634module_init(isac_mod_init);
1635module_exit(isac_mod_cleanup);
1636