linux/drivers/isdn/hisax/netjet.c
<<
>>
Prefs
   1/* $Id: netjet.c,v 1.29.2.4 2004/02/11 13:21:34 keil 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
 982
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.