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