1 /* $Id: w6692.c,v 1.18.2.4 2004/02/11 13:21:34 keil Exp $
3 * Winbond W6692 specific routines
6 * Copyright by Petr Novak <petr.novak@i.cz>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/config.h>
14 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/pci.h>
21 /* table entry in the PCI devices list */
29 static const PCI_ENTRY id_list
[] =
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"}
36 #define W6692_SV_USR 0x16ec
37 #define W6692_SD_USR 0x3409
38 #define W6692_WINBOND 0
39 #define W6692_DYNALINK 1
42 extern const char *CardType
[];
44 const char *w6692_revision
= "$Revision: 1.18.2.4 $";
46 #define DBUSY_TIMER_VALUE 80
48 static char *W6692Ver
[] __initdata
=
49 {"W6692 V00", "W6692 V01", "W6692 V10",
53 W6692Version(struct IsdnCardState
*cs
, char *s
)
57 val
= cs
->readW6692(cs
, W_D_RBCH
);
58 printk(KERN_INFO
"%s Winbond W6692 version (%x): %s\n", s
, val
, W6692Ver
[(val
>> 6) & 3]);
62 ph_command(struct IsdnCardState
*cs
, unsigned int command
)
64 if (cs
->debug
& L1_DEB_ISAC
)
65 debugl1(cs
, "ph_command %x", command
);
66 cs
->writeisac(cs
, W_CIX
, command
);
71 W6692_new_ph(struct IsdnCardState
*cs
)
73 switch (cs
->dc
.w6692
.ph_state
) {
75 ph_command(cs
, W_L1CMD_DRC
);
76 l1_msg(cs
, HW_RESET
| INDICATION
, NULL
);
79 l1_msg(cs
, HW_DEACTIVATE
| CONFIRM
, NULL
);
82 l1_msg(cs
, HW_DEACTIVATE
| INDICATION
, NULL
);
85 l1_msg(cs
, HW_POWERUP
| CONFIRM
, NULL
);
88 l1_msg(cs
, HW_RSYNC
| INDICATION
, NULL
);
91 l1_msg(cs
, HW_INFO2
| INDICATION
, NULL
);
94 l1_msg(cs
, HW_INFO4_P8
| INDICATION
, NULL
);
97 l1_msg(cs
, HW_INFO4_P10
| INDICATION
, NULL
);
105 W6692_bh(struct IsdnCardState
*cs
)
107 struct PStack
*stptr
;
111 if (test_and_clear_bit(D_CLEARBUSY
, &cs
->event
)) {
113 debugl1(cs
, "D-Channel Busy cleared");
115 while (stptr
!= NULL
) {
116 stptr
->l1
.l1l2(stptr
, PH_PAUSE
| CONFIRM
, NULL
);
120 if (test_and_clear_bit(D_L1STATECHANGE
, &cs
->event
))
122 if (test_and_clear_bit(D_RCVBUFREADY
, &cs
->event
))
123 DChannel_proc_rcv(cs
);
124 if (test_and_clear_bit(D_XMTBUFREADY
, &cs
->event
))
125 DChannel_proc_xmt(cs
);
127 if (test_and_clear_bit(D_RX_MON1, &cs->event))
128 arcofi_fsm(cs, ARCOFI_RX_END, NULL);
129 if (test_and_clear_bit(D_TX_MON1, &cs->event))
130 arcofi_fsm(cs, ARCOFI_TX_END, NULL);
135 W6692_empty_fifo(struct IsdnCardState
*cs
, int count
)
139 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
140 debugl1(cs
, "W6692_empty_fifo");
142 if ((cs
->rcvidx
+ count
) >= MAX_DFRAME_LEN_L1
) {
143 if (cs
->debug
& L1_DEB_WARN
)
144 debugl1(cs
, "W6692_empty_fifo overrun %d",
146 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_RACK
);
150 ptr
= cs
->rcvbuf
+ cs
->rcvidx
;
152 cs
->readW6692fifo(cs
, ptr
, count
);
153 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_RACK
);
154 if (cs
->debug
& L1_DEB_ISAC_FIFO
) {
157 t
+= sprintf(t
, "W6692_empty_fifo cnt %d", count
);
158 QuickHex(t
, ptr
, count
);
159 debugl1(cs
, cs
->dlog
);
164 W6692_fill_fifo(struct IsdnCardState
*cs
)
169 if ((cs
->debug
& L1_DEB_ISAC
) && !(cs
->debug
& L1_DEB_ISAC_FIFO
))
170 debugl1(cs
, "W6692_fill_fifo");
175 count
= cs
->tx_skb
->len
;
180 if (count
> W_D_FIFO_THRESH
) {
182 count
= W_D_FIFO_THRESH
;
184 ptr
= cs
->tx_skb
->data
;
185 skb_pull(cs
->tx_skb
, count
);
187 cs
->writeW6692fifo(cs
, ptr
, count
);
188 cs
->writeW6692(cs
, W_D_CMDR
, more
? W_D_CMDR_XMS
: (W_D_CMDR_XMS
| W_D_CMDR_XME
));
189 if (test_and_set_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
190 debugl1(cs
, "W6692_fill_fifo dbusytimer running");
191 del_timer(&cs
->dbusytimer
);
193 init_timer(&cs
->dbusytimer
);
194 cs
->dbusytimer
.expires
= jiffies
+ ((DBUSY_TIMER_VALUE
* HZ
) / 1000);
195 add_timer(&cs
->dbusytimer
);
196 if (cs
->debug
& L1_DEB_ISAC_FIFO
) {
199 t
+= sprintf(t
, "W6692_fill_fifo cnt %d", count
);
200 QuickHex(t
, ptr
, count
);
201 debugl1(cs
, cs
->dlog
);
206 W6692B_empty_fifo(struct BCState
*bcs
, int count
)
209 struct IsdnCardState
*cs
= bcs
->cs
;
211 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
212 debugl1(cs
, "W6692B_empty_fifo");
214 if (bcs
->hw
.w6692
.rcvidx
+ count
> HSCX_BUFMAX
) {
215 if (cs
->debug
& L1_DEB_WARN
)
216 debugl1(cs
, "W6692B_empty_fifo: incoming packet too large");
217 cs
->BC_Write_Reg(cs
, bcs
->channel
, W_B_CMDR
, W_B_CMDR_RACK
| W_B_CMDR_RACT
);
218 bcs
->hw
.w6692
.rcvidx
= 0;
221 ptr
= bcs
->hw
.w6692
.rcvbuf
+ bcs
->hw
.w6692
.rcvidx
;
222 bcs
->hw
.w6692
.rcvidx
+= count
;
223 READW6692BFIFO(cs
, bcs
->channel
, ptr
, count
);
224 cs
->BC_Write_Reg(cs
, bcs
->channel
, W_B_CMDR
, W_B_CMDR_RACK
| W_B_CMDR_RACT
);
225 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
228 t
+= sprintf(t
, "W6692B_empty_fifo %c cnt %d",
229 bcs
->channel
+ '1', count
);
230 QuickHex(t
, ptr
, count
);
231 debugl1(cs
, bcs
->blog
);
236 W6692B_fill_fifo(struct BCState
*bcs
)
238 struct IsdnCardState
*cs
= bcs
->cs
;
244 if (bcs
->tx_skb
->len
<= 0)
247 more
= (bcs
->mode
== L1_MODE_TRANS
) ? 1 : 0;
248 if (bcs
->tx_skb
->len
> W_B_FIFO_THRESH
) {
250 count
= W_B_FIFO_THRESH
;
252 count
= bcs
->tx_skb
->len
;
254 if ((cs
->debug
& L1_DEB_HSCX
) && !(cs
->debug
& L1_DEB_HSCX_FIFO
))
255 debugl1(cs
, "W6692B_fill_fifo%s%d", (more
? " ": " last "), count
);
257 ptr
= bcs
->tx_skb
->data
;
258 skb_pull(bcs
->tx_skb
, count
);
259 bcs
->tx_cnt
-= count
;
260 bcs
->hw
.w6692
.count
+= count
;
261 WRITEW6692BFIFO(cs
, bcs
->channel
, ptr
, count
);
262 cs
->BC_Write_Reg(cs
, bcs
->channel
, W_B_CMDR
, W_B_CMDR_RACT
| W_B_CMDR_XMS
| (more
? 0 : W_B_CMDR_XME
));
263 if (cs
->debug
& L1_DEB_HSCX_FIFO
) {
266 t
+= sprintf(t
, "W6692B_fill_fifo %c cnt %d",
267 bcs
->channel
+ '1', count
);
268 QuickHex(t
, ptr
, count
);
269 debugl1(cs
, bcs
->blog
);
274 W6692B_interrupt(struct IsdnCardState
*cs
, u_char bchan
)
282 bcs
= (cs
->bcs
->channel
== bchan
) ? cs
->bcs
: (cs
->bcs
+1);
283 val
= cs
->BC_Read_Reg(cs
, bchan
, W_B_EXIR
);
284 debugl1(cs
, "W6692B chan %d B_EXIR 0x%02X", bchan
, val
);
286 if (!test_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
287 debugl1(cs
, "W6692B not INIT yet");
290 if (val
& W_B_EXI_RME
) { /* RME */
291 r
= cs
->BC_Read_Reg(cs
, bchan
, W_B_STAR
);
292 if (r
& (W_B_STAR_RDOV
| W_B_STAR_CRCE
| W_B_STAR_RMB
)) {
293 if (cs
->debug
& L1_DEB_WARN
)
294 debugl1(cs
, "W6692 B STAR %x", r
);
295 if ((r
& W_B_STAR_RDOV
) && bcs
->mode
)
296 if (cs
->debug
& L1_DEB_WARN
)
297 debugl1(cs
, "W6692 B RDOV mode=%d",
299 if (r
& W_B_STAR_CRCE
)
300 if (cs
->debug
& L1_DEB_WARN
)
301 debugl1(cs
, "W6692 B CRC error");
302 cs
->BC_Write_Reg(cs
, bchan
, W_B_CMDR
, W_B_CMDR_RACK
| W_B_CMDR_RRST
| W_B_CMDR_RACT
);
304 count
= cs
->BC_Read_Reg(cs
, bchan
, W_B_RBCL
) & (W_B_FIFO_THRESH
- 1);
306 count
= W_B_FIFO_THRESH
;
307 W6692B_empty_fifo(bcs
, count
);
308 if ((count
= bcs
->hw
.w6692
.rcvidx
) > 0) {
309 if (cs
->debug
& L1_DEB_HSCX_FIFO
)
310 debugl1(cs
, "W6692 Bchan Frame %d", count
);
311 if (!(skb
= dev_alloc_skb(count
)))
312 printk(KERN_WARNING
"W6692: Bchan receive out of memory\n");
314 memcpy(skb_put(skb
, count
), bcs
->hw
.w6692
.rcvbuf
, count
);
315 skb_queue_tail(&bcs
->rqueue
, skb
);
319 bcs
->hw
.w6692
.rcvidx
= 0;
320 schedule_event(bcs
, B_RCVBUFREADY
);
322 if (val
& W_B_EXI_RMR
) { /* RMR */
323 W6692B_empty_fifo(bcs
, W_B_FIFO_THRESH
);
324 r
= cs
->BC_Read_Reg(cs
, bchan
, W_B_STAR
);
325 if (r
& W_B_STAR_RDOV
) {
326 if (cs
->debug
& L1_DEB_WARN
)
327 debugl1(cs
, "W6692 B RDOV(RMR) mode=%d",bcs
->mode
);
328 cs
->BC_Write_Reg(cs
, bchan
, W_B_CMDR
, W_B_CMDR_RACK
| W_B_CMDR_RRST
| W_B_CMDR_RACT
);
329 if (bcs
->mode
!= L1_MODE_TRANS
)
330 bcs
->hw
.w6692
.rcvidx
= 0;
332 if (bcs
->mode
== L1_MODE_TRANS
) {
333 /* receive audio data */
334 if (!(skb
= dev_alloc_skb(W_B_FIFO_THRESH
)))
335 printk(KERN_WARNING
"HiSax: receive out of memory\n");
337 memcpy(skb_put(skb
, W_B_FIFO_THRESH
), bcs
->hw
.w6692
.rcvbuf
, W_B_FIFO_THRESH
);
338 skb_queue_tail(&bcs
->rqueue
, skb
);
340 bcs
->hw
.w6692
.rcvidx
= 0;
341 schedule_event(bcs
, B_RCVBUFREADY
);
344 if (val
& W_B_EXI_XDUN
) { /* XDUN */
345 cs
->BC_Write_Reg(cs
, bchan
, W_B_CMDR
, W_B_CMDR_XRST
| W_B_CMDR_RACT
);
346 if (cs
->debug
& L1_DEB_WARN
)
347 debugl1(cs
, "W6692 B EXIR %x Lost TX", val
);
349 W6692B_fill_fifo(bcs
);
351 /* Here we lost an TX interrupt, so
352 * restart transmitting the whole frame.
355 skb_push(bcs
->tx_skb
, bcs
->hw
.w6692
.count
);
356 bcs
->tx_cnt
+= bcs
->hw
.w6692
.count
;
357 bcs
->hw
.w6692
.count
= 0;
362 if (val
& W_B_EXI_XFR
) { /* XFR */
363 r
= cs
->BC_Read_Reg(cs
, bchan
, W_B_STAR
);
364 if (r
& W_B_STAR_XDOW
) {
365 if (cs
->debug
& L1_DEB_WARN
)
366 debugl1(cs
, "W6692 B STAR %x XDOW", r
);
367 cs
->BC_Write_Reg(cs
, bchan
, W_B_CMDR
, W_B_CMDR_XRST
| W_B_CMDR_RACT
);
368 if (bcs
->tx_skb
&& (bcs
->mode
!= 1)) {
369 skb_push(bcs
->tx_skb
, bcs
->hw
.w6692
.count
);
370 bcs
->tx_cnt
+= bcs
->hw
.w6692
.count
;
371 bcs
->hw
.w6692
.count
= 0;
375 if (bcs
->tx_skb
->len
) {
376 W6692B_fill_fifo(bcs
);
379 if (test_bit(FLG_LLI_L1WAKEUP
,&bcs
->st
->lli
.flag
) &&
380 (PACKET_NOACK
!= bcs
->tx_skb
->pkt_type
)) {
382 spin_lock_irqsave(&bcs
->aclock
, flags
);
383 bcs
->ackcnt
+= bcs
->hw
.w6692
.count
;
384 spin_unlock_irqrestore(&bcs
->aclock
, flags
);
385 schedule_event(bcs
, B_ACKPENDING
);
387 dev_kfree_skb_irq(bcs
->tx_skb
);
388 bcs
->hw
.w6692
.count
= 0;
392 if ((bcs
->tx_skb
= skb_dequeue(&bcs
->squeue
))) {
393 bcs
->hw
.w6692
.count
= 0;
394 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
395 W6692B_fill_fifo(bcs
);
397 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
398 schedule_event(bcs
, B_XMTBUFREADY
);
404 W6692_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
406 struct IsdnCardState
*cs
= dev_id
;
407 u_char val
, exval
, v1
;
413 spin_lock_irqsave(&cs
->lock
, flags
);
414 val
= cs
->readW6692(cs
, W_ISTA
);
416 spin_unlock_irqrestore(&cs
->lock
, flags
);
420 if (cs
->debug
& L1_DEB_ISAC
)
421 debugl1(cs
, "W6692 ISTA %x", val
);
423 if (val
& W_INT_D_RME
) { /* RME */
424 exval
= cs
->readW6692(cs
, W_D_RSTA
);
425 if (exval
& (W_D_RSTA_RDOV
| W_D_RSTA_CRCE
| W_D_RSTA_RMB
)) {
426 if (exval
& W_D_RSTA_RDOV
)
427 if (cs
->debug
& L1_DEB_WARN
)
428 debugl1(cs
, "W6692 RDOV");
429 if (exval
& W_D_RSTA_CRCE
)
430 if (cs
->debug
& L1_DEB_WARN
)
431 debugl1(cs
, "W6692 D-channel CRC error");
432 if (exval
& W_D_RSTA_RMB
)
433 if (cs
->debug
& L1_DEB_WARN
)
434 debugl1(cs
, "W6692 D-channel ABORT");
435 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_RACK
| W_D_CMDR_RRST
);
437 count
= cs
->readW6692(cs
, W_D_RBCL
) & (W_D_FIFO_THRESH
- 1);
439 count
= W_D_FIFO_THRESH
;
440 W6692_empty_fifo(cs
, count
);
441 if ((count
= cs
->rcvidx
) > 0) {
443 if (!(skb
= alloc_skb(count
, GFP_ATOMIC
)))
444 printk(KERN_WARNING
"HiSax: D receive out of memory\n");
446 memcpy(skb_put(skb
, count
), cs
->rcvbuf
, count
);
447 skb_queue_tail(&cs
->rq
, skb
);
452 schedule_event(cs
, D_RCVBUFREADY
);
454 if (val
& W_INT_D_RMR
) { /* RMR */
455 W6692_empty_fifo(cs
, W_D_FIFO_THRESH
);
457 if (val
& W_INT_D_XFR
) { /* XFR */
458 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
459 del_timer(&cs
->dbusytimer
);
460 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
461 schedule_event(cs
, D_CLEARBUSY
);
463 if (cs
->tx_skb
->len
) {
467 dev_kfree_skb_irq(cs
->tx_skb
);
472 if ((cs
->tx_skb
= skb_dequeue(&cs
->sq
))) {
476 schedule_event(cs
, D_XMTBUFREADY
);
479 if (val
& (W_INT_XINT0
| W_INT_XINT1
)) { /* XINT0/1 - never */
480 if (cs
->debug
& L1_DEB_ISAC
)
481 debugl1(cs
, "W6692 spurious XINT!");
483 if (val
& W_INT_D_EXI
) { /* EXI */
484 exval
= cs
->readW6692(cs
, W_D_EXIR
);
485 if (cs
->debug
& L1_DEB_WARN
)
486 debugl1(cs
, "W6692 D_EXIR %02x", exval
);
487 if (exval
& (W_D_EXI_XDUN
| W_D_EXI_XCOL
)) { /* Transmit underrun/collision */
488 debugl1(cs
, "W6692 D-chan underrun/collision");
489 printk(KERN_WARNING
"HiSax: W6692 XDUN/XCOL\n");
490 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
491 del_timer(&cs
->dbusytimer
);
492 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
493 schedule_event(cs
, D_CLEARBUSY
);
494 if (cs
->tx_skb
) { /* Restart frame */
495 skb_push(cs
->tx_skb
, cs
->tx_cnt
);
499 printk(KERN_WARNING
"HiSax: W6692 XDUN/XCOL no skb\n");
500 debugl1(cs
, "W6692 XDUN/XCOL no skb");
501 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_XRST
);
504 if (exval
& W_D_EXI_RDOV
) { /* RDOV */
505 debugl1(cs
, "W6692 D-channel RDOV");
506 printk(KERN_WARNING
"HiSax: W6692 D-RDOV\n");
507 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_RRST
);
509 if (exval
& W_D_EXI_TIN2
) { /* TIN2 - never */
510 debugl1(cs
, "W6692 spurious TIN2 interrupt");
512 if (exval
& W_D_EXI_MOC
) { /* MOC - not supported */
513 debugl1(cs
, "W6692 spurious MOC interrupt");
514 v1
= cs
->readW6692(cs
, W_MOSR
);
515 debugl1(cs
, "W6692 MOSR %02x", v1
);
517 if (exval
& W_D_EXI_ISC
) { /* ISC - Level1 change */
518 v1
= cs
->readW6692(cs
, W_CIR
);
519 if (cs
->debug
& L1_DEB_ISAC
)
520 debugl1(cs
, "W6692 ISC CIR=0x%02X", v1
);
521 if (v1
& W_CIR_ICC
) {
522 cs
->dc
.w6692
.ph_state
= v1
& W_CIR_COD_MASK
;
523 if (cs
->debug
& L1_DEB_ISAC
)
524 debugl1(cs
, "ph_state_change %x", cs
->dc
.w6692
.ph_state
);
525 schedule_event(cs
, D_L1STATECHANGE
);
527 if (v1
& W_CIR_SCC
) {
528 v1
= cs
->readW6692(cs
, W_SQR
);
529 debugl1(cs
, "W6692 SCC SQR=0x%02X", v1
);
532 if (exval
& W_D_EXI_WEXP
) {
533 debugl1(cs
, "W6692 spurious WEXP interrupt!");
535 if (exval
& W_D_EXI_TEXP
) {
536 debugl1(cs
, "W6692 spurious TEXP interrupt!");
539 if (val
& W_INT_B1_EXI
) {
540 debugl1(cs
, "W6692 B channel 1 interrupt");
541 W6692B_interrupt(cs
, 0);
543 if (val
& W_INT_B2_EXI
) {
544 debugl1(cs
, "W6692 B channel 2 interrupt");
545 W6692B_interrupt(cs
, 1);
547 val
= cs
->readW6692(cs
, W_ISTA
);
553 printk(KERN_WARNING
"W6692 IRQ LOOP\n");
554 cs
->writeW6692(cs
, W_IMASK
, 0xff);
556 spin_unlock_irqrestore(&cs
->lock
, flags
);
561 W6692_l1hw(struct PStack
*st
, int pr
, void *arg
)
563 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
564 struct sk_buff
*skb
= arg
;
569 case (PH_DATA
| REQUEST
):
570 if (cs
->debug
& DEB_DLOG_HEX
)
571 LogFrame(cs
, skb
->data
, skb
->len
);
572 if (cs
->debug
& DEB_DLOG_VERBOSE
)
573 dlogframe(cs
, skb
, 0);
574 spin_lock_irqsave(&cs
->lock
, flags
);
576 skb_queue_tail(&cs
->sq
, skb
);
577 #ifdef L2FRAME_DEBUG /* psa */
578 if (cs
->debug
& L1_DEB_LAPD
)
579 Logl2Frame(cs
, skb
, "PH_DATA Queued", 0);
584 #ifdef L2FRAME_DEBUG /* psa */
585 if (cs
->debug
& L1_DEB_LAPD
)
586 Logl2Frame(cs
, skb
, "PH_DATA", 0);
590 spin_unlock_irqrestore(&cs
->lock
, flags
);
592 case (PH_PULL
| INDICATION
):
593 spin_lock_irqsave(&cs
->lock
, flags
);
595 if (cs
->debug
& L1_DEB_WARN
)
596 debugl1(cs
, " l2l1 tx_skb exist this shouldn't happen");
597 skb_queue_tail(&cs
->sq
, skb
);
598 spin_unlock_irqrestore(&cs
->lock
, flags
);
601 if (cs
->debug
& DEB_DLOG_HEX
)
602 LogFrame(cs
, skb
->data
, skb
->len
);
603 if (cs
->debug
& DEB_DLOG_VERBOSE
)
604 dlogframe(cs
, skb
, 0);
607 #ifdef L2FRAME_DEBUG /* psa */
608 if (cs
->debug
& L1_DEB_LAPD
)
609 Logl2Frame(cs
, skb
, "PH_DATA_PULLED", 0);
612 spin_unlock_irqrestore(&cs
->lock
, flags
);
614 case (PH_PULL
| REQUEST
):
615 #ifdef L2FRAME_DEBUG /* psa */
616 if (cs
->debug
& L1_DEB_LAPD
)
617 debugl1(cs
, "-> PH_REQUEST_PULL");
620 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
621 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
623 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
625 case (HW_RESET
| REQUEST
):
626 spin_lock_irqsave(&cs
->lock
, flags
);
627 if ((cs
->dc
.w6692
.ph_state
== W_L1IND_DRD
)) {
628 ph_command(cs
, W_L1CMD_ECK
);
629 spin_unlock_irqrestore(&cs
->lock
, flags
);
631 ph_command(cs
, W_L1CMD_RST
);
632 cs
->dc
.w6692
.ph_state
= W_L1CMD_RST
;
633 spin_unlock_irqrestore(&cs
->lock
, flags
);
637 case (HW_ENABLE
| REQUEST
):
638 spin_lock_irqsave(&cs
->lock
, flags
);
639 ph_command(cs
, W_L1CMD_ECK
);
640 spin_unlock_irqrestore(&cs
->lock
, flags
);
642 case (HW_INFO3
| REQUEST
):
643 spin_lock_irqsave(&cs
->lock
, flags
);
644 ph_command(cs
, W_L1CMD_AR8
);
645 spin_unlock_irqrestore(&cs
->lock
, flags
);
647 case (HW_TESTLOOP
| REQUEST
):
653 /* !!! not implemented yet */
655 case (HW_DEACTIVATE
| RESPONSE
):
656 skb_queue_purge(&cs
->rq
);
657 skb_queue_purge(&cs
->sq
);
659 dev_kfree_skb_any(cs
->tx_skb
);
662 if (test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
))
663 del_timer(&cs
->dbusytimer
);
664 if (test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
665 schedule_event(cs
, D_CLEARBUSY
);
668 if (cs
->debug
& L1_DEB_WARN
)
669 debugl1(cs
, "W6692_l1hw unknown %04x", pr
);
675 setstack_W6692(struct PStack
*st
, struct IsdnCardState
*cs
)
677 st
->l1
.l1hw
= W6692_l1hw
;
681 DC_Close_W6692(struct IsdnCardState
*cs
)
686 dbusy_timer_handler(struct IsdnCardState
*cs
)
688 struct PStack
*stptr
;
692 spin_lock_irqsave(&cs
->lock
, flags
);
693 if (test_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
)) {
694 rbch
= cs
->readW6692(cs
, W_D_RBCH
);
695 star
= cs
->readW6692(cs
, W_D_STAR
);
697 debugl1(cs
, "D-Channel Busy D_RBCH %02x D_STAR %02x",
699 if (star
& W_D_STAR_XBZ
) { /* D-Channel Busy */
700 test_and_set_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
702 while (stptr
!= NULL
) {
703 stptr
->l1
.l1l2(stptr
, PH_PAUSE
| INDICATION
, NULL
);
707 /* discard frame; reset transceiver */
708 test_and_clear_bit(FLG_DBUSY_TIMER
, &cs
->HW_Flags
);
710 dev_kfree_skb_any(cs
->tx_skb
);
714 printk(KERN_WARNING
"HiSax: W6692 D-Channel Busy no skb\n");
715 debugl1(cs
, "D-Channel Busy no skb");
717 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_XRST
); /* Transmitter reset */
718 spin_unlock_irqrestore(&cs
->lock
, flags
);
719 cs
->irq_func(cs
->irq
, cs
, NULL
);
723 spin_unlock_irqrestore(&cs
->lock
, flags
);
727 W6692Bmode(struct BCState
*bcs
, int mode
, int bchan
)
729 struct IsdnCardState
*cs
= bcs
->cs
;
731 if (cs
->debug
& L1_DEB_HSCX
)
732 debugl1(cs
, "w6692 %c mode %d ichan %d",
733 '1' + bchan
, mode
, bchan
);
735 bcs
->channel
= bchan
;
736 bcs
->hw
.w6692
.bchan
= bchan
;
740 cs
->BC_Write_Reg(cs
, bchan
, W_B_MODE
, 0);
742 case (L1_MODE_TRANS
):
743 cs
->BC_Write_Reg(cs
, bchan
, W_B_MODE
, W_B_MODE_MMS
);
746 cs
->BC_Write_Reg(cs
, bchan
, W_B_MODE
, W_B_MODE_ITF
);
747 cs
->BC_Write_Reg(cs
, bchan
, W_B_ADM1
, 0xff);
748 cs
->BC_Write_Reg(cs
, bchan
, W_B_ADM2
, 0xff);
752 cs
->BC_Write_Reg(cs
, bchan
, W_B_CMDR
, W_B_CMDR_RRST
|
753 W_B_CMDR_RACT
| W_B_CMDR_XRST
);
754 cs
->BC_Write_Reg(cs
, bchan
, W_B_EXIM
, 0x00);
758 W6692_l2l1(struct PStack
*st
, int pr
, void *arg
)
760 struct sk_buff
*skb
= arg
;
761 struct BCState
*bcs
= st
->l1
.bcs
;
765 case (PH_DATA
| REQUEST
):
766 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
768 skb_queue_tail(&bcs
->squeue
, skb
);
771 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
772 bcs
->hw
.w6692
.count
= 0;
773 bcs
->cs
->BC_Send_Data(bcs
);
775 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
777 case (PH_PULL
| INDICATION
):
779 printk(KERN_WARNING
"W6692_l2l1: this shouldn't happen\n");
782 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
783 test_and_set_bit(BC_FLG_BUSY
, &bcs
->Flag
);
785 bcs
->hw
.w6692
.count
= 0;
786 bcs
->cs
->BC_Send_Data(bcs
);
787 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
789 case (PH_PULL
| REQUEST
):
791 test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
792 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
794 test_and_set_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
);
796 case (PH_ACTIVATE
| REQUEST
):
797 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
798 test_and_set_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
799 W6692Bmode(bcs
, st
->l1
.mode
, st
->l1
.bc
);
800 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
801 l1_msg_b(st
, pr
, arg
);
803 case (PH_DEACTIVATE
| REQUEST
):
804 l1_msg_b(st
, pr
, arg
);
806 case (PH_DEACTIVATE
| CONFIRM
):
807 spin_lock_irqsave(&bcs
->cs
->lock
, flags
);
808 test_and_clear_bit(BC_FLG_ACTIV
, &bcs
->Flag
);
809 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
810 W6692Bmode(bcs
, 0, st
->l1
.bc
);
811 spin_unlock_irqrestore(&bcs
->cs
->lock
, flags
);
812 st
->l1
.l1l2(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
818 close_w6692state(struct BCState
*bcs
)
820 W6692Bmode(bcs
, 0, bcs
->channel
);
821 if (test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
822 if (bcs
->hw
.w6692
.rcvbuf
) {
823 kfree(bcs
->hw
.w6692
.rcvbuf
);
824 bcs
->hw
.w6692
.rcvbuf
= NULL
;
830 skb_queue_purge(&bcs
->rqueue
);
831 skb_queue_purge(&bcs
->squeue
);
833 dev_kfree_skb_any(bcs
->tx_skb
);
835 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
841 open_w6692state(struct IsdnCardState
*cs
, struct BCState
*bcs
)
843 if (!test_and_set_bit(BC_FLG_INIT
, &bcs
->Flag
)) {
844 if (!(bcs
->hw
.w6692
.rcvbuf
= kmalloc(HSCX_BUFMAX
, GFP_ATOMIC
))) {
846 "HiSax: No memory for w6692.rcvbuf\n");
847 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
850 if (!(bcs
->blog
= kmalloc(MAX_BLOG_SPACE
, GFP_ATOMIC
))) {
852 "HiSax: No memory for bcs->blog\n");
853 test_and_clear_bit(BC_FLG_INIT
, &bcs
->Flag
);
854 kfree(bcs
->hw
.w6692
.rcvbuf
);
855 bcs
->hw
.w6692
.rcvbuf
= NULL
;
858 skb_queue_head_init(&bcs
->rqueue
);
859 skb_queue_head_init(&bcs
->squeue
);
862 test_and_clear_bit(BC_FLG_BUSY
, &bcs
->Flag
);
864 bcs
->hw
.w6692
.rcvidx
= 0;
870 setstack_w6692(struct PStack
*st
, struct BCState
*bcs
)
872 bcs
->channel
= st
->l1
.bc
;
873 if (open_w6692state(st
->l1
.hardware
, bcs
))
876 st
->l2
.l2l1
= W6692_l2l1
;
877 setstack_manager(st
);
883 void resetW6692(struct IsdnCardState
*cs
)
885 cs
->writeW6692(cs
, W_D_CTL
, W_D_CTL_SRST
);
887 cs
->writeW6692(cs
, W_D_CTL
, 0x00);
889 cs
->writeW6692(cs
, W_IMASK
, 0xff);
890 cs
->writeW6692(cs
, W_D_SAM
, 0xff);
891 cs
->writeW6692(cs
, W_D_TAM
, 0xff);
892 cs
->writeW6692(cs
, W_D_EXIM
, 0x00);
893 cs
->writeW6692(cs
, W_D_MODE
, W_D_MODE_RACT
);
894 cs
->writeW6692(cs
, W_IMASK
, 0x18);
895 if (cs
->subtyp
== W6692_USR
) {
896 /* seems that USR implemented some power control features
897 * Pin 79 is connected to the oscilator circuit so we
898 * have to handle it here
900 cs
->writeW6692(cs
, W_PCTL
, 0x80);
901 cs
->writeW6692(cs
, W_XDATA
, 0x00);
905 void __init
initW6692(struct IsdnCardState
*cs
, int part
)
908 cs
->setstack_d
= setstack_W6692
;
909 cs
->DC_Close
= DC_Close_W6692
;
910 cs
->dbusytimer
.function
= (void *) dbusy_timer_handler
;
911 cs
->dbusytimer
.data
= (long) cs
;
912 init_timer(&cs
->dbusytimer
);
914 ph_command(cs
, W_L1CMD_RST
);
915 cs
->dc
.w6692
.ph_state
= W_L1CMD_RST
;
917 ph_command(cs
, W_L1CMD_ECK
);
919 cs
->bcs
[0].BC_SetStack
= setstack_w6692
;
920 cs
->bcs
[1].BC_SetStack
= setstack_w6692
;
921 cs
->bcs
[0].BC_Close
= close_w6692state
;
922 cs
->bcs
[1].BC_Close
= close_w6692state
;
923 W6692Bmode(cs
->bcs
, 0, 0);
924 W6692Bmode(cs
->bcs
+ 1, 0, 0);
927 /* Reenable all IRQ */
928 cs
->writeW6692(cs
, W_IMASK
, 0x18);
929 cs
->writeW6692(cs
, W_D_EXIM
, 0x00);
930 cs
->BC_Write_Reg(cs
, 0, W_B_EXIM
, 0x00);
931 cs
->BC_Write_Reg(cs
, 1, W_B_EXIM
, 0x00);
932 /* Reset D-chan receiver and transmitter */
933 cs
->writeW6692(cs
, W_D_CMDR
, W_D_CMDR_RRST
| W_D_CMDR_XRST
);
937 /* Interface functions */
940 ReadW6692(struct IsdnCardState
*cs
, u_char offset
)
942 return (inb(cs
->hw
.w6692
.iobase
+ offset
));
946 WriteW6692(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
948 outb(value
, cs
->hw
.w6692
.iobase
+ offset
);
952 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
954 insb(cs
->hw
.w6692
.iobase
+ W_D_RFIFO
, data
, size
);
958 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
960 outsb(cs
->hw
.w6692
.iobase
+ W_D_XFIFO
, data
, size
);
964 ReadW6692B(struct IsdnCardState
*cs
, int bchan
, u_char offset
)
966 return (inb(cs
->hw
.w6692
.iobase
+ (bchan
? 0x40 : 0) + offset
));
970 WriteW6692B(struct IsdnCardState
*cs
, int bchan
, u_char offset
, u_char value
)
972 outb(value
, cs
->hw
.w6692
.iobase
+ (bchan
? 0x40 : 0) + offset
);
976 w6692_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
983 cs
->writeW6692(cs
, W_IMASK
, 0xff);
984 release_region(cs
->hw
.w6692
.iobase
, 256);
985 if (cs
->subtyp
== W6692_USR
) {
986 cs
->writeW6692(cs
, W_XDATA
, 0x04);
1000 static struct pci_dev
*dev_w6692 __initdata
= NULL
;
1003 setup_w6692(struct IsdnCard
*card
)
1005 struct IsdnCardState
*cs
= card
->cs
;
1009 u_int pci_ioaddr
= 0;
1011 strcpy(tmp
, w6692_revision
);
1012 printk(KERN_INFO
"HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp
));
1013 if (cs
->typ
!= ISDN_CTYPE_W6692
)
1016 while (id_list
[id_idx
].vendor_id
) {
1017 dev_w6692
= pci_find_device(id_list
[id_idx
].vendor_id
,
1018 id_list
[id_idx
].device_id
,
1021 if (pci_enable_device(dev_w6692
))
1023 cs
->subtyp
= id_idx
;
1030 pci_irq
= dev_w6692
->irq
;
1031 /* I think address 0 is allways the configuration area */
1032 /* and address 1 is the real IO space KKe 03.09.99 */
1033 pci_ioaddr
= pci_resource_start(dev_w6692
, 1);
1034 /* USR ISDN PCI card TA need some special handling */
1035 if (cs
->subtyp
== W6692_WINBOND
) {
1036 if ((W6692_SV_USR
== dev_w6692
->subsystem_vendor
) &&
1037 (W6692_SD_USR
== dev_w6692
->subsystem_device
)) {
1038 cs
->subtyp
= W6692_USR
;
1043 printk(KERN_WARNING
"W6692: No PCI card found\n");
1048 printk(KERN_WARNING
"W6692: No IRQ for PCI card found\n");
1052 printk(KERN_WARNING
"W6692: NO I/O Base Address found\n");
1055 cs
->hw
.w6692
.iobase
= pci_ioaddr
;
1056 printk(KERN_INFO
"Found: %s %s, I/O base: 0x%x, irq: %d\n",
1057 id_list
[cs
->subtyp
].vendor_name
, id_list
[cs
->subtyp
].card_name
,
1058 pci_ioaddr
, pci_irq
);
1059 if (!request_region(cs
->hw
.w6692
.iobase
, 256, id_list
[cs
->subtyp
].card_name
)) {
1061 "HiSax: %s I/O ports %x-%x already in use\n",
1062 id_list
[cs
->subtyp
].card_name
,
1063 cs
->hw
.w6692
.iobase
,
1064 cs
->hw
.w6692
.iobase
+ 255);
1068 printk(KERN_WARNING
"HiSax: W6692 and NO_PCI_BIOS\n");
1069 printk(KERN_WARNING
"HiSax: W6692 unable to config\n");
1071 #endif /* CONFIG_PCI */
1074 "HiSax: %s config irq:%d I/O:%x\n",
1075 id_list
[cs
->subtyp
].card_name
, cs
->irq
,
1076 cs
->hw
.w6692
.iobase
);
1078 INIT_WORK(&cs
->tqueue
, (void *)(void *) W6692_bh
, cs
);
1079 cs
->readW6692
= &ReadW6692
;
1080 cs
->writeW6692
= &WriteW6692
;
1081 cs
->readisacfifo
= &ReadISACfifo
;
1082 cs
->writeisacfifo
= &WriteISACfifo
;
1083 cs
->BC_Read_Reg
= &ReadW6692B
;
1084 cs
->BC_Write_Reg
= &WriteW6692B
;
1085 cs
->BC_Send_Data
= &W6692B_fill_fifo
;
1086 cs
->cardmsg
= &w6692_card_msg
;
1087 cs
->irq_func
= &W6692_interrupt
;
1088 cs
->irq_flags
|= SA_SHIRQ
;
1089 W6692Version(cs
, "W6692:");
1090 printk(KERN_INFO
"W6692 ISTA=0x%X\n", ReadW6692(cs
, W_ISTA
));
1091 printk(KERN_INFO
"W6692 IMASK=0x%X\n", ReadW6692(cs
, W_IMASK
));
1092 printk(KERN_INFO
"W6692 D_EXIR=0x%X\n", ReadW6692(cs
, W_D_EXIR
));
1093 printk(KERN_INFO
"W6692 D_EXIM=0x%X\n", ReadW6692(cs
, W_D_EXIM
));
1094 printk(KERN_INFO
"W6692 D_RSTA=0x%X\n", ReadW6692(cs
, W_D_RSTA
));