The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/hscx.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  *---------------------------------------------------------------------------
   26  *
   27  *      i4b - Siemens HSCX chip (B-channel) handling
   28  *      --------------------------------------------
   29  *
   30  *      $Id: hscx.c,v 1.12 2005/12/11 12:21:26 christos Exp $
   31  *
   32  *      last edit-date: [Fri Jan  5 11:36:10 2001]
   33  *
   34  *---------------------------------------------------------------------------*/
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: hscx.c,v 1.12 2005/12/11 12:21:26 christos Exp $");
   38 
   39 #include <sys/param.h>
   40 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
   41 #include <sys/ioccom.h>
   42 #else
   43 #include <sys/ioctl.h>
   44 #endif
   45 #include <sys/kernel.h>
   46 #include <sys/systm.h>
   47 #include <sys/mbuf.h>
   48 #include <machine/stdarg.h>
   49 
   50 #ifdef __FreeBSD__
   51 #include <machine/clock.h>
   52 #include <i386/isa/isa_device.h>
   53 #else
   54 #ifndef __bsdi__
   55 #include <machine/bus.h>
   56 #endif
   57 #include <sys/device.h>
   58 #endif
   59 
   60 #include <sys/socket.h>
   61 #include <net/if.h>
   62 
   63 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   64 #include <sys/callout.h>
   65 #endif
   66 
   67 #ifdef __FreeBSD__
   68 #include <machine/i4b_debug.h>
   69 #include <machine/i4b_ioctl.h>
   70 #include <machine/i4b_trace.h>
   71 #else
   72 #include <netisdn/i4b_debug.h>
   73 #include <netisdn/i4b_ioctl.h>
   74 #include <netisdn/i4b_trace.h>
   75 #endif
   76 
   77 #include <netisdn/i4b_l2.h>
   78 #include <netisdn/i4b_l1l2.h>
   79 #include <netisdn/i4b_global.h>
   80 #include <netisdn/i4b_mbuf.h>
   81 
   82 #include <dev/ic/isic_l1.h>
   83 #include <dev/ic/isac.h>
   84 #include <dev/ic/hscx.h>
   85 
   86 /*---------------------------------------------------------------------------*
   87  *      HSCX IRQ Handler
   88  *---------------------------------------------------------------------------*/
   89 void
   90 isic_hscx_irq(register struct isic_softc *sc, u_char ista, int h_chan, u_char ex_irq)
   91 {
   92         register l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
   93         u_char exir = 0;
   94         int activity = -1;
   95         u_char cmd = 0;
   96 
   97         NDBGL1(L1_H_IRQ, "%#x", ista);
   98 
   99         if(ex_irq)
  100         {
  101                 /* get channel extended irq reg */
  102 
  103                 exir = HSCX_READ(h_chan, H_EXIR);
  104 
  105                 if(exir & HSCX_EXIR_RFO)
  106                 {
  107                         chan->stat_RFO++;
  108                         NDBGL1(L1_H_XFRERR, "ex_irq: receive data overflow");
  109                 }
  110 
  111                 if((exir & HSCX_EXIR_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */
  112                 {
  113                         chan->stat_XDU++;
  114                         NDBGL1(L1_H_XFRERR, "ex_irq: xmit data underrun");
  115                         isic_hscx_cmd(sc, h_chan, HSCX_CMDR_XRES);
  116 
  117                         if (chan->out_mbuf_head != NULL)  /* don't continue to transmit this buffer */
  118                         {
  119                                 i4b_Bfreembuf(chan->out_mbuf_head);
  120                                 chan->out_mbuf_cur = chan->out_mbuf_head = NULL;
  121                         }
  122                 }
  123 
  124         }
  125 
  126         /* rx message end, end of frame */
  127 
  128         if(ista & HSCX_ISTA_RME)
  129         {
  130                 register int fifo_data_len;
  131                 u_char rsta;
  132                 int error = 0;
  133 
  134                 rsta = HSCX_READ(h_chan, H_RSTA);
  135 
  136                 if((rsta & 0xf0) != 0xa0)
  137                 {
  138                         if((rsta & HSCX_RSTA_VFR) == 0)
  139                         {
  140                                 chan->stat_VFR++;
  141                                 cmd |= (HSCX_CMDR_RHR);
  142                                 NDBGL1(L1_H_XFRERR, "received invalid Frame");
  143                                 error++;
  144                         }
  145 
  146                         if(rsta & HSCX_RSTA_RDO)
  147                         {
  148                                 chan->stat_RDO++;
  149                                 NDBGL1(L1_H_XFRERR, "receive data overflow");
  150                                 error++;
  151                         }
  152 
  153                         if((rsta & HSCX_RSTA_CRC) == 0)
  154                         {
  155                                 chan->stat_CRC++;
  156                                 cmd |= (HSCX_CMDR_RHR);
  157                                 NDBGL1(L1_H_XFRERR, "CRC check failed");
  158                                 error++;
  159                         }
  160 
  161                         if(rsta & HSCX_RSTA_RAB)
  162                         {
  163                                 chan->stat_RAB++;
  164                                 NDBGL1(L1_H_XFRERR, "Receive message aborted");
  165                                 error++;
  166                         }
  167                 }
  168 
  169                 fifo_data_len = ((HSCX_READ(h_chan, H_RBCL)) &
  170                                                 ((sc->sc_bfifolen)-1));
  171 
  172                 if(fifo_data_len == 0)
  173                         fifo_data_len = sc->sc_bfifolen;
  174 
  175                 /* all error conditions checked, now decide and take action */
  176 
  177                 if(error == 0)
  178                 {
  179                         if(chan->in_mbuf == NULL)
  180                         {
  181                                 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
  182                                         panic("L1 isic_hscx_irq: RME, cannot allocate mbuf!");
  183                                 chan->in_cbptr = chan->in_mbuf->m_data;
  184                                 chan->in_len = 0;
  185                         }
  186 
  187                         fifo_data_len -= 1; /* last byte in fifo is RSTA ! */
  188 
  189                         if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN)
  190                         {
  191                                 /* read data from HSCX fifo */
  192 
  193                                 HSCX_RDFIFO(h_chan, chan->in_cbptr, fifo_data_len);
  194 
  195                                 cmd |= (HSCX_CMDR_RMC);
  196                                 isic_hscx_cmd(sc, h_chan, cmd);
  197                                 cmd = 0;
  198 
  199                                 chan->in_len += fifo_data_len;
  200                                 chan->rxcount += fifo_data_len;
  201 
  202                                 /* setup mbuf data length */
  203 
  204                                 chan->in_mbuf->m_len = chan->in_len;
  205                                 chan->in_mbuf->m_pkthdr.len = chan->in_len;
  206 
  207                                 if(sc->sc_trace & TRACE_B_RX)
  208                                 {
  209                                         i4b_trace_hdr hdr;
  210                                         hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  211                                         hdr.dir = FROM_NT;
  212                                         hdr.count = ++sc->sc_trace_bcount;
  213                                         isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data);
  214                                 }
  215 
  216                                 (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
  217 
  218                                 activity = ACT_RX;
  219 
  220                                 /* mark buffer ptr as unused */
  221 
  222                                 chan->in_mbuf = NULL;
  223                                 chan->in_cbptr = NULL;
  224                                 chan->in_len = 0;
  225                         }
  226                         else
  227                         {
  228                                 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RME, in_len=%d, fifolen=%d", chan->in_len, fifo_data_len);
  229                                 chan->in_cbptr = chan->in_mbuf->m_data;
  230                                 chan->in_len = 0;
  231                                 cmd |= (HSCX_CMDR_RHR | HSCX_CMDR_RMC);
  232                         }
  233                 }
  234                 else
  235                 {
  236                         if (chan->in_mbuf != NULL)
  237                         {
  238                                 i4b_Bfreembuf(chan->in_mbuf);
  239                                 chan->in_mbuf = NULL;
  240                                 chan->in_cbptr = NULL;
  241                                 chan->in_len = 0;
  242                         }
  243                         cmd |= (HSCX_CMDR_RMC);
  244                 }
  245         }
  246 
  247         /* rx fifo full */
  248 
  249         if(ista & HSCX_ISTA_RPF)
  250         {
  251                 if(chan->in_mbuf == NULL)
  252                 {
  253                         if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
  254                                 panic("L1 isic_hscx_irq: RPF, cannot allocate mbuf!");
  255                         chan->in_cbptr = chan->in_mbuf->m_data;
  256                         chan->in_len = 0;
  257                 }
  258 
  259                 chan->rxcount += sc->sc_bfifolen;
  260 
  261                 if((chan->in_len + sc->sc_bfifolen) <= BCH_MAX_DATALEN)
  262                 {
  263                         /* read data from HSCX fifo */
  264 
  265                         HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen);
  266 
  267                         chan->in_cbptr += sc->sc_bfifolen;
  268                         chan->in_len += sc->sc_bfifolen;
  269                 }
  270                 else
  271                 {
  272                         if(chan->bprot == BPROT_NONE)
  273                         {
  274                                 /* setup mbuf data length */
  275 
  276                                 chan->in_mbuf->m_len = chan->in_len;
  277                                 chan->in_mbuf->m_pkthdr.len = chan->in_len;
  278 
  279                                 if(sc->sc_trace & TRACE_B_RX)
  280                                 {
  281                                         i4b_trace_hdr hdr;
  282                                         hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  283                                         hdr.dir = FROM_NT;
  284                                         hdr.count = ++sc->sc_trace_bcount;
  285                                         isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr,chan->in_mbuf->m_len, chan->in_mbuf->m_data);
  286                                 }
  287 
  288                                 /* silence detection */
  289 
  290                                 if(!(isdn_bchan_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
  291                                         activity = ACT_RX;
  292 
  293                                 if(!(IF_QFULL(&chan->rx_queue)))
  294                                 {
  295                                         IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
  296                                 }
  297                                 else
  298                                 {
  299                                         i4b_Bfreembuf(chan->in_mbuf);
  300                                 }
  301 
  302                                 /* signal upper driver that data is available */
  303 
  304                                 (*chan->l4_driver->bch_rx_data_ready)(chan->l4_driver_softc);
  305 
  306                                 /* alloc new buffer */
  307 
  308                                 if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL)
  309                                         panic("L1 isic_hscx_irq: RPF, cannot allocate new mbuf!");
  310 
  311                                 /* setup new data ptr */
  312 
  313                                 chan->in_cbptr = chan->in_mbuf->m_data;
  314 
  315                                 /* read data from HSCX fifo */
  316 
  317                                 HSCX_RDFIFO(h_chan, chan->in_cbptr, sc->sc_bfifolen);
  318 
  319                                 chan->in_cbptr += sc->sc_bfifolen;
  320                                 chan->in_len = sc->sc_bfifolen;
  321 
  322                                 chan->rxcount += sc->sc_bfifolen;
  323                         }
  324                         else
  325                         {
  326                                 NDBGL1(L1_H_XFRERR, "RAWHDLC rx buffer overflow in RPF, in_len=%d", chan->in_len);
  327                                 chan->in_cbptr = chan->in_mbuf->m_data;
  328                                 chan->in_len = 0;
  329                                 cmd |= (HSCX_CMDR_RHR);
  330                         }
  331                 }
  332 
  333                 /* command to release fifo space */
  334 
  335                 cmd |= HSCX_CMDR_RMC;
  336         }
  337 
  338         /* transmit fifo empty, new data can be written to fifo */
  339 
  340         if(ista & HSCX_ISTA_XPR)
  341         {
  342                 /*
  343                  * for a description what is going on here, please have
  344                  * a look at isic_bchannel_start() in i4b_bchan.c !
  345                  */
  346 
  347                 int len;
  348                 int nextlen;
  349 
  350                 NDBGL1(L1_H_IRQ, "%s, chan %d - XPR, Tx Fifo Empty!", sc->sc_dev.dv_xname, h_chan);
  351 
  352                 if(chan->out_mbuf_cur == NULL)  /* last frame is transmitted */
  353                 {
  354                         IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
  355 
  356                         if(chan->out_mbuf_head == NULL)
  357                         {
  358                                 chan->state &= ~HSCX_TX_ACTIVE;
  359                                 (*chan->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
  360                         }
  361                         else
  362                         {
  363                                 chan->state |= HSCX_TX_ACTIVE;
  364                                 chan->out_mbuf_cur = chan->out_mbuf_head;
  365                                 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
  366                                 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
  367 
  368                                 if(sc->sc_trace & TRACE_B_TX)
  369                                 {
  370                                         i4b_trace_hdr hdr;
  371                                         hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  372                                         hdr.dir = FROM_TE;
  373                                         hdr.count = ++sc->sc_trace_bcount;
  374                                         isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
  375                                 }
  376 
  377                                 if(chan->bprot == BPROT_NONE)
  378                                 {
  379                                         if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
  380                                                 activity = ACT_TX;
  381                                 }
  382                                 else
  383                                 {
  384                                         activity = ACT_TX;
  385                                 }
  386                         }
  387                 }
  388 
  389                 len = 0;
  390 
  391                 while(chan->out_mbuf_cur && len != sc->sc_bfifolen)
  392                 {
  393                         nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len);
  394 
  395 #ifdef NOTDEF
  396                         printf("i:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ",
  397                                 chan->out_mbuf_head,
  398                                 chan->out_mbuf_cur,
  399                                 chan->out_mbuf_cur_ptr,
  400                                 chan->out_mbuf_cur_len,
  401                                 len,
  402                                 next_len);
  403 #endif
  404 
  405                         isic_hscx_waitxfw(sc, h_chan);  /* necessary !!! */
  406 
  407                         HSCX_WRFIFO(h_chan, chan->out_mbuf_cur_ptr, nextlen);
  408                         cmd |= HSCX_CMDR_XTF;
  409 
  410                         len += nextlen;
  411                         chan->txcount += nextlen;
  412 
  413                         chan->out_mbuf_cur_ptr += nextlen;
  414                         chan->out_mbuf_cur_len -= nextlen;
  415 
  416                         if(chan->out_mbuf_cur_len == 0)
  417                         {
  418                                 if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
  419                                 {
  420                                         chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
  421                                         chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
  422 
  423                                         if(sc->sc_trace & TRACE_B_TX)
  424                                         {
  425                                                 i4b_trace_hdr hdr;
  426                                                 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  427                                                 hdr.dir = FROM_TE;
  428                                                 hdr.count = ++sc->sc_trace_bcount;
  429                                                 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
  430                                         }
  431                                 }
  432                                 else
  433                                 {
  434                                         if (chan->bprot != BPROT_NONE)
  435                                                 cmd |= HSCX_CMDR_XME;
  436                                         i4b_Bfreembuf(chan->out_mbuf_head);
  437                                         chan->out_mbuf_head = NULL;
  438                                 }
  439 
  440                         }
  441                 }
  442         }
  443 
  444         if(cmd)         /* is there a command for the HSCX ? */
  445         {
  446                 isic_hscx_cmd(sc, h_chan, cmd); /* yes, to HSCX */
  447         }
  448 
  449         /* call timeout handling routine */
  450 
  451         if(activity == ACT_RX || activity == ACT_TX)
  452                 (*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
  453 }
  454 
  455 /*---------------------------------------------------------------------------*
  456  *      HSCX initialization
  457  *
  458  *      for telephony: extended transparent mode 1
  459  *      for raw hdlc:  transparent mode 0
  460  *---------------------------------------------------------------------------*/
  461 void
  462 isic_hscx_init(struct isic_softc *sc, int h_chan, int activate)
  463 {
  464         l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
  465 
  466         HSCX_WRITE(h_chan, H_MASK, 0xff);               /* mask irq's */
  467 
  468         if(sc->sc_ipac)
  469         {
  470                 /* CCR1: Power Up, Clock Mode 5 */
  471                 HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU  |      /* power up */
  472                               HSCX_CCR1_CM1);   /* IPAC clock mode 5 */
  473         }
  474         else
  475         {
  476                 /* CCR1: Power Up, Clock Mode 5 */
  477                 HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU  |      /* power up */
  478                               HSCX_CCR1_CM2 |   /* HSCX clock mode 5 */
  479                               HSCX_CCR1_CM0);
  480         }
  481 
  482         /* XAD1: Transmit Address Byte 1 */
  483         HSCX_WRITE(h_chan, H_XAD1, 0xff);
  484 
  485         /* XAD2: Transmit Address Byte 2 */
  486         HSCX_WRITE(h_chan, H_XAD2, 0xff);
  487 
  488         /* RAH2: Receive Address Byte High Reg. 2 */
  489         HSCX_WRITE(h_chan, H_RAH2, 0xff);
  490 
  491         /* XBCH: reset Transmit Byte Count High */
  492         HSCX_WRITE(h_chan, H_XBCH, 0x00);
  493 
  494         /* RLCR: reset Receive Length Check Register */
  495         HSCX_WRITE(h_chan, H_RLCR, 0x00);
  496 
  497         /* CCR2: set tx/rx clock shift bit 0    */
  498         /*       disable CTS irq, disable RIE irq*/
  499         HSCX_WRITE(h_chan, H_CCR2, HSCX_CCR2_XCS0|HSCX_CCR2_RCS0);
  500 
  501         /* XCCR: tx bit count per time slot */
  502         HSCX_WRITE(h_chan, H_XCCR, 0x07);
  503 
  504         /* RCCR: rx bit count per time slot */
  505         HSCX_WRITE(h_chan, H_RCCR, 0x07);
  506 
  507         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  508         {
  509                 switch(h_chan)
  510                 {
  511                         case HSCX_CH_A: /* Prepare HSCX channel A */
  512                                 /* TSAX: tx clock shift bits 1 & 2      */
  513                                 /*       tx time slot number            */
  514                                 HSCX_WRITE(h_chan, H_TSAX, 0x2f);
  515 
  516                                 /* TSAR: rx clock shift bits 1 & 2      */
  517                                 /*       rx time slot number            */
  518                                 HSCX_WRITE(h_chan, H_TSAR, 0x2f);
  519                                 break;
  520 
  521                         case HSCX_CH_B: /* Prepare HSCX channel B */
  522                                 /* TSAX: tx clock shift bits 1 & 2      */
  523                                 /*       tx time slot number            */
  524                                 HSCX_WRITE(h_chan, H_TSAX, 0x03);
  525 
  526                                 /* TSAR: rx clock shift bits 1 & 2      */
  527                                 /*       rx time slot number            */
  528                                 HSCX_WRITE(h_chan, H_TSAR, 0x03);
  529                                 break;
  530                 }
  531         }
  532         else    /* IOM 1 setup */
  533         {
  534                 /* TSAX: tx clock shift bits 1 & 2      */
  535                 /*       tx time slot number            */
  536                 HSCX_WRITE(h_chan, H_TSAX, 0x07);
  537 
  538                 /* TSAR: rx clock shift bits 1 & 2      */
  539                 /*       rx time slot number            */
  540                 HSCX_WRITE(h_chan, H_TSAR, 0x07);
  541         }
  542 
  543         if(activate)
  544         {
  545                 if(chan->bprot == BPROT_RHDLC)
  546                 {
  547                   /* HDLC Frames, transparent mode 0 */
  548                   HSCX_WRITE(h_chan, H_MODE,
  549                      HSCX_MODE_MDS1|HSCX_MODE_RAC|HSCX_MODE_RTS);
  550                 }
  551                 else
  552                 {
  553                   /* Raw Telephony, extended transparent mode 1 */
  554                   HSCX_WRITE(h_chan, H_MODE,
  555                      HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS);
  556                 }
  557 
  558                 isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR|HSCX_CMDR_XRES);
  559         }
  560         else
  561         {
  562                 /* TSAX: tx time slot */
  563                 HSCX_WRITE(h_chan, H_TSAX, 0xff);
  564 
  565                 /* TSAR: rx time slot */
  566                 HSCX_WRITE(h_chan, H_TSAR, 0xff);
  567 
  568                 /* Raw Telephony, extended transparent mode 1 */
  569                 HSCX_WRITE(h_chan, H_MODE,
  570                    HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS);
  571         }
  572 
  573         /* don't touch ICA, EXA and EXB bits, this could be HSCX_CH_B */
  574         /* always disable RSC and TIN */
  575 
  576         chan->hscx_mask |= HSCX_MASK_RSC | HSCX_MASK_TIN;
  577 
  578         if(activate)
  579         {
  580                 /* enable */
  581                 chan->hscx_mask &= ~(HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR);
  582         }
  583         else
  584         {
  585                 /* disable */
  586                 chan->hscx_mask |= HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR;
  587         }
  588 
  589         /* handle ICA, EXA, and EXB via interrupt mask of channel b */
  590 
  591         if (h_chan == HSCX_CH_A)
  592         {
  593                 if (activate)
  594                         HSCX_B_IMASK &= ~(HSCX_MASK_EXA | HSCX_MASK_ICA);
  595                 else
  596                         HSCX_B_IMASK |= HSCX_MASK_EXA | HSCX_MASK_ICA;
  597                 HSCX_WRITE(HSCX_CH_A, H_MASK, HSCX_A_IMASK);
  598                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  599         }
  600         else
  601         {
  602                 if (activate)
  603                         HSCX_B_IMASK &= ~HSCX_MASK_EXB;
  604                 else
  605                         HSCX_B_IMASK |= HSCX_MASK_EXB;
  606                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  607         }
  608 
  609         /* clear spurious interrupts left over */
  610 
  611         if(h_chan == HSCX_CH_A)
  612         {
  613                 HSCX_READ(h_chan, H_EXIR);
  614                 HSCX_READ(h_chan, H_ISTA);
  615         }
  616         else  /* mask ICA, because it must not be cleared by reading ISTA */
  617         {
  618                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK | HSCX_MASK_ICA);
  619                 HSCX_READ(h_chan, H_EXIR);
  620                 HSCX_READ(h_chan, H_ISTA);
  621                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  622         }
  623 }
  624 
  625 /*---------------------------------------------------------------------------*
  626  *      write command to HSCX command register
  627  *---------------------------------------------------------------------------*/
  628 void
  629 isic_hscx_cmd(struct isic_softc *sc, int h_chan, unsigned char cmd)
  630 {
  631         int timeout = 20;
  632 
  633         while(((HSCX_READ(h_chan, H_STAR)) & HSCX_STAR_CEC) && timeout)
  634         {
  635                 DELAY(10);
  636                 timeout--;
  637         }
  638 
  639         if(timeout == 0)
  640         {
  641                 NDBGL1(L1_H_ERR, "HSCX wait for CEC timeout!");
  642         }
  643 
  644         HSCX_WRITE(h_chan, H_CMDR, cmd);
  645 }
  646 
  647 /*---------------------------------------------------------------------------*
  648  *      wait for HSCX transmit FIFO write enable
  649  *---------------------------------------------------------------------------*/
  650 void
  651 isic_hscx_waitxfw(struct isic_softc *sc, int h_chan)
  652 {
  653 #define WAITVAL 50
  654 #define WAITTO  200
  655 
  656         int timeout = WAITTO;
  657 
  658         while((!(((HSCX_READ(h_chan, H_STAR)) &
  659                 (HSCX_STAR_CEC | HSCX_STAR_XFW)) == HSCX_STAR_XFW)) && timeout)
  660         {
  661                 DELAY(WAITVAL);
  662                 timeout--;
  663         }
  664 
  665         if(timeout == 0)
  666         {
  667                 NDBGL1(L1_H_ERR, "HSCX wait for XFW timeout!");
  668         }
  669         else if (timeout != WAITTO)
  670         {
  671                 NDBGL1(L1_H_XFRERR, "HSCX wait for XFW time: %d uS", (WAITTO-timeout)*50);
  672         }
  673 }
  674 

Cache object: f879e78cf09cbb0341f17120a6ab8e8d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.