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/ce/ceddk.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  * Middle-level code for Cronyx Tau32-PCI adapters.
    3  *
    4  * Copyright (C) 2004 Cronyx Engineering
    5  * Copyright (C) 2004 Roman Kurakin <rik@FreeBSD.org>
    6  *
    7  * This software is distributed with NO WARRANTIES, not even the implied
    8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    9  *
   10  * Authors grant any other persons or organisations a permission to use,
   11  * modify and redistribute this software in source and binary forms,
   12  * as long as this message is kept with the software, all derivative
   13  * works or modified versions.
   14  *
   15  * $Cronyx: ceddk.c,v 1.2.6.2 2005/11/17 16:04:13 rik Exp $
   16  */
   17 
   18 #include <sys/cdefs.h>
   19 __FBSDID("$FreeBSD: releng/9.0/sys/dev/ce/ceddk.c 154899 2006-01-27 09:02:09Z rik $");
   20 
   21 #include <dev/cx/machdep.h>
   22 #include <dev/ce/ceddk.h>
   23 
   24 #undef CE_DDK_DEBUG_ENABLED
   25 #ifdef CE_DDK_DEBUG_ENABLED
   26 #ifdef __FreeBSD__
   27 # define CE_DDK_DEBUG(b,c,s) \
   28         do { \
   29                 if (c) { \
   30                         printf("ce%d-%d: ",(b)->num,(c)->num); \
   31                 } else { \
   32                         printf("ce%d-*: ",(b)->num); \
   33                 } \
   34                 printf s; \
   35         } while (0)
   36 #else
   37 # define CE_DDK_DEBUG(b,c,s)    do {} while (0)
   38 #endif
   39 #else
   40 # define CE_DDK_DEBUG(b,c,s)    do {} while (0)
   41 #endif
   42 
   43 #if 0
   44 #define ENTER() \
   45         static int enter=0; \
   46         do { \
   47         enter++; \
   48         printf ("%s: >> enter (%16llx) %d\n", __FUNCTION__, rdtsc (), enter); \
   49         } while (0)
   50 
   51 #define EXIT(val...) \
   52         do { \
   53         enter--; \
   54         printf ("%s: << exit  (%16llx) %d line %d\n", __FUNCTION__, rdtsc (), enter, __LINE__); \
   55         return val; \
   56         } while (0)
   57 #else
   58 #define ENTER() \
   59         do {} while (0)
   60 
   61 #define EXIT(val...) \
   62         do {return val;} while (0)
   63 #endif
   64 
   65 #define CE_ENQUEUE(list,item) \
   66         do { \
   67                 TAU32_UserRequest **last; \
   68                 last = &(list); \
   69                 while (*last) { \
   70                         last = &(*last)->next; \
   71                 } \
   72                 (*last) = (item); \
   73                 (item)->next = NULL; \
   74         } while (0)
   75         
   76 #define CE_ENQUEUE_HEAD(list,item) \
   77         do { \
   78                 (item)->next = list; \
   79                 list = item; \
   80         } while (0)
   81         
   82 #define CE_DEQUEUE(list,item) \
   83         do { \
   84                 item = list; \
   85                 if (list) { \
   86                         list = (item)->next; \
   87                 } \
   88         } while (0)
   89         
   90 #define CE_PREREQUEST(b,c,list,item) \
   91         do { \
   92                 item = list; \
   93                 if (!item) { \
   94                         CE_DDK_DEBUG (b, c, ("Fatal error, no free structs " \
   95                                              "for UserRequest (%s:%d)\n", \
   96                                              __FUNCTION__, __LINE__)); \
   97                 } \
   98         } while (0)
   99 
  100 #define CE_DUMP_QUEUE(list) \
  101         do { \
  102                 TAU32_UserRequest *item; \
  103                 int i = 0; \
  104                 item = list; \
  105                 while (item) { \
  106                         printf ("item%d: %p\n", i, item); \
  107                         item = item->next; \
  108                         i++; \
  109                 } \
  110         } while (0)
  111 
  112 #define CE_FIND_ITEM(list,item,flag) \
  113         do { \
  114                 TAU32_UserRequest *citem; \
  115                 flag = 0; \
  116                 for (citem = list; citem; citem = citem->next) { \
  117                         if (citem == item) { \
  118                                 flag = 1; \
  119                                 break; \
  120                         } \
  121                 } \
  122         } while (0)
  123         
  124 #define CE_LAST_ITEM(list,item) \
  125         do { \
  126                 TAU32_UserRequest **last; \
  127                 last = &(list); \
  128                 while ((*last) && (*last)->next) { \
  129                         last = &(*last)->next; \
  130                 } \
  131                 (item) = (*last); \
  132         } while (0)
  133 
  134 #define CE_ASSERT(a) \
  135         do { \
  136                 if (!(a)) { \
  137                         printf ("ASSERT: %d %s\n", __LINE__, #a); \
  138                         __asm __volatile ("int $3"); \
  139                 } \
  140         } while (0)
  141 
  142 static void _ce_set_ts (ce_chan_t *c, unsigned long ts);
  143 static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname);
  144 
  145 #ifdef CE_DDK_DEBUG_ENABLED
  146 static char *ce_err2str (unsigned long err)
  147 {
  148         switch (err) {
  149         case TAU32_SUCCESSFUL:
  150                 return "Successful";
  151         case TAU32_ERROR_ALLOCATION:
  152                 return "Allocation error, not enough tx/rx descriptors";
  153         case TAU32_ERROR_BUS:
  154                 return "PEB could not access to host memory by PCI bus for load/store information";
  155         case TAU32_ERROR_FAIL:
  156                 return "PEB action request failed";
  157         case TAU32_ERROR_TIMEOUT:
  158                 return "PEB action request timeout";
  159         case TAU32_ERROR_CANCELLED:
  160                 return "request has been canceled";
  161         case TAU32_ERROR_TX_UNDERFLOW:
  162                 return "transmission underflow";
  163         case TAU32_ERROR_TX_PROTOCOL:
  164                 return "TX_PROTOCOL";
  165         case TAU32_ERROR_RX_OVERFLOW:
  166                 return "RX_OVERFLOW";
  167         case TAU32_ERROR_RX_ABORT:
  168                 return "RX_ABORT";
  169         case TAU32_ERROR_RX_CRC:
  170                 return "RX_CRC";
  171         case TAU32_ERROR_RX_SHORT:
  172                 return "RX_SHORT";
  173         case TAU32_ERROR_RX_SYNC:
  174                 return "RX_SYNC";
  175         case TAU32_ERROR_RX_FRAME:
  176                 return "RX_FRAME";
  177         case TAU32_ERROR_RX_LONG:
  178                 return "RX_LONG";
  179         case TAU32_ERROR_RX_SPLIT:
  180                 return "frame has splitted between two requests due rx-gap allocation";
  181         case TAU32_ERROR_RX_UNFIT:
  182                 return "frame can't be fit into request buffer";
  183         case TAU32_ERROR_TSP:
  184                 return "ERROR_TSP";
  185         case TAU32_ERROR_RSP:
  186                 return "ERROR_RSP";
  187         case TAU32_ERROR_INT_OVER_TX:
  188                 return "ERROR INT OVER TX";
  189         case TAU32_ERROR_INT_OVER_RX:
  190                 return "ERROR INT OVER RX";
  191         case TAU32_ERROR_INT_STORM:
  192                 return "irq storm";
  193         case TAU32_ERROR_INT_E1LOST:
  194                 return "ERROR_E1LOST";
  195         default:
  196                 return ("Unknown error");
  197         }
  198 }
  199 #endif
  200 
  201 void ce_set_dtr (ce_chan_t *c, int on)
  202 {
  203         c->dtr = on?1:0;
  204 }
  205 
  206 void ce_set_rts (ce_chan_t *c, int on)
  207 {
  208         c->rts = on?1:0;
  209 }
  210 
  211 static void TAU32_CALLBACK_TYPE ce_on_receive
  212         (TAU32_UserContext *pContext, TAU32_UserRequest *req)
  213 {
  214         ce_buf_item_t *item = (ce_buf_item_t *)req;
  215         ce_chan_t *c;
  216         ce_board_t *b;
  217         unsigned int error;
  218         int len;
  219 
  220         ENTER ();
  221         if (!req || !req->sys) {
  222                 EXIT ();
  223         }
  224 
  225         c = (ce_chan_t *)req->sys;
  226         b = c->board;
  227 
  228         len = req->Io.Rx.Received;
  229         error = req->ErrorCode;
  230         
  231         c->rintr++;
  232         if (error == TAU32_SUCCESSFUL) {
  233                 if (req->Io.Rx.FrameEnd) {
  234                         c->ipkts++;
  235                 } else {
  236                         CE_DDK_DEBUG (b, c, ("No FrameEnd\n"));
  237                         /* probably do something in some cases*/
  238                 }
  239                 c->ibytes += len;
  240                 if (c->receive)
  241                         c->receive (c, item->buf, len);
  242         } else if (error & TAU32_ERROR_BUS) {
  243                 c->overrun++;
  244                 if (c->error)
  245                         c->error (c, CE_OVERRUN);
  246         } else {
  247                 CE_DDK_DEBUG (b, c, ("Another receive error: %x\n", error));
  248                 /* Do some procesing */
  249         }
  250         
  251         CE_ASSERT (!req->pInternal);
  252         CE_ENQUEUE (c->rx_queue, req);
  253         while (c->rx_queue) {
  254                 CE_DEQUEUE (c->rx_queue, req);
  255                 CE_ASSERT (req);
  256                 item = (ce_buf_item_t *)req;
  257                 req->Command = TAU32_Rx_Data;
  258                 req->Io.Rx.Channel = c->num;
  259                 req->pCallback = ce_on_receive;
  260                 req->Io.Rx.BufferLength = BUFSZ+4;
  261                 req->Io.Rx.PhysicalDataAddress = item->phys;
  262                 if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
  263                         CE_DDK_DEBUG (b, c, ("RX submition failure\n"));
  264                         c->rx_pending--;
  265                         CE_ENQUEUE_HEAD (c->rx_queue, req);
  266                         break;
  267                 }
  268         }
  269         EXIT ();
  270 }
  271 
  272 static void TAU32_CALLBACK_TYPE ce_on_transmit
  273         (TAU32_UserContext *pContext, TAU32_UserRequest *req)
  274 {
  275         int len;
  276         unsigned int error;
  277         ce_chan_t *c;
  278         ENTER ();
  279 
  280         if (!req || !req->sys) {
  281                 EXIT ();
  282         }
  283 
  284         c = (ce_chan_t *)req->sys;
  285 
  286         len = req->Io.Tx.Transmitted;
  287         error = req->ErrorCode;
  288         
  289         c->tintr++;
  290         if (error == TAU32_SUCCESSFUL) {
  291                 c->obytes += len;
  292                 c->opkts++;
  293         } else if (error & TAU32_ERROR_BUS) {
  294                 c->underrun++;
  295                 if (c->error)
  296                         c->error (c, CE_UNDERRUN);              
  297         } else {
  298                 CE_DDK_DEBUG (c->board, c, ("Another transmit error: %x\n",
  299                                 error));
  300                 /* Do some procesing */
  301         }
  302         
  303         CE_ENQUEUE (c->tx_queue, req);
  304         c->tx_pending--;
  305         
  306         if (c->transmit)
  307                 c->transmit (c, 0, len);
  308         EXIT ();
  309 }
  310 
  311 int ce_transmit_space (ce_chan_t *c)
  312 {
  313         return c->tx_pending < (TAU32_IO_QUEUE);
  314 }
  315 
  316 int ce_send_packet (ce_chan_t *c, unsigned char *buf, int len, void *tag)
  317 {
  318         TAU32_UserRequest *req;
  319         ce_buf_item_t *item;
  320         
  321         ENTER ();
  322 
  323         if (!ce_transmit_space (c)) {
  324                 EXIT (-1);
  325         }
  326 
  327         if (len <= 0 || len > BUFSZ) {
  328                 EXIT (-2);
  329         }
  330 
  331         CE_DEQUEUE (c->tx_queue, req);
  332         CE_ASSERT (req);
  333         item = (ce_buf_item_t *)req;
  334                 
  335         if (buf != item->buf)
  336                 memcpy (item->buf, buf, len);
  337                 
  338         CE_ASSERT (!req->pInternal);
  339                 
  340         req->Command = TAU32_Tx_Data | TAU32_Tx_FrameEnd;
  341         req->Io.Tx.Channel = c->num;
  342         req->pCallback = ce_on_transmit;
  343         req->Io.Tx.DataLength = len;
  344         req->Io.Tx.PhysicalDataAddress = item->phys;
  345         c->tx_pending++;
  346         if (!TAU32_SubmitRequest (c->board->ddk.pControllerObject, req)) {
  347                 CE_DDK_DEBUG (c->board, c, ("Can't submit packet for "
  348                                             "transmission\n"));
  349                 CE_ENQUEUE_HEAD (c->tx_queue, req);
  350                 c->tx_pending--;
  351                 EXIT (-3);
  352         }
  353         EXIT (0);
  354 }
  355 
  356 static void TAU32_CALLBACK_TYPE ce_on_config
  357         (TAU32_UserContext *pContext, TAU32_UserRequest *req)
  358 {
  359         ce_board_t *b = (ce_board_t *) pContext;
  360         ENTER ();
  361         b->cr.pending--;
  362         if (req->ErrorCode)
  363                 CE_DDK_DEBUG (b, (ce_chan_t*)0, ("Config request failure: %lx\n",
  364                               req->ErrorCode));
  365         EXIT ();
  366 }
  367 
  368 static void TAU32_CALLBACK_TYPE ce_on_config_stop
  369         (TAU32_UserContext *pContext, TAU32_UserRequest *req)
  370 {
  371         int i, first;
  372         TAU32_UserRequest *rreq;
  373         ce_board_t *b = (ce_board_t *) pContext;
  374         ce_chan_t *c = b->chan + req->Io.ChannelNumber;
  375         
  376         ENTER ();
  377         /* Stop all requests */
  378         CE_ASSERT (0);/* Buggy */
  379         CE_LAST_ITEM (c->rx_queue, rreq);
  380         /* A little hacky, try to guess which is a first */
  381         first = rreq ? (c->rx_item - (ce_buf_item_t *)rreq) + 1 : 0;
  382         for (i = 0; i < TAU32_IO_QUEUE; i++) {
  383                 int is_pending;
  384                 rreq = &c->rx_item[(i + first) % TAU32_IO_QUEUE].req;
  385                 CE_FIND_ITEM (c->rx_queue, rreq, is_pending);
  386                 if (!is_pending)
  387                         continue;
  388                 TAU32_CancelRequest (b->ddk.pControllerObject, rreq, 1);
  389                 rreq->Command = TAU32_Rx_Data;
  390                 rreq->Io.Rx.Channel = c->num;
  391                 rreq->Io.Rx.BufferLength = BUFSZ+4;
  392                 rreq->Io.Rx.PhysicalDataAddress = ((ce_buf_item_t *)rreq)->phys;
  393                 c->rx_pending++;
  394                 if (!TAU32_SubmitRequest (b->ddk.pControllerObject, rreq)) {
  395                         CE_ASSERT (0);/* Buggy */
  396                         c->rx_pending--;
  397                         break;
  398                 }
  399         }
  400         
  401         c->tx_pending = 0;
  402 /*      c->rx_pending = 0;*/
  403         EXIT ();
  404 }
  405 
  406 static int ce_cfg_submit (ce_board_t *b)
  407 {
  408         TAU32_UserRequest *req;
  409         ENTER ();
  410 
  411         CE_DEQUEUE (b->cr.queue, req);
  412         CE_ASSERT (req);
  413         CE_ASSERT (!req->pInternal);
  414 
  415         req->pCallback = ce_on_config;
  416         b->cr.pending++;
  417         
  418         CE_DDK_DEBUG (b, (ce_chan_t *)0, ("config request pending: %d\n",
  419                       b->cr.pending));
  420 
  421         if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
  422                 CE_ENQUEUE_HEAD (b->cr.queue, req);
  423                 CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Fail to submit config request\n"));
  424                 b->cr.pending--;
  425                 EXIT (0);
  426         }
  427         
  428         EXIT (1);
  429 }
  430 
  431 void ce_init_board (ce_board_t *b)
  432 {
  433         int i;
  434 
  435         b->cr.queue = NULL;
  436 
  437         for (i = 0; i < CONFREQSZ; i++) {
  438                 CE_ENQUEUE (b->cr.queue, b->cr.req + i);
  439         }
  440 
  441         b->chan[0].config = TAU32_ais_on_loss;
  442 
  443         /* lloop = off, rloop = off */
  444         b->chan[0].config |= TAU32_LineNormal;
  445         b->chan[0].lloop = 0;
  446         b->chan[0].rloop = 0;
  447 
  448         /* unfram=off, scrambler=off, use16=off, crc4=off,
  449            higain=off, monitor=off*/
  450         b->chan[0].config |= (b->ddk.Interfaces == 2 ? TAU32_framed_cas_cross :
  451                                                        TAU32_framed_cas_set);
  452         b->chan[0].unfram = 0;
  453         b->chan[0].scrambler = 0;
  454         b->chan[0].use16 = 0;
  455         b->chan[0].crc4 = 0;
  456         b->chan[0].higain = 0;
  457         b->chan[0].monitor = 0;
  458 
  459         if (b->ddk.Interfaces == 2) {
  460                 b->chan[1].config = TAU32_ais_on_loss;
  461                 /* lloop = off, rloop = off */
  462                 b->chan[1].config |= TAU32_LineNormal;
  463                 /* unfram=off, scrambler=off, use16=off, crc4=off,
  464                    higain=off, monitor=off*/
  465                 b->chan[1].config |= TAU32_framed_cas_cross;
  466                 b->chan[1].unfram = 0;
  467                 b->chan[1].scrambler = 0;
  468                 b->chan[1].use16 = 0;
  469                 b->chan[1].crc4 = 0;
  470                 b->chan[1].higain = 0;
  471                 b->chan[1].monitor = 0;
  472         }
  473 
  474         for (i = 0; i < NCHAN; i++) {
  475                 /* Chan0 ts=1-15,17-31, Chan1 ts=1-2 */
  476                 b->chan[i].type = i < b->ddk.Interfaces ? T_E1 : T_DATA;
  477                 b->chan[i].ts = (i == 0 ? 0xfffefffe :
  478                                 (i != 1 ? 0 : 
  479                                 (b->ddk.Interfaces == 2 ? 0x6: 0)));
  480                 b->chan[i].dir = (b->ddk.Interfaces == 2) ? (i%2) : 0;
  481                 b->chan[i].mtu = 1504;
  482         }
  483 #if 0
  484         /* c->num == 0 */
  485         req = b->cr.queue;
  486         /* We must have some here */
  487         CE_ASSERT (req);
  488         req->Command = TAU32_Configure_E1;
  489         req->Io.InterfaceConfig.Interface = TAU32_E1_A;
  490         req->Io.InterfaceConfig.Config = b->chan[0].config;
  491         req->Io.InterfaceConfig.UnframedTsMask = 0;
  492         if (!ce_cfg_submit (b)) {
  493                 CE_DDK_DEBUG (b, b->chan + 0,
  494                               ("Submit request failure, line %d\n",
  495                               __LINE__));
  496         }
  497         /* c->num == 1 */
  498         if (b->ddk.Interfaces == 2) {
  499                 req = b->cr.queue;
  500                 /* We must have some here */
  501                 CE_ASSERT (req);
  502                 req->Command = TAU32_Configure_E1;
  503                 req->Io.InterfaceConfig.Interface = TAU32_E1_B;
  504                 req->Io.InterfaceConfig.Config = b->chan[1].config;
  505                 req->Io.InterfaceConfig.UnframedTsMask = 0;
  506                 if (!ce_cfg_submit (b)) {
  507                         CE_DDK_DEBUG (b, b->chan + 1,
  508                                       ("Submit request failure, line %d\n",
  509                                       __LINE__));
  510                 }
  511         }
  512 #endif
  513         /* Set default cross matrix */
  514         for (i = 0; i < 32; i++) {
  515                 /* -X-> Peb */
  516                 b->dxc[i] = TAU32_CROSS_OFF;
  517                 /* Link2 -> Link1 */
  518                 b->dxc[i + 32] = i + 64;
  519                 /* Link1 -> Link2 */
  520                 b->dxc[i + 64] = i + 32;
  521         }
  522 
  523         /* We have only mux mode for now. Later we will also have cross mode */
  524         b->mux = 1;
  525 }
  526 
  527 void ce_start_chan (ce_chan_t *c, int tx, int rx, ce_buf_t *cb,
  528         unsigned long phys)
  529 {
  530         int i;
  531         ce_board_t *b = c->board;
  532 
  533 /*      c->config = TAU32_ais_on_loss | TAU32_framed_cas_cross;*/
  534 
  535         if (cb) {
  536                 CE_DDK_DEBUG (b, c, ("ce_buf_t virt:%p phys:%p\n", cb,
  537                               (void *)phys));
  538                 c->tx_item = cb->tx_item;
  539                 c->rx_item = cb->rx_item;
  540                 c->tx_queue = NULL;
  541                 c->rx_queue = NULL;
  542                 for (i = 0; i < TAU32_IO_QUEUE; i++) {
  543                         c->tx_item[i].phys = phys +
  544                                 ((char *)(c->tx_item[i].buf)-(char *)cb);
  545                         c->rx_item[i].phys = phys +
  546                                 ((char *)(c->rx_item[i].buf)-(char *)cb);
  547                         cb->tx_item[i].req.sys = c;
  548                         cb->rx_item[i].req.sys = c;
  549                         CE_DDK_DEBUG (b, c, ("tx_item[%d].buf virt:%p phys:%p\n",
  550                                       i, c->tx_item[i].buf,
  551                                       (void *)c->tx_item[i].phys));
  552                         CE_DDK_DEBUG (b, c, ("rx_item[%d].buf virt:%p phys:%p\n",
  553                                       i, c->rx_item[i].buf,
  554                                       (void *)c->rx_item[i].phys));
  555                         CE_ENQUEUE (c->rx_queue, &c->rx_item[i].req);
  556                         CE_ENQUEUE (c->tx_queue, &c->tx_item[i].req);
  557                 }
  558                 c->tx_pending = 0;
  559                 c->rx_pending = 0;
  560         }
  561         
  562         /* submit rx */
  563         while (1) {
  564                 ce_buf_item_t *item;
  565                 TAU32_UserRequest *req;
  566                 
  567                 CE_DEQUEUE (c->rx_queue, req);
  568                 if (!req)
  569                         break;
  570                 item = (ce_buf_item_t *) req;
  571                 CE_ASSERT (c->rx_pending < TAU32_IO_QUEUE);
  572                 req->Command = TAU32_Rx_Data;
  573                 req->Io.Rx.Channel = c->num;
  574                 req->pCallback = ce_on_receive;
  575                 req->Io.Rx.BufferLength = c->mtu + (c->phony ? 0 : 4);
  576                 req->Io.Rx.PhysicalDataAddress = item->phys;
  577                 c->rx_pending++;
  578                 if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
  579                         CE_DDK_DEBUG (b, c, ("Faild to submit rx request\n"));
  580                         /*XXXRIK: shouldn't happen, but ... */
  581                         CE_ASSERT (0);
  582                         c->rx_pending--;
  583                         break;
  584                 }       
  585         }
  586         
  587         if (tx | rx) {
  588                 TAU32_UserRequest *req;
  589                 CE_PREREQUEST (b, c, b->cr.queue, req);
  590                 if (!req)
  591                         return;
  592                 req->Command = TAU32_Configure_Commit |
  593                                (tx ? TAU32_Tx_Start : 0) |
  594                                (rx ? TAU32_Rx_Start : 0);
  595                 req->Io.ChannelNumber = c->num;
  596                 if (!ce_cfg_submit (b)) {
  597                         CE_DDK_DEBUG (b, c, ("Can't start chan\n"));
  598                         /* Do some error processing */
  599                         return;
  600                 }
  601         }
  602         
  603         /* If we run just after ce_board_init we have prope values.
  604          * Else I hope you didn't set ts to incorrect value.
  605          */
  606         _ce_set_ts (c, c->ts);
  607         if (c->num < b->ddk.Interfaces) {
  608                 /* The same for other modes. We don't check them.
  609                  * We hope that config is correctly set. Just as we have
  610                  * after ce_board_init. If channel was stoped we hope that
  611                  * it's config was not broken just after it and we didn't
  612                  * brake it before start.
  613                  */
  614                 _ce_submit_configure_e1 (c, "start_init");
  615         }
  616 }
  617 
  618 void ce_stop_chan (ce_chan_t *c)
  619 {
  620         ce_board_t *b = c->board;
  621         TAU32_UserRequest *req;
  622         CE_DEQUEUE (b->cr.queue, req);
  623 
  624         /* XXXRIK: This function should be for comleteness, but for now I
  625          * don't use it. So I just start to write and didn't finished it yet.
  626          * It and it is VERY BUGGY!!! Do not use it. If you realy
  627          * need it ask me to fix it or rewrite it by your self.
  628          * Note: most buggy part of it in ce_on_config_stop!
  629          */
  630         if (!req) {
  631                 CE_DDK_DEBUG (b, c, ("Fatal error, no free structs for "
  632                               "UserRequest (%s:%d)\n", __FUNCTION__, __LINE__));
  633                 return;
  634         }
  635         req->Command = TAU32_Configure_Commit |
  636                        TAU32_Tx_Stop | TAU32_Rx_Stop;
  637         req->Command = 0;
  638         req->Io.ChannelNumber = c->num;
  639         req->pCallback = ce_on_config_stop;
  640         b->cr.pending++;
  641         
  642         if (!TAU32_SubmitRequest (b->ddk.pControllerObject, req)) {
  643                 CE_ENQUEUE_HEAD (b->cr.queue, req);
  644                 CE_DDK_DEBUG (b, c, ("Can't stop chan\n"));
  645                 b->cr.pending--;
  646         }
  647 }       
  648 
  649 
  650 void ce_register_transmit (ce_chan_t *c,
  651         void (*func) (ce_chan_t*, void*, int))
  652 {
  653         c->transmit = func;
  654 }
  655 
  656 void ce_register_receive (ce_chan_t *c,
  657         void (*func) (ce_chan_t*, unsigned char*, int))
  658 {
  659         c->receive = func;
  660 }
  661 
  662 void ce_register_error (ce_chan_t *c,
  663         void (*func) (ce_chan_t*, int))
  664 {
  665         c->error = func;
  666 }
  667 
  668 void TAU32_CALLBACK_TYPE ce_error_callback (TAU32_UserContext *pContext,
  669                                                 int Item, unsigned NotifyBits)
  670 {
  671         ce_board_t *b = (ce_board_t *) pContext;
  672         ENTER ();
  673         if (NotifyBits & (TAU32_ERROR_FAIL | TAU32_ERROR_TIMEOUT
  674                 | TAU32_ERROR_INT_OVER_TX | TAU32_ERROR_INT_OVER_RX
  675                 | TAU32_ERROR_INT_STORM)) {
  676                 /* Fatal: adapter failure, need reset & restart */
  677                 /* RIKXXX: probably I should add CE_FAILURE for ce_error */
  678                 CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Err, disable interrupts: %s\n",
  679                                 ce_err2str (NotifyBits)));
  680 /*              TAU32_DisableInterrupts (b->ddk.pControllerObject);*/
  681                 EXIT ();
  682         }
  683         if (Item >= 0) {
  684                 /* channel error */
  685                 ce_chan_t *c = b->chan + Item;
  686                 if (NotifyBits & TAU32_ERROR_TX_UNDERFLOW) {
  687                         c->underrun++;
  688                         if (c->error)
  689                                 c->error (c, CE_UNDERRUN);
  690                 }
  691                 if (NotifyBits & TAU32_ERROR_RX_OVERFLOW) {
  692                         c->overrun++;
  693                         if (c->error)
  694                                 c->error (c, CE_OVERFLOW);
  695                 }
  696                 if (NotifyBits & (TAU32_ERROR_RX_FRAME | TAU32_ERROR_RX_ABORT |
  697                     TAU32_ERROR_RX_SHORT | TAU32_ERROR_RX_LONG |
  698                     TAU32_ERROR_RX_SYNC | TAU32_ERROR_RX_SPLIT |
  699                     TAU32_ERROR_RX_UNFIT)) {
  700                         c->frame++;
  701                         CE_DDK_DEBUG (b, c, ("Frame error: %x\n", NotifyBits));
  702                         if (c->error)
  703                                 c->error (c, CE_FRAME);
  704                 }
  705                 if(NotifyBits & TAU32_ERROR_RX_CRC) {
  706                         c->crc++;
  707                         if (c->error)
  708                                 c->error (c, CE_CRC);
  709                 }
  710         } else {
  711                 CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another error: %x\n",
  712                               NotifyBits));
  713                 /* Adapter error, do smth */
  714         }
  715         EXIT ();
  716 }
  717 
  718 void TAU32_CALLBACK_TYPE ce_status_callback(TAU32_UserContext *pContext,
  719                                                 int Item, unsigned NotifyBits)
  720 {
  721         ce_board_t *b = (ce_board_t *) pContext;
  722         ENTER ();
  723         if(Item >= 0) {
  724                 /* e1 status */
  725                 ce_chan_t *c = b->chan + Item;
  726                 c->acc_status |= b->ddk.InterfacesInfo[Item].Status;
  727 /*              CE_DDK_DEBUG (b, c, ("Current status: %x\n", c->acc_status));*/
  728         } else {
  729                 CE_DDK_DEBUG (b, (ce_chan_t *)0, ("Another status: %x\n", NotifyBits));
  730                 /* Adapter status, do smth. */
  731         }
  732         EXIT ();
  733 }
  734 
  735 int ce_get_cd (ce_chan_t *c)
  736 {
  737         unsigned int e1status = c->board->ddk.InterfacesInfo[c->dir].Status;
  738 
  739         return (c->ts && !(e1status & (TAU32_RCL | TAU32_E1OFF)));
  740 }
  741 
  742 int ce_get_cts (ce_chan_t *c)
  743 {
  744         return 0;
  745 }
  746 
  747 int ce_get_dsr (ce_chan_t *c)
  748 {
  749         return 0;
  750 }
  751 
  752 void ce_e1_timer (ce_chan_t *c)
  753 {
  754         unsigned bpv, fas, crc4, ebit, pcv, oof, css;
  755         unsigned int acc_status;
  756         ce_board_t *b = c->board;
  757         TAU32_E1_State  *state;
  758 
  759         if (c->num >= b->ddk.Interfaces)
  760                 return;
  761         
  762         state = &b->ddk.InterfacesInfo[c->num];
  763         acc_status = c->acc_status;
  764         
  765         /* Clear acc_status */
  766         c->acc_status = b->ddk.InterfacesInfo[c->num].Status;
  767 
  768         /* Count seconds.
  769          * During the first second after the channel startup
  770          * the status registers are not stable yet,
  771          * we will so skip the first second. */
  772         ++c->cursec;
  773         if (! c->totsec && c->cursec <= 1)
  774                 return;
  775 
  776         c->status = 0;
  777 
  778         /* Compute the SNMP-compatible channel status. */
  779         oof = 0;
  780 
  781         if (acc_status & TAU32_RCL)
  782                 c->status |= ESTS_LOS;          /* loss of signal */
  783         if (acc_status & TAU32_RUA1)
  784                 c->status |= ESTS_AIS;          /* receiving all ones */
  785 
  786         /* Get error counters. */
  787         bpv = state->RxViolations;
  788         fas = 0;
  789         crc4 = 0;
  790         ebit = 0;
  791         css = 0;
  792 
  793         if (! c->unfram) {
  794                 if (! c->use16 && (acc_status & TAU32_RSA1))
  795                         c->status |= ESTS_AIS16;        /* signaling all ones */
  796                 if (! c->use16 && (acc_status & TAU32_RDMA))
  797                         c->status |= ESTS_FARLOMF;      /* alarm in timeslot 16 */
  798                 if (acc_status & TAU32_RRA)
  799                         c->status |= ESTS_FARLOF;       /* far loss of framing */
  800 
  801                 if (acc_status & TAU32_RFAS) {
  802                         c->status |= ESTS_LOF;          /* loss of framing */
  803                         ++oof;                          /* out of framing */
  804                 }
  805                 if ((! c->use16 && (acc_status & TAU32_RCAS)) ||
  806                     (c->crc4 && (acc_status & TAU32_RCRC4))) {
  807                         c->status |= ESTS_LOMF;         /* loss of multiframing */
  808                         ++oof;                          /* out of framing */
  809                 }
  810                 fas = state->FasErrors;
  811                 crc4 = state->Crc4Errors;
  812                 ebit = state->FarEndBlockErrors;
  813 
  814                 /* Controlled slip second -- any slip event. */
  815                 css = state->TransmitSlips + state->ReceiveSlips;
  816         }
  817         
  818         /* Clear state */
  819         state->RxViolations             = 0;
  820         state->FasErrors                = 0;
  821         state->Crc4Errors               = 0;
  822         state->FarEndBlockErrors        = 0;
  823         state->TransmitSlips            = 0;
  824         state->ReceiveSlips             = 0;
  825 
  826         if (c->status & ESTS_LOS)
  827                 c->status = ESTS_LOS;
  828         else if (c->status & ESTS_AIS)
  829                 c->status = ESTS_AIS;
  830         else if (c->status & ESTS_LOF)
  831                 c->status = ESTS_LOF;
  832         else if (c->status & ESTS_LOMF)
  833                 c->status &= ~(ESTS_FARLOMF | ESTS_AIS16);
  834 
  835         if (! c->status)
  836                 c->status = ESTS_NOALARM;
  837 
  838         c->currnt.bpv += bpv;
  839         c->currnt.fse += fas;
  840         if (c->crc4) {
  841                 c->currnt.crce += crc4;
  842                 c->currnt.rcrce += ebit;
  843         }
  844 
  845         /* Path code violation is frame sync error if CRC4 disabled,
  846          * or CRC error if CRC4 enabled. */
  847         pcv = fas;
  848         if (c->crc4)
  849                 pcv += crc4;
  850 
  851         /* Unavaiable second -- receiving all ones, or
  852          * loss of carrier, or loss of signal. */
  853         if (acc_status & (TAU32_RUA1 | TAU32_RCL))
  854                 /* Unavailable second -- no other counters. */
  855                 ++c->currnt.uas;
  856         else {
  857                 /* Line errored second -- any BPV. */
  858                 if (bpv)
  859                         ++c->currnt.les;
  860 
  861                 /* Errored second -- any PCV, or out of frame sync,
  862                  * or any slip events. */
  863                 if (pcv || oof || css)
  864                         ++c->currnt.es;
  865 
  866                 /* Severely errored framing second -- out of frame sync. */
  867                 if (oof)
  868                         ++c->currnt.oofs;
  869 
  870                 /* Severely errored seconds --
  871                  * 832 or more PCVs, or 2048 or more BPVs. */
  872                 if (bpv >= 2048 || pcv >= 832)
  873                         ++c->currnt.ses;
  874                 else {
  875                         /* Bursty errored seconds --
  876                          * no SES and more than 1 PCV. */
  877                         if (pcv > 1)
  878                                 ++c->currnt.bes;
  879 
  880                         /* Collect data for computing
  881                          * degraded minutes. */
  882                         ++c->degsec;
  883                         c->degerr += bpv + pcv;
  884                 }
  885         }
  886 
  887         /* Degraded minutes -- having error rate more than 10e-6,
  888          * not counting unavailable and severely errored seconds. */
  889         if (c->cursec % 60 == 0) {
  890                 if (c->degerr > c->degsec * 2048 / 1000)
  891                         ++c->currnt.dm;
  892                 c->degsec = 0;
  893                 c->degerr = 0;
  894         }
  895 
  896         /* Rotate statistics every 15 minutes. */
  897         if (c->cursec > 15*60) {
  898                 int i;
  899 
  900                 for (i=47; i>0; --i)
  901                         c->interval[i] = c->interval[i-1];
  902                 c->interval[0] = c->currnt;
  903 
  904                 /* Accumulate total statistics. */
  905                 c->total.bpv   += c->currnt.bpv;
  906                 c->total.fse   += c->currnt.fse;
  907                 c->total.crce  += c->currnt.crce;
  908                 c->total.rcrce += c->currnt.rcrce;
  909                 c->total.uas   += c->currnt.uas;
  910                 c->total.les   += c->currnt.les;
  911                 c->total.es    += c->currnt.es;
  912                 c->total.bes   += c->currnt.bes;
  913                 c->total.ses   += c->currnt.ses;
  914                 c->total.oofs  += c->currnt.oofs;
  915                 c->total.css   += c->currnt.css;
  916                 c->total.dm    += c->currnt.dm;
  917                 c->currnt.bpv   = 0;
  918                 c->currnt.fse   = 0;
  919                 c->currnt.crce  = 0;
  920                 c->currnt.rcrce = 0;
  921                 c->currnt.uas   = 0;
  922                 c->currnt.les   = 0;
  923                 c->currnt.es    = 0;
  924                 c->currnt.bes   = 0;
  925                 c->currnt.ses   = 0;
  926                 c->currnt.oofs  = 0;
  927                 c->currnt.css   = 0;
  928                 c->currnt.dm    = 0;
  929 
  930                 c->totsec += c->cursec;
  931                 c->cursec = 0;
  932         }
  933 }
  934 
  935 void ce_set_baud (ce_chan_t *c, unsigned long baud)
  936 {
  937         TAU32_UserRequest *req;
  938         ce_board_t *b = c->board;
  939         unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
  940         unsigned long ts;
  941         unsigned long kbps = (baud + 32000) / 64000 * 64;
  942         
  943         if (!c->unfram || c->num != 0 ||
  944                 baud == c->baud || b->cr.pending >= CONFREQSZ)
  945                 return;
  946         
  947         if (!kbps || kbps > 1024) {
  948                 ts = 0xffffffffUL;
  949                 cfg |= TAU32_unframed_2048;
  950         } else if (kbps > 512) {
  951                 ts = 0x0000ffffUL;
  952                 cfg |= TAU32_unframed_1024;
  953         } else if (kbps > 256) {
  954                 ts = 0x000000ffUL;
  955                 cfg |= TAU32_unframed_512;
  956         } else if (kbps > 128) {
  957                 ts = 0x0000000fUL;
  958                 cfg |= TAU32_unframed_256;
  959         } else if (kbps > 64) {
  960                 ts = 0x00000003UL;
  961                 cfg |= TAU32_unframed_128;
  962         } else {
  963                 ts = 0x00000001UL;
  964                 cfg |= TAU32_unframed_64;
  965         }
  966 
  967         /* _ce_set_ts () will set proper baud */
  968         _ce_set_ts (c, ts);
  969         CE_PREREQUEST (b, c, b->cr.queue, req);
  970         if (!req)
  971                 return;
  972         req->Command = TAU32_Configure_E1;
  973         req->Io.InterfaceConfig.Interface = TAU32_E1_A;
  974         req->Io.InterfaceConfig.Config = cfg;
  975         req->Io.InterfaceConfig.UnframedTsMask = ts;
  976         if (ce_cfg_submit (b)) {
  977                 c->baud = baud;
  978                 c->ts = ts;
  979                 c->config = cfg;
  980         }
  981 }
  982 
  983 void ce_set_lloop (ce_chan_t *c, unsigned char on)
  984 {
  985         TAU32_UserRequest *req;
  986         unsigned long cfg = c->config & ~(TAU32_line_mode_mask | TAU32_ais_on_loss);
  987         ce_board_t *b = c->board;
  988 
  989         if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
  990                 return;
  991         on = on ? 1 : 0;
  992         if (on == c->lloop)
  993                 return;
  994 
  995         cfg |= on ? TAU32_LineLoopInt : (TAU32_LineNormal | TAU32_ais_on_loss);
  996         CE_PREREQUEST (b, c, b->cr.queue, req);
  997         if (!req)
  998                 return;
  999         req->Command = TAU32_Configure_E1;
 1000         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1001         req->Io.InterfaceConfig.Config = cfg;
 1002         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1003         CE_DDK_DEBUG (b, c, ("Submit lloop\n"));
 1004         if (ce_cfg_submit (b)) {
 1005                 c->lloop = on ? 1 : 0;
 1006                 c->config = cfg;
 1007         } 
 1008 }
 1009 
 1010 void ce_set_rloop (ce_chan_t *c, unsigned char on)
 1011 {
 1012         TAU32_UserRequest *req;
 1013         unsigned long cfg = c->config & ~TAU32_line_mode_mask;
 1014         ce_board_t *b = c->board;
 1015 
 1016         if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
 1017                 return;
 1018         on = on ? 1 : 0;
 1019         if (on == c->rloop)
 1020                 return;
 1021 
 1022         cfg |= on ? TAU32_LineLoopExt : TAU32_LineNormal;
 1023         CE_PREREQUEST (b, c, b->cr.queue, req);
 1024         if (!req)
 1025                 return;
 1026         req->Command = TAU32_Configure_E1;
 1027         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1028         req->Io.InterfaceConfig.Config = cfg;
 1029         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1030         CE_DDK_DEBUG (b, c, ("Submit rloop\n"));
 1031         if (ce_cfg_submit (b)) {
 1032                 c->rloop = on ? 1 : 0;
 1033                 c->config = cfg;
 1034         }
 1035 }
 1036 
 1037 void ce_set_higain (ce_chan_t *c, unsigned char on)
 1038 {
 1039         TAU32_UserRequest *req;
 1040         unsigned long cfg = c->config & ~TAU32_higain;
 1041         ce_board_t *b = c->board;
 1042 
 1043         if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
 1044                 return;
 1045         on = on ? 1 : 0;
 1046         if (on == c->higain)
 1047                 return;
 1048 
 1049         cfg |= on ? TAU32_higain : 0;
 1050         CE_PREREQUEST (b, c, b->cr.queue, req);
 1051         if (!req)
 1052                 return;
 1053         req->Command = TAU32_Configure_E1;
 1054         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1055         req->Io.InterfaceConfig.Config = cfg;
 1056         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1057         CE_DDK_DEBUG (b, c, ("Submit higain\n"));
 1058         if (ce_cfg_submit (b)) {
 1059                 c->higain = on ? 1 : 0;
 1060                 c->config = cfg;
 1061         }
 1062 }
 1063 
 1064 static void _ce_set_ts (ce_chan_t *c, unsigned long ts)
 1065 {
 1066         TAU32_UserRequest *req;
 1067         ce_board_t *b = c->board;
 1068         unsigned long mask = 0, omask = 0;
 1069         int nts = 0, ots = 0, pts = 0;
 1070         int i, k;
 1071 
 1072         if (b->cr.pending >= CONFREQSZ)
 1073                 return;
 1074 
 1075         /*
 1076          * pts - number of busy "peb" ts
 1077          * ots - current (old) busy ts
 1078          * nts - new busy ts
 1079          */
 1080         for (i = 0; i < 32; i++) {
 1081                 if (c->ts & (1ul << i))
 1082                         ots++;
 1083                 if (ts & (1ul << i))
 1084                         nts++;
 1085                 if (b->dxc[i] != TAU32_CROSS_OFF)
 1086                         pts++;
 1087         }
 1088         
 1089         CE_DDK_DEBUG (b, c, ("pts: %d ots: %d nts: %d ts: %lx\n", pts, ots, nts,
 1090                       ts));
 1091         /* 32 - all busy + my old busy == free */
 1092         if (32 - pts + ots - nts < 0)
 1093                 return;
 1094                 
 1095         /* Ok. We have enougth "peb" ts. Clean old. */
 1096         /* We start from zero, cause this is peb cells */
 1097         for (i = 0; i < 32; i++) {
 1098                 int tin = b->dxc[i];
 1099                 int t = tin % 32;
 1100                 if (tin < (c->dir?64:32) || tin > (c->dir?95:63))
 1101                         continue;
 1102                 if (c->ts & (1ul << t)) {
 1103                         b->dxc[tin] = TAU32_CROSS_OFF;
 1104                         b->dxc[i] = TAU32_CROSS_OFF;
 1105                         if (b->dxc[t + 32] == TAU32_CROSS_OFF &&
 1106                             b->dxc[t + 64] == TAU32_CROSS_OFF) {
 1107                                 b->dxc[t + 32] = t + 64;
 1108                                 b->dxc[t + 64] = t + 32;
 1109                         }
 1110                         omask |= (1ul << t);
 1111                 }
 1112         }
 1113         
 1114         k = 0;
 1115         /* Set */
 1116         for (i = 0; i < 32; i++) {
 1117                 if ((ts & (1ul << i)) == 0)
 1118                         continue;
 1119                 while (b->dxc[k] != TAU32_CROSS_OFF) {
 1120                         k++;
 1121                         /* Paranoic */
 1122                         if (k >= 32) {
 1123                                 CE_DDK_DEBUG (b, c, ("TS count overflow\n"));
 1124                                 return;
 1125                         }
 1126                 }
 1127                 b->dxc[k] = (c->dir?64:32) + i;
 1128                 b->dxc[(c->dir?64:32) + i] = k;
 1129                 if (b->dxc[(c->dir?32:64) + i] == (c->dir?64:32) + i)
 1130                         b->dxc[(c->dir?32:64) + i] = TAU32_CROSS_OFF;
 1131                 mask |= (1ul << k);
 1132         }
 1133         
 1134         c->ts = ts;
 1135         c->baud = nts*64000;
 1136 
 1137         CE_PREREQUEST (b, c, b->cr.queue, req);
 1138         if (!req)
 1139                 return;
 1140 
 1141         req->Command = TAU32_Timeslots_Channel | TAU32_Configure_Commit;
 1142         req->Io.ChannelNumber = c->num;
 1143         req->Io.ChannelConfig.AssignedTsMask = mask;    
 1144         
 1145         if (c->phony) {
 1146                 b->pmask &= ~omask;
 1147                 b->pmask |= mask;
 1148         }
 1149         
 1150         CE_DDK_DEBUG (b, c, ("ts=%lx mask=%lx omask=%lx pmask=%lx\n", c->ts,
 1151                       mask, omask, b->pmask));
 1152         CE_DDK_DEBUG (b, c, ("Crossmatrix table:\n"));
 1153 
 1154 #ifdef CE_DDK_DEBUG_ENABLED
 1155         for (i = 0; i < 32*3; i++) {
 1156                 printf ("%3d\t%s", b->dxc[i], (i%8==7)?"\n":"");
 1157                 printf ("%s",(i%32==31)?"\n":"");
 1158         }
 1159 #endif
 1160 
 1161         CE_DDK_DEBUG (b, c, ("Submit tsmask\n"));
 1162         if (!ce_cfg_submit (b)) {
 1163                 CE_DDK_DEBUG (b, c, ("Fail to submit tsmask\n"));
 1164                 /* Do some error processing */
 1165                 return;
 1166         }
 1167         
 1168         CE_DDK_DEBUG (b, c, ("SetCrossMatrix\n"));
 1169         if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
 1170                 CE_DDK_DEBUG (b, c, ("Faild to SetCrossMatrix\n"));
 1171                 /* Do some error processing */
 1172                 return;
 1173         }
 1174 }
 1175 
 1176 void ce_set_ts (ce_chan_t *c, unsigned long ts)
 1177 {
 1178         ce_board_t *b = c->board;
 1179         ce_chan_t *x;
 1180 
 1181         if (c->ts == ts || b->chan->unfram)
 1182                 return;
 1183 
 1184         ts &= ~(1ul);
 1185 
 1186         if (!b->chan[c->dir].use16)
 1187                 ts &= ~(1ul << 16);
 1188                 
 1189         for (x = b->chan; x < b->chan + NCHAN; x++) {
 1190                 if (x == c || x->dir != c->dir)
 1191                         continue;
 1192                 ts &= ~x->ts;
 1193         }
 1194         
 1195         _ce_set_ts (c, ts);
 1196 }
 1197 
 1198 void ce_set_unfram (ce_chan_t *c, unsigned char on)
 1199 {
 1200         TAU32_UserRequest *req;
 1201         ce_board_t *b = c->board;
 1202         unsigned long cfg = c->config & ~TAU32_framing_mode_mask;
 1203         unsigned long i;
 1204         
 1205         if (c->num != 0 || b->cr.pending + 2*32 + 3>= CONFREQSZ)
 1206                 return;
 1207 
 1208         on = on ? 1 : 0;
 1209         
 1210         if (on == c->unfram)
 1211                 return;
 1212                 
 1213         if (on) {
 1214                 ce_set_dir (c, 0);
 1215                 for (i = 1; i < TAU32_CHANNELS; i++) {
 1216                         ce_set_ts (b->chan + i, 0);
 1217                         ce_set_phony (b->chan + i, 0);
 1218                 }
 1219                 ce_set_use16 (b->chan + 0, 0);
 1220                 ce_set_use16 (b->chan + 1, 0);
 1221                 /* Get current value, previous ce_set request may change it */
 1222                 cfg = c->config & ~TAU32_framing_mode_mask;
 1223                 cfg |= TAU32_unframed_2048;
 1224                 c->unfram = on;
 1225                 _ce_set_ts (b->chan, ~0ul);
 1226                 c->config = cfg;
 1227                 /* XXXRIK: Do extra checks on config queue size*/
 1228                 if (b->ddk.Interfaces) {
 1229                         CE_PREREQUEST (b, c, b->cr.queue, req);
 1230                         if (!req)
 1231                                 return;
 1232                         req->Command = TAU32_Configure_E1;
 1233                         req->Io.InterfaceConfig.Interface = TAU32_E1_B;
 1234                         req->Io.InterfaceConfig.Config = TAU32_LineOff;
 1235                         req->Io.InterfaceConfig.UnframedTsMask = 0;
 1236                         CE_DDK_DEBUG (b, c, ("unfram: B line off\n"));
 1237                         ce_cfg_submit (b);
 1238                 }
 1239                 CE_PREREQUEST (b, c, b->cr.queue, req);
 1240                 if (!req)
 1241                         return;
 1242                 req->Command = TAU32_Configure_E1;
 1243                 req->Io.InterfaceConfig.Interface = TAU32_E1_A;
 1244                 req->Io.InterfaceConfig.Config = cfg;
 1245                 req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1246                 CE_DDK_DEBUG (b, c, ("Submit unfram\n"));
 1247                 ce_cfg_submit (b);
 1248         } else {
 1249                 cfg |= TAU32_framed_cas_cross;
 1250                 CE_PREREQUEST (b, c, b->cr.queue, req);
 1251                 if (!req)
 1252                         return;
 1253                 req->Command = TAU32_Configure_E1;
 1254                 req->Io.InterfaceConfig.Interface = TAU32_E1_ALL;
 1255                 req->Io.InterfaceConfig.Config = cfg;
 1256                 req->Io.InterfaceConfig.UnframedTsMask = 0;
 1257                 CE_DDK_DEBUG (b, c, ("Submit framed\n"));
 1258                 ce_cfg_submit (b);
 1259                 ce_set_ts (c, 0);
 1260         }
 1261         c->unfram = on;
 1262 }
 1263 
 1264 void ce_set_phony (ce_chan_t *c, unsigned char on)
 1265 {
 1266         TAU32_UserRequest *req;
 1267         ce_board_t *b = c->board;
 1268         unsigned long mask = 0;
 1269         int i;
 1270         
 1271         if ((c->phony && on) || (c->phony == 0 && on == 0) ||
 1272             b->cr.pending >= CONFREQSZ)
 1273                 return;
 1274         
 1275         CE_PREREQUEST (b, c, b->cr.queue, req);
 1276         if (!req)
 1277                 return;
 1278 
 1279         req->Command = TAU32_Configure_Channel;
 1280         req->Io.InterfaceConfig.Config = on ? TAU32_TMA :
 1281                 (TAU32_HDLC | TAU32_fr_rx_splitcheck | TAU32_fr_rx_fitcheck);
 1282         req->Io.ChannelNumber = c->num;
 1283         CE_DDK_DEBUG (b, c, ("Submit phony\n"));
 1284         if (!ce_cfg_submit (b)) {
 1285                 /* Do some error processing */
 1286                 return;
 1287         }
 1288 
 1289         for (i = 0; i < 32; i++) {
 1290                 int t = b->dxc[i] % 32;
 1291                 if (b->dxc[i] < (c->dir?64:32) || b->dxc[i] > (c->dir?95:63))
 1292                         continue;
 1293                 if (c->ts & (1ul << t))
 1294                         mask |= (1ul << t);
 1295         }
 1296         
 1297         CE_DDK_DEBUG (b, c, ("phony mask:%lx\n", mask));
 1298         
 1299         if (on) {
 1300                 b->pmask |= mask;
 1301         } else {
 1302                 b->pmask &= ~mask;
 1303         }
 1304 
 1305         c->phony = on ? 1 : 0;
 1306         
 1307         CE_DDK_DEBUG (b, c, ("Submit (setcrosmatrix) phony\n"));
 1308         if (!TAU32_SetCrossMatrix(b->ddk.pControllerObject, b->dxc, b->pmask)) {
 1309                 /* Do some error processing */
 1310                 return;
 1311         }
 1312 }
 1313 
 1314 void ce_set_scrambler (ce_chan_t *c, unsigned char on)
 1315 {
 1316         TAU32_UserRequest *req;
 1317         unsigned long cfg = c->config & ~TAU32_scrambler;
 1318         ce_board_t *b = c->board;
 1319 
 1320         if (c->num != 0 || c->unfram == 0 || b->cr.pending >= CONFREQSZ)
 1321                 return;
 1322         on = on ? 1 : 0;
 1323         if (on == c->scrambler)
 1324                 return;
 1325 
 1326         cfg |= on ? TAU32_scrambler : 0;
 1327         CE_PREREQUEST (b, c, b->cr.queue, req);
 1328         if (!req)
 1329                 return;
 1330         req->Command = TAU32_Configure_E1;
 1331         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1332         req->Io.InterfaceConfig.Config = cfg;
 1333         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1334         CE_DDK_DEBUG (b, c, ("Submit scrambler\n"));
 1335         if (ce_cfg_submit (b)) {
 1336                 c->scrambler = on ? 1 : 0;
 1337                 c->config = cfg;
 1338         }
 1339 }
 1340 
 1341 void ce_set_monitor (ce_chan_t *c, unsigned char on)
 1342 {
 1343         TAU32_UserRequest *req;
 1344         unsigned long cfg = c->config & ~TAU32_monitor;
 1345         ce_board_t *b = c->board;
 1346 
 1347         if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
 1348                 return;
 1349         on = on ? 1 : 0;
 1350         if (on == c->monitor)
 1351                 return;
 1352 
 1353         cfg |= on ? TAU32_monitor : 0;
 1354         CE_PREREQUEST (b, c, b->cr.queue, req);
 1355         if (!req)
 1356                 return;
 1357         req->Command = TAU32_Configure_E1;
 1358         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1359         req->Io.InterfaceConfig.Config = cfg;
 1360         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1361         CE_DDK_DEBUG (b, c, ("Submit monitor\n"));
 1362         if (ce_cfg_submit (b)) {
 1363                 c->monitor = on ? 1 : 0;
 1364                 c->config = cfg;
 1365         }
 1366 }
 1367 
 1368 static void _ce_submit_configure_e1 (ce_chan_t *c, char *rname)
 1369 {
 1370         TAU32_UserRequest *req;
 1371         ce_board_t *b = c->board;
 1372 
 1373         CE_PREREQUEST (b, c, b->cr.queue, req);
 1374         if (!req)
 1375                 return;
 1376         req->Command = TAU32_Configure_E1;
 1377         req->Io.InterfaceConfig.Interface = c->num == 0 ? TAU32_E1_A : TAU32_E1_B;
 1378         req->Io.InterfaceConfig.Config = c->config;
 1379         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1380         CE_DDK_DEBUG (b, c, ("Submit %s\n", rname ? rname : ""));
 1381         if (!ce_cfg_submit (b)) {
 1382                 CE_DDK_DEBUG (b, c, ("Fail to submit %s\n", rname?rname:""));
 1383                 /* Do some error processing */
 1384                 return; 
 1385         }
 1386 }
 1387 
 1388 void ce_set_use16 (ce_chan_t *c, unsigned char on)
 1389 {
 1390         ce_board_t *b = c->board;
 1391         ce_chan_t *x;
 1392         unsigned long cfg[2];
 1393         int use[2];
 1394 
 1395         if (c->num >= b->ddk.Interfaces || b->cr.pending + 2 >= CONFREQSZ)
 1396                 return;
 1397 
 1398         cfg[0] = b->chan[0].config & ~TAU32_framing_mode_mask;
 1399         cfg[1] = b->chan[1].config & ~TAU32_framing_mode_mask;
 1400         
 1401         on = on ? 1 : 0;
 1402         
 1403         if (c->use16 == on || b->chan->unfram)
 1404                 return;
 1405                 
 1406         use[0] = b->chan[0].use16;
 1407         use[1] = b->chan[1].use16;
 1408         
 1409         /* Correct value */
 1410         use[c->num] = on;
 1411 
 1412         if (b->ddk.Interfaces == 1) {
 1413                 cfg[0] |= on ? TAU32_framed_cas_set : TAU32_framed_no_cas;
 1414         } else {
 1415                 if (use[0] == 0 && use[1] == 0) {
 1416                         cfg[0] |= TAU32_framed_cas_cross;
 1417                         cfg[1] |= TAU32_framed_cas_cross;
 1418                 } else if (use[0] == 0) {
 1419                         cfg[0] |= TAU32_framed_cas_set;
 1420                         cfg[1] |= TAU32_framed_no_cas;
 1421                 } else if (use[1] == 0) {
 1422                         cfg[0] |= TAU32_framed_no_cas;
 1423                         cfg[1] |= TAU32_framed_cas_set;
 1424                 } else {
 1425                         cfg[0] |= TAU32_framed_no_cas;
 1426                         cfg[1] |= TAU32_framed_no_cas;
 1427                 }
 1428         }
 1429 
 1430         c->use16 = on;
 1431 
 1432         for (x = b->chan; !on && x < b->chan + NCHAN; x++) {
 1433                 if (x->dir == c->num && x->ts & (1ul<<16)) {
 1434                         ce_set_ts (x, x->ts);
 1435                         break;
 1436                 }
 1437         }
 1438 
 1439         if (cfg[0] != b->chan[0].config) {
 1440                 b->chan[0].config = cfg[0];
 1441                 _ce_submit_configure_e1 (b->chan + 0, "use16");
 1442         }
 1443 
 1444         if (cfg[1] != b->chan[1].config) {
 1445                 b->chan[1].config = cfg[1];
 1446                 _ce_submit_configure_e1 (b->chan + 1, "use16");
 1447         }
 1448 }
 1449 
 1450 void ce_set_crc4 (ce_chan_t *c, unsigned char on)
 1451 {
 1452         TAU32_UserRequest *req;
 1453         unsigned long cfg = c->config & ~TAU32_crc4_mf;
 1454         ce_board_t *b = c->board;
 1455 
 1456         if (c->num >= b->ddk.Interfaces || b->cr.pending >= CONFREQSZ)
 1457                 return;
 1458         on = on ? 1 : 0;
 1459         if (on == c->crc4 || b->chan->unfram)
 1460                 return;
 1461 
 1462         cfg |= on ? TAU32_crc4_mf : 0;
 1463         CE_PREREQUEST (b, c, b->cr.queue, req);
 1464         if (!req)
 1465                 return;
 1466         req->Command = TAU32_Configure_E1;
 1467         req->Io.InterfaceConfig.Interface = c->num ? TAU32_E1_B : TAU32_E1_A;
 1468         req->Io.InterfaceConfig.Config = cfg;
 1469         req->Io.InterfaceConfig.UnframedTsMask = c->ts;
 1470         CE_DDK_DEBUG (b, c, ("Submit crc4\n"));
 1471         if (ce_cfg_submit (b)) {
 1472                 c->crc4 = on ? 1 : 0;
 1473                 c->config = cfg;
 1474         }
 1475 }
 1476 
 1477 void ce_set_gsyn (ce_chan_t *c, int syn)
 1478 {
 1479         ce_board_t *b = c->board;
 1480         unsigned int mode;
 1481 
 1482         if (c->num >= b->ddk.Interfaces)
 1483                 return;
 1484         
 1485         if (syn == GSYN_RCV)
 1486                 syn = c->num ? GSYN_RCV1 : GSYN_RCV0;
 1487 
 1488         switch (syn) {
 1489         default:        mode = TAU32_SYNC_INTERNAL;     break;
 1490         case GSYN_RCV0: mode = TAU32_SYNC_RCV_A;        break;
 1491         case GSYN_RCV1: mode = TAU32_SYNC_RCV_B;        break;
 1492         }
 1493 
 1494         CE_DDK_DEBUG (b, c, ("Set Sync Mode\n"));
 1495         if (TAU32_SetSyncMode (b->ddk.pControllerObject, mode)) {
 1496                 b->chan->gsyn = syn;
 1497                 if (b->ddk.Interfaces > 1)
 1498                         (b->chan + 1)->gsyn = syn;
 1499         }
 1500 }
 1501 
 1502 int ce_get_cable (ce_chan_t *c)
 1503 {
 1504         ce_board_t *b = c->board;
 1505         if (c->num >= b->ddk.Interfaces)
 1506                 return 0;
 1507 
 1508         return CABLE_TP;
 1509 }
 1510 
 1511 void ce_set_dir (ce_chan_t *c, int dir)
 1512 {
 1513         ce_board_t *b = c->board;
 1514         unsigned long ts;
 1515         if (b->cr.pending + 1>= CONFREQSZ || c->dir == dir)
 1516                 return;
 1517 
 1518         ts = c->ts;
 1519         ce_set_ts (c, 0);
 1520         c->dir = dir;
 1521         ce_set_ts (c, ts);
 1522 }

Cache object: 34e8bf83b1c2fde9f5848b8d8a3d599f


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