linux/drivers/isdn/hisax/hfc_sx.c
<<
>>
Prefs
   1/* $Id: hfc_sx.c,v 1.12.2.5 2004/02/11 13:21:33 keil Exp $
   2 *
   3 * level driver for Cologne Chip Designs hfc-s+/sp based cards
   4 *
   5 * Author       Werner Cornelius
   6 *              based on existing driver for CCD HFC PCI cards
   7 * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
   8 * 
   9 * This software may be used and distributed according to the terms
  10 * of the GNU General Public License, incorporated herein by reference.
  11 *
  12 */
  13
  14#include <linux/init.h>
  15#include "hisax.h"
  16#include "hfc_sx.h"
  17#include "isdnl1.h"
  18#include <linux/interrupt.h>
  19#include <linux/isapnp.h>
  20
  21static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
  22
  23/***************************************/
  24/* IRQ-table for CCDs demo board       */
  25/* IRQs 6,5,10,11,12,15 are supported  */
  26/***************************************/
  27
  28/* Teles 16.3c Vendor Id TAG2620, Version 1.0, Vendor version 2.1
  29 *
  30 * Thanks to Uwe Wisniewski
  31 *
  32 * ISA-SLOT  Signal      PIN
  33 * B25        IRQ3     92 IRQ_G
  34 * B23        IRQ5     94 IRQ_A
  35 * B4         IRQ2/9   95 IRQ_B
  36 * D3         IRQ10    96 IRQ_C
  37 * D4         IRQ11    97 IRQ_D
  38 * D5         IRQ12    98 IRQ_E
  39 * D6         IRQ15    99 IRQ_F
  40 */
  41
  42#undef CCD_DEMO_BOARD
  43#ifdef CCD_DEMO_BOARD
  44static u_char ccd_sp_irqtab[16] = {
  45  0,0,0,0,0,2,1,0,0,0,3,4,5,0,0,6
  46};
  47#else /* Teles 16.3c */
  48static u_char ccd_sp_irqtab[16] = {
  49  0,0,0,7,0,1,0,0,0,2,3,4,5,0,0,6
  50};
  51#endif
  52#define NT_T1_COUNT 20          /* number of 3.125ms interrupts for G2 timeout */
  53
  54#define byteout(addr,val) outb(val,addr)
  55#define bytein(addr) inb(addr)
  56
  57/******************************/
  58/* In/Out access to registers */
  59/******************************/
  60static inline void
  61Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val)
  62{
  63        byteout(cs->hw.hfcsx.base+1, regnum);
  64        byteout(cs->hw.hfcsx.base, val);
  65} 
  66
  67static inline u_char
  68Read_hfc(struct IsdnCardState *cs, u_char regnum)
  69{
  70        u_char ret; 
  71
  72        byteout(cs->hw.hfcsx.base+1, regnum);
  73        ret = bytein(cs->hw.hfcsx.base);
  74        return(ret);
  75} 
  76
  77
  78/**************************************************/
  79/* select a fifo and remember which one for reuse */
  80/**************************************************/
  81static void
  82fifo_select(struct IsdnCardState *cs, u_char fifo)
  83{
  84        if (fifo == cs->hw.hfcsx.last_fifo) 
  85          return; /* still valid */
  86
  87        byteout(cs->hw.hfcsx.base+1, HFCSX_FIF_SEL);
  88        byteout(cs->hw.hfcsx.base, fifo);
  89        while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
  90        udelay(4);
  91        byteout(cs->hw.hfcsx.base, fifo);
  92        while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
  93}
  94
  95/******************************************/
  96/* reset the specified fifo to defaults.  */
  97/* If its a send fifo init needed markers */
  98/******************************************/
  99static void
 100reset_fifo(struct IsdnCardState *cs, u_char fifo)
 101{
 102        fifo_select(cs, fifo); /* first select the fifo */
 103        byteout(cs->hw.hfcsx.base+1, HFCSX_CIRM);
 104        byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.cirm | 0x80); /* reset cmd */
 105        udelay(1);
 106        while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
 107} 
 108
 109
 110/*************************************************************/
 111/* write_fifo writes the skb contents to the desired fifo    */
 112/* if no space is available or an error occurs 0 is returned */
 113/* the skb is not released in any way.                       */
 114/*************************************************************/
 115static int
 116write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans_max)
 117{
 118       unsigned short *msp;
 119        int fifo_size, count, z1, z2;
 120        u_char f_msk, f1, f2, *src;
 121
 122        if (skb->len <= 0) return(0);
 123        if (fifo & 1) return(0); /* no write fifo */
 124
 125        fifo_select(cs, fifo);
 126        if (fifo & 4) {
 127          fifo_size = D_FIFO_SIZE; /* D-channel */
 128          f_msk = MAX_D_FRAMES;
 129          if (trans_max) return(0); /* only HDLC */
 130        }
 131        else {
 132          fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
 133          f_msk = MAX_B_FRAMES;
 134        }
 135
 136        z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
 137        z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
 138
 139        /* Check for transparent mode */
 140        if (trans_max) {
 141          z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
 142          z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
 143          count = z2 - z1;
 144          if (count <= 0)
 145            count += fifo_size; /* free bytes */
 146          if (count < skb->len+1) return(0); /* no room */
 147          count = fifo_size - count; /* bytes still not send */
 148          if (count > 2 * trans_max) return(0); /* delay to long */
 149          count = skb->len;
 150          src = skb->data;
 151          while (count--)
 152            Write_hfc(cs, HFCSX_FIF_DWR, *src++);
 153          return(1); /* success */
 154        }
 155
 156        msp = ((struct hfcsx_extra *)(cs->hw.hfcsx.extra))->marker;
 157        msp += (((fifo >> 1) & 3) * (MAX_B_FRAMES+1));
 158        f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
 159        f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
 160
 161        count = f1 - f2; /* frame count actually buffered */
 162        if (count < 0)
 163                count += (f_msk + 1);   /* if wrap around */
 164        if (count > f_msk-1) {
 165          if (cs->debug & L1_DEB_ISAC_FIFO)
 166            debugl1(cs, "hfcsx_write_fifo %d more as %d frames",fifo,f_msk-1);
 167          return(0);
 168        }
 169
 170        *(msp + f1) = z1; /* remember marker */
 171
 172        if (cs->debug & L1_DEB_ISAC_FIFO)
 173                debugl1(cs, "hfcsx_write_fifo %d f1(%x) f2(%x) z1(f1)(%x)",
 174                        fifo, f1, f2, z1);
 175        /* now determine free bytes in FIFO buffer */
 176        count = *(msp + f2) - z1;
 177        if (count <= 0)
 178          count += fifo_size;   /* count now contains available bytes */
 179
 180        if (cs->debug & L1_DEB_ISAC_FIFO)
 181          debugl1(cs, "hfcsx_write_fifo %d count(%ld/%d)",
 182                  fifo, skb->len, count);
 183        if (count < skb->len) {
 184          if (cs->debug & L1_DEB_ISAC_FIFO)
 185            debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo);
 186          return(0);
 187        }
 188        
 189        count = skb->len; /* get frame len */
 190        src = skb->data;        /* source pointer */
 191        while (count--)
 192          Write_hfc(cs, HFCSX_FIF_DWR, *src++);
 193        
 194        Read_hfc(cs, HFCSX_FIF_INCF1); /* increment F1 */
 195        udelay(1);
 196        while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
 197        return(1);
 198} 
 199
 200/***************************************************************/
 201/* read_fifo reads data to an skb from the desired fifo        */
 202/* if no data is available or an error occurs NULL is returned */
 203/* the skb is not released in any way.                         */
 204/***************************************************************/
 205static struct sk_buff * 
 206read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
 207{       int fifo_size, count, z1, z2;
 208        u_char f_msk, f1, f2, *dst;
 209        struct sk_buff *skb;
 210
 211        if (!(fifo & 1)) return(NULL); /* no read fifo */
 212        fifo_select(cs, fifo);
 213        if (fifo & 4) {
 214          fifo_size = D_FIFO_SIZE; /* D-channel */
 215          f_msk = MAX_D_FRAMES;
 216          if (trans_max) return(NULL); /* only hdlc */
 217        }
 218        else {
 219          fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
 220          f_msk = MAX_B_FRAMES;
 221        }
 222
 223        /* transparent mode */
 224        if (trans_max) {
 225          z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
 226          z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
 227          z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
 228          z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
 229          /* now determine bytes in actual FIFO buffer */
 230          count = z1 - z2;
 231          if (count <= 0)
 232            count += fifo_size; /* count now contains buffered bytes */
 233          count++;
 234          if (count > trans_max) 
 235            count = trans_max; /* limit length */
 236            if ((skb = dev_alloc_skb(count))) {
 237              dst = skb_put(skb, count);
 238              while (count--) 
 239                *dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
 240              return(skb);
 241            }
 242            else return(NULL); /* no memory */
 243        }
 244
 245        do {
 246          f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
 247          f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
 248
 249          if (f1 == f2) return(NULL); /* no frame available */
 250
 251          z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
 252          z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
 253          z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
 254          z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
 255
 256          if (cs->debug & L1_DEB_ISAC_FIFO)
 257            debugl1(cs, "hfcsx_read_fifo %d f1(%x) f2(%x) z1(f2)(%x) z2(f2)(%x)",
 258                        fifo, f1, f2, z1, z2);
 259          /* now determine bytes in actual FIFO buffer */
 260          count = z1 - z2;
 261          if (count <= 0)
 262            count += fifo_size; /* count now contains buffered bytes */
 263          count++;
 264
 265          if (cs->debug & L1_DEB_ISAC_FIFO)
 266            debugl1(cs, "hfcsx_read_fifo %d count %ld)",
 267                    fifo, count);
 268
 269          if ((count > fifo_size) || (count < 4)) {
 270            if (cs->debug & L1_DEB_WARN)
 271              debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count);
 272            while (count) {
 273              count--; /* empty fifo */
 274              Read_hfc(cs, HFCSX_FIF_DRD);
 275            }
 276            skb = NULL;
 277          } else 
 278            if ((skb = dev_alloc_skb(count - 3))) {
 279              count -= 3;
 280              dst = skb_put(skb, count);
 281
 282              while (count--) 
 283                *dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
 284                    
 285              Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */
 286              Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */
 287              if (Read_hfc(cs, HFCSX_FIF_DRD)) {
 288                dev_kfree_skb_irq(skb);
 289                if (cs->debug & L1_DEB_ISAC_FIFO)
 290                  debugl1(cs, "hfcsx_read_fifo %d crc error", fifo);
 291                skb = NULL;
 292              }
 293            } else {
 294              printk(KERN_WARNING "HFC-SX: receive out of memory\n");
 295              return(NULL);
 296            }
 297
 298          Read_hfc(cs, HFCSX_FIF_INCF2); /* increment F2 */
 299          udelay(1);
 300          while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
 301          udelay(1);
 302        } while (!skb); /* retry in case of crc error */
 303        return(skb);
 304} 
 305
 306/******************************************/
 307/* free hardware resources used by driver */
 308/******************************************/
 309static void
 310release_io_hfcsx(struct IsdnCardState *cs)
 311{
 312        cs->hw.hfcsx.int_m2 = 0;        /* interrupt output off ! */
 313        Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
 314        Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET); /* Reset On */
 315        msleep(30);                             /* Timeout 30ms */
 316        Write_hfc(cs, HFCSX_CIRM, 0);   /* Reset Off */
 317        del_timer(&cs->hw.hfcsx.timer);
 318        release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */
 319        kfree(cs->hw.hfcsx.extra);
 320        cs->hw.hfcsx.extra = NULL;
 321}
 322
 323/**********************************************************/
 324/* set_fifo_size determines the size of the RAM and FIFOs */
 325/* returning 0 -> need to reset the chip again.           */
 326/**********************************************************/
 327static int set_fifo_size(struct IsdnCardState *cs)
 328{
 329        
 330        if (cs->hw.hfcsx.b_fifo_size) return(1); /* already determined */
 331
 332        if ((cs->hw.hfcsx.chip >> 4) == 9) {
 333          cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_32K;
 334          return(1);
 335        }
 336
 337          cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_8K;
 338          cs->hw.hfcsx.cirm |= 0x10; /* only 8K of ram */
 339          return(0);
 340
 341}
 342
 343/********************************************************************************/
 344/* function called to reset the HFC SX chip. A complete software reset of chip */
 345/* and fifos is done.                                                           */
 346/********************************************************************************/
 347static void
 348reset_hfcsx(struct IsdnCardState *cs)
 349{
 350        cs->hw.hfcsx.int_m2 = 0;        /* interrupt output off ! */
 351        Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
 352
 353        printk(KERN_INFO "HFC_SX: resetting card\n");
 354        while (1) {
 355          Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET | cs->hw.hfcsx.cirm ); /* Reset */
 356          mdelay(30);
 357          Write_hfc(cs, HFCSX_CIRM, cs->hw.hfcsx.cirm); /* Reset Off */
 358          mdelay(20);
 359          if (Read_hfc(cs, HFCSX_STATUS) & 2)
 360            printk(KERN_WARNING "HFC-SX init bit busy\n");
 361          cs->hw.hfcsx.last_fifo = 0xff; /* invalidate */
 362          if (!set_fifo_size(cs)) continue;
 363          break;
 364        }
 365
 366        cs->hw.hfcsx.trm = 0 + HFCSX_BTRANS_THRESMASK;  /* no echo connect , threshold */
 367        Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
 368
 369        Write_hfc(cs, HFCSX_CLKDEL, 0x0e);      /* ST-Bit delay for TE-Mode */
 370        cs->hw.hfcsx.sctrl_e = HFCSX_AUTO_AWAKE;
 371        Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e);     /* S/T Auto awake */
 372        cs->hw.hfcsx.bswapped = 0;      /* no exchange */
 373        cs->hw.hfcsx.nt_mode = 0;       /* we are in TE mode */
 374        cs->hw.hfcsx.ctmt = HFCSX_TIM3_125 | HFCSX_AUTO_TIMER;
 375        Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
 376
 377        cs->hw.hfcsx.int_m1 = HFCSX_INTS_DTRANS | HFCSX_INTS_DREC | 
 378            HFCSX_INTS_L1STATE | HFCSX_INTS_TIMER;
 379        Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
 380
 381        /* Clear already pending ints */
 382        if (Read_hfc(cs, HFCSX_INT_S1));
 383
 384        Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 2);      /* HFC ST 2 */
 385        udelay(10);
 386        Write_hfc(cs, HFCSX_STATES, 2); /* HFC ST 2 */
 387        cs->hw.hfcsx.mst_m = HFCSX_MASTER;      /* HFC Master Mode */
 388
 389        Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
 390        cs->hw.hfcsx.sctrl = 0x40;      /* set tx_lo mode, error in datasheet ! */
 391        Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
 392        cs->hw.hfcsx.sctrl_r = 0;
 393        Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
 394
 395        /* Init GCI/IOM2 in master mode */
 396        /* Slots 0 and 1 are set for B-chan 1 and 2 */
 397        /* D- and monitor/CI channel are not enabled */
 398        /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */
 399        /* STIO2 is used as data input, B1+B2 from IOM->ST */
 400        /* ST B-channel send disabled -> continous 1s */
 401        /* The IOM slots are always enabled */
 402        cs->hw.hfcsx.conn = 0x36;       /* set data flow directions */
 403        Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 404        Write_hfc(cs, HFCSX_B1_SSL, 0x80);      /* B1-Slot 0 STIO1 out enabled */
 405        Write_hfc(cs, HFCSX_B2_SSL, 0x81);      /* B2-Slot 1 STIO1 out enabled */
 406        Write_hfc(cs, HFCSX_B1_RSL, 0x80);      /* B1-Slot 0 STIO2 in enabled */
 407        Write_hfc(cs, HFCSX_B2_RSL, 0x81);      /* B2-Slot 1 STIO2 in enabled */
 408
 409        /* Finally enable IRQ output */
 410        cs->hw.hfcsx.int_m2 = HFCSX_IRQ_ENABLE;
 411        Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
 412        if (Read_hfc(cs, HFCSX_INT_S2));
 413}
 414
 415/***************************************************/
 416/* Timer function called when kernel timer expires */
 417/***************************************************/
 418static void
 419hfcsx_Timer(struct IsdnCardState *cs)
 420{
 421        cs->hw.hfcsx.timer.expires = jiffies + 75;
 422        /* WD RESET */
 423/*      WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcsx.ctmt | 0x80);
 424   add_timer(&cs->hw.hfcsx.timer);
 425 */
 426}
 427
 428/************************************************/
 429/* select a b-channel entry matching and active */
 430/************************************************/
 431static
 432struct BCState *
 433Sel_BCS(struct IsdnCardState *cs, int channel)
 434{
 435        if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
 436                return (&cs->bcs[0]);
 437        else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
 438                return (&cs->bcs[1]);
 439        else
 440                return (NULL);
 441}
 442
 443/*******************************/
 444/* D-channel receive procedure */
 445/*******************************/
 446static
 447int
 448receive_dmsg(struct IsdnCardState *cs)
 449{
 450        struct sk_buff *skb;
 451        int count = 5;
 452
 453        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 454                debugl1(cs, "rec_dmsg blocked");
 455                return (1);
 456        }
 457
 458        do {
 459          skb = read_fifo(cs, HFCSX_SEL_D_RX, 0);
 460          if (skb) {
 461            skb_queue_tail(&cs->rq, skb);
 462            schedule_event(cs, D_RCVBUFREADY);
 463          }
 464        } while (--count && skb);
 465
 466        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 467        return (1);
 468}
 469
 470/**********************************/
 471/* B-channel main receive routine */
 472/**********************************/
 473static void
 474main_rec_hfcsx(struct BCState *bcs)
 475{
 476        struct IsdnCardState *cs = bcs->cs;
 477        int count = 5;
 478        struct sk_buff *skb;
 479
 480      Begin:
 481        count--;
 482        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 483                debugl1(cs, "rec_data %d blocked", bcs->channel);
 484                return;
 485        }
 486        skb = read_fifo(cs, ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? 
 487                        HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX,
 488                        (bcs->mode == L1_MODE_TRANS) ? 
 489                        HFCSX_BTRANS_THRESHOLD : 0);
 490
 491        if (skb) {
 492          skb_queue_tail(&bcs->rqueue, skb);
 493          schedule_event(bcs, B_RCVBUFREADY);
 494        }
 495
 496        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 497        if (count && skb)
 498                goto Begin;
 499        return;
 500}
 501
 502/**************************/
 503/* D-channel send routine */
 504/**************************/
 505static void
 506hfcsx_fill_dfifo(struct IsdnCardState *cs)
 507{
 508        if (!cs->tx_skb)
 509                return;
 510        if (cs->tx_skb->len <= 0)
 511                return;
 512
 513        if (write_fifo(cs, cs->tx_skb, HFCSX_SEL_D_TX, 0)) {
 514          dev_kfree_skb_any(cs->tx_skb);
 515          cs->tx_skb = NULL;
 516        }
 517        return;
 518}
 519
 520/**************************/
 521/* B-channel send routine */
 522/**************************/
 523static void
 524hfcsx_fill_fifo(struct BCState *bcs)
 525{
 526        struct IsdnCardState *cs = bcs->cs;
 527
 528        if (!bcs->tx_skb)
 529                return;
 530        if (bcs->tx_skb->len <= 0)
 531                return;
 532
 533        if (write_fifo(cs, bcs->tx_skb, 
 534                       ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? 
 535                       HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX,
 536                       (bcs->mode == L1_MODE_TRANS) ? 
 537                       HFCSX_BTRANS_THRESHOLD : 0)) {
 538
 539          bcs->tx_cnt -= bcs->tx_skb->len;
 540          if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
 541                (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 542                u_long  flags;
 543                spin_lock_irqsave(&bcs->aclock, flags);
 544                bcs->ackcnt += bcs->tx_skb->len;
 545                spin_unlock_irqrestore(&bcs->aclock, flags);
 546                schedule_event(bcs, B_ACKPENDING);
 547          }
 548          dev_kfree_skb_any(bcs->tx_skb);
 549          bcs->tx_skb = NULL;
 550          test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 551        }
 552}
 553
 554/**********************************************/
 555/* D-channel l1 state call for leased NT-mode */
 556/**********************************************/
 557static void
 558dch_nt_l2l1(struct PStack *st, int pr, void *arg)
 559{
 560        struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 561
 562        switch (pr) {
 563                case (PH_DATA | REQUEST):
 564                case (PH_PULL | REQUEST):
 565                case (PH_PULL | INDICATION):
 566                        st->l1.l1hw(st, pr, arg);
 567                        break;
 568                case (PH_ACTIVATE | REQUEST):
 569                        st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
 570                        break;
 571                case (PH_TESTLOOP | REQUEST):
 572                        if (1 & (long) arg)
 573                                debugl1(cs, "PH_TEST_LOOP B1");
 574                        if (2 & (long) arg)
 575                                debugl1(cs, "PH_TEST_LOOP B2");
 576                        if (!(3 & (long) arg))
 577                                debugl1(cs, "PH_TEST_LOOP DISABLED");
 578                        st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
 579                        break;
 580                default:
 581                        if (cs->debug)
 582                                debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
 583                        break;
 584        }
 585}
 586
 587
 588
 589/***********************/
 590/* set/reset echo mode */
 591/***********************/
 592static int
 593hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
 594{
 595        unsigned long flags;
 596        int i = *(unsigned int *) ic->parm.num;
 597
 598        if ((ic->arg == 98) &&
 599            (!(cs->hw.hfcsx.int_m1 & (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC + HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC)))) {
 600                spin_lock_irqsave(&cs->lock, flags);
 601                Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 0);      /* HFC ST G0 */
 602                udelay(10);
 603                cs->hw.hfcsx.sctrl |= SCTRL_MODE_NT;
 604                Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl); /* set NT-mode */
 605                udelay(10);
 606                Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 1);      /* HFC ST G1 */
 607                udelay(10);
 608                Write_hfc(cs, HFCSX_STATES, 1 | HFCSX_ACTIVATE | HFCSX_DO_ACTION);
 609                cs->dc.hfcsx.ph_state = 1;
 610                cs->hw.hfcsx.nt_mode = 1;
 611                cs->hw.hfcsx.nt_timer = 0;
 612                spin_unlock_irqrestore(&cs->lock, flags);
 613                cs->stlist->l2.l2l1 = dch_nt_l2l1;
 614                debugl1(cs, "NT mode activated");
 615                return (0);
 616        }
 617        if ((cs->chanlimit > 1) || (cs->hw.hfcsx.bswapped) ||
 618            (cs->hw.hfcsx.nt_mode) || (ic->arg != 12))
 619                return (-EINVAL);
 620
 621        if (i) {
 622                cs->logecho = 1;
 623                cs->hw.hfcsx.trm |= 0x20;       /* enable echo chan */
 624                cs->hw.hfcsx.int_m1 |= HFCSX_INTS_B2REC;
 625                /* reset Channel !!!!! */
 626        } else {
 627                cs->logecho = 0;
 628                cs->hw.hfcsx.trm &= ~0x20;      /* disable echo chan */
 629                cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_B2REC;
 630        }
 631        cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
 632        cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
 633        cs->hw.hfcsx.conn |= 0x10;      /* B2-IOM -> B2-ST */
 634        cs->hw.hfcsx.ctmt &= ~2;
 635        spin_lock_irqsave(&cs->lock, flags);
 636        Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
 637        Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
 638        Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
 639        Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 640        Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
 641        Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
 642        spin_unlock_irqrestore(&cs->lock, flags);
 643        return (0);
 644}                               /* hfcsx_auxcmd */
 645
 646/*****************************/
 647/* E-channel receive routine */
 648/*****************************/
 649static void
 650receive_emsg(struct IsdnCardState *cs)
 651{
 652        int count = 5;
 653        u_char *ptr;
 654        struct sk_buff *skb;
 655
 656        if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 657                debugl1(cs, "echo_rec_data blocked");
 658                return;
 659        }
 660        do {
 661          skb = read_fifo(cs, HFCSX_SEL_B2_RX, 0);
 662          if (skb) {
 663            if (cs->debug & DEB_DLOG_HEX) {
 664              ptr = cs->dlog;
 665              if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
 666                *ptr++ = 'E';
 667                *ptr++ = 'C';
 668                *ptr++ = 'H';
 669                *ptr++ = 'O';
 670                *ptr++ = ':';
 671                ptr += QuickHex(ptr, skb->data, skb->len);
 672                ptr--;
 673                *ptr++ = '\n';
 674                *ptr = 0;
 675                HiSax_putstatus(cs, NULL, cs->dlog);
 676              } else
 677                HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
 678            }
 679            dev_kfree_skb_any(skb);
 680          }
 681        } while (--count && skb);
 682
 683        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 684        return;
 685}                               /* receive_emsg */
 686
 687
 688/*********************/
 689/* Interrupt handler */
 690/*********************/
 691static irqreturn_t
 692hfcsx_interrupt(int intno, void *dev_id)
 693{
 694        struct IsdnCardState *cs = dev_id;
 695        u_char exval;
 696        struct BCState *bcs;
 697        int count = 15;
 698        u_long flags;
 699        u_char val, stat;
 700
 701        if (!(cs->hw.hfcsx.int_m2 & 0x08))
 702                return IRQ_NONE;                /* not initialised */
 703
 704        spin_lock_irqsave(&cs->lock, flags);
 705        if (HFCSX_ANYINT & (stat = Read_hfc(cs, HFCSX_STATUS))) {
 706                val = Read_hfc(cs, HFCSX_INT_S1);
 707                if (cs->debug & L1_DEB_ISAC)
 708                        debugl1(cs, "HFC-SX: stat(%02x) s1(%02x)", stat, val);
 709        } else {
 710                spin_unlock_irqrestore(&cs->lock, flags);
 711                return IRQ_NONE;
 712        }
 713        if (cs->debug & L1_DEB_ISAC)
 714                debugl1(cs, "HFC-SX irq %x %s", val,
 715                        test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ?
 716                        "locked" : "unlocked");
 717        val &= cs->hw.hfcsx.int_m1;
 718        if (val & 0x40) {       /* state machine irq */
 719                exval = Read_hfc(cs, HFCSX_STATES) & 0xf;
 720                if (cs->debug & L1_DEB_ISAC)
 721                        debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcsx.ph_state,
 722                                exval);
 723                cs->dc.hfcsx.ph_state = exval;
 724                schedule_event(cs, D_L1STATECHANGE);
 725                val &= ~0x40;
 726        }
 727        if (val & 0x80) {       /* timer irq */
 728                if (cs->hw.hfcsx.nt_mode) {
 729                        if ((--cs->hw.hfcsx.nt_timer) < 0)
 730                                schedule_event(cs, D_L1STATECHANGE);
 731                }
 732                val &= ~0x80;
 733                Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
 734        }
 735        while (val) {
 736                if (test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 737                        cs->hw.hfcsx.int_s1 |= val;
 738                        spin_unlock_irqrestore(&cs->lock, flags);
 739                        return IRQ_HANDLED;
 740                }
 741                if (cs->hw.hfcsx.int_s1 & 0x18) {
 742                        exval = val;
 743                        val = cs->hw.hfcsx.int_s1;
 744                        cs->hw.hfcsx.int_s1 = exval;
 745                }
 746                if (val & 0x08) {
 747                        if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) {
 748                                if (cs->debug)
 749                                        debugl1(cs, "hfcsx spurious 0x08 IRQ");
 750                        } else
 751                                main_rec_hfcsx(bcs);
 752                }
 753                if (val & 0x10) {
 754                        if (cs->logecho)
 755                                receive_emsg(cs);
 756                        else if (!(bcs = Sel_BCS(cs, 1))) {
 757                                if (cs->debug)
 758                                        debugl1(cs, "hfcsx spurious 0x10 IRQ");
 759                        } else
 760                                main_rec_hfcsx(bcs);
 761                }
 762                if (val & 0x01) {
 763                        if (!(bcs = Sel_BCS(cs, cs->hw.hfcsx.bswapped ? 1 : 0))) {
 764                                if (cs->debug)
 765                                        debugl1(cs, "hfcsx spurious 0x01 IRQ");
 766                        } else {
 767                                if (bcs->tx_skb) {
 768                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 769                                                hfcsx_fill_fifo(bcs);
 770                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 771                                        } else
 772                                                debugl1(cs, "fill_data %d blocked", bcs->channel);
 773                                } else {
 774                                        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 775                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 776                                                        hfcsx_fill_fifo(bcs);
 777                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 778                                                } else
 779                                                        debugl1(cs, "fill_data %d blocked", bcs->channel);
 780                                        } else {
 781                                                schedule_event(bcs, B_XMTBUFREADY);
 782                                        }
 783                                }
 784                        }
 785                }
 786                if (val & 0x02) {
 787                        if (!(bcs = Sel_BCS(cs, 1))) {
 788                                if (cs->debug)
 789                                        debugl1(cs, "hfcsx spurious 0x02 IRQ");
 790                        } else {
 791                                if (bcs->tx_skb) {
 792                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 793                                                hfcsx_fill_fifo(bcs);
 794                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 795                                        } else
 796                                                debugl1(cs, "fill_data %d blocked", bcs->channel);
 797                                } else {
 798                                        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 799                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 800                                                        hfcsx_fill_fifo(bcs);
 801                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 802                                                } else
 803                                                        debugl1(cs, "fill_data %d blocked", bcs->channel);
 804                                        } else {
 805                                                schedule_event(bcs, B_XMTBUFREADY);
 806                                        }
 807                                }
 808                        }
 809                }
 810                if (val & 0x20) {       /* receive dframe */
 811                        receive_dmsg(cs);
 812                }
 813                if (val & 0x04) {       /* dframe transmitted */
 814                        if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
 815                                del_timer(&cs->dbusytimer);
 816                        if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
 817                                schedule_event(cs, D_CLEARBUSY);
 818                        if (cs->tx_skb) {
 819                                if (cs->tx_skb->len) {
 820                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 821                                                hfcsx_fill_dfifo(cs);
 822                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 823                                        } else {
 824                                                debugl1(cs, "hfcsx_fill_dfifo irq blocked");
 825                                        }
 826                                        goto afterXPR;
 827                                } else {
 828                                        dev_kfree_skb_irq(cs->tx_skb);
 829                                        cs->tx_cnt = 0;
 830                                        cs->tx_skb = NULL;
 831                                }
 832                        }
 833                        if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
 834                                cs->tx_cnt = 0;
 835                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 836                                        hfcsx_fill_dfifo(cs);
 837                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 838                                } else {
 839                                        debugl1(cs, "hfcsx_fill_dfifo irq blocked");
 840                                }
 841                        } else
 842                                schedule_event(cs, D_XMTBUFREADY);
 843                }
 844              afterXPR:
 845                if (cs->hw.hfcsx.int_s1 && count--) {
 846                        val = cs->hw.hfcsx.int_s1;
 847                        cs->hw.hfcsx.int_s1 = 0;
 848                        if (cs->debug & L1_DEB_ISAC)
 849                                debugl1(cs, "HFC-SX irq %x loop %d", val, 15 - count);
 850                } else
 851                        val = 0;
 852        }
 853        spin_unlock_irqrestore(&cs->lock, flags);
 854        return IRQ_HANDLED;
 855}
 856
 857/********************************************************************/
 858/* timer callback for D-chan busy resolution. Currently no function */
 859/********************************************************************/
 860static void
 861hfcsx_dbusy_timer(struct IsdnCardState *cs)
 862{
 863}
 864
 865/*************************************/
 866/* Layer 1 D-channel hardware access */
 867/*************************************/
 868static void
 869HFCSX_l1hw(struct PStack *st, int pr, void *arg)
 870{
 871        struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 872        struct sk_buff *skb = arg;
 873        u_long flags;
 874
 875        switch (pr) {
 876                case (PH_DATA | REQUEST):
 877                        if (cs->debug & DEB_DLOG_HEX)
 878                                LogFrame(cs, skb->data, skb->len);
 879                        if (cs->debug & DEB_DLOG_VERBOSE)
 880                                dlogframe(cs, skb, 0);
 881                        spin_lock_irqsave(&cs->lock, flags);
 882                        if (cs->tx_skb) {
 883                                skb_queue_tail(&cs->sq, skb);
 884#ifdef L2FRAME_DEBUG            /* psa */
 885                                if (cs->debug & L1_DEB_LAPD)
 886                                        Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 887#endif
 888                        } else {
 889                                cs->tx_skb = skb;
 890                                cs->tx_cnt = 0;
 891#ifdef L2FRAME_DEBUG            /* psa */
 892                                if (cs->debug & L1_DEB_LAPD)
 893                                        Logl2Frame(cs, skb, "PH_DATA", 0);
 894#endif
 895                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 896                                        hfcsx_fill_dfifo(cs); 
 897                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 898                                } else
 899                                        debugl1(cs, "hfcsx_fill_dfifo blocked");
 900
 901                        }
 902                        spin_unlock_irqrestore(&cs->lock, flags);
 903                        break;
 904                case (PH_PULL | INDICATION):
 905                        spin_lock_irqsave(&cs->lock, flags);
 906                        if (cs->tx_skb) {
 907                                if (cs->debug & L1_DEB_WARN)
 908                                        debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
 909                                skb_queue_tail(&cs->sq, skb);
 910                                spin_unlock_irqrestore(&cs->lock, flags);
 911                                break;
 912                        }
 913                        if (cs->debug & DEB_DLOG_HEX)
 914                                LogFrame(cs, skb->data, skb->len);
 915                        if (cs->debug & DEB_DLOG_VERBOSE)
 916                                dlogframe(cs, skb, 0);
 917                        cs->tx_skb = skb;
 918                        cs->tx_cnt = 0;
 919#ifdef L2FRAME_DEBUG            /* psa */
 920                        if (cs->debug & L1_DEB_LAPD)
 921                                Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 922#endif
 923                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 924                                hfcsx_fill_dfifo(cs); 
 925                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 926                        } else
 927                                debugl1(cs, "hfcsx_fill_dfifo blocked");
 928                        spin_unlock_irqrestore(&cs->lock, flags);
 929                        break;
 930                case (PH_PULL | REQUEST):
 931#ifdef L2FRAME_DEBUG            /* psa */
 932                        if (cs->debug & L1_DEB_LAPD)
 933                                debugl1(cs, "-> PH_REQUEST_PULL");
 934#endif
 935                        if (!cs->tx_skb) {
 936                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 937                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 938                        } else
 939                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 940                        break;
 941                case (HW_RESET | REQUEST):
 942                        spin_lock_irqsave(&cs->lock, flags);
 943                        Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 3);      /* HFC ST 3 */
 944                        udelay(6);
 945                        Write_hfc(cs, HFCSX_STATES, 3); /* HFC ST 2 */
 946                        cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
 947                        Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
 948                        Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
 949                        spin_unlock_irqrestore(&cs->lock, flags);
 950                        l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
 951                        break;
 952                case (HW_ENABLE | REQUEST):
 953                        spin_lock_irqsave(&cs->lock, flags);
 954                        Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
 955                        spin_unlock_irqrestore(&cs->lock, flags);
 956                        break;
 957                case (HW_DEACTIVATE | REQUEST):
 958                        spin_lock_irqsave(&cs->lock, flags);
 959                        cs->hw.hfcsx.mst_m &= ~HFCSX_MASTER;
 960                        Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
 961                        spin_unlock_irqrestore(&cs->lock, flags);
 962                        break;
 963                case (HW_INFO3 | REQUEST):
 964                        spin_lock_irqsave(&cs->lock, flags);
 965                        cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
 966                        Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
 967                        spin_unlock_irqrestore(&cs->lock, flags);
 968                        break;
 969                case (HW_TESTLOOP | REQUEST):
 970                        spin_lock_irqsave(&cs->lock, flags);
 971                        switch ((long) arg) {
 972                                case (1):
 973                                        Write_hfc(cs, HFCSX_B1_SSL, 0x80);      /* tx slot */
 974                                        Write_hfc(cs, HFCSX_B1_RSL, 0x80);      /* rx slot */
 975                                        cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~7) | 1;
 976                                        Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 977                                        break;
 978                                case (2):
 979                                        Write_hfc(cs, HFCSX_B2_SSL, 0x81);      /* tx slot */
 980                                        Write_hfc(cs, HFCSX_B2_RSL, 0x81);      /* rx slot */
 981                                        cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~0x38) | 0x08;
 982                                        Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 983                                        break;
 984                                default:
 985                                        spin_unlock_irqrestore(&cs->lock, flags);
 986                                        if (cs->debug & L1_DEB_WARN)
 987                                                debugl1(cs, "hfcsx_l1hw loop invalid %4lx", arg);
 988                                        return;
 989                        }
 990                        cs->hw.hfcsx.trm |= 0x80;       /* enable IOM-loop */
 991                        Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
 992                        spin_unlock_irqrestore(&cs->lock, flags);
 993                        break;
 994                default:
 995                        if (cs->debug & L1_DEB_WARN)
 996                                debugl1(cs, "hfcsx_l1hw unknown pr %4x", pr);
 997                        break;
 998        }
 999}
