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