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/chips/tca100_if.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  * Mach Operating System
    3  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        tca100_if.c,v $
   29  * Revision 2.2  93/08/10  15:19:11  mrt
   30  *      Added a switch to turn off error printf's.
   31  *      [93/08/02            cmaeda]
   32  *      Initial check-in.
   33  *      [93/06/09  16:01:11  jcb]
   34  * 
   35  *
   36  */
   37 
   38 /*** TCA 100 ATM NETWORK INTERFACE  ***/
   39 
   40 #ifndef STUB
   41 #include <chips/tca100_if.h>
   42 # else
   43 #include "tca100_if.h"
   44 #endif
   45 
   46 #define SMALL_WINDOW_SIZE (BOM_DATA_SIZE + EOM_DATA_SIZE)
   47 #define INITIAL_WINDOW_SIZE BOM_DATA_SIZE
   48 #define CONTINUATION_WINDOW_SIZE (71 * COM_DATA_SIZE)
   49 #define FINAL_WINDOW_SIZE (70 * COM_DATA_SIZE + EOM_DATA_SIZE)
   50 #define MAX_LONG_RX 2
   51 #define MAX_LONG_TX 5
   52 #define BASE_TIME_OUT 5
   53 #define DELAYED_TIME_OUT 15
   54 #define MAX_RETRY 3
   55 #define POLL_LIMIT 100000
   56 #define POLL_IDLE_TIME 1
   57 #define POLL_CELL_TIME 8
   58 
   59 #define TCA_SYNCH  0xfc00
   60 #define TCA_ACK  (NW_SUCCESS << 10)
   61 #define TCA_NAK  (NW_FAILURE << 10)
   62 #define TCA_OVR  (NW_OVERRUN << 10)
   63 #define TCA_SEQ  (NW_INCONSISTENCY << 10)
   64 
   65 int tca100_verbose = 0;
   66 
   67 int tick[MAX_DEV];
   68 
   69 nw_control_s nw_tx_control[MAX_DEV][MAX_LONG_TX];
   70 nw_control_s nw_rx_control[MAX_DEV][MAX_LONG_RX];
   71 
   72 int long_tx_count[MAX_DEV], long_rx_count[MAX_DEV];
   73 
   74 nw_tx_header_t delayed_tx_first[MAX_DEV], delayed_tx_last[MAX_DEV];
   75 nw_rx_header_t delayed_rx_first[MAX_DEV], delayed_rx_last[MAX_DEV];
   76 
   77 nw_tcb tct[MAX_EP];
   78 
   79 u_int MTU[] = {9244, 65528, 65532, 65528};
   80 u_int MTU_URGENT[] = {32, 28, 32, 28};
   81 
   82 nw_dev_entry_s tca100_entry_table = {
   83   tca100_initialize, tca100_status, spans_timer_sweep, tca100_timer_sweep,
   84   tca100_poll, tca100_send, tca100_rpc, spans_input, spans_open, spans_accept,
   85   spans_close, spans_add, spans_drop};
   86 
   87 typedef enum {
   88   ATM_HEADER,
   89   SAR_HEADER,
   90   SAR_TRAILER,
   91   CS_HEADER,
   92   CS_TRAILER,
   93   FRAME_ERROR,
   94   DELIVERY_ERROR,
   95   SYNCH_ERROR,
   96   SEQ_ERROR,
   97   OVERRUN_ERROR,
   98   RX_RETRANSMISSION,
   99   TX_RETRANSMISSION
  100 } tca_error;
  101 
  102 int tca_ec[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  103 
  104 nw_result tca100_initialize(int dev) {
  105   nw_result rc;
  106   int i;
  107 
  108   rc = spans_initialize(dev);
  109   if (rc = NW_SUCCESS) {
  110     tick[dev] = 0;
  111     for (i = 0; i < MAX_LONG_TX; i++)
  112       nw_tx_control[dev][i].ep = 0;
  113     long_tx_count[dev] = 0;
  114     delayed_tx_first[dev] = delayed_tx_last[dev] = NULL;
  115     for (i = 0; i < MAX_LONG_RX; i++)
  116       nw_rx_control[dev][i].ep = 0;
  117     long_rx_count[dev] = 0;
  118     delayed_rx_first[dev] = delayed_rx_last[dev] = NULL;
  119     for (i = 0; i < MAX_EP; i++) {
  120       tct[i].rx_sar_header = 0;
  121       tct[i].rx_control = NULL;
  122       tct[i].tx_queued_count = 0;
  123       tct[i].tx_control = NULL;
  124     }
  125     rc = NW_SUCCESS;
  126   }
  127   return rc;
  128 }
  129 
  130 nw_result tca100_status(int dev) {
  131   nw_result rc;
  132   atm_device_t atmp;
  133   u_int status;
  134 
  135   atmp = (atm_device_t) devct[dev].addr;
  136   status = atmp->sreg;
  137   if (status & RX_NO_CARRIER) {
  138     atmp->creg_set = CR_RX_RESET;
  139     atmp->creg_clr = ~CR_RX_RESET;
  140     atmp->creg_set = CR_RX_ENABLE;
  141     atmp->sreg = 0;
  142     rc = NW_NO_CARRIER;
  143   } else if (status & RX_CELL_LOST) {
  144     atmp->sreg = RX_COUNT_INTR;
  145     rc = NW_OVERRUN;
  146   } else {
  147     rc = NW_SUCCESS;
  148   }
  149   return rc;
  150 }
  151 
  152 
  153 void tca100_synch_send(int dev, nw_tcb_t tcb, u_int reply) {
  154   vol_u_int *tx_fifo = &((atm_device_t) devct[dev].addr)->txfifo[0];
  155   
  156 #ifdef TRACING
  157   printf("Synch sent %x\n", reply);
  158 #endif
  159 
  160   tx_fifo[0] = tcb->tx_atm_header;
  161   tx_fifo[1] = SSM;
  162   tx_fifo[2] = HTONL(8);
  163   tx_fifo[3] = HTONL(NW_SYNCHRONIZATION);
  164   tx_fifo[4] = htonl(reply);
  165   tx_fifo[5] = HTONL(8);
  166   tx_fifo[6] = 0;
  167   tx_fifo[7] = 0;
  168   tx_fifo[8] = 0;
  169   tx_fifo[9] = 0;
  170   tx_fifo[10] = 0;
  171   tx_fifo[11] = 0;
  172   tx_fifo[12] = 0;
  173   tx_fifo[13] = SYNCH_SEGMENT_TRAILER;
  174 }
  175 
  176 #define broken_cell_mend(length) {    \
  177   missing = length;                                         \
  178   while (missing != 0) {                                    \
  179     if (missing > block_count) {                            \
  180       limit = 0;                                            \
  181       missing -= block_count;                               \
  182     } else {                                                \
  183       limit = block_count - missing;                        \
  184       missing = 0;                                          \
  185     }                                                       \
  186     while (block_count > limit) {                           \
  187       t1 = block[0];                                        \
  188       block++;                                              \
  189       tx_fifo[1] = t1;                                      \
  190       block_count -= 4;                                     \
  191     }                                                       \
  192     if (block_count == 0) {                                 \
  193       ecb->tx_current = tx_header = ecb->tx_current->next;  \
  194       if (tx_header != NULL) {                              \
  195         block_count = tx_header->block_length;              \
  196         block = (vol_u_int *) tx_header->block;             \
  197       }                                                     \
  198     }                                                       \
  199   }                                                         \
  200 }  
  201 
  202 
  203 nw_result tca100_window_send(int dev, nw_ecb_t ecb, nw_tcb_t tcb,
  204                              boolean_t initial) {
  205   nw_result rc;
  206   register vol_u_int *tx_fifo = &((atm_device_t) devct[dev].addr)->txfifo[0];
  207   register vol_u_int *block;
  208   register u_int block_count, msg_count;
  209   register int com_count;
  210   int eom_count;
  211   register u_int atm_header, sar_header, sar_trailer;
  212   u_int cs_header, end_count;
  213   int limit, missing;
  214   register u_int t1, t2;
  215   nw_tx_header_t tx_header;
  216   nw_options options;
  217 
  218   atm_header = tcb->tx_atm_header;
  219   if (initial) {
  220     sar_header = tcb->tx_sar_header & MID;
  221     tx_header = ecb->tx_initial;
  222     block = (vol_u_int *) tx_header->block;
  223     block_count = tx_header->block_length;
  224     options = tx_header->options;
  225     msg_count = tx_header->msg_length;
  226     if (ecb->protocol == NW_LINE)
  227       msg_count += 4;
  228     if (options == NW_URGENT)
  229       msg_count += 4;
  230     cs_header = ecb->protocol | (sar_header & 0xff) << 8 |
  231       (msg_count & 0xff00) << 8 | msg_count << 24;
  232     tcb->tx_cs_header = cs_header;
  233 
  234     if (msg_count <= SSM_DATA_SIZE) {      /*Single segment message*/
  235       tx_fifo[0] = atm_header;
  236       sar_trailer = (msg_count + 8) << 26;
  237       tx_fifo[1] = SSM | sar_header;      /*Sequence number 0 is implicit*/
  238       end_count = msg_count + 4;
  239       tx_fifo[1] = cs_header;
  240       if (options == NW_URGENT) {
  241         tx_fifo[1] = HTONL(NW_URGENT);
  242         msg_count -= 4;
  243       }
  244       if (ecb->protocol == NW_LINE) {
  245         tx_fifo[1] = tx_header->peer.local_ep >> 8 |
  246                      (tx_header->peer.local_ep & 0x00ff) << 8 |
  247                      (tx_header->peer.remote_ep & 0xff00) << 8 |
  248                      tx_header->peer.remote_ep << 24;
  249         msg_count -= 4;
  250       }
  251       if (ecb->protocol == NW_SEQ_PACKET) {
  252         tcb->tx_synch = 0;
  253       } else {
  254         tcb->tx_synch = -1;
  255       }
  256       goto EOM_payload;
  257       
  258     } else {                              /*Beginning of message*/
  259       tx_fifo[0] = atm_header;
  260       sar_trailer = FULL_SEGMENT_TRAILER;
  261       tx_fifo[1] = BOM | sar_header;      /*Sequence number 0 is implicit*/
  262       tx_fifo[2] = cs_header;
  263       if (block_count < BOM_DATA_SIZE) {
  264         if (ecb->protocol == NW_LINE) {
  265           t1 = tx_header->peer.local_ep >> 8 |
  266                (tx_header->peer.local_ep & 0x00ff) << 8 |
  267                (tx_header->peer.remote_ep & 0xff00) << 8 |
  268                tx_header->peer.remote_ep << 24;
  269           missing = BOM_DATA_SIZE - 4;
  270           tx_fifo[3] = t1;
  271         } else {
  272           missing = BOM_DATA_SIZE;
  273         }
  274         broken_cell_mend(missing);
  275       } else {
  276         if (ecb->protocol == NW_LINE) {
  277           t1 = tx_header->peer.local_ep >> 8 |
  278                (tx_header->peer.local_ep & 0x00ff) << 8 |
  279                (tx_header->peer.remote_ep & 0xff00) << 8 |
  280                tx_header->peer.remote_ep << 24;
  281         } else {
  282           t1 = block[0];
  283           block_count -= 4;
  284           block++;
  285         }
  286         t2 = block[0];
  287         tx_fifo[3] = t1;
  288         tx_fifo[4] = t2;
  289         t1 = block[1];
  290         t2 = block[2];
  291         tx_fifo[5] = t1;
  292         tx_fifo[6] = t2;
  293         t1 = block[3];
  294         t2 = block[4];
  295         tx_fifo[7] = t1;
  296         tx_fifo[8] = t2;
  297         t1 = block[5];
  298         t2 = block[6];
  299         tx_fifo[9] = t1;
  300         tx_fifo[10] = t2;
  301         t1 = block[7];
  302         t2 = block[8];
  303         tx_fifo[11] = t1;
  304         tx_fifo[12] = t2;
  305         block_count -= (BOM_DATA_SIZE - 4);
  306         block += 9;
  307       }
  308       if (ecb->protocol == NW_RAW) {
  309         msg_count -= BOM_DATA_SIZE;
  310         com_count = msg_count / COM_DATA_SIZE;
  311         msg_count = msg_count % COM_DATA_SIZE;
  312         eom_count = 1;
  313         tcb->tx_synch = -1;
  314       } else if (msg_count > SMALL_WINDOW_SIZE) {
  315         com_count = eom_count = 0;
  316         tcb->tx_synch = msg_count;
  317         msg_count -= BOM_DATA_SIZE;       
  318       } else {
  319         com_count = 0;
  320         eom_count = 1;
  321         if (ecb->protocol == NW_SEQ_PACKET) {
  322           tcb->tx_synch = 0;
  323         } else {
  324           tcb->tx_synch = -1;
  325         }
  326         msg_count -= BOM_DATA_SIZE;       
  327       }
  328       tx_fifo[13] = sar_trailer;
  329       sar_header += SEQ_INC;
  330     }
  331 
  332   } else {
  333     sar_header = tcb->tx_sar_header;
  334     sar_trailer = FULL_SEGMENT_TRAILER;
  335     block = (vol_u_int *) tcb->tx_p;
  336     block_count = tcb->tx_block_count;
  337     msg_count = tcb->tx_msg_count;
  338     if (msg_count > FINAL_WINDOW_SIZE) {
  339       com_count = (CONTINUATION_WINDOW_SIZE / COM_DATA_SIZE);
  340       eom_count = 0;
  341       tcb->tx_synch = msg_count;
  342       msg_count -= CONTINUATION_WINDOW_SIZE;
  343     } else {
  344       com_count = msg_count / COM_DATA_SIZE;
  345       msg_count = msg_count % COM_DATA_SIZE;
  346       eom_count = 1;
  347       if (ecb->protocol == NW_SEQ_PACKET) {
  348         tcb->tx_synch = 0;
  349       } else {
  350         tcb->tx_synch = -1;
  351       }
  352     }
  353   }
  354 
  355   while (com_count-- > 0) {                 /*Continuation of message*/
  356     tx_fifo[0] = atm_header;
  357     tx_fifo[1] = sar_header;               /*COM is 0 and is implicit*/
  358     if (block_count >= COM_DATA_SIZE) {
  359       t1 = block[0];
  360       t2 = block[1];
  361       tx_fifo[2] = t1;
  362       tx_fifo[3] = t2;
  363       t1 = block[2];
  364       t2 = block[3];
  365       tx_fifo[4] = t1;
  366       tx_fifo[5] = t2;
  367       t1 = block[4];
  368       t2 = block[5];
  369       tx_fifo[6] = t1;
  370       tx_fifo[7] = t2;
  371       t1 = block[6];
  372       t2 = block[7];
  373       tx_fifo[8] = t1;
  374       tx_fifo[9] = t2;
  375       t1 = block[8];
  376       t2 = block[9];
  377       tx_fifo[10] = t1;
  378       tx_fifo[11] = t2;
  379       t1 = block[10];
  380       block_count -= COM_DATA_SIZE;
  381       tx_fifo[12] = t1;
  382       tx_fifo[13] = sar_trailer;
  383       block += 11;
  384       sar_header = (sar_header + SEQ_INC) & (SEQ_NO | MID);
  385     } else {
  386       broken_cell_mend(COM_DATA_SIZE);
  387       tx_fifo[13] = sar_trailer;
  388       sar_header = (sar_header + SEQ_INC) & (SEQ_NO | MID);
  389     }
  390   }
  391 
  392   if (eom_count != 0) {                               /*End of message*/
  393     tx_fifo[0] = atm_header;
  394     tx_fifo[1] = EOM | sar_header;
  395     end_count = msg_count;
  396     sar_trailer = (msg_count + 4) << 26;
  397 
  398  EOM_payload:
  399     if (block_count >= msg_count) {
  400       if (msg_count & 0x4) {
  401         t1 = block[0];
  402         tx_fifo[1] = t1;
  403       }
  404       block = (vol_u_int *) ((char *) block + msg_count);
  405       switch (msg_count >> 3) {
  406       case 5:
  407         t1 = block[-10];
  408         t2 = block[-9];
  409         tx_fifo[1] = t1;
  410         tx_fifo[1] = t2;
  411       case 4:
  412         t1 = block[-8];
  413         t2 = block[-7];
  414         tx_fifo[1] = t1;
  415         tx_fifo[1] = t2;
  416       case 3:
  417         t1 = block[-6];
  418         t2 = block[-5];
  419         tx_fifo[1] = t1;
  420         tx_fifo[1] = t2;
  421       case 2:
  422         t1 = block[-4];
  423         t2 = block[-3];
  424         tx_fifo[1] = t1;
  425         tx_fifo[1] = t2;
  426       case 1:
  427         t1 = block[-2];
  428         t2 = block[-1];
  429         tx_fifo[1] = t1;
  430         tx_fifo[1] = t2;
  431       }
  432       msg_count = 0;
  433     } else {
  434       broken_cell_mend(msg_count);
  435       msg_count = 0;
  436     }
  437 
  438   EOM_cs_trailer:
  439     tx_fifo[1] = tcb->tx_cs_header;
  440     switch (end_count) {
  441     case 0: tx_fifo[1] = 0;
  442     case 4: tx_fifo[1] = 0;
  443     case 8: tx_fifo[1] = 0;
  444     case 12: tx_fifo[1] = 0;
  445     case 16: tx_fifo[1] = 0;
  446     case 20: tx_fifo[1] = 0;
  447     case 24: tx_fifo[1] = 0;
  448     case 28: tx_fifo[1] = 0;
  449     case 32: tx_fifo[1] = 0;
  450     case 36: tx_fifo[1] = 0;
  451     }
  452     tx_fifo[13] = sar_trailer;
  453   }
  454 
  455   if (tcb->tx_synch == -1) { 
  456 
  457 #ifdef TRACING
  458     printf("Final window sent\n");
  459 #endif
  460 
  461     sar_header = (sar_header + MID_INC) & MID;
  462     if (sar_header == 0)
  463       sar_header = 1;
  464     tcb->tx_sar_header = sar_header;
  465     rc = NW_SUCCESS;
  466   } else {
  467 
  468 #ifdef TRACING
  469     printf("Window synch at %x\n", msg_count);
  470 #endif
  471 
  472     tcb->tx_sar_header = sar_header;
  473     tcb->tx_p = (u_int *) block;
  474     tcb->tx_block_count = block_count;
  475     tcb->tx_msg_count = msg_count;
  476     rc = NW_SYNCH;
  477   }
  478   return rc;
  479 }
  480 
  481 nw_result tca100_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
  482   nw_result rc;
  483   int i, dev;
  484   nw_ecb_t ecb;
  485   nw_tcb_t tcb;
  486   nw_control_t control;
  487   nw_tx_header_t tx_header, tx_previous;
  488 
  489   dev = NW_DEVICE(header->peer.rem_addr_1);
  490   ecb = &ect[ep];
  491   tcb = &tct[ep];
  492   if ((options == NW_URGENT && header->msg_length >
  493        MTU_URGENT[ecb->protocol]) || header->msg_length > MTU[ecb->protocol]) {
  494     rc = NW_BAD_LENGTH;
  495   } else if (tcb->tx_queued_count != 0 ||
  496              (ecb->protocol != NW_RAW &&
  497               long_tx_count[dev] >= MAX_LONG_TX &&
  498               (header->msg_length > SMALL_WINDOW_SIZE ||
  499                ecb->protocol == NW_SEQ_PACKET))) {
  500     if (options == NW_URGENT && tcb->tx_queued_count != 0) {
  501       tx_header = delayed_tx_first[dev];
  502       tx_previous = NULL;
  503       while (tx_header != NULL && tx_header->sender != ep) {
  504         tx_previous = tx_header;
  505         tx_header = tx_header->next;
  506       }
  507       if (tx_previous == NULL) 
  508         delayed_tx_first[dev] = header;
  509       else 
  510         tx_previous->next = header;
  511       while (header->next != NULL)
  512         header = header->next;
  513       header->next = tx_header;
  514     } else {
  515       if (delayed_tx_first[dev] == NULL)
  516         delayed_tx_first[dev] = header;
  517       else
  518         delayed_tx_last[dev]->next = header;
  519       delayed_tx_last[dev] = header;
  520     }
  521     tcb->tx_queued_count++;
  522     rc = NW_QUEUED;
  523 
  524 #ifdef TRACING
  525     printf("Send enqueued ep %d\n", ep);
  526 #endif
  527     
  528   } else {
  529 
  530 
  531 #ifdef TRACING
  532     printf("Send ep %d\n", ep);
  533 #endif
  534 
  535     ecb->tx_initial = ecb->tx_current = header;
  536     rc = tca100_window_send(dev, ecb, tcb, TRUE);
  537     if (rc == NW_SUCCESS) {
  538       while (header != NULL) {
  539         if (header->buffer != NULL)
  540           nc_buffer_deallocate(ep, header->buffer);
  541         header = header->next;
  542       }
  543       nc_tx_header_deallocate(ecb->tx_initial);
  544       ecb->tx_initial = ecb->tx_current = NULL;
  545     } else {
  546       control = &nw_tx_control[dev][0];
  547       while (control->ep != 0) 
  548         control++; 
  549       control->ep = ep;
  550       control->time_out = tick[dev] + BASE_TIME_OUT;
  551       control->retry = 0;
  552       tcb->reply = TCA_SYNCH;
  553       tcb->tx_control = control;
  554       tcb->tx_queued_count++;
  555       if (long_tx_count[dev] + long_rx_count[dev] == 0)
  556         nc_fast_timer_set(dev);
  557       long_tx_count[dev]++;
  558     }
  559   }
  560   return rc;
  561 }
  562 
  563 
  564 nw_result tx_slot_free(int dev, nw_control_t control) {
  565   nw_result rc;
  566   nw_tcb_t tcb;
  567   nw_ecb_t ecb;
  568   nw_tx_header_t tx_header;
  569   nw_ep ep;
  570 
  571   tcb = &tct[control->ep];
  572   tcb->tx_control = NULL;                               
  573   tcb->tx_queued_count--;                             
  574   do {                                                            
  575     tx_header = delayed_tx_first[dev];                            
  576     if (tx_header == NULL) {                                      
  577       control->ep = 0;                                            
  578       long_tx_count[dev]--;                                       
  579       rc = NW_FAILURE;                                            
  580     } else {
  581       ep = tx_header->sender;
  582 
  583 #ifdef TRACING
  584     printf("Send dequeued ep %d\n", ep);
  585 #endif
  586 
  587       ecb = &ect[ep];
  588       tcb = &tct[ep];
  589       ecb->tx_initial = ecb->tx_current =  tx_header;
  590       while (tx_header->next != NULL &&                           
  591              tx_header->next->msg_length == 0) {                  
  592         tx_header = tx_header->next;                              
  593       }                                                         
  594       delayed_tx_first[dev] = tx_header->next;                    
  595       if (tx_header->next == NULL)                                
  596         delayed_tx_last[dev] = NULL;                              
  597       tx_header->next = NULL;                                     
  598       rc = tca100_window_send(dev, ecb, tcb, TRUE); 
  599       if (rc == NW_SYNCH) {                                         
  600         control->ep = ep;                            
  601         tcb->tx_control = control;                
  602         tcb->reply = TCA_SYNCH;                                 
  603         control->time_out = tick[dev] + BASE_TIME_OUT;              
  604         control->retry = 0;                                         
  605       }                                                             
  606     }                                                               
  607   } while (rc == NW_SUCCESS);                                       
  608   return rc;
  609 }
  610 
  611 nw_result rx_slot_free(int dev, nw_control_t control) {
  612   nw_result rc;
  613   nw_rx_header_t rx_header;
  614   nw_ep ep;
  615   nw_tcb_t tcb;
  616 
  617   if (control == NULL) {   
  618     rc = NW_SUCCESS;
  619   } else {
  620     tct[control->ep].rx_control = NULL;                               
  621     while ((rx_header = delayed_rx_first[dev]) != NULL &&             
  622            tick[dev] >= rx_header->time_stamp) {                      
  623       delayed_rx_first[dev] = rx_header->next;                        
  624       nc_buffer_deallocate(rx_header->buffer->peer.local_ep,          
  625                            rx_header->buffer);                        
  626       ep = rx_header->receiver;
  627       tcb = &tct[ep];
  628       tcb->rx_sar_header = SSM | (tcb->rx_sar_header & MID);         
  629       nc_rx_header_deallocate(rx_header);                             
  630     }                                                                 
  631     if (rx_header == NULL) {                                          
  632       delayed_rx_last[dev] = NULL;                                    
  633       control->ep = 0;                                                
  634       long_rx_count[dev]--;                                           
  635       rc = NW_FAILURE;
  636     } else {                                                          
  637       delayed_rx_first[dev] = rx_header->next;                        
  638       if (rx_header->next == NULL)                                    
  639         delayed_rx_last[dev] = NULL;                                  
  640       ep = rx_header->receiver;
  641       tcb = &tct[ep];
  642       tca100_synch_send(dev, tcb, rx_header->reply);
  643       control->ep = ep;
  644       control->time_out = tick[dev] + BASE_TIME_OUT;                  
  645       tcb->rx_control = control;                  
  646       nc_rx_header_deallocate(rx_header);                             
  647     }                                                                 
  648   }
  649 }
  650 
  651 
  652 int tca100_poll(int dev) {
  653   vol_u_int *status = &((atm_device_t) devct[dev].addr)->sreg;
  654   vol_u_int *ctl_set = &((atm_device_t) devct[dev].addr)->creg_set;
  655   vol_u_int *rx_counter = &((atm_device_t) devct[dev].addr)->rxcount;
  656   register vol_u_int *rx_fifo = &((atm_device_t) devct[dev].addr)->rxfifo[0];
  657   register u_int rx_cell_count;
  658   register u_int predicted_atm_header = 0;
  659   register u_int predicted_sar_header;
  660   u_int atm_header, sar_header, predicted_sar_trailer,
  661         cs_header, end_count, cs_pad, rx_cell_total, reply,
  662         block_length, initial_offset;
  663   register vol_u_int *msg;
  664   register int msg_count;
  665   register int next_synch;
  666   register u_int t1, t2;
  667   nw_ecb_t ecb, tx_ecb;
  668   nw_tcb_t new_tcb, tx_tcb;
  669   nw_tcb dummy_tcb_s;
  670   nw_tcb_t tcb = &dummy_tcb_s;
  671   nw_control_t control;
  672   nw_buffer_t buffer;
  673   nw_protocol protocol;
  674   nw_ep lep, rep;
  675   nw_delivery delivery_type = NW_RECEIVE;
  676   nw_rx_header_t rx_header;
  677   nw_tx_header_t tx_header;
  678   int i;
  679   u_int tx_seqno, rx_seqno, tx_count, rx_count;
  680 
  681   rx_cell_total = 0;
  682   while ((rx_cell_count = *rx_counter & RX_COUNTER_MASK) != 0) {
  683     rx_cell_total += rx_cell_count;
  684     while (rx_cell_count-- > 0) {
  685       atm_header = rx_fifo[0];         /*Check ATM header and SAR header*/
  686       sar_header = (rx_fifo[1] & SAR_HEADER_MASK);
  687       if (atm_header != predicted_atm_header) {
  688                               /*Must be cell from a different connection*/
  689         if (atm_header & ~(ATM_VPVC_MASK | ATM_HEADER_RSV_BITS)) {
  690  atm_header_error:
  691           tca_ec[ATM_HEADER]++;
  692           if (tca100_verbose)
  693                   printf("ATM header error %x\n", atm_header);
  694  discard_cell:
  695           *((char *) rx_fifo) = 0; 
  696           delivery_type = NW_RECEIVE;
  697           continue;
  698         } else {
  699           t1 = (atm_header & ATM_VPVC_MASK) >> ATM_VPVC_SHIFT;
  700           new_tcb = &tct[t1];
  701           ecb = &ect[t1];
  702 
  703           /*Switch cached connection*/
  704           if (new_tcb->rx_sar_header == 0)
  705             goto atm_header_error;
  706           tcb->rx_sar_header = predicted_sar_header;
  707           tcb->rx_p = (u_int *) msg;
  708           tcb->rx_count = msg_count;
  709           tcb->rx_next_synch = next_synch;
  710           predicted_atm_header = atm_header;
  711           tcb = new_tcb;
  712           predicted_sar_header = tcb->rx_sar_header;
  713           msg = tcb->rx_p;
  714           msg_count = tcb->rx_count;
  715           next_synch = tcb->rx_next_synch;
  716         }
  717       }
  718       
  719       if (sar_header != predicted_sar_header) {
  720         if ((sar_header ^ predicted_sar_header) == EOM &&
  721             ((predicted_sar_header & BOM) || msg_count <= EOM_DATA_SIZE)) {
  722                                     /*Difference on end of message bit only*/
  723           predicted_sar_header = sar_header;
  724         } else if (sar_header == SSM) {                             /*MID 0*/
  725           cs_header = rx_fifo[2];
  726           t1 = rx_fifo[3];
  727           if (cs_header == HTONL(8) && t1 == HTONL(NW_SYNCHRONIZATION)) {
  728             reply = rx_fifo[4];                                /*Synch cell*/
  729             if (rx_fifo[5] != cs_header)
  730               goto cs_header_error;
  731             cs_pad = rx_fifo[6];
  732             t1 = rx_fifo[7];
  733             t2 = rx_fifo[8];
  734             cs_pad |= t1;
  735             cs_pad |= t2;
  736             t1 = rx_fifo[9];
  737             t2 = rx_fifo[10];
  738             cs_pad |= t1;
  739             cs_pad |= t2;
  740             t1 = rx_fifo[11];
  741             t2 = rx_fifo[12];
  742             cs_pad |= t1;
  743             cs_pad |= t2;
  744             t1 = rx_fifo[13];
  745             if (cs_pad)
  746               goto cs_trailer_error;
  747             if ((t1 & SAR_TRAILER_MASK) != SYNCH_SEGMENT_TRAILER)
  748               goto sar_trailer_error;
  749             if (tcb->tx_control == NULL) {
  750               tca_ec[SYNCH_ERROR]++;
  751               if (tca100_verbose)
  752                       printf("Synch error %x\n", ntohl(reply));
  753             } else {
  754               tcb->reply = ntohl(reply);
  755 
  756 #ifdef TRACING
  757               printf("Received synch ep %d %x\n", ecb->id, tcb->reply);
  758 #endif
  759 
  760             }
  761             continue;
  762           } else if (t1 == HTONL(NW_URGENT)) {              /*Urgent cell*/
  763             delivery_type = NW_RECEIVE_URGENT;
  764             goto cs_header_check;
  765           } else {                                          /*Bad segment*/
  766             goto sar_header_error;
  767           }
  768         } else if (!(sar_header & ATM_HEADER_CRC_SYNDROME) &&
  769                    (sar_header & BOM) && (sar_header & SEQ_NO) == 0) {
  770           if ((sar_header & MID) == (predicted_sar_header & MID)) {
  771                                                          /*Retransmission*/
  772             if (tcb->rx_control != NULL) {
  773               tcb->rx_control->ep = 0;
  774               long_rx_count[dev]--;
  775             }
  776             nc_buffer_deallocate(tcb->rx_buffer->peer.local_ep,
  777                                  tcb->rx_buffer);
  778             predicted_sar_header = sar_header;
  779             tca_ec[RX_RETRANSMISSION]++;
  780             if (tca100_verbose)
  781                     printf("Receiving retransmission ep %d sar %x\n",
  782                            ecb->id, sar_header); 
  783           } else if (predicted_sar_header & BOM) {
  784                                                     /*Sequence number error*/
  785             if (tca100_verbose)
  786                     printf("Sequence error ep %d pred %x real %x\n", ecb->id,
  787                            predicted_sar_header, sar_header);
  788             if (ecb->protocol == NW_SEQ_PACKET) {
  789               reply = 0xffff0000 | TCA_SEQ | (predicted_sar_header & MID);
  790               tca100_synch_send(dev, tcb, reply);
  791               tca_ec[SEQ_ERROR]++;
  792               goto discard_cell;
  793             } else {
  794               predicted_sar_header = sar_header;
  795             }
  796           } else {
  797             goto sar_header_error;                     /*Badly out of synch*/
  798           }
  799         } else {                                                /*Cell loss*/
  800 
  801  sar_header_error:
  802           if (!(predicted_sar_header & BOM)) {
  803             rx_slot_free(dev, tcb->rx_control);
  804             nc_buffer_deallocate(tcb->rx_buffer->peer.local_ep,
  805                                  tcb->rx_buffer);
  806             predicted_sar_header = SSM | (predicted_sar_header & MID);
  807           }
  808           tca_ec[SAR_HEADER]++;
  809           if (tca100_verbose)
  810                   printf("SAR header error ep %d pred %x real %x\n", ecb->id,
  811                          predicted_sar_header, sar_header);
  812           goto discard_cell;
  813         }  
  814       }
  815 
  816       if ((predicted_sar_header & SEG_TYPE) == COM) { 
  817                                                    /*Continuation of message*/
  818         if (msg_count <= next_synch) {
  819           if (msg_count == next_synch &&
  820               msg_count >= CONTINUATION_WINDOW_SIZE) {
  821             reply = (msg_count << 16) | TCA_ACK | (predicted_sar_header & MID);
  822             tca100_synch_send(dev, tcb, reply);
  823             if (msg_count > (CONTINUATION_WINDOW_SIZE + FINAL_WINDOW_SIZE)) {
  824               next_synch = msg_count - CONTINUATION_WINDOW_SIZE;
  825             } else if (ecb->protocol == NW_SEQ_PACKET) {
  826               next_synch = 0;
  827             } else {
  828               next_synch = -1;
  829             }
  830             tcb->rx_control->time_out = tick[dev] + BASE_TIME_OUT;
  831           } else {
  832             rx_slot_free(dev, tcb->rx_control);
  833             nc_buffer_deallocate(tcb->rx_buffer->peer.local_ep,
  834                                  tcb->rx_buffer);
  835             predicted_sar_header = SSM | (predicted_sar_header & MID);
  836             tca_ec[FRAME_ERROR]++;
  837             if (tca100_verbose)
  838                     printf("Frame error ep %d\n", ecb->id);
  839             goto discard_cell;
  840           }
  841         }
  842         t1 = rx_fifo[2];
  843         t2 = rx_fifo[3];
  844         msg[0] = t1;
  845         msg[1] = t2;
  846         t1 = rx_fifo[4];
  847         t2 = rx_fifo[5];
  848         msg[2] = t1;
  849         msg[3] = t2;
  850         t1 = rx_fifo[6];
  851         t2 = rx_fifo[7];
  852         msg[4] = t1;
  853         msg[5] = t2;
  854         t1 = rx_fifo[8];
  855         t2 = rx_fifo[9];
  856         msg[6] = t1;
  857         msg[7] = t2;
  858         t1 = rx_fifo[10];
  859         t2 = rx_fifo[11];
  860         msg[8] = t1;
  861         msg[9] = t2;
  862         t1 = rx_fifo[12];
  863         t2 = rx_fifo[13];
  864         msg[10] = t1;
  865         if ((t2 & SAR_TRAILER_MASK) != FULL_SEGMENT_TRAILER) {
  866           t1 = t2;
  867           goto sar_trailer_error;
  868         }
  869         predicted_sar_header = (predicted_sar_header + SEQ_INC) &
  870                                                             (SEQ_NO | MID);
  871         msg_count -= COM_DATA_SIZE;
  872         msg += 11;
  873 
  874       } else if ((predicted_sar_header & BOM) != 0) {
  875         cs_header = rx_fifo[2];
  876 
  877  cs_header_check:
  878         block_length = msg_count = (((cs_header >> 8) & 0xff00) |
  879                                     (cs_header >> 24));
  880         protocol = cs_header & 0x00ff;
  881         if (protocol == NW_RAW || protocol == NW_SEQ_PACKET) {
  882           lep = ecb->conn->peer.local_ep;
  883           rep = ecb->conn->peer.remote_ep;
  884           if (delivery_type == NW_RECEIVE)
  885             initial_offset = 0;
  886           else
  887             initial_offset = 4;
  888         } else {
  889           t1 = rx_fifo[3];
  890           block_length -= 4;
  891           lep = (t1 >> 8) & 0xff00 | t1 >> 24;
  892           rep = (t1 & 0xff00) >> 8 | (t1 & 0x00ff) << 8;
  893           if (delivery_type == NW_RECEIVE)
  894             initial_offset = 4;
  895           else
  896             initial_offset = 8;
  897         } 
  898         if (protocol != ecb->protocol || (protocol == NW_DATAGRAM) ||
  899             (protocol == NW_LINE && ect[lep].protocol != NW_DATAGRAM) ||
  900             ((predicted_sar_header & 0x00ff) << 8) != (cs_header & 0xff00) ||
  901             ((delivery_type != NW_RECEIVE) &&
  902              msg_count - initial_offset > MTU_URGENT[protocol]) ||
  903             msg_count > MTU[protocol] || (msg_count & 0x3)) {
  904 
  905  cs_header_error:
  906           if ((protocol != NW_RAW && msg_count > SMALL_WINDOW_SIZE) ||
  907               protocol == NW_SEQ_PACKET) {
  908             reply = 0xffff0000 | TCA_NAK | (predicted_sar_header & MID);
  909             tca100_synch_send(dev, tcb, reply);
  910           }
  911           tca_ec[CS_HEADER]++;
  912           if (tca100_verbose)
  913                   printf("CS header error ep %d sar %x cs %x\n", ecb->id,
  914                          predicted_sar_header, cs_header);
  915           goto discard_cell;
  916         }
  917         buffer = nc_buffer_allocate(lep, sizeof(nw_buffer_s) + block_length);
  918         if (buffer == NULL) {
  919           if ((protocol != NW_RAW && msg_count > SMALL_WINDOW_SIZE) ||
  920               protocol == NW_SEQ_PACKET) {
  921             reply = 0xffff0000 | TCA_OVR | (predicted_sar_header & MID);
  922             tca100_synch_send(dev, tcb, reply);
  923           }
  924           tca_ec[OVERRUN_ERROR]++;
  925           if (tca100_verbose)
  926                   printf("Overrun error ep %d\n", ecb->id);
  927           goto discard_cell;
  928         }
  929         if (protocol == NW_RAW) {
  930           next_synch = -1;
  931         } else if (msg_count > SMALL_WINDOW_SIZE) {
  932           reply = (msg_count << 16) | TCA_ACK | (predicted_sar_header & MID);
  933           if (long_rx_count[dev] >= MAX_LONG_RX) {
  934             rx_header = nc_rx_header_allocate();
  935             if (rx_header == NULL) {
  936               nc_buffer_deallocate(lep, buffer);
  937               tca_ec[OVERRUN_ERROR]++;
  938               goto discard_cell;
  939             }
  940             rx_header->buffer = buffer;
  941             rx_header->receiver = ecb->id;
  942             rx_header->reply = reply;
  943             rx_header->time_stamp = tick[dev] + DELAYED_TIME_OUT;
  944             rx_header->next = NULL;
  945             if (delayed_rx_last[dev] == NULL)
  946               delayed_rx_first[dev] = rx_header;
  947             else
  948               delayed_rx_last[dev]->next = rx_header;
  949             delayed_rx_last[dev] = rx_header;
  950           } else {
  951             tca100_synch_send(dev, tcb, reply);
  952             control = &nw_rx_control[dev][0];
  953             while (control->ep != 0)
  954               control++;
  955             control->ep = ecb->id;
  956             control->time_out = tick[dev] + BASE_TIME_OUT;
  957             tcb->rx_control = control;
  958             if (long_rx_count[dev] + long_tx_count[dev] == 0)
  959               nc_fast_timer_set(dev);
  960             long_rx_count[dev]++;
  961           }
  962           if (msg_count > INITIAL_WINDOW_SIZE + FINAL_WINDOW_SIZE)
  963             next_synch = msg_count - INITIAL_WINDOW_SIZE;
  964           else if (protocol == NW_SEQ_PACKET)
  965             next_synch = 0;
  966           else
  967             next_synch = -1;
  968         } else if (protocol == NW_SEQ_PACKET) {
  969           next_synch = 0;
  970         } else {
  971           next_synch = -1;
  972         }
  973         msg = (vol_u_int *) ((char *) buffer + sizeof(nw_buffer_s));
  974         tcb->rx_cs_header = cs_header;
  975         tcb->rx_buffer = buffer;
  976         buffer->buf_next = NULL;
  977         buffer->msg_seqno = sar_header & MID;
  978         buffer->block_offset = sizeof(nw_buffer_s);
  979         buffer->block_length = block_length;
  980         buffer->peer.rem_addr_1 = ecb->conn->peer.rem_addr_1;
  981         buffer->peer.rem_addr_2 = ecb->conn->peer.rem_addr_2;
  982         buffer->peer.local_ep = lep;
  983         buffer->peer.remote_ep = rep;
  984 
  985         if ((predicted_sar_header & EOM) == 0) {                  /*BOM*/
  986           if (initial_offset == 0) {
  987             t1 = rx_fifo[3];
  988             t2 = rx_fifo[4];
  989             msg[0] = t1;
  990             msg[1] = t2;
  991             msg += 2;
  992           } else {
  993             msg[0] = rx_fifo[4];
  994             msg++;
  995           }
  996           t1 = rx_fifo[5];
  997           t2 = rx_fifo[6];
  998           msg[0] = t1;
  999           msg[1] = t2;
 1000           t1 = rx_fifo[7];
 1001           t2 = rx_fifo[8];
 1002           msg[2] = t1;
 1003           msg[3] = t2;
 1004           t1 = rx_fifo[9];
 1005           t2 = rx_fifo[10];
 1006           msg[4] = t1;
 1007           msg[5] = t2;
 1008           t1 = rx_fifo[11];
 1009           t2 = rx_fifo[12];
 1010           msg[6] = t1;
 1011           t1 = rx_fifo[13];
 1012           msg[7] = t2;
 1013           if ((t1 & SAR_TRAILER_MASK) != FULL_SEGMENT_TRAILER)
 1014             goto sar_trailer_error;
 1015           msg_count -= BOM_DATA_SIZE;
 1016           msg += 8;
 1017           predicted_sar_header = (predicted_sar_header + SEQ_INC) &
 1018                                                           (SEQ_NO | MID);
 1019 
 1020         } else {                                                  /*SSM*/
 1021           end_count = msg_count + 4;
 1022           predicted_sar_trailer = (msg_count + 8) << 26;
 1023           if (delivery_type != NW_RECEIVE) {
 1024             msg[0] = NW_URGENT;
 1025             msg++;
 1026           }
 1027           msg_count -= initial_offset;
 1028           goto EOM_payload;
 1029         }
 1030       } else {                                                    /*EOM*/
 1031         end_count = msg_count;
 1032         predicted_sar_trailer = (msg_count + 4) << 26;
 1033         
 1034  EOM_payload:
 1035         if (msg_count & 0x4) {
 1036           msg[0] = rx_fifo[2];
 1037         }
 1038         msg = (vol_u_int *) ((char *) msg + msg_count);
 1039         /*Fall-through the cases is intentional*/
 1040         switch (msg_count >> 3) {
 1041         case 5:
 1042           t1 = rx_fifo[2];
 1043           t2 = rx_fifo[2];
 1044           msg[-10] = t1;
 1045           msg[-9] = t2;
 1046         case 4:
 1047           t1 = rx_fifo[2];
 1048           t2 = rx_fifo[2];
 1049           msg[-8] = t1;
 1050           msg[-7] = t2;
 1051         case 3:
 1052           t1 = rx_fifo[2];
 1053           t2 = rx_fifo[2];
 1054           msg[-6] = t1;
 1055           msg[-5] = t2;
 1056         case 2:
 1057           t1 = rx_fifo[2];
 1058           t2 = rx_fifo[2];
 1059           msg[-4] = t1;
 1060           msg[-3] = t2;
 1061         case 1:
 1062           t1 = rx_fifo[2];
 1063           t2 = rx_fifo[2];
 1064           msg[-2] = t1;
 1065           msg[-1] = t2;
 1066         }
 1067 
 1068         /*CS trailer should be equal to the CS header, followed by
 1069           padding zeros*/
 1070         cs_pad = (rx_fifo[2] != tcb->rx_cs_header);
 1071         /*Fall-through the cases is intentional*/
 1072         t1 = t2 = 0;
 1073         switch (end_count) {
 1074         case 0:
 1075           t1 = rx_fifo[2];
 1076         case 4:
 1077           t2 = rx_fifo[2];
 1078           cs_pad |= t1;
 1079         case 8:
 1080           t1 = rx_fifo[2];
 1081           cs_pad |= t2;
 1082         case 12:
 1083           t2 = rx_fifo[2];
 1084           cs_pad |= t1;
 1085         case 16:
 1086           t1 = rx_fifo[2];
 1087           cs_pad |= t2;
 1088         case 20:
 1089           t2 = rx_fifo[2];
 1090           cs_pad |= t1;
 1091         case 24:
 1092           t1 = rx_fifo[2];
 1093           cs_pad |= t2;
 1094         case 28:
 1095           t2 = rx_fifo[2];
 1096           cs_pad |= t1;
 1097         case 32:
 1098           t1 = rx_fifo[2];
 1099           cs_pad |= t2;
 1100         case 36:
 1101           t2 = rx_fifo[2];
 1102           cs_pad |= t1;
 1103           cs_pad |= t2;
 1104         }
 1105         t1 = rx_fifo[13];
 1106         if (cs_pad != 0) {
 1107                                              /*Errors in CS trailer or pad*/
 1108  cs_trailer_error:
 1109           tca_ec[CS_TRAILER]++;
 1110           if (tca100_verbose)
 1111                   printf("CS trailer error ep %d hd %x pad %x\n", ecb->id,
 1112                          tcb->rx_cs_header, cs_pad);
 1113           goto trailer_error;
 1114 
 1115         } else if ((t1 & SAR_TRAILER_MASK) != predicted_sar_trailer) {
 1116                                          /*Error in SAR trailer or framing*/
 1117  sar_trailer_error:
 1118           tca_ec[SAR_TRAILER]++;
 1119           if (tca100_verbose)
 1120                   printf("SAR trailer error ep %d pred %x real %x\n", ecb->id,
 1121                          predicted_sar_trailer, t1);
 1122           goto trailer_error;
 1123 
 1124         } else if (!nc_deliver_result(tcb->rx_buffer->peer.local_ep,
 1125                                       delivery_type, (int) tcb->rx_buffer)) {
 1126           tca_ec[DELIVERY_ERROR]++;
 1127           if (tca100_verbose)
 1128                   printf("Delivery error ep %d\n", ecb->id);
 1129 
 1130  trailer_error:
 1131           if (next_synch >= 0 && !(t1 & HEADER_CRC_ERROR)) {
 1132             reply = (msg_count << 16) | TCA_NAK | (predicted_sar_header & MID);
 1133             tca100_synch_send(dev, tcb, reply);
 1134           }
 1135           rx_slot_free(dev, tcb->rx_control);
 1136           nc_buffer_deallocate(tcb->rx_buffer->peer.local_ep,
 1137                                tcb->rx_buffer);
 1138           predicted_sar_header = SSM | (predicted_sar_header & MID);
 1139           delivery_type = NW_RECEIVE;
 1140         } else {
 1141 
 1142 #ifdef TRACING
 1143           printf("Received correctly ep %d\n", ecb->id);
 1144 #endif
 1145 
 1146           if (next_synch == 0) {
 1147             reply = TCA_ACK | (predicted_sar_header & MID);
 1148             tca100_synch_send(dev, tcb, reply);
 1149           }
 1150           rx_slot_free(dev, tcb->rx_control);
 1151           if (delivery_type != NW_RECEIVE) {
 1152             delivery_type = NW_RECEIVE;
 1153             predicted_sar_header = SSM | (predicted_sar_header & MID);
 1154           } else {
 1155             predicted_sar_header = (predicted_sar_header + MID_INC) & MID;
 1156             if (predicted_sar_header == 0)
 1157               predicted_sar_header = 1;
 1158             predicted_sar_header |= SSM;
 1159           }
 1160         }
 1161       }
 1162     }
 1163 
 1164     control = &nw_tx_control[dev][0];
 1165     for (i = 0; i < MAX_LONG_TX; i++) {
 1166       if (control->ep != 0 && tct[control->ep].reply != TCA_SYNCH) {
 1167         tx_ecb = &ect[control->ep];
 1168         tx_tcb = &tct[control->ep];
 1169         rx_seqno = tx_tcb->reply & MID;
 1170         tx_seqno = tx_tcb->tx_sar_header & MID;
 1171         rx_count = tx_tcb->reply >> 16;
 1172         tx_count = tx_tcb->tx_synch;
 1173         reply = tx_tcb->reply & TCA_SYNCH;
 1174         if (reply == TCA_ACK) {
 1175           if (rx_seqno == tx_seqno && rx_count == tx_count) {
 1176             if (rx_count == 0) {
 1177 #ifdef TRACING
 1178               printf("Received final ack ep %d\n", tx_ecb->id);
 1179 #endif
 1180 
 1181               tx_seqno = (tx_seqno + MID_INC) & MID;
 1182               if (tx_seqno == 0)
 1183                 tx_seqno = 1;
 1184               tx_tcb->tx_sar_header = tx_seqno;
 1185               tx_slot_free(dev, control);
 1186               tx_tcb->reply = NW_SUCCESS;
 1187               nc_deliver_result(tx_ecb->id, NW_SEND, NW_SUCCESS);
 1188             } else {
 1189               if (tca100_window_send(dev, tx_ecb, tx_tcb,
 1190                                      FALSE) == NW_SUCCESS) {
 1191                 nc_deliver_result(control->ep, NW_SEND, NW_SUCCESS);
 1192                 tx_tcb->reply = NW_SUCCESS;
 1193                 tx_slot_free(dev, control);
 1194               } else {
 1195                 control->time_out = tick[dev] + BASE_TIME_OUT;
 1196                 tx_tcb->reply = TCA_SYNCH;
 1197               }
 1198             }
 1199           } else {
 1200             goto synch_error;
 1201           }
 1202         } else if (reply == TCA_OVR) {
 1203           if (rx_seqno == tx_seqno && rx_count == 0xffff &&
 1204               ((int) tx_ecb->tx_initial->msg_length -
 1205                (int) tx_tcb->tx_synch) <= (int) SMALL_WINDOW_SIZE) {
 1206             nc_deliver_result(control->ep, NW_SEND, NW_OVERRUN);
 1207             tx_tcb->reply = NW_OVERRUN;
 1208             tx_slot_free(dev, control);
 1209           } else {
 1210             goto synch_error;
 1211           }
 1212         } else if (reply == TCA_NAK) {
 1213           if (rx_seqno == tx_seqno &&
 1214               (rx_count == tx_count || (rx_count == 0xffff &&
 1215                  ((int) tx_ecb->tx_initial->msg_length -
 1216                   (int) tx_tcb->tx_synch) <= (int) SMALL_WINDOW_SIZE))) {
 1217             if (++control->retry < MAX_RETRY) {
 1218               if (tca100_verbose)
 1219                       printf("Sending retransmission ep %d\n", tx_ecb->id);
 1220               if (tca100_window_send(dev, tx_ecb, tx_tcb,
 1221                                      TRUE) == NW_SUCCESS) {
 1222                 nc_deliver_result(control->ep, NW_SEND, NW_SUCCESS);
 1223                 tx_tcb->reply = NW_SUCCESS;
 1224                 tx_slot_free(dev, control);
 1225               } else {
 1226                 control->time_out = tick[dev] + BASE_TIME_OUT;
 1227                 tx_tcb->reply = TCA_SYNCH;
 1228               }
 1229               tca_ec[TX_RETRANSMISSION]++;
 1230             } else {
 1231               nc_deliver_result(control->ep, NW_SEND, NW_FAILURE);
 1232               tx_tcb->reply = NW_FAILURE;
 1233               tx_slot_free(dev, control);
 1234             }
 1235           } else {
 1236             goto synch_error;
 1237           }
 1238         } else if (reply == TCA_SEQ) {
 1239           if (rx_count == 0xffff && tx_ecb->protocol == NW_SEQ_PACKET &&
 1240               ((int) tx_ecb->tx_initial->msg_length -
 1241                (int) tx_tcb->tx_synch) <= (int) SMALL_WINDOW_SIZE &&
 1242               rx_seqno == ((((tx_seqno + MID_INC) & MID) == 0) ?
 1243                            1 : tx_seqno + MID_INC)) {
 1244             tx_tcb->tx_sar_header = rx_seqno;
 1245             if (tca100_window_send(dev, tx_ecb, tx_tcb, 
 1246                                    TRUE) == NW_SUCCESS) {
 1247               nc_deliver_result(control->ep, NW_SEND, NW_SUCCESS);
 1248               tx_tcb->reply = NW_SUCCESS;
 1249               tx_slot_free(dev, control);
 1250             } else {
 1251               control->time_out = tick[dev] + BASE_TIME_OUT;
 1252               tx_tcb->reply = TCA_SYNCH;
 1253             }
 1254             tca_ec[TX_RETRANSMISSION]++;
 1255             if (tca100_verbose)
 1256                     printf("Sending seq retransmission ep %d\n", tx_ecb->id);
 1257           } else {
 1258             goto synch_error;
 1259           }
 1260         } else {
 1261  synch_error:
 1262           tca_ec[SYNCH_ERROR]++;
 1263           tx_tcb->reply = NW_FAILURE;
 1264           if (tca100_verbose)
 1265                   printf("Synch error\n");
 1266         }
 1267       }
 1268       control++;
 1269     }
 1270   }
 1271   *status = ~(RX_COUNT_INTR | RX_EOM_INTR | RX_TIME_INTR);
 1272   tcb->rx_sar_header = predicted_sar_header;
 1273   tcb->rx_p = (u_int *) msg;
 1274   tcb->rx_count = msg_count;
 1275   tcb->rx_next_synch = next_synch;
 1276   *ctl_set = RX_COUNT_INTR;
 1277   return rx_cell_total;
 1278 }
 1279 
 1280 
 1281 
 1282 void tca100_timer_sweep(int dev) {
 1283   int i, rt;
 1284   u_int reply;
 1285   nw_control_t control;
 1286   nw_ecb_t ecb;
 1287   nw_tcb_t tcb;
 1288   nw_tx_header_t tx_header;
 1289   nw_rx_header_t rx_header;
 1290 
 1291   tick[dev]++;
 1292   control = &nw_rx_control[dev][0];
 1293   for (i = 0; i < MAX_LONG_RX; i++) {
 1294     if (control->ep != 0 && control->time_out < tick[dev]) {
 1295       rx_slot_free(dev, control);
 1296       tcb = &tct[control->ep];
 1297       nc_buffer_deallocate(tcb->rx_buffer->peer.local_ep, tcb->rx_buffer);
 1298       tcb->rx_sar_header = SSM | (tcb->rx_sar_header & MID);
 1299     }
 1300     control++;
 1301   }
 1302   control = &nw_tx_control[dev][0];
 1303   for (i = 0; i < MAX_LONG_TX; i++) {
 1304     if (control->ep != 0 && control->time_out < tick[dev]) {
 1305       ecb = &ect[control->ep];
 1306       tcb = &tct[control->ep];
 1307       if (++control->retry < MAX_RETRY) {
 1308         if (control->retry == 1) 
 1309           rt = ( /* random() */ + devct[dev].local_addr_2) & 0x000f;
 1310         else
 1311           rt = ( /* random() */ + devct[dev].local_addr_1
 1312                 + devct[dev].local_addr_2) & 0x00ff;
 1313         control->time_out = tick[dev] + BASE_TIME_OUT + rt;
 1314         tca100_window_send(dev, ecb, tcb, TRUE);
 1315         tca_ec[TX_RETRANSMISSION]++;
 1316       } else {
 1317         nc_deliver_result(control->ep, NW_SEND, NW_TIME_OUT);
 1318         tx_slot_free(dev, control);
 1319       }
 1320     }
 1321     control++;
 1322   }
 1323   if (long_tx_count[dev] + long_rx_count[dev] > 0)
 1324     nc_fast_timer_set(dev);
 1325   else
 1326     tick[dev] = 0;
 1327 }
 1328 
 1329 nw_buffer_t tca100_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
 1330   nw_result rc;
 1331   nw_buffer_t buf;
 1332   nw_ecb_t ecb;
 1333   nw_tcb_t tcb;
 1334   nw_rx_header_t rx_header;
 1335   int dev, poll_time, ncells;
 1336 
 1337   tcb = &tct[ep];
 1338   ecb = &ect[header->peer.local_ep];
 1339   dev = NW_DEVICE(header->peer.rem_addr_1);
 1340   if ((rc = tca100_send(ep, header, options)) == NW_BAD_LENGTH) {
 1341     buf = NW_BUFFER_ERROR;
 1342   } else if (rc == NW_QUEUED) {
 1343     buf = NULL;
 1344   } else {
 1345     poll_time = 0;
 1346     if (rc == NW_SYNCH) {
 1347       while (tcb->reply == TCA_SYNCH && poll_time < POLL_LIMIT) {
 1348         ncells = tca100_poll(dev);
 1349         if (ncells == 0)
 1350           poll_time += POLL_IDLE_TIME;
 1351         else
 1352           poll_time += ncells * POLL_CELL_TIME;
 1353       }
 1354     }
 1355     if (tcb->reply != NW_SUCCESS) {
 1356       buf = NW_BUFFER_ERROR;
 1357     } else {
 1358       while (ecb->rx_first == NULL && poll_time < POLL_LIMIT) {
 1359         ncells = tca100_poll(dev);
 1360         if (ncells == 0)
 1361           poll_time += POLL_IDLE_TIME;
 1362         else
 1363           poll_time += ncells * POLL_CELL_TIME;
 1364       }
 1365       if (ecb->rx_first == NULL) {
 1366         buf = NULL;
 1367       } else {
 1368         rx_header = ecb->rx_first;
 1369         buf = rx_header->buffer;
 1370         ecb->rx_first = rx_header->next;
 1371         if (ecb->rx_first == NULL)
 1372           ecb->rx_last = NULL;
 1373         nc_rx_header_deallocate(rx_header);
 1374       }
 1375     }
 1376   }
 1377 
 1378   return buf;
 1379 }
 1380 
 1381 
 1382 
 1383 
 1384 
 1385 
 1386 
 1387 
 1388 

Cache object: 289f190ccf068828b53e39f124febb12


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