1000
1001/***********************************************/
1002/* called during init setting l1 stack pointer */
1003/***********************************************/
1004static void
1005setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
1006{
1007        st->l1.l1hw = HFCSX_l1hw;
1008}
1009
1010/**************************************/
1011/* send B-channel data if not blocked */
1012/**************************************/
1013static void
1014hfcsx_send_data(struct BCState *bcs)
1015{
1016        struct IsdnCardState *cs = bcs->cs;
1017
1018        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
1019          hfcsx_fill_fifo(bcs);
1020                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
1021        } else
1022                debugl1(cs, "send_data %d blocked", bcs->channel);
1023}
1024
1025/***************************************************************/
1026/* activate/deactivate hardware for selected channels and mode */
1027/***************************************************************/
1028static void
1029mode_hfcsx(struct BCState *bcs, int mode, int bc)
1030{
1031        struct IsdnCardState *cs = bcs->cs;
1032        int fifo2;
1033
1034        if (cs->debug & L1_DEB_HSCX)
1035                debugl1(cs, "HFCSX bchannel mode %d bchan %d/%d",
1036                        mode, bc, bcs->channel);
1037        bcs->mode = mode;
1038        bcs->channel = bc;
1039        fifo2 = bc;
1040        if (cs->chanlimit > 1) {
1041                cs->hw.hfcsx.bswapped = 0;      /* B1 and B2 normal mode */
1042                cs->hw.hfcsx.sctrl_e &= ~0x80;
1043        } else {
1044                if (bc) {
1045                        if (mode != L1_MODE_NULL) {
1046                                cs->hw.hfcsx.bswapped = 1;      /* B1 and B2 exchanged */
1047                                cs->hw.hfcsx.sctrl_e |= 0x80;
1048                        } else {
1049                                cs->hw.hfcsx.bswapped = 0;      /* B1 and B2 normal mode */
1050                                cs->hw.hfcsx.sctrl_e &= ~0x80;
1051                        }
1052                        fifo2 = 0;
1053                } else {
1054                        cs->hw.hfcsx.bswapped = 0;      /* B1 and B2 normal mode */
1055                        cs->hw.hfcsx.sctrl_e &= ~0x80;
1056                }
1057        }
1058        switch (mode) {
1059                case (L1_MODE_NULL):
1060                        if (bc) {
1061                                cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
1062                                cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
1063                        } else {
1064                                cs->hw.hfcsx.sctrl &= ~SCTRL_B1_ENA;
1065                                cs->hw.hfcsx.sctrl_r &= ~SCTRL_B1_ENA;
1066                        }
1067                        if (fifo2) {
1068                                cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1069                        } else {
1070                                cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1071                        }
1072                        break;
1073                case (L1_MODE_TRANS):
1074                        if (bc) {
1075                                cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1076                                cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1077                        } else {
1078                                cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1079                                cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1080                        }
1081                        if (fifo2) {
1082                                cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1083                                cs->hw.hfcsx.ctmt |= 2;
1084                                cs->hw.hfcsx.conn &= ~0x18;
1085                        } else {
1086                                cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1087                                cs->hw.hfcsx.ctmt |= 1;
1088                                cs->hw.hfcsx.conn &= ~0x03;
1089                        }
1090                        break;
1091                case (L1_MODE_HDLC):
1092                        if (bc) {
1093                                cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1094                                cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1095                        } else {
1096                                cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1097                                cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1098                        }
1099                        if (fifo2) {
1100                                cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1101                                cs->hw.hfcsx.ctmt &= ~2;
1102                                cs->hw.hfcsx.conn &= ~0x18;
1103                        } else {
1104                                cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1105                                cs->hw.hfcsx.ctmt &= ~1;
1106                                cs->hw.hfcsx.conn &= ~0x03;
1107                        }
1108                        break;
1109                case (L1_MODE_EXTRN):
1110                        if (bc) {
1111                                cs->hw.hfcsx.conn |= 0x10;
1112                                cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
1113                                cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
1114                                cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
1115                        } else {
1116                                cs->hw.hfcsx.conn |= 0x02;
1117                                cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
1118                                cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
1119                                cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
1120                        }
1121                        break;
1122        }
1123        Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e);
1124        Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1125        Write_hfc(cs, HFCSX_SCTRL, cs->hw.hfcsx.sctrl);
1126        Write_hfc(cs, HFCSX_SCTRL_R, cs->hw.hfcsx.sctrl_r);
1127        Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
1128        Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
1129        if (mode != L1_MODE_EXTRN) {
1130          reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX);
1131          reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX);
1132        }
1133}
1134
1135/******************************/
1136/* Layer2 -> Layer 1 Transfer */
1137/******************************/
1138static void
1139hfcsx_l2l1(struct PStack *st, int pr, void *arg)
1140{
1141        struct BCState *bcs = st->l1.bcs;
1142        struct sk_buff *skb = arg;
1143        u_long flags;
1144
1145        switch (pr) {
1146                case (PH_DATA | REQUEST):
1147                        spin_lock_irqsave(&bcs->cs->lock, flags);
1148                        if (bcs->tx_skb) {
1149                                skb_queue_tail(&bcs->squeue, skb);
1150                        } else {
1151                                bcs->tx_skb = skb;
1152//                              test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
1153                                bcs->cs->BC_Send_Data(bcs);
1154                        }
1155                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
1156                        break;
1157                case (PH_PULL | INDICATION):
1158                        spin_lock_irqsave(&bcs->cs->lock, flags);
1159                        if (bcs->tx_skb) {
1160                                printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
1161                        } else {
1162//                              test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
1163                                bcs->tx_skb = skb;
1164                                bcs->cs->BC_Send_Data(bcs);
1165                        }
1166                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
1167                        break;
1168                case (PH_PULL | REQUEST):
1169                        if (!bcs->tx_skb) {
1170                                test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1171                                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
1172                        } else
1173                                test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
1174                        break;
1175                case (PH_ACTIVATE | REQUEST):
1176                        spin_lock_irqsave(&bcs->cs->lock, flags);
1177                        test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
1178                        mode_hfcsx(bcs, st->l1.mode, st->l1.bc);
1179                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
1180                        l1_msg_b(st, pr, arg);
1181                        break;
1182                case (PH_DEACTIVATE | REQUEST):
1183                        l1_msg_b(st, pr, arg);
1184                        break;
1185                case (PH_DEACTIVATE | CONFIRM):
1186                        spin_lock_irqsave(&bcs->cs->lock, flags);
1187                        test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
1188                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1189                        mode_hfcsx(bcs, 0, st->l1.bc);
1190                        spin_unlock_irqrestore(&bcs->cs->lock, flags);
1191                        st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
1192                        break;
1193        }
1194}
1195
1196/******************************************/
1197/* deactivate B-channel access and queues */
1198/******************************************/
1199static void
1200close_hfcsx(struct BCState *bcs)
1201{
1202        mode_hfcsx(bcs, 0, bcs->channel);
1203        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
1204                skb_queue_purge(&bcs->rqueue);
1205                skb_queue_purge(&bcs->squeue);
1206                if (bcs->tx_skb) {
1207                        dev_kfree_skb_any(bcs->tx_skb);
1208                        bcs->tx_skb = NULL;
1209                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1210                }
1211        }
1212}
1213
1214/*************************************/
1215/* init B-channel queues and control */
1216/*************************************/
1217static int
1218open_hfcsxstate(struct IsdnCardState *cs, struct BCState *bcs)
1219{
1220        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
1221                skb_queue_head_init(&bcs->rqueue);
1222                skb_queue_head_init(&bcs->squeue);
1223        }
1224        bcs->tx_skb = NULL;
1225        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
1226        bcs->event = 0;
1227        bcs->tx_cnt = 0;
1228        return (0);
1229}
1230
1231/*********************************/
1232/* inits the stack for B-channel */
1233/*********************************/
1234static int
1235setstack_2b(struct PStack *st, struct BCState *bcs)
1236{
1237        bcs->channel = st->l1.bc;
1238        if (open_hfcsxstate(st->l1.hardware, bcs))
1239                return (-1);
1240        st->l1.bcs = bcs;
1241        st->l2.l2l1 = hfcsx_l2l1;
1242        setstack_manager(st);
1243        bcs->st = st;
1244        setstack_l1_B(st);
1245        return (0);
1246}
1247
1248/***************************/
1249/* handle L1 state changes */
1250/***************************/
1251static void
1252hfcsx_bh(struct work_struct *work)
1253{
1254        struct IsdnCardState *cs =
1255                container_of(work, struct IsdnCardState, tqueue);
1256        u_long flags;
1257
1258        if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
1259                if (!cs->hw.hfcsx.nt_mode)
1260                        switch (cs->dc.hfcsx.ph_state) {
1261                                case (0):
1262                                        l1_msg(cs, HW_RESET | INDICATION, NULL);
1263                                        break;
1264                                case (3):
1265                                        l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
1266                                        break;
1267                                case (8):
1268                                        l1_msg(cs, HW_RSYNC | INDICATION, NULL);
1269                                        break;
1270                                case (6):
1271                                        l1_msg(cs, HW_INFO2 | INDICATION, NULL);
1272                                        break;
1273                                case (7):
1274                                        l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
1275                                        break;
1276                                default:
1277                                        break;
1278                } else {
1279                        switch (cs->dc.hfcsx.ph_state) {
1280                                case (2):
1281                                        spin_lock_irqsave(&cs->lock, flags);
1282                                        if (cs->hw.hfcsx.nt_timer < 0) {
1283                                                cs->hw.hfcsx.nt_timer = 0;
1284                                                cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1285                                                Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1286                                                /* Clear already pending ints */
1287                                                if (Read_hfc(cs, HFCSX_INT_S1));
1288
1289                                                Write_hfc(cs, HFCSX_STATES, 4 | HFCSX_LOAD_STATE);
1290                                                udelay(10);
1291                                                Write_hfc(cs, HFCSX_STATES, 4);
1292                                                cs->dc.hfcsx.ph_state = 4;
1293                                        } else {
1294                                                cs->hw.hfcsx.int_m1 |= HFCSX_INTS_TIMER;
1295                                                Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1296                                                cs->hw.hfcsx.ctmt &= ~HFCSX_AUTO_TIMER;
1297                                                cs->hw.hfcsx.ctmt |= HFCSX_TIM3_125;
1298                                                Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
1299                                                Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
1300                                                cs->hw.hfcsx.nt_timer = NT_T1_COUNT;
1301                                                Write_hfc(cs, HFCSX_STATES, 2 | HFCSX_NT_G2_G3);        /* allow G2 -> G3 transition */
1302                                        }
1303                                        spin_unlock_irqrestore(&cs->lock, flags);
1304                                        break;
1305                                case (1):
1306                                case (3):
1307                                case (4):
1308                                        spin_lock_irqsave(&cs->lock, flags);
1309                                        cs->hw.hfcsx.nt_timer = 0;
1310                                        cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1311                                        Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1312                                        spin_unlock_irqrestore(&cs->lock, flags);
1313                                        break;
1314                                default:
1315                                        break;
1316                        }
1317                }
1318        }
1319        if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
1320                DChannel_proc_rcv(cs);
1321        if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
1322                DChannel_proc_xmt(cs);
1323}
1324
1325
1326/********************************/
1327/* called for card init message */
1328/********************************/
1329static void inithfcsx(struct IsdnCardState *cs)
1330{
1331        cs->setstack_d = setstack_hfcsx;
1332        cs->BC_Send_Data = &hfcsx_send_data;
1333        cs->bcs[0].BC_SetStack = setstack_2b;
1334        cs->bcs[1].BC_SetStack = setstack_2b;
1335        cs->bcs[0].BC_Close = close_hfcsx;
1336        cs->bcs[1].BC_Close = close_hfcsx;
1337        mode_hfcsx(cs->bcs, 0, 0);
1338        mode_hfcsx(cs->bcs + 1, 0, 1);
1339}
1340
1341
1342
1343/*******************************************/
1344/* handle card messages from control layer */
1345/*******************************************/
1346static int
1347hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
1348{
1349        u_long flags;
1350
1351        if (cs->debug & L1_DEB_ISAC)
1352                debugl1(cs, "HFCSX: card_msg %x", mt);
1353        switch (mt) {
1354                case CARD_RESET:
1355                        spin_lock_irqsave(&cs->lock, flags);
1356                        reset_hfcsx(cs);
1357                        spin_unlock_irqrestore(&cs->lock, flags);
1358                        return (0);
1359                case CARD_RELEASE:
1360                        release_io_hfcsx(cs);
1361                        return (0);
1362                case CARD_INIT:
1363                        spin_lock_irqsave(&cs->lock, flags);
1364                        inithfcsx(cs);
1365                        spin_unlock_irqrestore(&cs->lock, flags);
1366                        msleep(80);                             /* Timeout 80ms */
1367                        /* now switch timer interrupt off */
1368                        spin_lock_irqsave(&cs->lock, flags);
1369                        cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
1370                        Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1371                        /* reinit mode reg */
1372                        Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
1373                        spin_unlock_irqrestore(&cs->lock, flags);
1374                        return (0);
1375                case CARD_TEST:
1376                        return (0);
1377        }
1378        return (0);
1379}
1380
1381#ifdef __ISAPNP__
1382static struct isapnp_device_id hfc_ids[] __devinitdata = {
1383        { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
1384          ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), 
1385          (unsigned long) "Teles 16.3c2" },
1386        { 0, }
1387};
1388
1389static struct isapnp_device_id *ipid __devinitdata = &hfc_ids[0];
1390static struct pnp_card *pnp_c __devinitdata = NULL;
1391#endif
1392
1393int __devinit
1394setup_hfcsx(struct IsdnCard *card)
1395{
1396        struct IsdnCardState *cs = card->cs;
1397        char tmp[64];
1398
1399        strcpy(tmp, hfcsx_revision);
1400        printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp));
1401#ifdef __ISAPNP__
1402        if (!card->para[1] && isapnp_present()) {
1403                struct pnp_dev *pnp_d;
1404                while(ipid->card_vendor) {
1405                        if ((pnp_c = pnp_find_card(ipid->card_vendor,
1406                                ipid->card_device, pnp_c))) {
1407                                pnp_d = NULL;
1408                                if ((pnp_d = pnp_find_dev(pnp_c,
1409                                        ipid->vendor, ipid->function, pnp_d))) {
1410                                        int err;
1411
1412                                        printk(KERN_INFO "HiSax: %s detected\n",
1413                                                (char *)ipid->driver_data);
1414                                        pnp_disable_dev(pnp_d);
1415                                        err = pnp_activate_dev(pnp_d);
1416                                        if (err<0) {
1417                                                printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
1418                                                        __func__, err);
1419                                                return(0);
1420                                        }
1421                                        card->para[1] = pnp_port_start(pnp_d, 0);
1422                                        card->para[0] = pnp_irq(pnp_d, 0);
1423                                        if (!card->para[0] || !card->para[1]) {
1424                                                printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n",
1425                                                        card->para[0], card->para[1]);
1426                                                pnp_disable_dev(pnp_d);
1427                                                return(0);
1428                                        }
1429                                        break;
1430                                } else {
1431                                        printk(KERN_ERR "HFC PnP: PnP error card found, no device\n");
1432                                }
1433                        }
1434                        ipid++;
1435                        pnp_c = NULL;
1436                } 
1437                if (!ipid->card_vendor) {
1438                        printk(KERN_INFO "HFC PnP: no ISAPnP card found\n");
1439                        return(0);
1440                }
1441        }
1442#endif
1443        cs->hw.hfcsx.base = card->para[1] & 0xfffe;
1444        cs->irq = card->para[0];
1445        cs->hw.hfcsx.int_s1 = 0;
1446        cs->dc.hfcsx.ph_state = 0;
1447        cs->hw.hfcsx.fifo = 255;
1448        if ((cs->typ == ISDN_CTYPE_HFC_SX) || 
1449            (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) {
1450                if ((!cs->hw.hfcsx.base) || !request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn")) {
1451                  printk(KERN_WARNING
1452                         "HiSax: HFC-SX io-base %#lx already in use\n",
1453                          cs->hw.hfcsx.base);
1454                  return(0);
1455                }
1456                byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
1457                byteout(cs->hw.hfcsx.base + 1,
1458                        ((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
1459                udelay(10);
1460                cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
1461                switch (cs->hw.hfcsx.chip >> 4) {
1462                  case 1: 
1463                    tmp[0] ='+';
1464                    break;
1465                  case 9: 
1466                    tmp[0] ='P';
1467                    break;
1468                  default:
1469                    printk(KERN_WARNING
1470                           "HFC-SX: invalid chip id 0x%x\n",
1471                           cs->hw.hfcsx.chip >> 4);
1472                    release_region(cs->hw.hfcsx.base, 2);
1473                    return(0);
1474                }  
1475                if (!ccd_sp_irqtab[cs->irq & 0xF]) {
1476                  printk(KERN_WARNING 
1477                         "HFC_SX: invalid irq %d specified\n",cs->irq & 0xF);
1478                  release_region(cs->hw.hfcsx.base, 2);
1479                  return(0);
1480                }  
1481                if (!(cs->hw.hfcsx.extra = (void *)
1482                      kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) {
1483                  release_region(cs->hw.hfcsx.base, 2);
1484                  printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
1485                  return(0);
1486                }
1487                printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n",
1488                        tmp[0], (u_int) cs->hw.hfcsx.base, cs->irq, HZ);
1489                cs->hw.hfcsx.int_m2 = 0;        /* disable alle interrupts */
1490                cs->hw.hfcsx.int_m1 = 0;
1491                Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
1492                Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2);
1493        } else
1494                return (0);     /* no valid card type */
1495
1496        cs->dbusytimer.function = (void *) hfcsx_dbusy_timer;
1497        cs->dbusytimer.data = (long) cs;
1498        init_timer(&cs->dbusytimer);
1499        INIT_WORK(&cs->tqueue, hfcsx_bh);
1500        cs->readisac = NULL;
1501        cs->writeisac = NULL;
1502        cs->readisacfifo = NULL;
1503        cs->writeisacfifo = NULL;
1504        cs->BC_Read_Reg = NULL;
1505        cs->BC_Write_Reg = NULL;
1506        cs->irq_func = &hfcsx_interrupt;
1507
1508        cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer;
1509        cs->hw.hfcsx.timer.data = (long) cs;
1510        cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */
1511        cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */
1512        init_timer(&cs->hw.hfcsx.timer);
1513
1514        reset_hfcsx(cs);
1515        cs->cardmsg = &hfcsx_card_msg;
1516        cs->auxcmd = &hfcsx_auxcmd;
1517        return (1);
1518}
1519