1/* $Id: netjet.c,v 1.1.1.1 2007/08/03 18:52:35 Exp $ 2 * 3 * low level stuff for Traverse Technologie NETJet ISDN cards 4 * 5 * Author Karsten Keil 6 * Copyright by Karsten Keil <keil@isdn4linux.de> 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 * Thanks to Traverse Technologies Australia for documents and information 12 * 13 * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au) 14 * 15 */ 16 17#include <linux/init.h> 18#include "hisax.h" 19#include "isac.h" 20#include "hscx.h" 21#include "isdnl1.h" 22#include <linux/interrupt.h> 23#include <linux/ppp_defs.h> 24#include <asm/io.h> 25#include "netjet.h" 26 27/* Interface functions */ 28 29u_char 30NETjet_ReadIC(struct IsdnCardState *cs, u_char offset) 31{ 32 u_char ret; 33 34 cs->hw.njet.auxd &= 0xfc; 35 cs->hw.njet.auxd |= (offset>>4) & 3; 36 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 37 ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2)); 38 return(ret); 39} 40 41void 42NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value) 43{ 44 cs->hw.njet.auxd &= 0xfc; 45 cs->hw.njet.auxd |= (offset>>4) & 3; 46 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 47 byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value); 48} 49 50void 51NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size) 52{ 53 cs->hw.njet.auxd &= 0xfc; 54 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 55 insb(cs->hw.njet.isac, data, size); 56} 57 58void 59NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size) 60{ 61 cs->hw.njet.auxd &= 0xfc; 62 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 63 outsb(cs->hw.njet.isac, data, size); 64} 65 66static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill) 67{ 68 u_int mask=0x000000ff, val = 0, *p=pos; 69 u_int i; 70 71 val |= fill; 72 if (chan) { 73 val <<= 8; 74 mask <<= 8; 75 } 76 mask ^= 0xffffffff; 77 for (i=0; i<cnt; i++) { 78 *p &= mask; 79 *p++ |= val; 80 if (p > bcs->hw.tiger.s_end) 81 p = bcs->hw.tiger.send; 82 } 83} 84 85static void 86mode_tiger(struct BCState *bcs, int mode, int bc) 87{ 88 struct IsdnCardState *cs = bcs->cs; 89 u_char led; 90 91 if (cs->debug & L1_DEB_HSCX) 92 debugl1(cs, "Tiger mode %d bchan %d/%d", 93 mode, bc, bcs->channel); 94 bcs->mode = mode; 95 bcs->channel = bc; 96 switch (mode) { 97 case (L1_MODE_NULL): 98 fill_mem(bcs, bcs->hw.tiger.send, 99 NETJET_DMA_TXSIZE, bc, 0xff); 100 if (cs->debug & L1_DEB_HSCX) 101 debugl1(cs, "Tiger stat rec %d/%d send %d", 102 bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err, 103 bcs->hw.tiger.s_tot); 104 if ((cs->bcs[0].mode == L1_MODE_NULL) && 105 (cs->bcs[1].mode == L1_MODE_NULL)) { 106 cs->hw.njet.dmactrl = 0; 107 byteout(cs->hw.njet.base + NETJET_DMACTRL, 108 cs->hw.njet.dmactrl); 109 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); 110 } 111 if (cs->typ == ISDN_CTYPE_NETJET_S) 112 { 113 // led off 114 led = bc & 0x01; 115 led = 0x01 << (6 + led); // convert to mask 116 led = ~led; 117 cs->hw.njet.auxd &= led; 118 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 119 } 120 break; 121 case (L1_MODE_TRANS): 122 break; 123 case (L1_MODE_HDLC_56K): 124 case (L1_MODE_HDLC): 125 fill_mem(bcs, bcs->hw.tiger.send, 126 NETJET_DMA_TXSIZE, bc, 0xff); 127 bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH; 128 bcs->hw.tiger.r_tot = 0; 129 bcs->hw.tiger.r_bitcnt = 0; 130 bcs->hw.tiger.r_one = 0; 131 bcs->hw.tiger.r_err = 0; 132 bcs->hw.tiger.s_tot = 0; 133 if (! cs->hw.njet.dmactrl) { 134 fill_mem(bcs, bcs->hw.tiger.send, 135 NETJET_DMA_TXSIZE, !bc, 0xff); 136 cs->hw.njet.dmactrl = 1; 137 byteout(cs->hw.njet.base + NETJET_DMACTRL, 138 cs->hw.njet.dmactrl); 139 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f); 140 /* was 0x3f now 0x0f for TJ300 and TJ320 GE 13/07/00 */ 141 } 142 bcs->hw.tiger.sendp = bcs->hw.tiger.send; 143 bcs->hw.tiger.free = NETJET_DMA_TXSIZE; 144 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); 145 if (cs->typ == ISDN_CTYPE_NETJET_S) 146 { 147 // led on 148 led = bc & 0x01; 149 led = 0x01 << (6 + led); // convert to mask 150 cs->hw.njet.auxd |= led; 151 byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); 152 } 153 break; 154 } 155 if (cs->debug & L1_DEB_HSCX) 156 debugl1(cs, "tiger: set %x %x %x %x/%x pulse=%d", 157 bytein(cs->hw.njet.base + NETJET_DMACTRL), 158 bytein(cs->hw.njet.base + NETJET_IRQMASK0), 159 bytein(cs->hw.njet.base + NETJET_IRQSTAT0), 160 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), 161 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), 162 bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); 163} 164 165static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) { 166 char tmp[128]; 167 char *t = tmp; 168 int i=count,j; 169 u_char *p = buf; 170 171 t += sprintf(t, "tiger %s(%4d)", s, count); 172 while (i>0) { 173 if (i>16) 174 j=16; 175 else 176 j=i; 177 QuickHex(t, p, j); 178 debugl1(cs, tmp); 179 p += j; 180 i -= j; 181 t = tmp; 182 t += sprintf(t, "tiger %s ", s); 183 } 184} 185 186// macro for 64k 187 188#define MAKE_RAW_BYTE for (j=0; j<8; j++) { \ 189 bitcnt++;\ 190 s_val >>= 1;\ 191 if (val & 1) {\ 192 s_one++;\ 193 s_val |= 0x80;\ 194 } else {\ 195 s_one = 0;\ 196 s_val &= 0x7f;\ 197 }\ 198 if (bitcnt==8) {\ 199 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\ 200 bitcnt = 0;\ 201 }\ 202 if (s_one == 5) {\ 203 s_val >>= 1;\ 204 s_val &= 0x7f;\ 205 bitcnt++;\ 206 s_one = 0;\ 207 }\ 208 if (bitcnt==8) {\ 209 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\ 210 bitcnt = 0;\ 211 }\ 212 val >>= 1;\ 213 } 214 215static int make_raw_data(struct BCState *bcs) { 216// this make_raw is for 64k 217 register u_int i,s_cnt=0; 218 register u_char j; 219 register u_char val; 220 register u_char s_one = 0; 221 register u_char s_val = 0; 222 register u_char bitcnt = 0; 223 u_int fcs; 224 225 if (!bcs->tx_skb) { 226 debugl1(bcs->cs, "tiger make_raw: NULL skb"); 227 return(1); 228 } 229 bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE; 230 fcs = PPP_INITFCS; 231 for (i=0; i<bcs->tx_skb->len; i++) { 232 val = bcs->tx_skb->data[i]; 233 fcs = PPP_FCS (fcs, val); 234 MAKE_RAW_BYTE; 235 } 236 fcs ^= 0xffff; 237 val = fcs & 0xff; 238 MAKE_RAW_BYTE; 239 val = (fcs>>8) & 0xff; 240 MAKE_RAW_BYTE; 241 val = HDLC_FLAG_VALUE; 242 for (j=0; j<8; j++) { 243 bitcnt++; 244 s_val >>= 1; 245 if (val & 1) 246 s_val |= 0x80; 247 else 248 s_val &= 0x7f; 249 if (bitcnt==8) { 250 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 251 bitcnt = 0; 252 } 253 val >>= 1; 254 } 255 if (bcs->cs->debug & L1_DEB_HSCX) 256 debugl1(bcs->cs,"tiger make_raw: in %ld out %d.%d", 257 bcs->tx_skb->len, s_cnt, bitcnt); 258 if (bitcnt) { 259 while (8>bitcnt++) { 260 s_val >>= 1; 261 s_val |= 0x80; 262 } 263 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 264 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix 265 } 266 bcs->hw.tiger.sendcnt = s_cnt; 267 bcs->tx_cnt -= bcs->tx_skb->len; 268 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; 269 return(0); 270} 271 272// macro for 56k 273 274#define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \ 275 bitcnt++;\ 276 s_val >>= 1;\ 277 if (val & 1) {\ 278 s_one++;\ 279 s_val |= 0x80;\ 280 } else {\ 281 s_one = 0;\ 282 s_val &= 0x7f;\ 283 }\ 284 if (bitcnt==7) {\ 285 s_val >>= 1;\ 286 s_val |= 0x80;\ 287 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\ 288 bitcnt = 0;\ 289 }\ 290 if (s_one == 5) {\ 291 s_val >>= 1;\ 292 s_val &= 0x7f;\ 293 bitcnt++;\ 294 s_one = 0;\ 295 }\ 296 if (bitcnt==7) {\ 297 s_val >>= 1;\ 298 s_val |= 0x80;\ 299 bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\ 300 bitcnt = 0;\ 301 }\ 302 val >>= 1;\ 303 } 304 305static int make_raw_data_56k(struct BCState *bcs) { 306// this make_raw is for 56k 307 register u_int i,s_cnt=0; 308 register u_char j; 309 register u_char val; 310 register u_char s_one = 0; 311 register u_char s_val = 0; 312 register u_char bitcnt = 0; 313 u_int fcs; 314 315 if (!bcs->tx_skb) { 316 debugl1(bcs->cs, "tiger make_raw_56k: NULL skb"); 317 return(1); 318 } 319 val = HDLC_FLAG_VALUE; 320 for (j=0; j<8; j++) { 321 bitcnt++; 322 s_val >>= 1; 323 if (val & 1) 324 s_val |= 0x80; 325 else 326 s_val &= 0x7f; 327 if (bitcnt==7) { 328 s_val >>= 1; 329 s_val |= 0x80; 330 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 331 bitcnt = 0; 332 } 333 val >>= 1; 334 }; 335 fcs = PPP_INITFCS; 336 for (i=0; i<bcs->tx_skb->len; i++) { 337 val = bcs->tx_skb->data[i]; 338 fcs = PPP_FCS (fcs, val); 339 MAKE_RAW_BYTE_56K; 340 } 341 fcs ^= 0xffff; 342 val = fcs & 0xff; 343 MAKE_RAW_BYTE_56K; 344 val = (fcs>>8) & 0xff; 345 MAKE_RAW_BYTE_56K; 346 val = HDLC_FLAG_VALUE; 347 for (j=0; j<8; j++) { 348 bitcnt++; 349 s_val >>= 1; 350 if (val & 1) 351 s_val |= 0x80; 352 else 353 s_val &= 0x7f; 354 if (bitcnt==7) { 355 s_val >>= 1; 356 s_val |= 0x80; 357 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 358 bitcnt = 0; 359 } 360 val >>= 1; 361 } 362 if (bcs->cs->debug & L1_DEB_HSCX) 363 debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d", 364 bcs->tx_skb->len, s_cnt, bitcnt); 365 if (bitcnt) { 366 while (8>bitcnt++) { 367 s_val >>= 1; 368 s_val |= 0x80; 369 } 370 bcs->hw.tiger.sendbuf[s_cnt++] = s_val; 371 bcs->hw.tiger.sendbuf[s_cnt++] = 0xff; // NJ<->NJ thoughput bug fix 372 } 373 bcs->hw.tiger.sendcnt = s_cnt; 374 bcs->tx_cnt -= bcs->tx_skb->len; 375 bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf; 376 return(0); 377} 378 379static void got_frame(struct BCState *bcs, int count) { 380 struct sk_buff *skb; 381 382 if (!(skb = dev_alloc_skb(count))) 383 printk(KERN_WARNING "TIGER: receive out of memory\n"); 384 else { 385 memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count); 386 skb_queue_tail(&bcs->rqueue, skb); 387 } 388 test_and_set_bit(B_RCVBUFREADY, &bcs->event); 389 schedule_work(&bcs->tqueue); 390 391 if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME) 392 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec"); 393} 394 395 396 397static void read_raw(struct BCState *bcs, u_int *buf, int cnt){ 398 int i; 399 register u_char j; 400 register u_char val; 401 u_int *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1; 402 register u_char state = bcs->hw.tiger.r_state; 403 register u_char r_one = bcs->hw.tiger.r_one; 404 register u_char r_val = bcs->hw.tiger.r_val; 405 register u_int bitcnt = bcs->hw.tiger.r_bitcnt; 406 u_int *p = buf; 407 int bits; 408 u_char mask; 409 410 if (bcs->mode == L1_MODE_HDLC) { // it's 64k 411 mask = 0xff; 412 bits = 8; 413 } 414 else { // it's 56K 415 mask = 0x7f; 416 bits = 7; 417 }; 418 for (i=0;i<cnt;i++) { 419 val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff); 420 p++; 421 if (p > pend) 422 p = bcs->hw.tiger.rec; 423 if ((val & mask) == mask) { 424 state = HDLC_ZERO_SEARCH; 425 bcs->hw.tiger.r_tot++; 426 bitcnt = 0; 427 r_one = 0; 428 continue; 429 } 430 for (j=0;j<bits;j++) { 431 if (state == HDLC_ZERO_SEARCH) { 432 if (val & 1) { 433 r_one++; 434 } else { 435 r_one=0; 436 state= HDLC_FLAG_SEARCH; 437 if (bcs->cs->debug & L1_DEB_HSCX) 438 debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x", 439 bcs->hw.tiger.r_tot,i,j,val); 440 } 441 } else if (state == HDLC_FLAG_SEARCH) { 442 if (val & 1) { 443 r_one++; 444 if (r_one>6) { 445 state=HDLC_ZERO_SEARCH; 446 } 447 } else { 448 if (r_one==6) { 449 bitcnt=0; 450 r_val=0; 451 state=HDLC_FLAG_FOUND; 452 if (bcs->cs->debug & L1_DEB_HSCX) 453 debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x", 454 bcs->hw.tiger.r_tot,i,j,val); 455 } 456 r_one=0; 457 } 458 } else if (state == HDLC_FLAG_FOUND) { 459 if (val & 1) { 460 r_one++; 461 if (r_one>6) { 462 state=HDLC_ZERO_SEARCH; 463 } else { 464 r_val >>= 1; 465 r_val |= 0x80; 466 bitcnt++; 467 } 468 } else { 469 if (r_one==6) { 470 bitcnt=0; 471 r_val=0; 472 r_one=0; 473 val >>= 1; 474 continue; 475 } else if (r_one!=5) { 476 r_val >>= 1; 477 r_val &= 0x7f; 478 bitcnt++; 479 } 480 r_one=0; 481 } 482 if ((state != HDLC_ZERO_SEARCH) && 483 !(bitcnt & 7)) { 484 state=HDLC_FRAME_FOUND; 485 bcs->hw.tiger.r_fcs = PPP_INITFCS; 486 bcs->hw.tiger.rcvbuf[0] = r_val; 487 bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val); 488 if (bcs->cs->debug & L1_DEB_HSCX) 489 debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x", 490 bcs->hw.tiger.r_tot,i,j,r_val,val, 491 bcs->cs->hw.njet.irqstat0); 492 } 493 } else if (state == HDLC_FRAME_FOUND) { 494 if (val & 1) { 495 r_one++; 496 if (r_one>6) { 497 state=HDLC_ZERO_SEARCH; 498 bitcnt=0; 499 } else { 500 r_val >>= 1; 501 r_val |= 0x80; 502 bitcnt++; 503 } 504 } else { 505 if (r_one==6) { 506 r_val=0; 507 r_one=0; 508 bitcnt++; 509 if (bitcnt & 7) { 510 debugl1(bcs->cs, "tiger: frame not byte aligned"); 511 state=HDLC_FLAG_SEARCH; 512 bcs->hw.tiger.r_err++; 513#ifdef ERROR_STATISTIC 514 bcs->err_inv++; 515#endif 516 } else { 517 if (bcs->cs->debug & L1_DEB_HSCX) 518 debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x", 519 i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0); 520 if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) { 521 got_frame(bcs, (bitcnt>>3)-3); 522 } else { 523 if (bcs->cs->debug) { 524 debugl1(bcs->cs, "tiger FCS error"); 525 printframe(bcs->cs, bcs->hw.tiger.rcvbuf, 526 (bitcnt>>3)-1, "rec"); 527 bcs->hw.tiger.r_err++; 528 } 529#ifdef ERROR_STATISTIC 530 bcs->err_crc++; 531#endif 532 } 533 state=HDLC_FLAG_FOUND; 534 } 535 bitcnt=0; 536 } else if (r_one==5) { 537 val >>= 1; 538 r_one=0; 539 continue; 540 } else { 541 r_val >>= 1; 542 r_val &= 0x7f; 543 bitcnt++; 544 } 545 r_one=0; 546 } 547 if ((state == HDLC_FRAME_FOUND) && 548 !(bitcnt & 7)) { 549 if ((bitcnt>>3)>=HSCX_BUFMAX) { 550 debugl1(bcs->cs, "tiger: frame too big"); 551 r_val=0; 552 state=HDLC_FLAG_SEARCH; 553 bcs->hw.tiger.r_err++; 554#ifdef ERROR_STATISTIC 555 bcs->err_inv++; 556#endif 557 } else { 558 bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val; 559 bcs->hw.tiger.r_fcs = 560 PPP_FCS (bcs->hw.tiger.r_fcs, r_val); 561 } 562 } 563 } 564 val >>= 1; 565 } 566 bcs->hw.tiger.r_tot++; 567 } 568 bcs->hw.tiger.r_state = state; 569 bcs->hw.tiger.r_one = r_one; 570 bcs->hw.tiger.r_val = r_val; 571 bcs->hw.tiger.r_bitcnt = bitcnt; 572} 573 574void read_tiger(struct IsdnCardState *cs) { 575 u_int *p; 576 int cnt = NETJET_DMA_RXSIZE/2; 577 578 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { 579 debugl1(cs,"tiger warn read double dma %x/%x", 580 cs->hw.njet.irqstat0, cs->hw.njet.last_is0); 581#ifdef ERROR_STATISTIC 582 if (cs->bcs[0].mode) 583 cs->bcs[0].err_rdo++; 584 if (cs->bcs[1].mode) 585 cs->bcs[1].err_rdo++; 586#endif 587 return; 588 } else { 589 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ; 590 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ); 591 } 592 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1) 593 p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1; 594 else 595 p = cs->bcs[0].hw.tiger.rec + cnt - 1; 596 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) 597 read_raw(cs->bcs, p, cnt); 598 599 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) 600 read_raw(cs->bcs + 1, p, cnt); 601 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ; 602} 603 604static void write_raw(struct BCState *bcs, u_int *buf, int cnt); 605 606void netjet_fill_dma(struct BCState *bcs) 607{ 608 register u_int *p, *sp; 609 register int cnt; 610 611 if (!bcs->tx_skb) 612 return; 613 if (bcs->cs->debug & L1_DEB_HSCX) 614 debugl1(bcs->cs,"tiger fill_dma1: c%d %4x", bcs->channel, 615 bcs->Flag); 616 if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag)) 617 return; 618 if (bcs->mode == L1_MODE_HDLC) { // it's 64k 619 if (make_raw_data(bcs)) 620 return; 621 } 622 else { // it's 56k 623 if (make_raw_data_56k(bcs)) 624 return; 625 }; 626 if (bcs->cs->debug & L1_DEB_HSCX) 627 debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel, 628 bcs->Flag); 629 if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { 630 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); 631 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { 632 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); 633 sp = bcs->hw.tiger.sendp; 634 if (p == bcs->hw.tiger.s_end) 635 p = bcs->hw.tiger.send -1; 636 if (sp == bcs->hw.tiger.s_end) 637 sp = bcs->hw.tiger.send -1; 638 cnt = p - sp; 639 if (cnt <0) { 640 write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free); 641 } else { 642 p++; 643 cnt++; 644 if (p > bcs->hw.tiger.s_end) 645 p = bcs->hw.tiger.send; 646 p++; 647 cnt++; 648 if (p > bcs->hw.tiger.s_end) 649 p = bcs->hw.tiger.send; 650 write_raw(bcs, p, bcs->hw.tiger.free - cnt); 651 } 652 } else if (test_and_clear_bit(BC_FLG_EMPTY, &bcs->Flag)) { 653 p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR)); 654 cnt = bcs->hw.tiger.s_end - p; 655 if (cnt < 2) { 656 p = bcs->hw.tiger.send + 1; 657 cnt = NETJET_DMA_TXSIZE/2 - 2; 658 } else { 659 p++; 660 p++; 661 if (cnt <= (NETJET_DMA_TXSIZE/2)) 662 cnt += NETJET_DMA_TXSIZE/2; 663 cnt--; 664 cnt--; 665 } 666 write_raw(bcs, p, cnt); 667 } 668 if (bcs->cs->debug & L1_DEB_HSCX) 669 debugl1(bcs->cs,"tiger fill_dma3: c%d %4x", bcs->channel, 670 bcs->Flag); 671} 672 673static void write_raw(struct BCState *bcs, u_int *buf, int cnt) { 674 u_int mask, val, *p=buf; 675 u_int i, s_cnt; 676 677 if (cnt <= 0) 678 return; 679 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) { 680 if (bcs->hw.tiger.sendcnt> cnt) { 681 s_cnt = cnt; 682 bcs->hw.tiger.sendcnt -= cnt; 683 } else { 684 s_cnt = bcs->hw.tiger.sendcnt; 685 bcs->hw.tiger.sendcnt = 0; 686 } 687 if (bcs->channel) 688 mask = 0xffff00ff; 689 else 690 mask = 0xffffff00; 691 for (i=0; i<s_cnt; i++) { 692 val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) : 693 (bcs->hw.tiger.sp[i]); 694 *p &= mask; 695 *p++ |= val; 696 if (p>bcs->hw.tiger.s_end) 697 p = bcs->hw.tiger.send; 698 } 699 bcs->hw.tiger.s_tot += s_cnt; 700 if (bcs->cs->debug & L1_DEB_HSCX) 701 debugl1(bcs->cs,"tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel, 702 buf, p, s_cnt, cnt, 703 bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0); 704 if (bcs->cs->debug & L1_DEB_HSCX_FIFO) 705 printframe(bcs->cs, bcs->hw.tiger.sp, s_cnt, "snd"); 706 bcs->hw.tiger.sp += s_cnt; 707 bcs->hw.tiger.sendp = p; 708 if (!bcs->hw.tiger.sendcnt) { 709 if (!bcs->tx_skb) { 710 debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt); 711 } else { 712 if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) && 713 (PACKET_NOACK != bcs->tx_skb->pkt_type)) { 714 u_long flags; 715 spin_lock_irqsave(&bcs->aclock, flags); 716 bcs->ackcnt += bcs->tx_skb->len; 717 spin_unlock_irqrestore(&bcs->aclock, flags); 718 schedule_event(bcs, B_ACKPENDING); 719 } 720 dev_kfree_skb_any(bcs->tx_skb); 721 bcs->tx_skb = NULL; 722 } 723 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 724 bcs->hw.tiger.free = cnt - s_cnt; 725 if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2)) 726 test_and_set_bit(BC_FLG_HALF, &bcs->Flag); 727 else { 728 test_and_clear_bit(BC_FLG_HALF, &bcs->Flag); 729 test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag); 730 } 731 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { 732 netjet_fill_dma(bcs); 733 } else { 734 mask ^= 0xffffffff; 735 if (s_cnt < cnt) { 736 for (i=s_cnt; i<cnt;i++) { 737 *p++ |= mask; 738 if (p>bcs->hw.tiger.s_end) 739 p = bcs->hw.tiger.send; 740 } 741 if (bcs->cs->debug & L1_DEB_HSCX) 742 debugl1(bcs->cs, "tiger write_raw: fill rest %d", 743 cnt - s_cnt); 744 } 745 test_and_set_bit(B_XMTBUFREADY, &bcs->event); 746 schedule_work(&bcs->tqueue); 747 } 748 } 749 } else if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) { 750 test_and_set_bit(BC_FLG_HALF, &bcs->Flag); 751 fill_mem(bcs, buf, cnt, bcs->channel, 0xff); 752 bcs->hw.tiger.free += cnt; 753 if (bcs->cs->debug & L1_DEB_HSCX) 754 debugl1(bcs->cs,"tiger write_raw: fill half"); 755 } else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) { 756 test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag); 757 fill_mem(bcs, buf, cnt, bcs->channel, 0xff); 758 if (bcs->cs->debug & L1_DEB_HSCX) 759 debugl1(bcs->cs,"tiger write_raw: fill full"); 760 } 761} 762 763void write_tiger(struct IsdnCardState *cs) { 764 u_int *p, cnt = NETJET_DMA_TXSIZE/2; 765 766 if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { 767 debugl1(cs,"tiger warn write double dma %x/%x", 768 cs->hw.njet.irqstat0, cs->hw.njet.last_is0); 769#ifdef ERROR_STATISTIC 770 if (cs->bcs[0].mode) 771 cs->bcs[0].err_tx++; 772 if (cs->bcs[1].mode) 773 cs->bcs[1].err_tx++; 774#endif 775 return; 776 } else { 777 cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE; 778 cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE); 779 } 780 if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE_1) 781 p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; 782 else 783 p = cs->bcs[0].hw.tiger.send + cnt - 1; 784 if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K)) 785 write_raw(cs->bcs, p, cnt); 786 if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K)) 787 write_raw(cs->bcs + 1, p, cnt); 788 cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE; 789} 790 791static void 792tiger_l2l1(struct PStack *st, int pr, void *arg) 793{ 794 struct BCState *bcs = st->l1.bcs; 795 struct sk_buff *skb = arg; 796 u_long flags; 797 798 switch (pr) { 799 case (PH_DATA | REQUEST): 800 spin_lock_irqsave(&bcs->cs->lock, flags); 801 if (bcs->tx_skb) { 802 skb_queue_tail(&bcs->squeue, skb); 803 } else { 804 bcs->tx_skb = skb; 805 bcs->cs->BC_Send_Data(bcs); 806 } 807 spin_unlock_irqrestore(&bcs->cs->lock, flags); 808 break; 809 case (PH_PULL | INDICATION): 810 spin_lock_irqsave(&bcs->cs->lock, flags); 811 if (bcs->tx_skb) { 812 printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n"); 813 } else { 814 bcs->tx_skb = skb; 815 bcs->cs->BC_Send_Data(bcs); 816 } 817 spin_unlock_irqrestore(&bcs->cs->lock, flags); 818 break; 819 case (PH_PULL | REQUEST): 820 if (!bcs->tx_skb) { 821 test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 822 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); 823 } else 824 test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); 825 break; 826 case (PH_ACTIVATE | REQUEST): 827 spin_lock_irqsave(&bcs->cs->lock, flags); 828 test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag); 829 mode_tiger(bcs, st->l1.mode, st->l1.bc); 830 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ 831 spin_unlock_irqrestore(&bcs->cs->lock, flags); 832 bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc)); 833 l1_msg_b(st, pr, arg); 834 break; 835 case (PH_DEACTIVATE | REQUEST): 836 /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */ 837 bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc)); 838 l1_msg_b(st, pr, arg); 839 break; 840 case (PH_DEACTIVATE | CONFIRM): 841 spin_lock_irqsave(&bcs->cs->lock, flags); 842 test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); 843 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 844 mode_tiger(bcs, 0, st->l1.bc); 845 spin_unlock_irqrestore(&bcs->cs->lock, flags); 846 st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); 847 break; 848 } 849} 850 851 852static void 853close_tigerstate(struct BCState *bcs) 854{ 855 mode_tiger(bcs, 0, bcs->channel); 856 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 857 kfree(bcs->hw.tiger.rcvbuf); 858 bcs->hw.tiger.rcvbuf = NULL; 859 kfree(bcs->hw.tiger.sendbuf); 860 bcs->hw.tiger.sendbuf = NULL; 861 skb_queue_purge(&bcs->rqueue); 862 skb_queue_purge(&bcs->squeue); 863 if (bcs->tx_skb) { 864 dev_kfree_skb_any(bcs->tx_skb); 865 bcs->tx_skb = NULL; 866 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 867 } 868 } 869} 870 871static int 872open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs) 873{ 874 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { 875 if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { 876 printk(KERN_WARNING 877 "HiSax: No memory for tiger.rcvbuf\n"); 878 return (1); 879 } 880 if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) { 881 printk(KERN_WARNING 882 "HiSax: No memory for tiger.sendbuf\n"); 883 return (1); 884 } 885 skb_queue_head_init(&bcs->rqueue); 886 skb_queue_head_init(&bcs->squeue); 887 } 888 bcs->tx_skb = NULL; 889 bcs->hw.tiger.sendcnt = 0; 890 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); 891 bcs->event = 0; 892 bcs->tx_cnt = 0; 893 return (0); 894} 895 896static int 897setstack_tiger(struct PStack *st, struct BCState *bcs) 898{ 899 bcs->channel = st->l1.bc; 900 if (open_tigerstate(st->l1.hardware, bcs)) 901 return (-1); 902 st->l1.bcs = bcs; 903 st->l2.l2l1 = tiger_l2l1; 904 setstack_manager(st); 905 bcs->st = st; 906 setstack_l1_B(st); 907 return (0); 908} 909 910 911void 912inittiger(struct IsdnCardState *cs) 913{ 914 if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int), 915 GFP_KERNEL | GFP_DMA))) { 916 printk(KERN_WARNING 917 "HiSax: No memory for tiger.send\n"); 918 return; 919 } 920 cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1; 921 cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1; 922 cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send; 923 cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq; 924 cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end; 925 926 memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int)); 927 debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send, 928 cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1); 929 outl(virt_to_bus(cs->bcs[0].hw.tiger.send), 930 cs->hw.njet.base + NETJET_DMA_READ_START); 931 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq), 932 cs->hw.njet.base + NETJET_DMA_READ_IRQ); 933 outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end), 934 cs->hw.njet.base + NETJET_DMA_READ_END); 935 if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int), 936 GFP_KERNEL | GFP_DMA))) { 937 printk(KERN_WARNING 938 "HiSax: No memory for tiger.rec\n"); 939 return; 940 } 941 debugl1(cs, "tiger: rec buf %p - %p", cs->bcs[0].hw.tiger.rec, 942 cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1); 943 cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec; 944 memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int)); 945 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec), 946 cs->hw.njet.base + NETJET_DMA_WRITE_START); 947 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1), 948 cs->hw.njet.base + NETJET_DMA_WRITE_IRQ); 949 outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1), 950 cs->hw.njet.base + NETJET_DMA_WRITE_END); 951 debugl1(cs, "tiger: dmacfg %x/%x pulse=%d", 952 inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR), 953 inl(cs->hw.njet.base + NETJET_DMA_READ_ADR), 954 bytein(cs->hw.njet.base + NETJET_PULSE_CNT)); 955 cs->hw.njet.last_is0 = 0; 956 cs->bcs[0].BC_SetStack = setstack_tiger; 957 cs->bcs[1].BC_SetStack = setstack_tiger; 958 cs->bcs[0].BC_Close = close_tigerstate; 959 cs->bcs[1].BC_Close = close_tigerstate; 960} 961 962static void 963releasetiger(struct IsdnCardState *cs) 964{ 965 kfree(cs->bcs[0].hw.tiger.send); 966 cs->bcs[0].hw.tiger.send = NULL; 967 cs->bcs[1].hw.tiger.send = NULL; 968 kfree(cs->bcs[0].hw.tiger.rec); 969 cs->bcs[0].hw.tiger.rec = NULL; 970 cs->bcs[1].hw.tiger.rec = NULL; 971} 972 973void 974release_io_netjet(struct IsdnCardState *cs) 975{ 976 byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); 977 byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); 978 releasetiger(cs); 979 release_region(cs->hw.njet.base, 256); 980} 981