FreeCalypso > hg > fc-magnetite
comparison src/g23m-fad/l2r/l2r_upf.c @ 174:90eb61ecd093
src/g23m-fad: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 12 Oct 2016 05:40:46 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
173:bf64d785238a | 174:90eb61ecd093 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : CSD (8411) | |
4 | Modul : L2r_upf.c | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : This Modul defines the procedures and functions for | |
18 | the component L2R of the base station | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 | |
22 #ifndef L2R_UPF_C | |
23 #define L2R_UPF_C | |
24 #endif | |
25 | |
26 #define ENTITY_L2R | |
27 | |
28 /*==== INCLUDES ===================================================*/ | |
29 | |
30 #include <string.h> | |
31 #include "typedefs.h" | |
32 #include "pconst.cdg" | |
33 #include "vsi.h" | |
34 #include "macdef.h" | |
35 #include "custom.h" | |
36 #include "gsm.h" | |
37 #include "cus_l2r.h" | |
38 #include "cnf_l2r.h" | |
39 #include "mon_l2r.h" | |
40 #include "prim.h" | |
41 #include "pei.h" | |
42 #include "tok.h" | |
43 #include "dti.h" /* functionality of the dti library */ | |
44 | |
45 #include "cl_ribu.h" | |
46 #include "l2r.h" | |
47 | |
48 /*==== CONST =======================================================*/ | |
49 | |
50 /*==== TYPES =======================================================*/ | |
51 | |
52 /*==== VAR EXPORT ==================================================*/ | |
53 | |
54 /*==== VAR LOCAL ===================================================*/ | |
55 | |
56 /*==== FUNCTIONS ===================================================*/ | |
57 | |
58 /* | |
59 +------------------------------------------------------------------------------ | |
60 | Function : up_init | |
61 +------------------------------------------------------------------------------ | |
62 | Description : initialise the l2r data for the uplink process | |
63 | | |
64 | Parameters : - | |
65 | | |
66 | | |
67 | Return : - | |
68 +------------------------------------------------------------------------------ | |
69 */ | |
70 | |
71 GLOBAL void up_init(T_UP *dup) | |
72 { | |
73 register ULONG i; | |
74 | |
75 TRACE_FUNCTION ("up_init()"); | |
76 | |
77 dup->FlowCtrlUsed = FALSE; | |
78 dup->DnFlow = FL_INACTIVE; | |
79 dup->UpFlow = FL_INACTIVE; | |
80 dup->ULFlow = FL_INACTIVE; | |
81 dup->LLFlow = FL_INACTIVE; | |
82 dup->MrgFlow = FL_INACTIVE; | |
83 dup->FlowThreshLo = MAX_UPRIM_RIBU_SIZE/2; | |
84 dup->FlowThreshHi = 3*MAX_UPRIM_RIBU_SIZE/4; | |
85 dup->DataSize = 0; | |
86 dup->FrameSize = 0; | |
87 dup->OldFrameSize = 0; | |
88 dup->FramesPerPrim = L2R_FRAMES_PER_PRIM_MAX; | |
89 dup->LastRcvdSa = 0; | |
90 dup->LastRcvdSb = 0; | |
91 dup->LastSentSa = 0; | |
92 dup->LastSentSb = 0; | |
93 dup->LastSentFlow = FL_INACTIVE; | |
94 dup->StoreDataActive = FALSE; | |
95 dup->UrgentMsg = FALSE; | |
96 dup->DiscardRemapData = FALSE; | |
97 dup->QRemapRead = 0; | |
98 dup->QRemapWrite = 0; | |
99 dup->BRemapAdr = NULL; | |
100 dup->BRemapLen = 0; | |
101 dup->BRemapSa = 0; | |
102 dup->BRemapSb = 0; | |
103 dup->BRemapLastState = 0; | |
104 dup->QRemapPrimDesc.prim = NULL; | |
105 | |
106 for (i = 0; i < MAX_UP_REMAP_QUEUE_SIZE; i++) | |
107 { | |
108 dup->QRemap[i] = NULL; | |
109 } | |
110 | |
111 for (i = 0; i < UP_REMAP_BUFFER_SIZE; i++) | |
112 { | |
113 dup->BRemap[i] = 0; | |
114 } | |
115 | |
116 dup->RiBu.idx.depth = MAX_UPRIM_RIBU_SIZE; | |
117 | |
118 INIT_STATE (UP_UL, IW_IDLE); | |
119 INIT_STATE (UP_LL, ISW_IDLE); | |
120 INIT_STATE (UP, UP_DISCONNECTED); | |
121 } | |
122 | |
123 /* | |
124 +------------------------------------------------------------------------------ | |
125 | Function : up_alloc_prim | |
126 +------------------------------------------------------------------------------ | |
127 | Description : | |
128 | | |
129 | Parameters : - | |
130 | | |
131 | | |
132 | Return : - | |
133 +------------------------------------------------------------------------------ | |
134 */ | |
135 | |
136 | |
137 LOCAL void up_alloc_prim(void) | |
138 { | |
139 T_UP *dup = &l2r_data->up; | |
140 | |
141 T_PRIM_INDEX m; | |
142 T_P_UPRIM_DESCRIPTOR primDesc; | |
143 USHORT sduSize; | |
144 | |
145 TRACE_FUNCTION ("up_alloc_prim()"); | |
146 | |
147 sduSize = dup->FramesPerPrim * dup->FrameSize * 8; | |
148 primDesc = dup->RiBu.primDesc[dup->RiBu.alloc]; | |
149 { | |
150 PALLOC_SDU(data_req, RLP_DATA_REQ, sduSize); | |
151 primDesc->prim = data_req; | |
152 } | |
153 | |
154 #ifdef _SIMULATION_ | |
155 /* Clear SDU for test environment */ | |
156 { | |
157 UBYTE *p; | |
158 UBYTE *pend; | |
159 p = &primDesc->prim->sdu.buf[0]; | |
160 pend = p + (sduSize >> 3); | |
161 while (p < pend) | |
162 { | |
163 *p++ = 0; | |
164 } | |
165 } | |
166 #endif | |
167 | |
168 primDesc->prim->sdu.o_buf = 0; | |
169 primDesc->prim->sdu.l_buf = sduSize; | |
170 primDesc->nFr = dup->FramesPerPrim; | |
171 primDesc->index = 0; | |
172 primDesc->offset = 0; | |
173 primDesc->off_status = 0; | |
174 primDesc->full = FALSE; | |
175 primDesc->sa = FL_INACTIVE; | |
176 primDesc->sb = FL_INACTIVE; | |
177 /*lint -e416 (Warning -- Likely creation of out-of-bounds) */ | |
178 for (m = 0; m != dup->FramesPerPrim; m++) | |
179 { | |
180 (*primDesc->adr)[m] = (T_P_L2R_FRAME)(primDesc->prim->sdu.buf +L2R_ENCODING_OFFSET + m * dup->FrameSize); | |
181 } | |
182 /*lint +e416 (Warning -- Likely creation of out-of-bounds) */ | |
183 dup->RiBu.alloc++; | |
184 if (dup->RiBu.alloc EQ dup->RiBu.idx.depth) | |
185 { | |
186 dup->RiBu.alloc = 0; | |
187 } | |
188 } | |
189 | |
190 /* | |
191 +------------------------------------------------------------------------------ | |
192 | Function : up_send_prim_timeout | |
193 +------------------------------------------------------------------------------ | |
194 | Description : | |
195 | | |
196 | Parameters : - | |
197 | | |
198 | | |
199 | Return : - | |
200 +------------------------------------------------------------------------------ | |
201 */ | |
202 | |
203 | |
204 GLOBAL void up_send_prim_timeout(void) | |
205 { | |
206 T_UP *dup = &l2r_data->up; | |
207 | |
208 TRACE_FUNCTION ("up_send_prim_timeout()"); | |
209 | |
210 if (!dup->RiBu.idx.filled) | |
211 { | |
212 if (dup->RiBu.alloc EQ dup->RiBu.idx.wi) | |
213 { | |
214 /* No primitive is there, so we allocate one */ | |
215 up_alloc_prim(); | |
216 } | |
217 | |
218 /* | |
219 No primitive is ready, so we take one away from the relay entity | |
220 */ | |
221 cl_ribu_write_index(&dup->RiBu.idx); /* point to next primitive */ | |
222 } | |
223 up_send_current_prim(); | |
224 } | |
225 | |
226 /* | |
227 +------------------------------------------------------------------------------ | |
228 | Function : up_next_remap_frame | |
229 +------------------------------------------------------------------------------ | |
230 | Description : Local function, which is used by up_copy_data_from_l2r | |
231 | to advance to the next frame in the primitive. | |
232 | The variable primDesc of the calling function is updated. | |
233 | | |
234 | Parameters : primDesc - | |
235 | | |
236 | Return : 1 - | |
237 | 0 - | |
238 +------------------------------------------------------------------------------ | |
239 */ | |
240 | |
241 LOCAL UBYTE up_next_remap_frame(T_RPRIM_DESCRIPTOR *primDesc) | |
242 { | |
243 T_UP *dup = &l2r_data->up; | |
244 | |
245 U8 i; | |
246 T_P_RLP_REMAP_DATA_IND prim; | |
247 | |
248 /* next frame */ | |
249 primDesc->index++; | |
250 | |
251 if (primDesc->index >= primDesc->nFr) | |
252 { | |
253 /* primitive is completely read out */ | |
254 PFREE(dup->QRemap [dup->QRemapRead]); | |
255 | |
256 /* next primitive */ | |
257 (dup->QRemapRead)++; | |
258 if (dup->QRemapRead >= MAX_UP_REMAP_QUEUE_SIZE) | |
259 { | |
260 dup->QRemapRead = 0; | |
261 } | |
262 if (dup->QRemapRead EQ dup->QRemapWrite) | |
263 { | |
264 /* no primitive is ready */ | |
265 primDesc->prim = NULL; | |
266 return (1); | |
267 } | |
268 | |
269 /* point to next primitive descriptor */ | |
270 | |
271 prim = dup->QRemap[dup->QRemapRead]; | |
272 primDesc->prim = prim; | |
273 primDesc->nFr = prim->sdu.l_buf / (8 * prim->data_size + HT_LEN); | |
274 primDesc->index = 0; | |
275 | |
276 for (i = 0; i < primDesc->nFr; i++) | |
277 { | |
278 primDesc->adr[i] = (T_P_L2R_FRAME)(prim->sdu.buf + (prim->sdu.o_buf>>3) | |
279 + HEADER_LEN + i * (prim->data_size + HT_LEN)); | |
280 } | |
281 } | |
282 primDesc->offset = 0; | |
283 primDesc->off_status = 0; | |
284 return (0); | |
285 } | |
286 | |
287 /* | |
288 +------------------------------------------------------------------------------ | |
289 | Function : up_copy_data_from_rq | |
290 +------------------------------------------------------------------------------ | |
291 | Description : | |
292 | | |
293 | Parameters : buf - | |
294 | len - | |
295 | sa - | |
296 | sb - | |
297 | bytesCopied - | |
298 | | |
299 | Return : - | |
300 +------------------------------------------------------------------------------ | |
301 */ | |
302 | |
303 LOCAL void up_copy_data_from_rq(U8 *buf, U16 len, U8 *sa, U8 *sb, U16 *bytesCopied) | |
304 { | |
305 T_UP *dup = &l2r_data->up; | |
306 | |
307 register ULONG i; | |
308 register T_P_UBYTE pFrame; | |
309 register T_P_UBYTE pBuf; | |
310 register T_P_UBYTE pStat; | |
311 T_P_RLP_REMAP_DATA_IND prim; | |
312 T_P_L2R_FRAME frame; | |
313 T_P_UBYTE pEnd; | |
314 USHORT bytesToCopy; | |
315 USHORT blocklen; | |
316 UBYTE statOct; | |
317 UBYTE lastState; | |
318 | |
319 T_RPRIM_DESCRIPTOR *primDesc = &dup->QRemapPrimDesc; | |
320 | |
321 #ifdef _SIMULATION_ | |
322 TRACE_FUNCTION ("up_copy_data_from_rq()"); | |
323 #endif | |
324 | |
325 bytesToCopy = len; | |
326 | |
327 if (primDesc->prim EQ NULL) | |
328 { | |
329 prim = dup->QRemap[dup->QRemapRead]; | |
330 primDesc->prim = prim; | |
331 primDesc->nFr = prim->sdu.l_buf / ((prim->data_size<<3) + HT_LEN); | |
332 primDesc->index = 0; | |
333 primDesc->offset = 0; | |
334 primDesc->off_status = 0; | |
335 | |
336 for (i = 0; i < primDesc->nFr; i++) | |
337 { | |
338 primDesc->adr[i] = (T_P_L2R_FRAME)(prim->sdu.buf + (prim->sdu.o_buf>>3) | |
339 + HEADER_LEN + i * (prim->data_size + HT_LEN)); | |
340 } | |
341 } | |
342 | |
343 /* skip empty primitive */ | |
344 if (primDesc->nFr EQ 0) | |
345 { | |
346 *bytesCopied = 0; | |
347 return; | |
348 } | |
349 | |
350 frame = primDesc->adr[primDesc->index]; /* point to current l2r frame in primitive */ | |
351 pBuf = buf; /* point to destination buffer */ | |
352 pFrame = &((*frame)[primDesc->offset]); | |
353 pStat = &((*frame)[primDesc->off_status]); | |
354 | |
355 if (pFrame EQ pStat) | |
356 { | |
357 /* current byte is status octet */ | |
358 dup->BRemapLastState = *pFrame & SO_STATUS_BITS_MASK; | |
359 } | |
360 | |
361 lastState = dup->BRemapLastState; | |
362 *sa = GET_SO_SA_BIT(lastState); | |
363 *sb = GET_SO_SB_BIT(lastState); | |
364 | |
365 /************************************************************************************ | |
366 * loop until either | |
367 * - no more data are available or | |
368 * - status in L2R frame changes or | |
369 * - buffer for data is full | |
370 ************************************************************************************/ | |
371 | |
372 for (;;) | |
373 { | |
374 #ifdef _SIMULATION_ | |
375 TRACE_FUNCTION ("loop"); | |
376 #endif | |
377 | |
378 blocklen = pStat - pFrame; | |
379 if (blocklen EQ 0) | |
380 { | |
381 /* | |
382 * current byte is status octet | |
383 * (only in the first pass of the loop, there may be no status octet) | |
384 */ | |
385 | |
386 /***************************** | |
387 * evaluate status bits | |
388 *****************************/ | |
389 statOct = *pFrame; | |
390 if (lastState NEQ (statOct & SO_STATUS_BITS_MASK)) | |
391 { | |
392 /* | |
393 * status has changed. We have to stop, | |
394 * since only one state can be transmitted to the upper layer | |
395 */ | |
396 primDesc->offset = primDesc->off_status = pFrame - (T_P_UBYTE)frame; | |
397 | |
398 *bytesCopied = len - bytesToCopy; | |
399 return; | |
400 } | |
401 | |
402 pFrame++; | |
403 | |
404 /************************************ | |
405 * evaluate addrss bits | |
406 ************************************/ | |
407 statOct &= SO_ADR_MASK; | |
408 | |
409 switch (statOct) | |
410 { | |
411 case SO_BREAK_ACK: | |
412 case SO_BREAK_REQ: | |
413 case SO_END_EMPTY: | |
414 /* no more data in this frame */ | |
415 if (up_next_remap_frame(primDesc) EQ 1) | |
416 { | |
417 /* no more data available */ | |
418 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
419 return; | |
420 } | |
421 | |
422 frame = primDesc->adr[primDesc->index]; | |
423 pFrame = (T_P_UBYTE)frame; | |
424 pStat = (T_P_UBYTE)frame; | |
425 continue; /* continue with next frame */ | |
426 | |
427 case SO_END_FULL: | |
428 pStat = &((*frame)[primDesc->prim->data_size]); | |
429 blocklen = pStat - pFrame; | |
430 break; | |
431 | |
432 case SO_TWO_OCTET: | |
433 blocklen = *pFrame++ & SO_ADR_MASK_TWO_OCT; | |
434 pStat = pFrame + blocklen; | |
435 break; | |
436 | |
437 default: | |
438 blocklen = statOct; | |
439 pStat = pFrame + blocklen; | |
440 break; | |
441 } | |
442 } | |
443 | |
444 if (bytesToCopy < blocklen) | |
445 { | |
446 /*************************************** | |
447 * There is not enough space in the | |
448 * buffer to copy the complete block | |
449 ***************************************/ | |
450 | |
451 pEnd = pFrame + bytesToCopy; | |
452 | |
453 while (pFrame < pEnd) | |
454 { | |
455 *pBuf++ = *pFrame++; | |
456 } | |
457 | |
458 if (pFrame EQ &((*frame)[primDesc->prim->data_size])) | |
459 { | |
460 /* end of frame reached */ | |
461 up_next_remap_frame(primDesc); | |
462 } | |
463 else | |
464 { | |
465 primDesc->offset = pFrame - (T_P_UBYTE)frame; | |
466 primDesc->off_status = pStat - (T_P_UBYTE)frame; | |
467 } | |
468 *bytesCopied = len; /* this much data could be copied */ | |
469 return; | |
470 } | |
471 else | |
472 { | |
473 /*************************************** | |
474 * Copy the complete block | |
475 ***************************************/ | |
476 bytesToCopy -= blocklen; | |
477 | |
478 while (pFrame < pStat) | |
479 { | |
480 *pBuf++ = *pFrame++; | |
481 } | |
482 | |
483 if (pFrame EQ &((*frame)[primDesc->prim->data_size])) | |
484 { | |
485 /* end of frame reached */ | |
486 if (up_next_remap_frame(primDesc) EQ 1) | |
487 { | |
488 /* no more data available */ | |
489 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
490 return; | |
491 } | |
492 frame = primDesc->adr[primDesc->index]; | |
493 pFrame = (T_P_UBYTE)frame; | |
494 pStat = (T_P_UBYTE)frame; | |
495 } | |
496 if (bytesToCopy EQ 0) | |
497 { | |
498 primDesc->offset = pFrame - (T_P_UBYTE)frame; | |
499 primDesc->off_status = pStat - (T_P_UBYTE)frame; | |
500 *bytesCopied = len; /* this much data could be copied */ | |
501 return; | |
502 } | |
503 } | |
504 } | |
505 } | |
506 | |
507 /* | |
508 +------------------------------------------------------------------------------ | |
509 | Function : up_fill_in_status_octet | |
510 +------------------------------------------------------------------------------ | |
511 | Description : local function, which is used patch a status octet into a | |
512 | l2r frame. This function takes into acount the two octet | |
513 | format for 14400. | |
514 | | |
515 | Parameters : pFrame - points to begin of l2r frame | |
516 | offstat1 - offset of status octet to be patched | |
517 | offstat2 - offset of next status octet | |
518 | | |
519 | Return : | |
520 +------------------------------------------------------------------------------ | |
521 */ | |
522 | |
523 LOCAL BOOL up_fill_in_status_octet(T_P_UBYTE pFrame, UBYTE offstat1, UBYTE offstat2) | |
524 { | |
525 register T_P_UBYTE pStat, pSrc, pDes, pEnd; | |
526 register UBYTE dataLen; | |
527 | |
528 dataLen = offstat2 - offstat1 - 1; /* number of data bytes between status octets */ | |
529 pStat = pFrame + offstat1; | |
530 | |
531 if (dataLen <= DATA_SIZE_SHORT-2) | |
532 { | |
533 *pStat |= dataLen; | |
534 return (FALSE); | |
535 } | |
536 else | |
537 { | |
538 /* this is only possible with 14400 */ | |
539 if (offstat2 < DATA_SIZE_LONG - 1) | |
540 { | |
541 /* a two octet status must be inserted */ | |
542 pSrc = pFrame + offstat2; | |
543 pDes = pSrc + 1; | |
544 pEnd = pFrame + offstat1; | |
545 while (pSrc > pEnd) | |
546 { | |
547 *--pDes = *--pSrc; | |
548 } | |
549 *pStat |= SO_TWO_OCTET; | |
550 pStat++; | |
551 *pStat = dataLen; | |
552 } | |
553 else | |
554 { | |
555 /* a additional status octet (FULL) must be inserted somewhere in the frame */ | |
556 pSrc = pFrame + offstat2; | |
557 pDes = pSrc + 1; | |
558 pEnd = pFrame + offstat1 + DATA_SIZE_SHORT - 1; | |
559 while (pSrc > pEnd) | |
560 { | |
561 *--pDes = *--pSrc; | |
562 } | |
563 *pStat |= DATA_SIZE_SHORT - 2; | |
564 *pEnd = *pStat & SO_STATUS_BITS_MASK | SO_END_FULL; | |
565 } | |
566 return (TRUE); | |
567 } | |
568 } | |
569 | |
570 /* | |
571 +------------------------------------------------------------------------------ | |
572 | Function : up_next_frame | |
573 +------------------------------------------------------------------------------ | |
574 | Description : local function, which is used by up_copy_data_into_l2r to | |
575 | advance to the next frame in the primitive | |
576 | The variables primDesc, frame and pFrame of the calling function | |
577 | are updated. Moreover the return values of the calling function | |
578 | primToSend and bytesCopied are set. | |
579 | | |
580 | | |
581 | Parameters : primDesc - | |
582 | primToSend - | |
583 | | |
584 | Return : | |
585 +------------------------------------------------------------------------------ | |
586 */ | |
587 | |
588 LOCAL UBYTE up_next_frame(T_P_UPRIM_DESCRIPTOR *primDesc, BOOL *primToSend) | |
589 { | |
590 T_UP *dup = &l2r_data->up; | |
591 | |
592 TRACE_FUNCTION("up_next_frame()"); | |
593 | |
594 (*primDesc)->index++; | |
595 (*primDesc)->offset = 0; | |
596 | |
597 if ((*primDesc)->index >= dup->FramesPerPrim) /* primitive is filled */ | |
598 { | |
599 (*primDesc)->full = TRUE; | |
600 *primToSend = TRUE; | |
601 | |
602 cl_ribu_write_index(&dup->RiBu.idx); /* point to next primitive */ | |
603 | |
604 if (dup->RiBu.alloc EQ dup->RiBu.idx.wi) | |
605 { | |
606 /* no primitive is ready */ | |
607 return (1); | |
608 } | |
609 | |
610 /* point to next primitive descriptor */ | |
611 *primDesc = dup->RiBu.primDesc[dup->RiBu.idx.wi]; | |
612 (*primDesc)->index = 0; | |
613 } | |
614 return (0); | |
615 } | |
616 | |
617 LOCAL void up_copy_data_into_l2r(U8 *buf, U16 len, U8 sa, U8 sb, U8 x, BOOL *primToSend, U16 *bytesCopied) | |
618 { | |
619 T_UP *dup = &l2r_data->up; | |
620 | |
621 T_P_UPRIM_DESCRIPTOR primDesc; | |
622 T_P_L2R_FRAME frame; | |
623 register T_P_UBYTE pFrame; | |
624 register T_P_UBYTE pEnd; | |
625 register T_P_UBYTE pBuf; | |
626 USHORT bytesToCopy; | |
627 UBYTE frameCount; | |
628 T_FLOW flow = FL_INVALID; | |
629 | |
630 #ifdef _SIMULATION_ | |
631 TRACE_FUNCTION ("up_copy_data_into_l2r()"); | |
632 #endif | |
633 | |
634 switch (x) | |
635 { | |
636 case DTI_FLOW_ON: | |
637 flow = FL_INACTIVE; | |
638 break; | |
639 case DTI_FLOW_OFF: | |
640 flow = FL_ACTIVE; | |
641 break; | |
642 } | |
643 | |
644 #ifdef _TARGET_ | |
645 if (dup->DataSize > DATA_SIZE_SHORT) | |
646 { | |
647 frameCount = 1; | |
648 } | |
649 else | |
650 { | |
651 frameCount = 2; | |
652 } | |
653 #else | |
654 { | |
655 frameCount = 100; | |
656 } | |
657 #endif | |
658 | |
659 up_store_status(sa, sb, flow); | |
660 | |
661 if (dup->LastSentFlow EQ dup->MrgFlow) | |
662 { | |
663 *primToSend = FALSE; | |
664 } | |
665 else | |
666 { | |
667 *primToSend = TRUE; | |
668 } | |
669 | |
670 /* don't copy into primitive if no primitive is ready */ | |
671 if (dup->RiBu.alloc EQ dup->RiBu.idx.wi) | |
672 { | |
673 *bytesCopied = 0; | |
674 return; | |
675 } | |
676 | |
677 bytesToCopy = len; | |
678 | |
679 primDesc = dup->RiBu.primDesc[dup->RiBu.idx.wi]; /* point to current primitive descriptor */ | |
680 frame = (*primDesc->adr)[primDesc->index]; /* point to current l2r frame in primitive */ | |
681 pFrame = &(*frame)[primDesc->offset]; /* point to current byte in frame */ | |
682 pBuf = buf; /* point to source buffer */ | |
683 | |
684 /************************************************************************************ | |
685 * | |
686 * Handle a partly filled frame, which has been written in the primitive previously | |
687 * | |
688 ************************************************************************************/ | |
689 | |
690 if (primDesc->offset NEQ 0) | |
691 { | |
692 /* partly filled frame is there */ | |
693 | |
694 if (bytesToCopy EQ 0) | |
695 /* no data to copy -> quit without writing status octet */ | |
696 { | |
697 *bytesCopied = len; | |
698 return; | |
699 } | |
700 | |
701 if (sa NEQ primDesc->sa OR sb NEQ primDesc->sb) | |
702 { | |
703 /* | |
704 * status has changed since last time | |
705 */ | |
706 | |
707 /* finish previous status octet */ | |
708 if ( | |
709 up_fill_in_status_octet( | |
710 (T_P_UBYTE)frame, | |
711 primDesc->off_status, | |
712 primDesc->offset | |
713 ) | |
714 ) | |
715 { | |
716 /* frame data has been moved to make space for two octet status */ | |
717 pFrame++; | |
718 (primDesc->offset)++; | |
719 | |
720 if (primDesc->offset >= (dup->DataSize)) | |
721 { | |
722 /* frame is just filled by patching the previous status frame */ | |
723 | |
724 if (up_next_frame(&primDesc, primToSend) EQ 1) | |
725 { | |
726 /* no more space for data */ | |
727 *bytesCopied = 0; /* no data could be copied */ | |
728 return; | |
729 } | |
730 frameCount--; | |
731 #ifdef _TARGET_ | |
732 if (frameCount EQ 0) | |
733 { | |
734 *bytesCopied = 0; /* no data could be copied */ | |
735 return; | |
736 } | |
737 #endif | |
738 frame = (*primDesc->adr)[primDesc->index]; /* point to current l2r frame in primitive */ | |
739 pFrame = &(*frame)[primDesc->offset]; /* point to current byte in frame */ | |
740 } | |
741 } | |
742 | |
743 if (primDesc->offset NEQ 0) | |
744 { | |
745 /* write status octet */ | |
746 *pFrame++ = (U8)(sa << SO_SA_BIT | sb << SO_SB_BIT | 0 << SO_X_BIT); /* x is set to 0 (inactive) by default */ | |
747 | |
748 /* store current status for next call */ | |
749 primDesc->sa = sa; | |
750 primDesc->sb = sb; | |
751 | |
752 primDesc->off_status = primDesc->offset; | |
753 (primDesc->offset)++; | |
754 if (primDesc->offset >= (dup->DataSize)) | |
755 { | |
756 /* frame is just filled by the status octet */ | |
757 | |
758 /* finish previous status octet */ | |
759 (*frame)[primDesc->off_status] |= SO_END_EMPTY; | |
760 | |
761 if (up_next_frame(&primDesc, primToSend) EQ 1) | |
762 { | |
763 /* no more space for data */ | |
764 *bytesCopied = 0; /* no data could be copied */ | |
765 return; | |
766 } | |
767 frameCount--; | |
768 if (frameCount EQ 0) | |
769 { | |
770 *bytesCopied = 0; /* no data could be copied */ | |
771 return; | |
772 } | |
773 frame = (*primDesc->adr)[primDesc->index]; /* point to current l2r frame in primitive */ | |
774 pFrame = &(*frame)[primDesc->offset]; /* point to current byte in frame */ | |
775 } | |
776 } | |
777 } | |
778 | |
779 /* | |
780 * write data into partly filled frame | |
781 */ | |
782 if (primDesc->offset NEQ 0) | |
783 { | |
784 if (bytesToCopy >= dup->DataSize - primDesc->offset) | |
785 { | |
786 /* enough data to fill frame completly */ | |
787 | |
788 for (pEnd = pFrame + dup->DataSize - primDesc->offset; pFrame < pEnd; ) | |
789 { | |
790 *pFrame++ = *pBuf++; | |
791 } | |
792 | |
793 /* finish previous status octet */ | |
794 (*frame)[primDesc->off_status] |= SO_END_FULL; | |
795 | |
796 bytesToCopy -= dup->DataSize - primDesc->offset; | |
797 | |
798 if (up_next_frame(&primDesc, primToSend) EQ 1) | |
799 { | |
800 /* no more space for data */ | |
801 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
802 return; | |
803 } | |
804 frameCount--; | |
805 if (frameCount EQ 0) | |
806 { | |
807 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
808 return; | |
809 } | |
810 frame = (*primDesc->adr)[primDesc->index]; /* point to current l2r frame in primitive */ | |
811 pFrame = &(*frame)[primDesc->offset]; /* point to current byte in frame */ | |
812 | |
813 } | |
814 else | |
815 { | |
816 /* not enough data to fill frame completly */ | |
817 | |
818 for (pEnd = pFrame + bytesToCopy; pFrame < pEnd; ) | |
819 { | |
820 *pFrame++ = *pBuf++; | |
821 } | |
822 primDesc->offset += bytesToCopy; | |
823 *bytesCopied = len; | |
824 return; /* Nothing else to do */ | |
825 } | |
826 } | |
827 } | |
828 | |
829 /************************************************************************************ | |
830 * | |
831 * Handle consecutive frames, which are filled starting with byte 0 | |
832 * | |
833 ************************************************************************************/ | |
834 | |
835 while (bytesToCopy > 0) | |
836 { | |
837 if (bytesToCopy >= dup->DataSize - 1) | |
838 { | |
839 /* | |
840 * There are enough data to fill a frame completely | |
841 */ | |
842 *pFrame++ = sa << SO_SA_BIT | sb << SO_SB_BIT | 0 << SO_X_BIT | SO_END_FULL; /* x is set to 0 (inactive) by default */ | |
843 | |
844 /* store current status for next call */ | |
845 primDesc->sa = sa; | |
846 primDesc->sb = sb; | |
847 | |
848 for (pEnd = pFrame + dup->DataSize - 1; pFrame < pEnd; ) | |
849 { | |
850 *pFrame++ = *pBuf++; | |
851 } | |
852 bytesToCopy -= dup->DataSize - 1; | |
853 | |
854 /* advance to next frame */ | |
855 if (up_next_frame(&primDesc, primToSend) EQ 1) | |
856 { | |
857 /* running out of primitives */ | |
858 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
859 return; | |
860 } | |
861 frameCount--; | |
862 if (frameCount EQ 0) | |
863 { | |
864 *bytesCopied = len - bytesToCopy; /* this much data could be copied */ | |
865 return; | |
866 } | |
867 frame = (*primDesc->adr)[primDesc->index]; /* point to current l2r frame in primitive */ | |
868 pFrame = &(*frame)[primDesc->offset]; /* point to current byte in frame */ | |
869 } | |
870 else | |
871 { | |
872 /* | |
873 * There are some data, but not enough to fill a frame completely | |
874 */ | |
875 *pFrame++ = (U8)(sa << SO_SA_BIT | sb << SO_SB_BIT | 0 << SO_X_BIT); /* x is set to 0 (inactive) by default */ | |
876 | |
877 /* store current status for next call */ | |
878 primDesc->sa = sa; | |
879 primDesc->sb = sb; | |
880 | |
881 for (pEnd = pFrame + bytesToCopy; pFrame < pEnd; ) | |
882 { | |
883 *pFrame++ = *pBuf++; | |
884 } | |
885 primDesc->off_status = 0; | |
886 primDesc->offset = bytesToCopy + 1; | |
887 bytesToCopy = 0; | |
888 } | |
889 } | |
890 *bytesCopied = len; | |
891 } | |
892 | |
893 /* | |
894 +------------------------------------------------------------------------------ | |
895 | Function : up_copy_remap_data | |
896 +------------------------------------------------------------------------------ | |
897 | Description : | |
898 | | |
899 | Parameters : - | |
900 | | |
901 | | |
902 | Return : - | |
903 +------------------------------------------------------------------------------ | |
904 */ | |
905 | |
906 LOCAL void up_copy_remap_data(void) | |
907 { | |
908 T_UP *dup = &l2r_data->up; | |
909 | |
910 USHORT bytesCopied; | |
911 BOOL dummy; | |
912 | |
913 #ifdef _SIMULATION_ | |
914 TRACE_FUNCTION ("up_copy_remap_data()"); | |
915 #endif | |
916 | |
917 do | |
918 { | |
919 if (dup->BRemapLen EQ 0) | |
920 { | |
921 dup->BRemapAdr = dup->BRemap; | |
922 up_copy_data_from_rq | |
923 ( | |
924 dup->BRemapAdr, | |
925 UP_REMAP_BUFFER_SIZE, | |
926 &dup->BRemapSa, | |
927 &dup->BRemapSb, | |
928 &dup->BRemapLen | |
929 ); | |
930 if (dup->BRemapLen EQ 0) | |
931 { | |
932 up_check_flow(); | |
933 return; | |
934 } | |
935 } | |
936 up_copy_data_into_l2r | |
937 ( | |
938 dup->BRemapAdr, | |
939 dup->BRemapLen, | |
940 dup->BRemapSa, | |
941 dup->BRemapSb, | |
942 DTI_FLOW_OFF, | |
943 &dummy, | |
944 &bytesCopied | |
945 ); | |
946 dup->BRemapAdr += bytesCopied; | |
947 dup->BRemapLen -= bytesCopied; | |
948 | |
949 } while (bytesCopied NEQ 0); | |
950 } | |
951 | |
952 /* | |
953 +------------------------------------------------------------------------------ | |
954 | Function : up_check_alloc | |
955 +------------------------------------------------------------------------------ | |
956 | Description : This procedure allocates new primitives until there are | |
957 | UP_RIBU_PREALLOC primitives ready. | |
958 | | |
959 | I.e.: alloc = write + UP_RIBU_PREALLOC | |
960 | | |
961 | It may be less than this, if otherwise the alloc pointer | |
962 | would reach the read pointer. | |
963 | | |
964 | | |
965 | Parameters : - | |
966 | | |
967 | | |
968 | Return : - | |
969 +------------------------------------------------------------------------------ | |
970 */ | |
971 | |
972 GLOBAL void up_check_alloc(void) | |
973 { | |
974 T_UP *dup = &l2r_data->up; | |
975 | |
976 S8 i_from, i_to; | |
977 | |
978 TRACE_FUNCTION ("up_check_alloc()"); | |
979 | |
980 i_to = dup->RiBu.idx.ri - dup->RiBu.idx.wi - 1; | |
981 | |
982 if (i_to < 0) | |
983 { | |
984 i_to = i_to + dup->RiBu.idx.depth; | |
985 } | |
986 | |
987 if (i_to > UP_RIBU_PREALLOC) | |
988 { | |
989 i_to = UP_RIBU_PREALLOC; | |
990 } | |
991 | |
992 i_from = dup->RiBu.alloc - dup->RiBu.idx.wi; | |
993 | |
994 if (i_from < 0) | |
995 { | |
996 i_from = i_from + dup->RiBu.idx.depth; | |
997 } | |
998 | |
999 if (i_from >= i_to) | |
1000 { | |
1001 return; | |
1002 } | |
1003 | |
1004 do | |
1005 { | |
1006 up_alloc_prim(); | |
1007 i_from++; | |
1008 } while (i_from < i_to); | |
1009 | |
1010 if (dup->QRemapRead NEQ dup->QRemapWrite) | |
1011 { | |
1012 up_copy_remap_data(); | |
1013 return; | |
1014 } | |
1015 | |
1016 switch (GET_STATE (UP_UL)) | |
1017 { | |
1018 case IW_WAIT: | |
1019 break; | |
1020 | |
1021 case IW_IDLE: | |
1022 if (dup->StoreDataActive EQ FALSE AND dup->Prim NEQ NULL) | |
1023 { | |
1024 up_store_data(); | |
1025 } | |
1026 break; | |
1027 } | |
1028 } | |
1029 | |
1030 /* | |
1031 +------------------------------------------------------------------------------ | |
1032 | Function : up_check_flow | |
1033 +------------------------------------------------------------------------------ | |
1034 | Description : | |
1035 | | |
1036 | Parameters : - | |
1037 | | |
1038 | | |
1039 | Return : - | |
1040 +------------------------------------------------------------------------------ | |
1041 */ | |
1042 | |
1043 GLOBAL void up_check_flow(void) | |
1044 { | |
1045 T_UP *dup = &l2r_data->up; | |
1046 | |
1047 U8 primCount; | |
1048 | |
1049 TRACE_FUNCTION ("up_check_flow()"); | |
1050 | |
1051 if (!dup->FlowCtrlUsed) | |
1052 { | |
1053 return; | |
1054 } | |
1055 | |
1056 primCount = dup->RiBu.idx.filled; | |
1057 | |
1058 switch (dup->UpFlow) | |
1059 { | |
1060 case FL_ACTIVE: | |
1061 if (primCount < dup->FlowThreshLo) | |
1062 { | |
1063 dup->UpFlow = FL_INACTIVE; | |
1064 } | |
1065 else | |
1066 { | |
1067 return; | |
1068 } | |
1069 break; | |
1070 | |
1071 case FL_INACTIVE: | |
1072 if (primCount >= dup->FlowThreshHi) | |
1073 { | |
1074 dup->UpFlow = FL_ACTIVE; | |
1075 } | |
1076 else | |
1077 { | |
1078 return; | |
1079 } | |
1080 break; | |
1081 } | |
1082 sig_up_dn_flow(dup->UpFlow); | |
1083 } | |
1084 | |
1085 /* | |
1086 +------------------------------------------------------------------------------ | |
1087 | Function : up_store_data | |
1088 +------------------------------------------------------------------------------ | |
1089 | Description : This procedure copies data from a dti_data_req primitive | |
1090 | into the uplink ring buffer. | |
1091 | | |
1092 | | |
1093 | Parameters : - | |
1094 | | |
1095 | | |
1096 | Return : - | |
1097 +------------------------------------------------------------------------------ | |
1098 */ | |
1099 | |
1100 GLOBAL void up_store_data(void) | |
1101 { | |
1102 T_UP *dup = &l2r_data->up; | |
1103 | |
1104 T_P_UBYTE adr; | |
1105 USHORT len; | |
1106 BOOL primToSend; | |
1107 USHORT bytesCopied; | |
1108 USHORT i, j; | |
1109 T_desc2 *desc; | |
1110 | |
1111 TRACE_FUNCTION ("up_store_data()"); | |
1112 | |
1113 dup->StoreDataActive = TRUE; | |
1114 | |
1115 do | |
1116 { | |
1117 desc = (T_desc2*)dup->Prim->desc_list2.first; | |
1118 if (desc) | |
1119 { | |
1120 len = desc->len; | |
1121 adr = desc->buffer; | |
1122 } | |
1123 else | |
1124 { | |
1125 len = 0; | |
1126 adr = NULL; | |
1127 } | |
1128 | |
1129 up_copy_data_into_l2r (adr, | |
1130 len, | |
1131 dup->Prim->parameters.st_lines.st_line_sa, | |
1132 dup->Prim->parameters.st_lines.st_line_sb, | |
1133 dup->Prim->parameters.st_lines.st_flow, | |
1134 &primToSend, | |
1135 &bytesCopied); | |
1136 | |
1137 dup->Prim->desc_list2.list_len -= bytesCopied; | |
1138 | |
1139 if (desc) | |
1140 { | |
1141 if ((bytesCopied EQ len)) | |
1142 { | |
1143 /* | |
1144 * Block has been copied successfully | |
1145 */ | |
1146 dup->Prim->desc_list2.first = desc->next; | |
1147 MFREE (desc); | |
1148 } | |
1149 else if (bytesCopied > 0) | |
1150 { | |
1151 /* | |
1152 * remaining data must be copied to begin of block | |
1153 */ | |
1154 /*lint -e{661} (Warning -- Likely creation of out-of-bounds) */ | |
1155 for (i=0, j = bytesCopied; j < len; i++, j++) | |
1156 { | |
1157 desc->buffer[i] = desc->buffer[j]; | |
1158 } | |
1159 desc->len -= bytesCopied; | |
1160 } | |
1161 } | |
1162 up_check_alloc(); | |
1163 | |
1164 } while (dup->Prim->desc_list2.first NEQ 0 AND dup->RiBu.alloc NEQ dup->RiBu.idx.wi); | |
1165 | |
1166 if (dup->Prim->desc_list2.first EQ 0) | |
1167 { | |
1168 PFREE (dup->Prim); | |
1169 dup->Prim = NULL; | |
1170 up_send_ready(); | |
1171 } | |
1172 dup->StoreDataActive = FALSE; | |
1173 } | |
1174 | |
1175 /* | |
1176 +------------------------------------------------------------------------------ | |
1177 | Function : up_send_ready | |
1178 +------------------------------------------------------------------------------ | |
1179 | Description : only used in test environment | |
1180 | | |
1181 | Parameters : - | |
1182 | | |
1183 | | |
1184 | Return : - | |
1185 +------------------------------------------------------------------------------ | |
1186 */ | |
1187 | |
1188 GLOBAL void up_send_ready(void) | |
1189 { | |
1190 TRACE_FUNCTION ("up_send_ready()"); | |
1191 | |
1192 if (GET_STATE (UP_UL) EQ IW_IDLE) | |
1193 { | |
1194 if (l2r_data->up.DtiConnected EQ FALSE) | |
1195 { | |
1196 TRACE_EVENT("DTI not connected, but up_send_ready() called -> break"); | |
1197 return; /* jk: DTI_READY_IND primitive cannot be sent when DTI disconnected (!) */ | |
1198 } | |
1199 | |
1200 dti_start ( | |
1201 l2r_hDTI, | |
1202 L2R_DTI_UP_DEF_INSTANCE, | |
1203 L2R_DTI_UP_INTERFACE, | |
1204 L2R_DTI_UP_CHANNEL | |
1205 ); | |
1206 SET_STATE (UP_UL, IW_WAIT); | |
1207 } | |
1208 } | |
1209 | |
1210 LOCAL void clear_primDesc(T_P_UPRIM_DESCRIPTOR primDesc) | |
1211 { | |
1212 primDesc->prim = NULL; | |
1213 | |
1214 primDesc->nFr = 0; | |
1215 primDesc->index = 0; | |
1216 primDesc->offset = 0; | |
1217 primDesc->off_status = 0; | |
1218 primDesc->full = FALSE; | |
1219 primDesc->sa = FL_INACTIVE; | |
1220 primDesc->sb = FL_INACTIVE; | |
1221 } | |
1222 | |
1223 /* | |
1224 +------------------------------------------------------------------------------ | |
1225 | Function : up_free_prim | |
1226 +------------------------------------------------------------------------------ | |
1227 | Description : | |
1228 | | |
1229 | Parameters : primDesc | |
1230 | | |
1231 | | |
1232 | Return : - | |
1233 +------------------------------------------------------------------------------ | |
1234 */ | |
1235 | |
1236 LOCAL void up_free_prim(T_P_UPRIM_DESCRIPTOR primDesc) | |
1237 { | |
1238 TRACE_FUNCTION ("up_free_prim()"); | |
1239 | |
1240 if (primDesc->prim NEQ NULL) | |
1241 { | |
1242 PFREE (primDesc->prim); | |
1243 clear_primDesc(primDesc); | |
1244 } | |
1245 } | |
1246 | |
1247 /* | |
1248 +------------------------------------------------------------------------------ | |
1249 | Function : up_deinit_ribu | |
1250 +------------------------------------------------------------------------------ | |
1251 | Description : | |
1252 | | |
1253 | Parameters : - | |
1254 | | |
1255 | | |
1256 | Return : - | |
1257 +------------------------------------------------------------------------------ | |
1258 */ | |
1259 | |
1260 GLOBAL void up_deinit_ribu(void) | |
1261 { | |
1262 T_UP *dup = &l2r_data->up; | |
1263 | |
1264 T_PRIM_DESC_RIBU_INDEX n; | |
1265 | |
1266 T_P_UPRIM_DESCRIPTOR primDesc; | |
1267 | |
1268 TRACE_FUNCTION ("up_deinit_ribu()"); | |
1269 | |
1270 for (n = 0; n < dup->RiBu.idx.depth; n++) | |
1271 { | |
1272 primDesc = dup->RiBu.primDesc[n]; | |
1273 if (primDesc->prim NEQ NULL) | |
1274 { | |
1275 up_free_prim(primDesc); | |
1276 } | |
1277 } | |
1278 if (GET_STATE (UP_LL) EQ ISW_SEND) | |
1279 { | |
1280 SET_STATE (UP_LL, ISW_IDLE); | |
1281 } | |
1282 } | |
1283 | |
1284 /* | |
1285 +------------------------------------------------------------------------------ | |
1286 | Function : up_send_status | |
1287 +------------------------------------------------------------------------------ | |
1288 | Description : | |
1289 | | |
1290 | Parameters : sa - | |
1291 | sb - | |
1292 | flow - | |
1293 | adr - | |
1294 | | |
1295 | Return : - | |
1296 +------------------------------------------------------------------------------ | |
1297 */ | |
1298 | |
1299 | |
1300 | |
1301 GLOBAL void up_send_status | |
1302 ( | |
1303 T_BIT sa, | |
1304 T_BIT sb, | |
1305 T_FLOW flow, | |
1306 UBYTE adr | |
1307 ) | |
1308 { | |
1309 T_UP *dup = &l2r_data->up; | |
1310 | |
1311 T_P_UPRIM_DESCRIPTOR primDesc; | |
1312 T_P_L2R_FRAME frame; | |
1313 T_BIT x = 0; | |
1314 | |
1315 TRACE_FUNCTION ("up_send_status()"); | |
1316 | |
1317 primDesc = dup->RiBu.primDesc[dup->RiBu.idx.wi]; | |
1318 frame = (*primDesc->adr)[0]; | |
1319 | |
1320 switch (flow) | |
1321 { | |
1322 case FL_ACTIVE: | |
1323 x = 1; | |
1324 break; | |
1325 case FL_INACTIVE: | |
1326 x = 0; | |
1327 break; | |
1328 } | |
1329 (*frame)[0] = sa << SO_SA_BIT | sb << SO_SB_BIT | x << SO_X_BIT | adr; | |
1330 | |
1331 /* jk:030501 - TEST CASE 251 - | |
1332 new funktion parameter 'adr' was introduced | |
1333 in order to cancel the older function 'up_send_break(...)' | |
1334 */ | |
1335 primDesc->sa = sa; /* the status has to be saved in order to be correctly stored later */ | |
1336 primDesc->sb = sb; /* on into "dup->LastSentSa/Sb" [up_send current_prim()] */ | |
1337 | |
1338 primDesc->index = 1; | |
1339 primDesc->offset = 0; | |
1340 | |
1341 cl_ribu_write_index(&dup->RiBu.idx); /* point to next primitive */ | |
1342 } | |
1343 | |
1344 /* | |
1345 +------------------------------------------------------------------------------ | |
1346 | Function : up_set_flow_in_prim | |
1347 +------------------------------------------------------------------------------ | |
1348 | Description : | |
1349 | | |
1350 | Parameters : prim - | |
1351 | | |
1352 | | |
1353 | Return : - | |
1354 +------------------------------------------------------------------------------ | |
1355 */ | |
1356 | |
1357 LOCAL void up_set_flow_in_prim(T_P_RLP_DATA_REQ prim) | |
1358 { | |
1359 T_UP *dup = &l2r_data->up; | |
1360 | |
1361 if (dup->MrgFlow EQ FL_INACTIVE) | |
1362 { | |
1363 TRACE_FUNCTION ("up_set_flow_in_prim(INACTIVE)"); | |
1364 } | |
1365 else | |
1366 { | |
1367 T_PRIM_INDEX frames; | |
1368 T_PRIM_INDEX ind; | |
1369 UBYTE off; | |
1370 register UBYTE statOct; | |
1371 T_P_L2R_FRAME frame; | |
1372 | |
1373 TRACE_FUNCTION ("up_set_flow_in_prim(ACTIVE)"); | |
1374 | |
1375 frames = prim->sdu.l_buf / (8 * dup->FrameSize); | |
1376 frame = (T_P_L2R_FRAME) (prim->sdu.buf + (prim->sdu.o_buf / 8) + HEADER_LEN); | |
1377 off = 0; | |
1378 ind = 0; | |
1379 | |
1380 while (ind < frames) | |
1381 { | |
1382 statOct = (*frame)[off]; | |
1383 SET_BIT(statOct, SO_X_BIT); | |
1384 (*frame)[off] = statOct; | |
1385 | |
1386 switch (statOct & SO_ADR_MASK) | |
1387 { | |
1388 case SO_BREAK_REQ: | |
1389 case SO_BREAK_ACK: | |
1390 case SO_END_EMPTY: | |
1391 case SO_END_FULL: | |
1392 ind++; | |
1393 frame = (T_P_L2R_FRAME)((UBYTE*)frame + dup->FrameSize); | |
1394 off = 0; | |
1395 break; | |
1396 | |
1397 case SO_TWO_OCTET: | |
1398 off++; | |
1399 off += ((*frame)[off] & SO_ADR_MASK_TWO_OCT) + 1; | |
1400 if (off >= dup->DataSize) | |
1401 { | |
1402 ind++; | |
1403 frame = (T_P_L2R_FRAME)((UBYTE*)frame + dup->FrameSize); | |
1404 off = 0; | |
1405 } | |
1406 break; | |
1407 | |
1408 default: | |
1409 off += (statOct & SO_ADR_MASK) + 1; | |
1410 if (off >= dup->DataSize) | |
1411 { | |
1412 ind++; | |
1413 frame = (T_P_L2R_FRAME)((UBYTE*)frame + dup->FrameSize); | |
1414 off = 0; | |
1415 } | |
1416 break; | |
1417 } | |
1418 } | |
1419 } | |
1420 dup->LastSentFlow = dup->MrgFlow; | |
1421 } | |
1422 | |
1423 /* | |
1424 +------------------------------------------------------------------------------ | |
1425 | Function : up_send_current_prim | |
1426 +------------------------------------------------------------------------------ | |
1427 | Description : | |
1428 | | |
1429 | Parameters : - | |
1430 | | |
1431 | | |
1432 | Return : - | |
1433 +------------------------------------------------------------------------------ | |
1434 */ | |
1435 | |
1436 GLOBAL void up_send_current_prim(void) | |
1437 { | |
1438 T_UP *dup = &l2r_data->up; | |
1439 T_P_UPRIM_DESCRIPTOR primDesc = dup->RiBu.primDesc[dup->RiBu.idx.ri]; | |
1440 | |
1441 TRACE_FUNCTION ("up_send_current_prim()"); | |
1442 | |
1443 if (!primDesc->full AND primDesc->index < primDesc->nFr) | |
1444 { | |
1445 TRACE_FUNCTION ("prim is not full"); | |
1446 if (primDesc->offset > 0) | |
1447 { | |
1448 if (up_fill_in_status_octet((T_P_UBYTE)(*primDesc->adr)[primDesc->index], primDesc->off_status, primDesc->offset)) | |
1449 { | |
1450 primDesc->offset++; | |
1451 if (primDesc->offset >= dup->DataSize) | |
1452 { | |
1453 primDesc->offset = 0; | |
1454 primDesc->index++; | |
1455 } | |
1456 } | |
1457 } | |
1458 | |
1459 if (primDesc->offset > 0 OR primDesc->index EQ 0) | |
1460 { | |
1461 /* | |
1462 * Add status octet, if there is a partly filled frame | |
1463 * or if status has changed since last write | |
1464 */ | |
1465 (*(*primDesc->adr)[primDesc->index])[primDesc->offset] = | |
1466 dup->LastRcvdSa << SO_SA_BIT | | |
1467 dup->LastRcvdSb << SO_SB_BIT | | |
1468 0 << SO_X_BIT | | |
1469 SO_END_EMPTY; | |
1470 primDesc->sa = dup->LastRcvdSa; | |
1471 primDesc->sb = dup->LastRcvdSb; | |
1472 primDesc->index++; | |
1473 } | |
1474 primDesc->prim->sdu.l_buf = primDesc->index * dup->FrameSize * 8; | |
1475 } | |
1476 | |
1477 dup->LastSentSa = primDesc->sa; | |
1478 dup->LastSentSb = primDesc->sb; | |
1479 up_set_flow_in_prim(primDesc->prim); | |
1480 | |
1481 PSENDX (RLP, primDesc->prim); | |
1482 | |
1483 clear_primDesc(primDesc); /* this primitive doesn't belong to us any longer */ | |
1484 | |
1485 cl_ribu_read_index(&dup->RiBu.idx); /* point to next primitive */ | |
1486 | |
1487 dup->UrgentMsg = FALSE; | |
1488 up_check_alloc(); | |
1489 up_check_flow(); | |
1490 } | |
1491 | |
1492 | |
1493 /* | |
1494 +------------------------------------------------------------------------------ | |
1495 | Function : up_send_prim_cond | |
1496 +------------------------------------------------------------------------------ | |
1497 | Description : | |
1498 | | |
1499 | Parameters : - | |
1500 | | |
1501 | | |
1502 | Return : - | |
1503 +------------------------------------------------------------------------------ | |
1504 */ | |
1505 | |
1506 GLOBAL void up_send_prim_cond(void) | |
1507 { | |
1508 TRACE_FUNCTION ("up_send_prim_cond()"); | |
1509 | |
1510 switch (GET_STATE (UP_LL)) | |
1511 { | |
1512 case ISW_WAIT: | |
1513 TIMERSTOP (TIMER_TUP_SND); | |
1514 up_send_current_prim(); | |
1515 SET_STATE (UP_LL, ISW_IDLE); | |
1516 break; | |
1517 | |
1518 default: | |
1519 l2r_data->up.UrgentMsg = TRUE; | |
1520 up_check_flow(); | |
1521 up_check_alloc(); | |
1522 SET_STATE (UP_LL, ISW_SEND); | |
1523 break; | |
1524 } | |
1525 } | |
1526 | |
1527 /* | |
1528 +------------------------------------------------------------------------------ | |
1529 | Function : up_init_ribu | |
1530 +------------------------------------------------------------------------------ | |
1531 | Description : | |
1532 | | |
1533 | Parameters : - | |
1534 | | |
1535 | | |
1536 | Return : - | |
1537 +------------------------------------------------------------------------------ | |
1538 */ | |
1539 | |
1540 | |
1541 GLOBAL void up_init_ribu(void) | |
1542 { | |
1543 T_UP *dup = &l2r_data->up; | |
1544 | |
1545 T_PRIM_DESC_RIBU_INDEX n; | |
1546 T_PRIM_INDEX m; | |
1547 | |
1548 TRACE_FUNCTION ("up_init_ribu()"); | |
1549 | |
1550 dup->RiBu.alloc = 0; | |
1551 | |
1552 cl_ribu_init(&dup->RiBu.idx, dup->RiBu.idx.depth); | |
1553 | |
1554 for (n = 0; n < dup->RiBu.idx.depth; n++) | |
1555 { | |
1556 dup->RiBu.primDesc[n] = &(dup->PrimDesc[n]); | |
1557 | |
1558 dup->PrimDesc[n].nFr = 0; | |
1559 dup->PrimDesc[n].adr = (T_P_ADR_VECTOR)&(dup->AdrVec[n]); | |
1560 dup->PrimDesc[n].index = 0; | |
1561 dup->PrimDesc[n].offset = 0; | |
1562 dup->PrimDesc[n].off_status = 0; | |
1563 dup->PrimDesc[n].full = FALSE; | |
1564 dup->PrimDesc[n].sa = FL_INACTIVE; | |
1565 dup->PrimDesc[n].sb = FL_INACTIVE; | |
1566 dup->PrimDesc[n].prim = NULL; | |
1567 | |
1568 for(m = 0;m < L2R_FRAMES_PER_PRIM_MAX; m++) | |
1569 { | |
1570 dup->AdrVec[n][m] = NULL; | |
1571 } | |
1572 | |
1573 if (dup->RiBu.alloc < UP_RIBU_PREALLOC) | |
1574 { | |
1575 up_alloc_prim(); | |
1576 } | |
1577 } | |
1578 } | |
1579 | |
1580 /* | |
1581 +------------------------------------------------------------------------------ | |
1582 | Function : up_store_status | |
1583 +------------------------------------------------------------------------------ | |
1584 | Description : | |
1585 | | |
1586 | Parameters : sa | |
1587 | sb | |
1588 | flow | |
1589 | | |
1590 | Return : - | |
1591 +------------------------------------------------------------------------------ | |
1592 */ | |
1593 | |
1594 | |
1595 GLOBAL void up_store_status | |
1596 ( | |
1597 T_BIT sa, | |
1598 T_BIT sb, | |
1599 T_FLOW flow | |
1600 ) | |
1601 { | |
1602 T_UP *dup = &l2r_data->up; | |
1603 | |
1604 #ifdef _SIMULATION_ | |
1605 TRACE_FUNCTION ("up_store_status()"); | |
1606 #endif | |
1607 | |
1608 dup->LastRcvdSa = sa; | |
1609 dup->LastRcvdSb = sb; | |
1610 | |
1611 if (dup->FlowCtrlUsed EQ FALSE OR flow EQ dup->ULFlow) | |
1612 { | |
1613 return; | |
1614 } | |
1615 | |
1616 dup->ULFlow = flow; | |
1617 | |
1618 up_merge_flow(); | |
1619 sig_up_dn_ul_flow(dup->ULFlow); | |
1620 } | |
1621 | |
1622 /* | |
1623 +------------------------------------------------------------------------------ | |
1624 | Function : up_send_empty_frame | |
1625 +------------------------------------------------------------------------------ | |
1626 | Description : | |
1627 | | |
1628 | Parameters : sa - | |
1629 | sb - | |
1630 | flow - | |
1631 | | |
1632 | Return : - | |
1633 +------------------------------------------------------------------------------ | |
1634 */ | |
1635 | |
1636 | |
1637 GLOBAL void up_send_empty_frame(T_BIT sa, T_BIT sb, T_FLOW flow) | |
1638 { | |
1639 T_UP *dup = &l2r_data->up; | |
1640 | |
1641 T_BIT x = 0; | |
1642 USHORT sduSize = dup->FrameSize << 3; | |
1643 | |
1644 PALLOC_SDU(data_req, RLP_DATA_REQ, sduSize); | |
1645 | |
1646 TRACE_FUNCTION ("up_send_empty_frame()"); | |
1647 | |
1648 #ifdef _SIMULATION_ | |
1649 /* Clear SDU for test environment */ | |
1650 { | |
1651 UBYTE *p; | |
1652 UBYTE *pend; | |
1653 p = &data_req->sdu.buf[0]; | |
1654 pend = p + dup->FrameSize; | |
1655 while (p < pend) | |
1656 { | |
1657 *p++ = 0; | |
1658 } | |
1659 } | |
1660 #endif | |
1661 | |
1662 data_req->sdu.o_buf = 0; | |
1663 data_req->sdu.l_buf = sduSize; | |
1664 | |
1665 switch (flow) | |
1666 { | |
1667 case FL_ACTIVE: | |
1668 x = 1; | |
1669 break; | |
1670 case FL_INACTIVE: | |
1671 x = 0; | |
1672 break; | |
1673 } | |
1674 /*lint -e416 (Warning -- Likely creation of out-of-bounds pointer) */ | |
1675 /*lint -e415 (Warning -- Likely access of out-of-bounds pointer) */ | |
1676 data_req->sdu.buf[L2R_ENCODING_OFFSET] = sa << SO_SA_BIT | sb << SO_SB_BIT | x << SO_X_BIT | SO_END_EMPTY; | |
1677 /*lint +e416 (Warning -- Likely creation of out-of-bounds pointer) */ | |
1678 /*lint +e415 (Warning -- Likely access of out-of-bounds pointer) */ | |
1679 | |
1680 dup->LastSentFlow = flow; | |
1681 dup->LastSentSa = sa; | |
1682 dup->LastSentSb = sb; | |
1683 | |
1684 PSENDX (RLP, data_req); | |
1685 } | |
1686 | |
1687 /* | |
1688 +------------------------------------------------------------------------------ | |
1689 | Function : up_merge_flow | |
1690 +------------------------------------------------------------------------------ | |
1691 | Description : | |
1692 | | |
1693 | Parameters : - | |
1694 | | |
1695 | | |
1696 | Return : - | |
1697 +------------------------------------------------------------------------------ | |
1698 */ | |
1699 | |
1700 | |
1701 GLOBAL void up_merge_flow(void) | |
1702 { | |
1703 T_UP *dup = &l2r_data->up; | |
1704 | |
1705 #ifdef _SIMULATION_ | |
1706 TRACE_FUNCTION ("up_merge_flow()"); | |
1707 #endif | |
1708 | |
1709 if (dup->FlowCtrlUsed AND (dup->DnFlow EQ FL_ACTIVE OR dup->ULFlow EQ FL_ACTIVE)) | |
1710 { | |
1711 /* flow control active */ | |
1712 dup->MrgFlow = FL_ACTIVE; | |
1713 } | |
1714 else | |
1715 { | |
1716 /* flow control inactive */ | |
1717 dup->MrgFlow = FL_INACTIVE; | |
1718 } | |
1719 | |
1720 } | |
1721 | |
1722 /* | |
1723 +------------------------------------------------------------------------------ | |
1724 | Function : up_rq_init | |
1725 +------------------------------------------------------------------------------ | |
1726 | Description : | |
1727 | | |
1728 | Parameters : - | |
1729 | | |
1730 | | |
1731 | Return : - | |
1732 +------------------------------------------------------------------------------ | |
1733 */ | |
1734 | |
1735 GLOBAL void up_rq_init(void) | |
1736 { | |
1737 #ifdef _SIMULATION_ | |
1738 TRACE_FUNCTION ("up_rq_init()"); | |
1739 #endif | |
1740 | |
1741 l2r_data->up.QRemapWrite = 0; | |
1742 l2r_data->up.QRemapRead = 0; | |
1743 } | |
1744 | |
1745 /* | |
1746 +------------------------------------------------------------------------------ | |
1747 | Function : up_some_data_to_send | |
1748 +------------------------------------------------------------------------------ | |
1749 | Description : | |
1750 | | |
1751 | Parameters : - | |
1752 | | |
1753 | | |
1754 | Return : TRUE - | |
1755 | FALSE - | |
1756 +------------------------------------------------------------------------------ | |
1757 */ | |
1758 | |
1759 GLOBAL BOOL up_some_data_to_send(void) | |
1760 { | |
1761 T_UP *dup = &l2r_data->up; | |
1762 | |
1763 #ifdef _SIMULATION_ | |
1764 TRACE_EVENT ("check if any data to send"); | |
1765 #endif | |
1766 | |
1767 if ( | |
1768 dup->RiBu.idx.filled OR | |
1769 (dup->RiBu.primDesc[dup->RiBu.idx.ri]->index > 0) OR | |
1770 (dup->RiBu.primDesc[dup->RiBu.idx.ri]->offset > 0) OR | |
1771 (dup->LastRcvdSa NEQ dup->LastSentSa) OR | |
1772 (dup->LastRcvdSb NEQ dup->LastSentSb) | |
1773 ) | |
1774 { | |
1775 return (TRUE); | |
1776 } | |
1777 return (FALSE); | |
1778 } |