1/* $Id: w6692.c,v 1.18.2.4 2004/02/11 13:21:34 keil Exp $
2 *
3 * Winbond W6692 specific routines
4 *
5 * Author       Petr Novak
6 * Copyright    by Petr Novak        <petr.novak@i.cz>
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 *
11 */
12
13#include <linux/init.h>
14#include "hisax.h"
15#include "w6692.h"
16#include "isdnl1.h"
17#include <linux/interrupt.h>
18#include <linux/pci.h>
19#include <linux/slab.h>
20
21/* table entry in the PCI devices list */
22typedef struct {
23	int vendor_id;
24	int device_id;
25	char *vendor_name;
26	char *card_name;
27} PCI_ENTRY;
28
29static const PCI_ENTRY id_list[] =
30{
31	{PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"},
32	{PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"},
33	{0, 0, "U.S.Robotics", "ISDN PCI Card TA"}
34};
35
36#define W6692_SV_USR   0x16ec
37#define W6692_SD_USR   0x3409
38#define W6692_WINBOND  0
39#define W6692_DYNALINK 1
40#define W6692_USR      2
41
42static const char *w6692_revision = "$Revision: 1.18.2.4 $";
43
44#define DBUSY_TIMER_VALUE 80
45
46static char *W6692Ver[] =
47{"W6692 V00", "W6692 V01", "W6692 V10",
48 "W6692 V11"};
49
50static void
51W6692Version(struct IsdnCardState *cs, char *s)
52{
53	int val;
54
55	val = cs->readW6692(cs, W_D_RBCH);
56	printk(KERN_INFO "%s Winbond W6692 version (%x): %s\n", s, val, W6692Ver[(val >> 6) & 3]);
57}
58
59static void
60ph_command(struct IsdnCardState *cs, unsigned int command)
61{
62	if (cs->debug & L1_DEB_ISAC)
63		debugl1(cs, "ph_command %x", command);
64	cs->writeisac(cs, W_CIX, command);
65}
66
67
68static void
69W6692_new_ph(struct IsdnCardState *cs)
70{
71	switch (cs->dc.w6692.ph_state) {
72	case (W_L1CMD_RST):
73		ph_command(cs, W_L1CMD_DRC);
74		l1_msg(cs, HW_RESET | INDICATION, NULL);
75		/* fallthru */
76	case (W_L1IND_CD):
77		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
78		break;
79	case (W_L1IND_DRD):
80		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
81		break;
82	case (W_L1IND_CE):
83		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
84		break;
85	case (W_L1IND_LD):
86		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
87		break;
88	case (W_L1IND_ARD):
89		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
90		break;
91	case (W_L1IND_AI8):
92		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
93		break;
94	case (W_L1IND_AI10):
95		l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
96		break;
97	default:
98		break;
99	}
100}
101
102static void
103W6692_bh(struct work_struct *work)
104{
105	struct IsdnCardState *cs =
106		container_of(work, struct IsdnCardState, tqueue);
107	struct PStack *stptr;
108
109	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
110		if (cs->debug)
111			debugl1(cs, "D-Channel Busy cleared");
112		stptr = cs->stlist;
113		while (stptr != NULL) {
114			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
115			stptr = stptr->next;
116		}
117	}
118	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
119		W6692_new_ph(cs);
120	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
121		DChannel_proc_rcv(cs);
122	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
123		DChannel_proc_xmt(cs);
124/*
125  if (test_and_clear_bit(D_RX_MON1, &cs->event))
126  arcofi_fsm(cs, ARCOFI_RX_END, NULL);
127  if (test_and_clear_bit(D_TX_MON1, &cs->event))
128  arcofi_fsm(cs, ARCOFI_TX_END, NULL);
129*/
130}
131
132static void
133W6692_empty_fifo(struct IsdnCardState *cs, int count)
134{
135	u_char *ptr;
136
137	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
138		debugl1(cs, "W6692_empty_fifo");
139
140	if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
141		if (cs->debug & L1_DEB_WARN)
142			debugl1(cs, "W6692_empty_fifo overrun %d",
143				cs->rcvidx + count);
144		cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK);
145		cs->rcvidx = 0;
146		return;
147	}
148	ptr = cs->rcvbuf + cs->rcvidx;
149	cs->rcvidx += count;
150	cs->readW6692fifo(cs, ptr, count);
151	cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK);
152	if (cs->debug & L1_DEB_ISAC_FIFO) {
153		char *t = cs->dlog;
154
155		t += sprintf(t, "W6692_empty_fifo cnt %d", count);
156		QuickHex(t, ptr, count);
157		debugl1(cs, "%s", cs->dlog);
158	}
159}
160
161static void
162W6692_fill_fifo(struct IsdnCardState *cs)
163{
164	int count, more;
165	u_char *ptr;
166
167	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
168		debugl1(cs, "W6692_fill_fifo");
169
170	if (!cs->tx_skb)
171		return;
172
173	count = cs->tx_skb->len;
174	if (count <= 0)
175		return;
176
177	more = 0;
178	if (count > W_D_FIFO_THRESH) {
179		more = !0;
180		count = W_D_FIFO_THRESH;
181	}
182	ptr = cs->tx_skb->data;
183	skb_pull(cs->tx_skb, count);
184	cs->tx_cnt += count;
185	cs->writeW6692fifo(cs, ptr, count);
186	cs->writeW6692(cs, W_D_CMDR, more ? W_D_CMDR_XMS : (W_D_CMDR_XMS | W_D_CMDR_XME));
187	if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
188		debugl1(cs, "W6692_fill_fifo dbusytimer running");
189		del_timer(&cs->dbusytimer);
190	}
191	init_timer(&cs->dbusytimer);
192	cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
193	add_timer(&cs->dbusytimer);
194	if (cs->debug & L1_DEB_ISAC_FIFO) {
195		char *t = cs->dlog;
196
197		t += sprintf(t, "W6692_fill_fifo cnt %d", count);
198		QuickHex(t, ptr, count);
199		debugl1(cs, "%s", cs->dlog);
200	}
201}
202
203static void
204W6692B_empty_fifo(struct BCState *bcs, int count)
205{
206	u_char *ptr;
207	struct IsdnCardState *cs = bcs->cs;
208
209	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
210		debugl1(cs, "W6692B_empty_fifo");
211
212	if (bcs->hw.w6692.rcvidx + count > HSCX_BUFMAX) {
213		if (cs->debug & L1_DEB_WARN)
214			debugl1(cs, "W6692B_empty_fifo: incoming packet too large");
215		cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
216		bcs->hw.w6692.rcvidx = 0;
217		return;
218	}
219	ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx;
220	bcs->hw.w6692.rcvidx += count;
221	READW6692BFIFO(cs, bcs->channel, ptr, count);
222	cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
223	if (cs->debug & L1_DEB_HSCX_FIFO) {
224		char *t = bcs->blog;
225
226		t += sprintf(t, "W6692B_empty_fifo %c cnt %d",
227			     bcs->channel + '1', count);
228		QuickHex(t, ptr, count);
229		debugl1(cs, "%s", bcs->blog);
230	}
231}
232
233static void
234W6692B_fill_fifo(struct BCState *bcs)
235{
236	struct IsdnCardState *cs = bcs->cs;
237	int more, count;
238	u_char *ptr;
239
240	if (!bcs->tx_skb)
241		return;
242	if (bcs->tx_skb->len <= 0)
243		return;
244
245	more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
246	if (bcs->tx_skb->len > W_B_FIFO_THRESH) {
247		more = 1;
248		count = W_B_FIFO_THRESH;
249	} else
250		count = bcs->tx_skb->len;
251
252	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
253		debugl1(cs, "W6692B_fill_fifo%s%d", (more ? " " : " last "), count);
254
255	ptr = bcs->tx_skb->data;
256	skb_pull(bcs->tx_skb, count);
257	bcs->tx_cnt -= count;
258	bcs->hw.w6692.count += count;
259	WRITEW6692BFIFO(cs, bcs->channel, ptr, count);
260	cs->BC_Write_Reg(cs, bcs->channel, W_B_CMDR, W_B_CMDR_RACT | W_B_CMDR_XMS | (more ? 0 : W_B_CMDR_XME));
261	if (cs->debug & L1_DEB_HSCX_FIFO) {
262		char *t = bcs->blog;
263
264		t += sprintf(t, "W6692B_fill_fifo %c cnt %d",
265			     bcs->channel + '1', count);
266		QuickHex(t, ptr, count);
267		debugl1(cs, "%s", bcs->blog);
268	}
269}
270
271static void
272W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
273{
274	u_char val;
275	u_char r;
276	struct BCState *bcs;
277	struct sk_buff *skb;
278	int count;
279
280	bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs + 1);
281	val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR);
282	debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val);
283
284	if (!test_bit(BC_FLG_INIT, &bcs->Flag)) {
285		debugl1(cs, "W6692B not INIT yet");
286		return;
287	}
288	if (val & W_B_EXI_RME) {	/* RME */
289		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
290		if (r & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
291			if (cs->debug & L1_DEB_WARN)
292				debugl1(cs, "W6692 B STAR %x", r);
293			if ((r & W_B_STAR_RDOV) && bcs->mode)
294				if (cs->debug & L1_DEB_WARN)
295					debugl1(cs, "W6692 B RDOV mode=%d",
296						bcs->mode);
297			if (r & W_B_STAR_CRCE)
298				if (cs->debug & L1_DEB_WARN)
299					debugl1(cs, "W6692 B CRC error");
300			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
301		} else {
302			count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1);
303			if (count == 0)
304				count = W_B_FIFO_THRESH;
305			W6692B_empty_fifo(bcs, count);
306			if ((count = bcs->hw.w6692.rcvidx) > 0) {
307				if (cs->debug & L1_DEB_HSCX_FIFO)
308					debugl1(cs, "W6692 Bchan Frame %d", count);
309				if (!(skb = dev_alloc_skb(count)))
310					printk(KERN_WARNING "W6692: Bchan receive out of memory\n");
311				else {
312					memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count);
313					skb_queue_tail(&bcs->rqueue, skb);
314				}
315			}
316		}
317		bcs->hw.w6692.rcvidx = 0;
318		schedule_event(bcs, B_RCVBUFREADY);
319	}
320	if (val & W_B_EXI_RMR) {	/* RMR */
321		W6692B_empty_fifo(bcs, W_B_FIFO_THRESH);
322		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
323		if (r & W_B_STAR_RDOV) {
324			if (cs->debug & L1_DEB_WARN)
325				debugl1(cs, "W6692 B RDOV(RMR) mode=%d", bcs->mode);
326			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
327			if (bcs->mode != L1_MODE_TRANS)
328				bcs->hw.w6692.rcvidx = 0;
329		}
330		if (bcs->mode == L1_MODE_TRANS) {
331			/* receive audio data */
332			if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH)))
333				printk(KERN_WARNING "HiSax: receive out of memory\n");
334			else {
335				memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH);
336				skb_queue_tail(&bcs->rqueue, skb);
337			}
338			bcs->hw.w6692.rcvidx = 0;
339			schedule_event(bcs, B_RCVBUFREADY);
340		}
341	}
342	if (val & W_B_EXI_XDUN) {	/* XDUN */
343		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
344		if (cs->debug & L1_DEB_WARN)
345			debugl1(cs, "W6692 B EXIR %x Lost TX", val);
346		if (bcs->mode == 1)
347			W6692B_fill_fifo(bcs);
348		else {
349			/* Here we lost an TX interrupt, so
350			 * restart transmitting the whole frame.
351			 */
352			if (bcs->tx_skb) {
353				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
354				bcs->tx_cnt += bcs->hw.w6692.count;
355				bcs->hw.w6692.count = 0;
356			}
357		}
358		return;
359	}
360	if (val & W_B_EXI_XFR) {	/* XFR */
361		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
362		if (r & W_B_STAR_XDOW) {
363			if (cs->debug & L1_DEB_WARN)
364				debugl1(cs, "W6692 B STAR %x XDOW", r);
365			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
366			if (bcs->tx_skb && (bcs->mode != 1)) {
367				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
368				bcs->tx_cnt += bcs->hw.w6692.count;
369				bcs->hw.w6692.count = 0;
370			}
371		}
372		if (bcs->tx_skb) {
373			if (bcs->tx_skb->len) {
374				W6692B_fill_fifo(bcs);
375				return;
376			} else {
377				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
378				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
379					u_long flags;
380					spin_lock_irqsave(&bcs->aclock, flags);
381					bcs->ackcnt += bcs->hw.w6692.count;
382					spin_unlock_irqrestore(&bcs->aclock, flags);
383					schedule_event(bcs, B_ACKPENDING);
384				}
385				dev_kfree_skb_irq(bcs->tx_skb);
386				bcs->hw.w6692.count = 0;
387				bcs->tx_skb = NULL;
388			}
389		}
390		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
391			bcs->hw.w6692.count = 0;
392			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
393			W6692B_fill_fifo(bcs);
394		} else {
395			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
396			schedule_event(bcs, B_XMTBUFREADY);
397		}
398	}
399}
400
401static irqreturn_t
402W6692_interrupt(int intno, void *dev_id)
403{
404	struct IsdnCardState	*cs = dev_id;
405	u_char			val, exval, v1;
406	struct sk_buff		*skb;
407	u_int			count;
408	u_long			flags;
409	int			icnt = 5;
410
411	spin_lock_irqsave(&cs->lock, flags);
412	val = cs->readW6692(cs, W_ISTA);
413	if (!val) {
414		spin_unlock_irqrestore(&cs->lock, flags);
415		return IRQ_NONE;
416	}
417StartW6692:
418	if (cs->debug & L1_DEB_ISAC)
419		debugl1(cs, "W6692 ISTA %x", val);
420
421	if (val & W_INT_D_RME) {	/* RME */
422		exval = cs->readW6692(cs, W_D_RSTA);
423		if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
424			if (exval & W_D_RSTA_RDOV)
425				if (cs->debug & L1_DEB_WARN)
426					debugl1(cs, "W6692 RDOV");
427			if (exval & W_D_RSTA_CRCE)
428				if (cs->debug & L1_DEB_WARN)
429					debugl1(cs, "W6692 D-channel CRC error");
430			if (exval & W_D_RSTA_RMB)
431				if (cs->debug & L1_DEB_WARN)
432					debugl1(cs, "W6692 D-channel ABORT");
433			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
434		} else {
435			count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
436			if (count == 0)
437				count = W_D_FIFO_THRESH;
438			W6692_empty_fifo(cs, count);
439			if ((count = cs->rcvidx) > 0) {
440				cs->rcvidx = 0;
441				if (!(skb = alloc_skb(count, GFP_ATOMIC)))
442					printk(KERN_WARNING "HiSax: D receive out of memory\n");
443				else {
444					memcpy(skb_put(skb, count), cs->rcvbuf, count);
445					skb_queue_tail(&cs->rq, skb);
446				}
447			}
448		}
449		cs->rcvidx = 0;
450		schedule_event(cs, D_RCVBUFREADY);
451	}
452	if (val & W_INT_D_RMR) {	/* RMR */
453		W6692_empty_fifo(cs, W_D_FIFO_THRESH);
454	}
455	if (val & W_INT_D_XFR) {	/* XFR */
456		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
457			del_timer(&cs->dbusytimer);
458		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
459			schedule_event(cs, D_CLEARBUSY);
460		if (cs->tx_skb) {
461			if (cs->tx_skb->len) {
462				W6692_fill_fifo(cs);
463				goto afterXFR;
464			} else {
465				dev_kfree_skb_irq(cs->tx_skb);
466				cs->tx_cnt = 0;
467				cs->tx_skb = NULL;
468			}
469		}
470		if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
471			cs->tx_cnt = 0;
472			W6692_fill_fifo(cs);
473		} else
474			schedule_event(cs, D_XMTBUFREADY);
475	}
476afterXFR:
477	if (val & (W_INT_XINT0 | W_INT_XINT1)) {	/* XINT0/1 - never */
478		if (cs->debug & L1_DEB_ISAC)
479			debugl1(cs, "W6692 spurious XINT!");
480	}
481	if (val & W_INT_D_EXI) {	/* EXI */
482		exval = cs->readW6692(cs, W_D_EXIR);
483		if (cs->debug & L1_DEB_WARN)
484			debugl1(cs, "W6692 D_EXIR %02x", exval);
485		if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {	/* Transmit underrun/collision */
486			debugl1(cs, "W6692 D-chan underrun/collision");
487			printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n");
488			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
489				del_timer(&cs->dbusytimer);
490			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
491				schedule_event(cs, D_CLEARBUSY);
492			if (cs->tx_skb) {	/* Restart frame */
493				skb_push(cs->tx_skb, cs->tx_cnt);
494				cs->tx_cnt = 0;
495				W6692_fill_fifo(cs);
496			} else {
497				printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n");
498				debugl1(cs, "W6692 XDUN/XCOL no skb");
499				cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);
500			}
501		}
502		if (exval & W_D_EXI_RDOV) {	/* RDOV */
503			debugl1(cs, "W6692 D-channel RDOV");
504			printk(KERN_WARNING "HiSax: W6692 D-RDOV\n");
505			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST);
506		}
507		if (exval & W_D_EXI_TIN2) {	/* TIN2 - never */
508			debugl1(cs, "W6692 spurious TIN2 interrupt");
509		}
510		if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
511			debugl1(cs, "W6692 spurious MOC interrupt");
512			v1 = cs->readW6692(cs, W_MOSR);
513			debugl1(cs, "W6692 MOSR %02x", v1);
514		}
515		if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
516			v1 = cs->readW6692(cs, W_CIR);
517			if (cs->debug & L1_DEB_ISAC)
518				debugl1(cs, "W6692 ISC CIR=0x%02X", v1);
519			if (v1 & W_CIR_ICC) {
520				cs->dc.w6692.ph_state = v1 & W_CIR_COD_MASK;
521				if (cs->debug & L1_DEB_ISAC)
522					debugl1(cs, "ph_state_change %x", cs->dc.w6692.ph_state);
523				schedule_event(cs, D_L1STATECHANGE);
524			}
525			if (v1 & W_CIR_SCC) {
526				v1 = cs->readW6692(cs, W_SQR);
527				debugl1(cs, "W6692 SCC SQR=0x%02X", v1);
528			}
529		}
530		if (exval & W_D_EXI_WEXP) {
531			debugl1(cs, "W6692 spurious WEXP interrupt!");
532		}
533		if (exval & W_D_EXI_TEXP) {
534			debugl1(cs, "W6692 spurious TEXP interrupt!");
535		}
536	}
537	if (val & W_INT_B1_EXI) {
538		debugl1(cs, "W6692 B channel 1 interrupt");
539		W6692B_interrupt(cs, 0);
540	}
541	if (val & W_INT_B2_EXI) {
542		debugl1(cs, "W6692 B channel 2 interrupt");
543		W6692B_interrupt(cs, 1);
544	}
545	val = cs->readW6692(cs, W_ISTA);
546	if (val && icnt) {
547		icnt--;
548		goto StartW6692;
549	}
550	if (!icnt) {
551		printk(KERN_WARNING "W6692 IRQ LOOP\n");
552		cs->writeW6692(cs, W_IMASK, 0xff);
553	}
554	spin_unlock_irqrestore(&cs->lock, flags);
555	return IRQ_HANDLED;
556}
557
558static void
559W6692_l1hw(struct PStack *st, int pr, void *arg)
560{
561	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
562	struct sk_buff *skb = arg;
563	u_long flags;
564	int val;
565
566	switch (pr) {
567	case (PH_DATA | REQUEST):
568		if (cs->debug & DEB_DLOG_HEX)
569			LogFrame(cs, skb->data, skb->len);
570		if (cs->debug & DEB_DLOG_VERBOSE)
571			dlogframe(cs, skb, 0);
572		spin_lock_irqsave(&cs->lock, flags);
573		if (cs->tx_skb) {
574			skb_queue_tail(&cs->sq, skb);
575#ifdef L2FRAME_DEBUG		/* psa */
576			if (cs->debug & L1_DEB_LAPD)
577				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
578#endif
579		} else {
580			cs->tx_skb = skb;
581			cs->tx_cnt = 0;
582#ifdef L2FRAME_DEBUG		/* psa */
583			if (cs->debug & L1_DEB_LAPD)
584				Logl2Frame(cs, skb, "PH_DATA", 0);
585#endif
586			W6692_fill_fifo(cs);
587		}
588		spin_unlock_irqrestore(&cs->lock, flags);
589		break;
590	case (PH_PULL | INDICATION):
591		spin_lock_irqsave(&cs->lock, flags);
592		if (cs->tx_skb) {
593			if (cs->debug & L1_DEB_WARN)
594				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
595			skb_queue_tail(&cs->sq, skb);
596			spin_unlock_irqrestore(&cs->lock, flags);
597			break;
598		}
599		if (cs->debug & DEB_DLOG_HEX)
600			LogFrame(cs, skb->data, skb->len);
601		if (cs->debug & DEB_DLOG_VERBOSE)
602			dlogframe(cs, skb, 0);
603		cs->tx_skb = skb;
604		cs->tx_cnt = 0;
605#ifdef L2FRAME_DEBUG		/* psa */
606		if (cs->debug & L1_DEB_LAPD)
607			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
608#endif
609		W6692_fill_fifo(cs);
610		spin_unlock_irqrestore(&cs->lock, flags);
611		break;
612	case (PH_PULL | REQUEST):
613#ifdef L2FRAME_DEBUG		/* psa */
614		if (cs->debug & L1_DEB_LAPD)
615			debugl1(cs, "-> PH_REQUEST_PULL");
616#endif
617		if (!cs->tx_skb) {
618			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
619			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
620		} else
621			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
622		break;
623	case (HW_RESET | REQUEST):
624		spin_lock_irqsave(&cs->lock, flags);
625		if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) {
626			ph_command(cs, W_L1CMD_ECK);
627			spin_unlock_irqrestore(&cs->lock, flags);
628		} else {
629			ph_command(cs, W_L1CMD_RST);
630			cs->dc.w6692.ph_state = W_L1CMD_RST;
631			spin_unlock_irqrestore(&cs->lock, flags);
632			W6692_new_ph(cs);
633		}
634		break;
635	case (HW_ENABLE | REQUEST):
636		spin_lock_irqsave(&cs->lock, flags);
637		ph_command(cs, W_L1CMD_ECK);
638		spin_unlock_irqrestore(&cs->lock, flags);
639		break;
640	case (HW_INFO3 | REQUEST):
641		spin_lock_irqsave(&cs->lock, flags);
642		ph_command(cs, W_L1CMD_AR8);
643		spin_unlock_irqrestore(&cs->lock, flags);
644		break;
645	case (HW_TESTLOOP | REQUEST):
646		val = 0;
647		if (1 & (long) arg)
648			val |= 0x0c;
649		if (2 & (long) arg)
650			val |= 0x3;
651		/* !!! not implemented yet */
652		break;
653	case (HW_DEACTIVATE | RESPONSE):
654		skb_queue_purge(&cs->rq);
655		skb_queue_purge(&cs->sq);
656		if (cs->tx_skb) {
657			dev_kfree_skb_any(cs->tx_skb);
658			cs->tx_skb = NULL;
659		}
660		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
661			del_timer(&cs->dbusytimer);
662		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
663			schedule_event(cs, D_CLEARBUSY);
664		break;
665	default:
666		if (cs->debug & L1_DEB_WARN)
667			debugl1(cs, "W6692_l1hw unknown %04x", pr);
668		break;
669	}
670}
671
672static void
673setstack_W6692(struct PStack *st, struct IsdnCardState *cs)
674{
675	st->l1.l1hw = W6692_l1hw;
676}
677
678static void
679DC_Close_W6692(struct IsdnCardState *cs)
680{
681}
682
683static void
684dbusy_timer_handler(struct IsdnCardState *cs)
685{
686	struct PStack *stptr;
687	int rbch, star;
688	u_long flags;
689
690	spin_lock_irqsave(&cs->lock, flags);
691	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
692		rbch = cs->readW6692(cs, W_D_RBCH);
693		star = cs->readW6692(cs, W_D_STAR);
694		if (cs->debug)
695			debugl1(cs, "D-Channel Busy D_RBCH %02x D_STAR %02x",
696				rbch, star);
697		if (star & W_D_STAR_XBZ) {	/* D-Channel Busy */
698			test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
699			stptr = cs->stlist;
700			while (stptr != NULL) {
701				stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
702				stptr = stptr->next;
703			}
704		} else {
705			/* discard frame; reset transceiver */
706			test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags);
707			if (cs->tx_skb) {
708				dev_kfree_skb_any(cs->tx_skb);
709				cs->tx_cnt = 0;
710				cs->tx_skb = NULL;
711			} else {
712				printk(KERN_WARNING "HiSax: W6692 D-Channel Busy no skb\n");
713				debugl1(cs, "D-Channel Busy no skb");
714			}
715			cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST);	/* Transmitter reset */
716			spin_unlock_irqrestore(&cs->lock, flags);
717			cs->irq_func(cs->irq, cs);
718			return;
719		}
720	}
721	spin_unlock_irqrestore(&cs->lock, flags);
722}
723
724static void
725W6692Bmode(struct BCState *bcs, int mode, int bchan)
726{
727	struct IsdnCardState *cs = bcs->cs;
728
729	if (cs->debug & L1_DEB_HSCX)
730		debugl1(cs, "w6692 %c mode %d ichan %d",
731			'1' + bchan, mode, bchan);
732	bcs->mode = mode;
733	bcs->channel = bchan;
734	bcs->hw.w6692.bchan = bchan;
735
736	switch (mode) {
737	case (L1_MODE_NULL):
738		cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0);
739		break;
740	case (L1_MODE_TRANS):
741		cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS);
742		break;
743	case (L1_MODE_HDLC):
744		cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF);
745		cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff);
746		cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff);
747		break;
748	}
749	if (mode)
750		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RRST |
751				 W_B_CMDR_RACT | W_B_CMDR_XRST);
752	cs->BC_Write_Reg(cs, bchan, W_B_EXIM, 0x00);
753}
754
755static void
756W6692_l2l1(struct PStack *st, int pr, void *arg)
757{
758	struct sk_buff *skb = arg;
759	struct BCState *bcs = st->l1.bcs;
760	u_long flags;
761
762	switch (pr) {
763	case (PH_DATA | REQUEST):
764		spin_lock_irqsave(&bcs->cs->lock, flags);
765		if (bcs->tx_skb) {
766			skb_queue_tail(&bcs->squeue, skb);
767		} else {
768			bcs->tx_skb = skb;
769			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
770			bcs->hw.w6692.count = 0;
771			bcs->cs->BC_Send_Data(bcs);
772		}
773		spin_unlock_irqrestore(&bcs->cs->lock, flags);
774		break;
775	case (PH_PULL | INDICATION):
776		if (bcs->tx_skb) {
777			printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n");
778			break;
779		}
780		spin_lock_irqsave(&bcs->cs->lock, flags);
781		test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
782		bcs->tx_skb = skb;
783		bcs->hw.w6692.count = 0;
784		bcs->cs->BC_Send_Data(bcs);
785		spin_unlock_irqrestore(&bcs->cs->lock, flags);
786		break;
787	case (PH_PULL | REQUEST):
788		if (!bcs->tx_skb) {
789			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
790			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
791		} else
792			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
793		break;
794	case (PH_ACTIVATE | REQUEST):
795		spin_lock_irqsave(&bcs->cs->lock, flags);
796		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
797		W6692Bmode(bcs, st->l1.mode, st->l1.bc);
798		spin_unlock_irqrestore(&bcs->cs->lock, flags);
799		l1_msg_b(st, pr, arg);
800		break;
801	case (PH_DEACTIVATE | REQUEST):
802		l1_msg_b(st, pr, arg);
803		break;
804	case (PH_DEACTIVATE | CONFIRM):
805		spin_lock_irqsave(&bcs->cs->lock, flags);
806		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
807		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
808		W6692Bmode(bcs, 0, st->l1.bc);
809		spin_unlock_irqrestore(&bcs->cs->lock, flags);
810		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
811		break;
812	}
813}
814
815static void
816close_w6692state(struct BCState *bcs)
817{
818	W6692Bmode(bcs, 0, bcs->channel);
819	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
820		kfree(bcs->hw.w6692.rcvbuf);
821		bcs->hw.w6692.rcvbuf = NULL;
822		kfree(bcs->blog);
823		bcs->blog = NULL;
824		skb_queue_purge(&bcs->rqueue);
825		skb_queue_purge(&bcs->squeue);
826		if (bcs->tx_skb) {
827			dev_kfree_skb_any(bcs->tx_skb);
828			bcs->tx_skb = NULL;
829			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
830		}
831	}
832}
833
834static int
835open_w6692state(struct IsdnCardState *cs, struct BCState *bcs)
836{
837	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
838		if (!(bcs->hw.w6692.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
839			printk(KERN_WARNING
840			       "HiSax: No memory for w6692.rcvbuf\n");
841			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
842			return (1);
843		}
844		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
845			printk(KERN_WARNING
846			       "HiSax: No memory for bcs->blog\n");
847			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
848			kfree(bcs->hw.w6692.rcvbuf);
849			bcs->hw.w6692.rcvbuf = NULL;
850			return (2);
851		}
852		skb_queue_head_init(&bcs->rqueue);
853		skb_queue_head_init(&bcs->squeue);
854	}
855	bcs->tx_skb = NULL;
856	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
857	bcs->event = 0;
858	bcs->hw.w6692.rcvidx = 0;
859	bcs->tx_cnt = 0;
860	return (0);
861}
862
863static int
864setstack_w6692(struct PStack *st, struct BCState *bcs)
865{
866	bcs->channel = st->l1.bc;
867	if (open_w6692state(st->l1.hardware, bcs))
868		return (-1);
869	st->l1.bcs = bcs;
870	st->l2.l2l1 = W6692_l2l1;
871	setstack_manager(st);
872	bcs->st = st;
873	setstack_l1_B(st);
874	return (0);
875}
876
877static void resetW6692(struct IsdnCardState *cs)
878{
879	cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
880	mdelay(10);
881	cs->writeW6692(cs, W_D_CTL, 0x00);
882	mdelay(10);
883	cs->writeW6692(cs, W_IMASK, 0xff);
884	cs->writeW6692(cs, W_D_SAM, 0xff);
885	cs->writeW6692(cs, W_D_TAM, 0xff);
886	cs->writeW6692(cs, W_D_EXIM, 0x00);
887	cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
888	cs->writeW6692(cs, W_IMASK, 0x18);
889	if (cs->subtyp == W6692_USR) {
890		/* seems that USR implemented some power control features
891		 * Pin 79 is connected to the oscilator circuit so we
892		 * have to handle it here
893		 */
894		cs->writeW6692(cs, W_PCTL, 0x80);
895		cs->writeW6692(cs, W_XDATA, 0x00);
896	}
897}
898
899static void initW6692(struct IsdnCardState *cs, int part)
900{
901	if (part & 1) {
902		cs->setstack_d = setstack_W6692;
903		cs->DC_Close = DC_Close_W6692;
904		cs->dbusytimer.function = (void *) dbusy_timer_handler;
905		cs->dbusytimer.data = (long) cs;
906		init_timer(&cs->dbusytimer);
907		resetW6692(cs);
908		ph_command(cs, W_L1CMD_RST);
909		cs->dc.w6692.ph_state = W_L1CMD_RST;
910		W6692_new_ph(cs);
911		ph_command(cs, W_L1CMD_ECK);
912
913		cs->bcs[0].BC_SetStack = setstack_w6692;
914		cs->bcs[1].BC_SetStack = setstack_w6692;
915		cs->bcs[0].BC_Close = close_w6692state;
916		cs->bcs[1].BC_Close = close_w6692state;
917		W6692Bmode(cs->bcs, 0, 0);
918		W6692Bmode(cs->bcs + 1, 0, 0);
919	}
920	if (part & 2) {
921		/* Reenable all IRQ */
922		cs->writeW6692(cs, W_IMASK, 0x18);
923		cs->writeW6692(cs, W_D_EXIM, 0x00);
924		cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00);
925		cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00);
926		/* Reset D-chan receiver and transmitter */
927		cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
928	}
929}
930
931/* Interface functions */
932
933static u_char
934ReadW6692(struct IsdnCardState *cs, u_char offset)
935{
936	return (inb(cs->hw.w6692.iobase + offset));
937}
938
939static void
940WriteW6692(struct IsdnCardState *cs, u_char offset, u_char value)
941{
942	outb(value, cs->hw.w6692.iobase + offset);
943}
944
945static void
946ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
947{
948	insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size);
949}
950
951static void
952WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
953{
954	outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size);
955}
956
957static u_char
958ReadW6692B(struct IsdnCardState *cs, int bchan, u_char offset)
959{
960	return (inb(cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset));
961}
962
963static void
964WriteW6692B(struct IsdnCardState *cs, int bchan, u_char offset, u_char value)
965{
966	outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset);
967}
968
969static int
970w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
971{
972	switch (mt) {
973	case CARD_RESET:
974		resetW6692(cs);
975		return (0);
976	case CARD_RELEASE:
977		cs->writeW6692(cs, W_IMASK, 0xff);
978		release_region(cs->hw.w6692.iobase, 256);
979		if (cs->subtyp == W6692_USR) {
980			cs->writeW6692(cs, W_XDATA, 0x04);
981		}
982		return (0);
983	case CARD_INIT:
984		initW6692(cs, 3);
985		return (0);
986	case CARD_TEST:
987		return (0);
988	}
989	return (0);
990}
991
992static int id_idx;
993
994static struct pci_dev *dev_w6692 = NULL;
995
996int setup_w6692(struct IsdnCard *card)
997{
998	struct IsdnCardState *cs = card->cs;
999	char tmp[64];
1000	u_char found = 0;
1001	u_char pci_irq = 0;
1002	u_int pci_ioaddr = 0;
1003
1004	strcpy(tmp, w6692_revision);
1005	printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp));
1006	if (cs->typ != ISDN_CTYPE_W6692)
1007		return (0);
1008
1009	while (id_list[id_idx].vendor_id) {
1010		dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
1011						  id_list[id_idx].device_id,
1012						  dev_w6692);
1013		if (dev_w6692) {
1014			if (pci_enable_device(dev_w6692))
1015				continue;
1016			cs->subtyp = id_idx;
1017			break;
1018		}
1019		id_idx++;
1020	}
1021	if (dev_w6692) {
1022		found = 1;
1023		pci_irq = dev_w6692->irq;
1024		/* I think address 0 is allways the configuration area */
1025		/* and address 1 is the real IO space KKe 03.09.99 */
1026		pci_ioaddr = pci_resource_start(dev_w6692, 1);
1027		/* USR ISDN PCI card TA need some special handling */
1028		if (cs->subtyp == W6692_WINBOND) {
1029			if ((W6692_SV_USR == dev_w6692->subsystem_vendor) &&
1030			    (W6692_SD_USR == dev_w6692->subsystem_device)) {
1031				cs->subtyp = W6692_USR;
1032			}
1033		}
1034	}
1035	if (!found) {
1036		printk(KERN_WARNING "W6692: No PCI card found\n");
1037		return (0);
1038	}
1039	cs->irq = pci_irq;
1040	if (!cs->irq) {
1041		printk(KERN_WARNING "W6692: No IRQ for PCI card found\n");
1042		return (0);
1043	}
1044	if (!pci_ioaddr) {
1045		printk(KERN_WARNING "W6692: NO I/O Base Address found\n");
1046		return (0);
1047	}
1048	cs->hw.w6692.iobase = pci_ioaddr;
1049	printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
1050	       id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
1051	       pci_ioaddr, pci_irq);
1052	if (!request_region(cs->hw.w6692.iobase, 256, id_list[cs->subtyp].card_name)) {
1053		printk(KERN_WARNING
1054		       "HiSax: %s I/O ports %x-%x already in use\n",
1055		       id_list[cs->subtyp].card_name,
1056		       cs->hw.w6692.iobase,
1057		       cs->hw.w6692.iobase + 255);
1058		return (0);
1059	}
1060
1061	printk(KERN_INFO
1062	       "HiSax: %s config irq:%d I/O:%x\n",
1063	       id_list[cs->subtyp].card_name, cs->irq,
1064	       cs->hw.w6692.iobase);
1065
1066	INIT_WORK(&cs->tqueue, W6692_bh);
1067	cs->readW6692 = &ReadW6692;
1068	cs->writeW6692 = &WriteW6692;
1069	cs->readisacfifo = &ReadISACfifo;
1070	cs->writeisacfifo = &WriteISACfifo;
1071	cs->BC_Read_Reg = &ReadW6692B;
1072	cs->BC_Write_Reg = &WriteW6692B;
1073	cs->BC_Send_Data = &W6692B_fill_fifo;
1074	cs->cardmsg = &w6692_card_msg;
1075	cs->irq_func = &W6692_interrupt;
1076	cs->irq_flags |= IRQF_SHARED;
1077	W6692Version(cs, "W6692:");
1078	printk(KERN_INFO "W6692 ISTA=0x%X\n", ReadW6692(cs, W_ISTA));
1079	printk(KERN_INFO "W6692 IMASK=0x%X\n", ReadW6692(cs, W_IMASK));
1080	printk(KERN_INFO "W6692 D_EXIR=0x%X\n", ReadW6692(cs, W_D_EXIR));
1081	printk(KERN_INFO "W6692 D_EXIM=0x%X\n", ReadW6692(cs, W_D_EXIM));
1082	printk(KERN_INFO "W6692 D_RSTA=0x%X\n", ReadW6692(cs, W_D_RSTA));
1083	return (1);
1084}
1085