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.9 2002/09/27 15:37:16 provos 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.9 2002/09/27 15:37:16 provos 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 activity = -1;
  348                 int len;
  349                 int nextlen;
  350 
  351                 NDBGL1(L1_H_IRQ, "%s, chan %d - XPR, Tx Fifo Empty!", sc->sc_dev.dv_xname, h_chan);
  352 
  353                 if(chan->out_mbuf_cur == NULL)  /* last frame is transmitted */
  354                 {
  355                         IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head);
  356 
  357                         if(chan->out_mbuf_head == NULL)
  358                         {
  359                                 chan->state &= ~HSCX_TX_ACTIVE;
  360                                 (*chan->l4_driver->bch_tx_queue_empty)(chan->l4_driver_softc);
  361                         }
  362                         else
  363                         {
  364                                 chan->state |= HSCX_TX_ACTIVE;
  365                                 chan->out_mbuf_cur = chan->out_mbuf_head;
  366                                 chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
  367                                 chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
  368 
  369                                 if(sc->sc_trace & TRACE_B_TX)
  370                                 {
  371                                         i4b_trace_hdr hdr;
  372                                         hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  373                                         hdr.dir = FROM_TE;
  374                                         hdr.count = ++sc->sc_trace_bcount;
  375                                         isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
  376                                 }
  377                                 
  378                                 if(chan->bprot == BPROT_NONE)
  379                                 {
  380                                         if(!(isdn_bchan_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len)))
  381                                                 activity = ACT_TX;
  382                                 }
  383                                 else
  384                                 {
  385                                         activity = ACT_TX;
  386                                 }
  387                         }
  388                 }
  389                         
  390                 len = 0;
  391 
  392                 while(chan->out_mbuf_cur && len != sc->sc_bfifolen)
  393                 {
  394                         nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len);
  395 
  396 #ifdef NOTDEF                   
  397                         printf("i:mh=%x, mc=%x, mcp=%x, mcl=%d l=%d nl=%d # ",
  398                                 chan->out_mbuf_head,
  399                                 chan->out_mbuf_cur,                     
  400                                 chan->out_mbuf_cur_ptr,
  401                                 chan->out_mbuf_cur_len,
  402                                 len,
  403                                 next_len);
  404 #endif
  405 
  406                         isic_hscx_waitxfw(sc, h_chan);  /* necessary !!! */
  407                         
  408                         HSCX_WRFIFO(h_chan, chan->out_mbuf_cur_ptr, nextlen);
  409                         cmd |= HSCX_CMDR_XTF;
  410         
  411                         len += nextlen;
  412                         chan->txcount += nextlen;
  413         
  414                         chan->out_mbuf_cur_ptr += nextlen;
  415                         chan->out_mbuf_cur_len -= nextlen;
  416                         
  417                         if(chan->out_mbuf_cur_len == 0) 
  418                         {
  419                                 if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL)
  420                                 {
  421                                         chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data;
  422                                         chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len;
  423         
  424                                         if(sc->sc_trace & TRACE_B_TX)
  425                                         {
  426                                                 i4b_trace_hdr hdr;
  427                                                 hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2);
  428                                                 hdr.dir = FROM_TE;
  429                                                 hdr.count = ++sc->sc_trace_bcount;
  430                                                 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data);
  431                                         }
  432                                 }
  433                                 else
  434                                 {
  435                                         if (chan->bprot != BPROT_NONE)
  436                                                 cmd |= HSCX_CMDR_XME;
  437                                         i4b_Bfreembuf(chan->out_mbuf_head);
  438                                         chan->out_mbuf_head = NULL;
  439                                 }
  440 
  441                         }
  442                 }
  443         }
  444 
  445         if(cmd)         /* is there a command for the HSCX ? */
  446         {
  447                 isic_hscx_cmd(sc, h_chan, cmd); /* yes, to HSCX */
  448         }
  449 
  450         /* call timeout handling routine */
  451         
  452         if(activity == ACT_RX || activity == ACT_TX)
  453                 (*chan->l4_driver->bch_activity)(chan->l4_driver_softc, activity);
  454 }
  455 
  456 /*---------------------------------------------------------------------------*
  457  *      HSCX initialization
  458  *
  459  *      for telephony: extended transparent mode 1
  460  *      for raw hdlc:  transparent mode 0
  461  *---------------------------------------------------------------------------*/
  462 void
  463 isic_hscx_init(struct isic_softc *sc, int h_chan, int activate)
  464 {       
  465         l1_bchan_state_t *chan = &sc->sc_chan[h_chan];
  466 
  467         HSCX_WRITE(h_chan, H_MASK, 0xff);               /* mask irq's */
  468 
  469         if(sc->sc_ipac)
  470         {
  471                 /* CCR1: Power Up, Clock Mode 5 */
  472                 HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU  |      /* power up */
  473                               HSCX_CCR1_CM1);   /* IPAC clock mode 5 */
  474         }
  475         else
  476         {
  477                 /* CCR1: Power Up, Clock Mode 5 */
  478                 HSCX_WRITE(h_chan, H_CCR1, HSCX_CCR1_PU  |      /* power up */
  479                               HSCX_CCR1_CM2 |   /* HSCX clock mode 5 */
  480                               HSCX_CCR1_CM0);
  481         }
  482                 
  483         /* XAD1: Transmit Address Byte 1 */
  484         HSCX_WRITE(h_chan, H_XAD1, 0xff);
  485         
  486         /* XAD2: Transmit Address Byte 2 */
  487         HSCX_WRITE(h_chan, H_XAD2, 0xff);
  488 
  489         /* RAH2: Receive Address Byte High Reg. 2 */
  490         HSCX_WRITE(h_chan, H_RAH2, 0xff);
  491         
  492         /* XBCH: reset Transmit Byte Count High */
  493         HSCX_WRITE(h_chan, H_XBCH, 0x00);
  494         
  495         /* RLCR: reset Receive Length Check Register */
  496         HSCX_WRITE(h_chan, H_RLCR, 0x00);
  497         
  498         /* CCR2: set tx/rx clock shift bit 0    */
  499         /*       disable CTS irq, disable RIE irq*/
  500         HSCX_WRITE(h_chan, H_CCR2, HSCX_CCR2_XCS0|HSCX_CCR2_RCS0);
  501 
  502         /* XCCR: tx bit count per time slot */
  503         HSCX_WRITE(h_chan, H_XCCR, 0x07);
  504 
  505         /* RCCR: rx bit count per time slot */
  506         HSCX_WRITE(h_chan, H_RCCR, 0x07);
  507         
  508         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  509         {
  510                 switch(h_chan) 
  511                 {
  512                         case HSCX_CH_A: /* Prepare HSCX channel A */
  513                                 /* TSAX: tx clock shift bits 1 & 2      */
  514                                 /*       tx time slot number            */
  515                                 HSCX_WRITE(h_chan, H_TSAX, 0x2f);
  516 
  517                                 /* TSAR: rx clock shift bits 1 & 2      */
  518                                 /*       rx time slot number            */
  519                                 HSCX_WRITE(h_chan, H_TSAR, 0x2f);
  520                                 break;
  521 
  522                         case HSCX_CH_B: /* Prepare HSCX channel B */
  523                                 /* TSAX: tx clock shift bits 1 & 2      */
  524                                 /*       tx time slot number            */
  525                                 HSCX_WRITE(h_chan, H_TSAX, 0x03);
  526 
  527                                 /* TSAR: rx clock shift bits 1 & 2      */
  528                                 /*       rx time slot number            */
  529                                 HSCX_WRITE(h_chan, H_TSAR, 0x03);
  530                                 break;
  531                 }
  532         }
  533         else    /* IOM 1 setup */
  534         {
  535                 /* TSAX: tx clock shift bits 1 & 2      */
  536                 /*       tx time slot number            */
  537                 HSCX_WRITE(h_chan, H_TSAX, 0x07);
  538 
  539                 /* TSAR: rx clock shift bits 1 & 2      */
  540                 /*       rx time slot number            */
  541                 HSCX_WRITE(h_chan, H_TSAR, 0x07);
  542         }
  543 
  544         if(activate)
  545         {
  546                 if(chan->bprot == BPROT_RHDLC)
  547                 {
  548                   /* HDLC Frames, transparent mode 0 */
  549                   HSCX_WRITE(h_chan, H_MODE,
  550                      HSCX_MODE_MDS1|HSCX_MODE_RAC|HSCX_MODE_RTS);
  551                 }
  552                 else
  553                 {
  554                   /* Raw Telephony, extended transparent mode 1 */
  555                   HSCX_WRITE(h_chan, H_MODE,
  556                      HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS);
  557                 }
  558 
  559                 isic_hscx_cmd(sc, h_chan, HSCX_CMDR_RHR|HSCX_CMDR_XRES);
  560         }
  561         else
  562         {
  563                 /* TSAX: tx time slot */
  564                 HSCX_WRITE(h_chan, H_TSAX, 0xff);
  565 
  566                 /* TSAR: rx time slot */
  567                 HSCX_WRITE(h_chan, H_TSAR, 0xff);
  568 
  569                 /* Raw Telephony, extended transparent mode 1 */
  570                 HSCX_WRITE(h_chan, H_MODE,
  571                    HSCX_MODE_MDS1|HSCX_MODE_MDS0|HSCX_MODE_ADM|HSCX_MODE_RTS);
  572         }
  573 
  574         /* don't touch ICA, EXA and EXB bits, this could be HSCX_CH_B */        
  575         /* always disable RSC and TIN */
  576 
  577         chan->hscx_mask |= HSCX_MASK_RSC | HSCX_MASK_TIN;
  578 
  579         if(activate)
  580         {
  581                 /* enable */
  582                 chan->hscx_mask &= ~(HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR);
  583         }
  584         else
  585         {
  586                 /* disable */
  587                 chan->hscx_mask |= HSCX_MASK_RME | HSCX_MASK_RPF | HSCX_MASK_XPR;
  588         }
  589 
  590         /* handle ICA, EXA, and EXB via interrupt mask of channel b */
  591 
  592         if (h_chan == HSCX_CH_A)
  593         {
  594                 if (activate) 
  595                         HSCX_B_IMASK &= ~(HSCX_MASK_EXA | HSCX_MASK_ICA);
  596                 else
  597                         HSCX_B_IMASK |= HSCX_MASK_EXA | HSCX_MASK_ICA;
  598                 HSCX_WRITE(HSCX_CH_A, H_MASK, HSCX_A_IMASK);
  599                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  600         }
  601         else
  602         {
  603                 if (activate)
  604                         HSCX_B_IMASK &= ~HSCX_MASK_EXB;
  605                 else
  606                         HSCX_B_IMASK |= HSCX_MASK_EXB;
  607                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  608         }
  609 
  610         /* clear spurious interrupts left over */
  611 
  612         if(h_chan == HSCX_CH_A)
  613         {
  614                 HSCX_READ(h_chan, H_EXIR);
  615                 HSCX_READ(h_chan, H_ISTA);
  616         }
  617         else  /* mask ICA, because it must not be cleared by reading ISTA */
  618         {
  619                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK | HSCX_MASK_ICA);
  620                 HSCX_READ(h_chan, H_EXIR);
  621                 HSCX_READ(h_chan, H_ISTA);
  622                 HSCX_WRITE(HSCX_CH_B, H_MASK, HSCX_B_IMASK);
  623         }
  624 }
  625 
  626 /*---------------------------------------------------------------------------*
  627  *      write command to HSCX command register
  628  *---------------------------------------------------------------------------*/
  629 void
  630 isic_hscx_cmd(struct isic_softc *sc, int h_chan, unsigned char cmd)
  631 {       
  632         int timeout = 20;
  633 
  634         while(((HSCX_READ(h_chan, H_STAR)) & HSCX_STAR_CEC) && timeout)
  635         {
  636                 DELAY(10);
  637                 timeout--;
  638         }
  639 
  640         if(timeout == 0)
  641         {
  642                 NDBGL1(L1_H_ERR, "HSCX wait for CEC timeout!");
  643         }
  644 
  645         HSCX_WRITE(h_chan, H_CMDR, cmd);        
  646 }
  647 
  648 /*---------------------------------------------------------------------------*
  649  *      wait for HSCX transmit FIFO write enable
  650  *---------------------------------------------------------------------------*/
  651 void
  652 isic_hscx_waitxfw(struct isic_softc *sc, int h_chan)
  653 {       
  654 #define WAITVAL 50
  655 #define WAITTO  200
  656 
  657         int timeout = WAITTO;
  658 
  659         while((!(((HSCX_READ(h_chan, H_STAR)) &
  660                 (HSCX_STAR_CEC | HSCX_STAR_XFW)) == HSCX_STAR_XFW)) && timeout)
  661         {
  662                 DELAY(WAITVAL);
  663                 timeout--;
  664         }
  665 
  666         if(timeout == 0)
  667         {
  668                 NDBGL1(L1_H_ERR, "HSCX wait for XFW timeout!");
  669         }
  670         else if (timeout != WAITTO)
  671         {
  672                 NDBGL1(L1_H_XFRERR, "HSCX wait for XFW time: %d uS", (WAITTO-timeout)*50);
  673         }
  674 }
  675 

Cache object: 02f1d07f04bc3013c175f2bd6d956257


[ 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.