Added code for MAC-PHY interface, DU_APP, F1AP, SCTP and CU stub
[o-du/l2.git] / src / mt / ss_rbuf.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 /*
20   Steps to Add a new Ring Buffer
21
22 1. Add Buffer Id to enum in ss_rbuf.h
23 2. Update Static SsRngCfgTbl below for ring and element size. Add a macro in ss_rbuf.h
24 3. typedef a structure for element type if not available in ss_rbuf.h
25 4. Call SCreateSRngBuf for new Buffer id from bcInitRingBuffers() in bc_cpu_init.c
26 5. Call SAttachSRngBuf from producer and consumer ActvInit
27 6. Call SEnqSRngBuf and SDeqSRngBuf from producer and consumer respectively
28  
29 */
30 #include "envopt.h"        /* environment options     */
31 #include "envdep.h"        /* environment dependent   */
32 #include "envind.h"        /* environment independent */
33 #include "gen.h"           /* general                 */
34 #include "ssi.h"           /* system services         */
35 #include "cm_err.h"       
36 #include <stdlib.h>
37 #include "gen.x"           /* general layer */
38 #include "ssi.x"           /* system services */
39 #include "ss_rbuf.h"
40 #include "ss_rbuf.x"
41
42 U32 ssRngBufStatus = 0;
43
44 /* Global Ring Loop Up Table */
45 SsRngBufTbl SsRngInfoTbl[SS_RNG_BUF_MAX];
46
47
48 PUBLIC Void SsRngBufEnable(Void)
49 {
50   ssRngBufStatus = TRUE;
51 }
52
53
54 PUBLIC Void SsRngBufDisable(Void)
55 {
56   ssRngBufStatus = FALSE;
57
58 }
59 /*
60 Func: SCreateSRngBuf
61 Desc: Creates Ring Buffer for the given Id.
62       Ring Structure is allocated from given 
63       Region and Pool
64 */
65 #ifdef ANSI
66 PUBLIC S16 SCreateSRngBuf
67 (
68 U32 id,  
69 Region region,
70 Pool pool,
71 U32 elmSize,
72 U32 rngSize
73 )
74 #else
75 PUBLIC S16 SCreateSRngBuf (id, region, pool, elmSize, rngSize)
76 U32 id; 
77 Region region;
78 Pool pool;
79 U32 elmSize;
80 U32 rngSize;
81 #endif
82 {
83    SsRngBuf* ring;
84
85    /* Validate Id */
86    if(id >= SS_RNG_BUF_MAX)
87    {
88 #if (ERRCLASS & ERRCLS_DEBUG)
89       SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
90 #endif
91       RETVALUE(RFAILED);
92    }
93    if(SsRngInfoTbl[id].r_addr != 0)
94    {
95 #if (ERRCLASS & ERRCLS_DEBUG)
96       SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, 
97             "Failed to Create Ring Buffer Id Ring already exist");
98 #endif
99       RETVALUE(RFAILED);
100    }
101    /* Get Element Size */
102    
103    /* Get Ring Size    */
104    /* Allocate memory for Ring structure */
105    ring = (SsRngBuf* )malloc(sizeof(SsRngBuf));
106    if(ring == NULLP)
107    {
108 #if (ERRCLASS & ERRCLS_DEBUG)
109       SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring  Failed!!!")
110 #endif
111       RETVALUE(RFAILED);
112    }
113 #if (ERRCLASS & ERRCLS_DEBUG)
114       SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ring, 
115             "Failed to Create Ring Buffer Id Ring already exist");
116 #endif
117
118    ring->size  = rngSize; /* No empty elem */
119    ring->read  = 0;
120    ring->write = 0;
121    ring->type  = elmSize;
122
123    /* Allocate elements memory */
124    ring->elem  = calloc(ring->size, ring->type);
125    if(ring->elem == NULLP)
126     {
127 #if (ERRCLASS & ERRCLS_DEBUG)
128       SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring  Failed!!!")
129 #endif
130       free(ring);
131       RETVALUE(RFAILED);
132     }
133     /* Update Buffer Id Table */
134     SsRngInfoTbl[id].r_addr   = ring;
135     SsRngInfoTbl[id].rngState = SS_RNG_CREATED;
136     SsRngInfoTbl[id].n_write  = 0;
137     SsRngInfoTbl[id].n_read   = 0;
138
139 #ifndef ALIGN_64BIT
140     printf("Ring Buffer Created with id =%ld rSize:%ld eSize:%ld %lx\n",id,ring->size,ring->type,(PTR)ring);
141 #else
142     printf("Ring Buffer Created with id =%d rSize:%d eSize:%d %lx\n",id,ring->size,ring->type,(PTR)ring);
143 #endif
144     RETVALUE(ROK);
145 }
146
147 /*
148 Func: SAttachSRngBuf
149 Desc: Attach the calling Entity to a ring buffer 
150       as consumer(Rx) or producer (Tx)
151 */
152 #ifdef ANSI
153 PUBLIC S16 SAttachSRngBuf
154 (
155 U32 id,  
156 U32 ent,
157 U32 txRx
158 )
159 #else
160 PUBLIC S16 SAttachSRngBuf (id, ent, txRx)
161 U32 id;
162 U32 ent;
163 U32 txRx;
164 #endif
165 {
166     /* Retrive Buffer from Global Info Table */
167     if( id >= SS_RNG_BUF_MAX)
168     {
169 #if (ERRCLASS & ERRCLS_DEBUG)
170       SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
171 #endif
172        RETVALUE(RFAILED);
173     }
174     if(SsRngInfoTbl[id].rngState < SS_RNG_CREATED)
175     {
176 #if (ERRCLASS & ERRCLS_DEBUG)
177       SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, 
178             "Attach Request in Invalid Ring ID");
179 #endif
180 #ifndef ALIGN_64BIT
181        printf("Attach Request in Invalid Ring State %ld id%ld \n",
182          SsRngInfoTbl[id].rngState,id);
183 #else
184        printf("Attach Request in Invalid Ring State %d id%d \n",
185          SsRngInfoTbl[id].rngState,id);
186 #endif
187        RETVALUE(RFAILED);
188     }
189     if(txRx == SS_RNG_TX)
190     {
191         SsRngInfoTbl[id].txEnt = ent;
192         SsRngInfoTbl[id].rngState = SS_RNG_TX_ATTACHED;
193     }
194     else if(txRx == SS_RNG_RX)
195     {
196         SsRngInfoTbl[id].rxEnt = ent;
197         SsRngInfoTbl[id].rngState = SS_RNG_RX_ATTACHED;
198     }
199     RETVALUE(ROK);
200 }
201 /* 
202 Func: SConnectSRngBuf
203 Desc: Establish a pipe between producer and consumer
204
205 */
206 #ifdef ANSI
207 PUBLIC S16 SConnectSRngBuf
208 (
209 U32 id,  
210 U32 rxEnt
211 )
212 #else
213 PUBLIC S16 SConnectSRngBuf (id, rxEnt)
214 U32 id;
215 U32 rxEnt;
216 #endif
217 {
218    /* Send to Reciever ENT*/ 
219    RETVALUE(ROK); 
220 }
221
222 /*
223 Func: IsFull
224 Desc: Checks if Ring is full
225 */
226 inline static S16 IsFull(SsRngBuf* rBuf)
227 {
228 #if 0
229    /* write+1 == read implies ring is full */
230    return ((((rBuf->write + 1)> rBuf->size)?0:(rBuf->write+1))==rBuf->read);
231 #endif
232 #if 1
233    if((rBuf->write+1) == rBuf->read)
234    {
235      return 1;
236    }
237    if((rBuf->write+1) == (rBuf->read + rBuf->size))
238    {
239      return 1;
240    }
241    if((rBuf->write + 1) > rBuf->size )
242    {
243      return 1;
244    }
245    return 0;
246 #endif
247
248 /*
249 Func: IsEmpty
250 Desc: Checks if ring is empty
251 */
252 inline static S16 IsEmpty(SsRngBuf* rBuf)
253 {
254    /* write == read implies Buffer is empty*/
255    return (rBuf->write == rBuf->read); 
256 }
257
258 PUBLIC S16 isRngEmpty(U32 id)
259 {
260    return (IsEmpty(SsRngInfoTbl[id].r_addr));
261 }
262 /*
263 Func: SEnqSRngBuf
264 Desc: Perform Queue operation on Ring bufer
265 */
266 #ifdef ANSI
267 PUBLIC S16 SEnqSRngBuf 
268 (
269 U32 id, 
270 Void* elem
271 )
272 #else
273 PUBLIC S16 SEnqSRngBuf(id,elem) 
274 U32 id;
275 Void* elem;
276 #endif
277 {
278    U8* w_ptr;
279    U8 i=0;
280    U8 *element = (U8 *)elem;
281    U32 wrIndex;
282    /* TBD To replace id with ring addr when SAttachSRngBuf is used*/
283    /* Retrive Buffer from Id */
284    SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
285    if (IsFull(ring))
286    {
287         SsRngInfoTbl[id].nWriteFail++;
288         RETVALUE(RFAILED);
289    }
290    /* TBD Avoid multiplication for optimisation */
291    w_ptr = (U8*)ring->elem + (ring->write * ring->type);
292    /* TBD Avoid for loop - use memcpy */
293    for( i=0; i < ring->type; i++)
294    {
295       *(U8*)w_ptr = *(U8*)element;
296       w_ptr++;
297       (U8*)element++;
298    }
299    /* Increment write index */
300     wrIndex = ring->write + 1 ;
301     ring->write = (wrIndex == ring->size)?0: wrIndex;
302    /* Update Statistics */
303    SsRngInfoTbl[id].n_write++;
304    RETVALUE(ROK);
305 }
306
307 #ifdef ANSI
308 PUBLIC S16 SGetNumElemInRng
309 (
310 U32 id
311 )
312 #else
313 PUBLIC S16 SGetNumElemInRng (id)
314 U32 id;
315 #endif
316 {
317
318    S16 freeDist = (SsRngInfoTbl[id].n_write- SsRngInfoTbl[id].n_read);
319
320         RETVALUE(freeDist);
321 }
322 /*
323 Func: SDeqSRngBuf
324 Desc: Perform DeQueue operation on Ring bufer
325 */
326 #ifdef ANSI
327 PUBLIC S16 SDeqSRngBuf
328 (
329 U32 id,
330 Void *elem
331 )
332 #else
333 PUBLIC S16 SDeqSRngBuf (id,elem)
334 U8 id;
335 Void *elem;
336 #endif
337 {
338    U8* r_ptr;
339    U8 i=0;
340    U8 *element = (U8 *)elem;
341    U32 rdIndex;
342    /* Retrive Buffer from Id*/
343    SsRngBuf* ring  = SsRngInfoTbl[id].r_addr;
344    if(IsEmpty(ring))
345    {  
346        SsRngInfoTbl[id].nReadFail++;
347        RETVALUE(RFAILED);
348    }
349    r_ptr = (U8*)ring->elem + (ring->read * ring->type);
350    for(i=0; i<ring->type; i++)
351    {
352       *(U8*)element = *r_ptr;
353       (U8*)element++;
354       r_ptr++;
355    }
356    // Avoiding % operation for wrap around
357    rdIndex= ring->read + 1;
358    ring->read = (rdIndex == ring->size)?0:rdIndex;
359    SsRngInfoTbl[id].n_read++;
360    RETVALUE(ROK);
361 }
362
363 #ifdef ANSI
364 PUBLIC S16 SDestroySRngBuf 
365 (
366 U32 id,
367 Region region,
368 Pool pool
369 )
370 #else
371 PUBLIC S16 SDestroySRngBuf(id, region, pool)
372 U32 id;
373 Region region;
374 Pool pool;
375 #endif
376 {
377    /* Retrive Buffer from Id */
378    SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
379    if(ring)
380    {   
381       //SPutSBuf(region, pool, (Data *)ring->elem, (ring->size * ring->type));
382       //SPutSBuf(region, pool, (Data *)ring, sizeof(SsRngBuf));
383       
384       free(ring->elem); /* OK if null */ 
385       free(ring); /* OK if null */ 
386
387       /* Update Global Info  table */
388       SsRngInfoTbl[id].rngState = SS_RNG_DESTROYED;
389       SsRngInfoTbl[id].r_addr = 0;
390    }
391    RETVALUE(ROK);
392 }
393
394 #ifdef ANSI
395 PUBLIC S16 SPrintSRngStats
396 (
397 Void
398 )
399 #else
400 PUBLIC S16 SPrintSRngStats ()
401 Void;
402 #endif
403 {
404 U32 i; 
405
406    Txt   prntBuf[100];
407
408 #ifdef RGL_SPECIFIC_CHANGES
409    RETVALUE(ROK);
410 #endif
411    for(i=0; i< SS_RNG_BUF_MAX;i++)
412    {
413       if(SsRngInfoTbl[i].r_addr != 0 )
414       {
415 #ifndef ALIGN_64BIT
416          sprintf(prntBuf,"\n=======Ring %ld Stats========\n",i);
417          SDisplay(0, prntBuf);
418          sprintf(prntBuf,"r_addr      = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
419          SDisplay(0, prntBuf);
420          sprintf(prntBuf,"txEnt       = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
421          SDisplay(0, prntBuf);
422          sprintf(prntBuf,"rxEnt       = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
423          SDisplay(0, prntBuf);
424          sprintf(prntBuf,"n_write     = %lu\n", SsRngInfoTbl[i].n_write);
425          SDisplay(0, prntBuf);
426          sprintf(prntBuf,"n_read      = %lu\n", SsRngInfoTbl[i].n_read);
427          SDisplay(0, prntBuf);
428          sprintf(prntBuf,"nWriteFail  = %lu\n", SsRngInfoTbl[i].nWriteFail);
429          SDisplay(0, prntBuf);
430          sprintf(prntBuf,"nReadFail   = %lu\n", SsRngInfoTbl[i].nReadFail);
431          SDisplay(0, prntBuf);
432          sprintf(prntBuf,"pktDrop     = %lu\n", SsRngInfoTbl[i].pktDrop);
433          SDisplay(0, prntBuf);
434          sprintf(prntBuf,"State       = %lu\n\n", SsRngInfoTbl[i].rngState);
435          SDisplay(0, prntBuf);
436          sprintf(prntBuf,"nPktProc    = %lu\n\n", SsRngInfoTbl[i].nPktProc);
437          SDisplay(0, prntBuf);
438 #else
439          sprintf(prntBuf,"\n=======Ring %d Stats========\n",i);
440          SDisplay(0, prntBuf);
441          sprintf(prntBuf,"r_addr      = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
442          SDisplay(0, prntBuf);
443          sprintf(prntBuf,"txEnt       = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
444          SDisplay(0, prntBuf);
445          sprintf(prntBuf,"rxEnt       = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
446          SDisplay(0, prntBuf);
447          sprintf(prntBuf,"n_write     = %u\n", SsRngInfoTbl[i].n_write);
448          SDisplay(0, prntBuf);
449          sprintf(prntBuf,"n_read      = %u\n", SsRngInfoTbl[i].n_read);
450          SDisplay(0, prntBuf);
451          sprintf(prntBuf,"nWriteFail  = %u\n", SsRngInfoTbl[i].nWriteFail);
452          SDisplay(0, prntBuf);
453          sprintf(prntBuf,"nReadFail   = %u\n", SsRngInfoTbl[i].nReadFail);
454          SDisplay(0, prntBuf);
455          sprintf(prntBuf,"pktDrop     = %u\n", SsRngInfoTbl[i].pktDrop);
456          SDisplay(0, prntBuf);
457          sprintf(prntBuf,"State       = %u\n\n", SsRngInfoTbl[i].rngState);
458          SDisplay(0, prntBuf);
459          sprintf(prntBuf,"nPktProc    = %u\n\n", SsRngInfoTbl[i].nPktProc);
460          SDisplay(0, prntBuf);
461
462 #endif
463       }
464    }
465    RETVALUE(ROK); 
466 }
467
468 #ifdef ANSI
469 PUBLIC Void* SRngGetWIndx
470 (
471 U32 rngId
472 )
473 #else
474 PUBLIC Void* SRngGetWIndx (rngId)
475 U32 rngId;
476 #endif
477 {
478    /* Retrive Buffer from Id*/
479    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
480    if (IsFull(ring))
481    {
482       SsRngInfoTbl[rngId].nWriteFail++;
483       RETVALUE(NULLP);
484    }
485    else
486    {
487       RETVALUE(((U8 *)ring->elem) + (ring->type * ring->write));
488    }
489 }
490
491 #ifdef ANSI
492 PUBLIC Void* SRngGetRIndx
493 (
494 U32 rngId
495 )
496 #else
497 PUBLIC Void* SRngGetRIndx (rngId)
498 U32 rngId;
499 #endif
500 {
501    /* Retrive Buffer from Id*/
502    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
503    if(IsEmpty(ring))
504    {
505       SsRngInfoTbl[rngId].nReadFail++;
506       RETVALUE(NULLP);
507    }
508    else
509    {
510       RETVALUE(((U8 *)ring->elem) + (ring->type * ring->read));
511    }
512 }
513
514 #ifdef ANSI
515 PUBLIC Void SRngIncrWIndx
516 (
517 U32 rngId
518 )
519 #else
520 PUBLIC Void SRngIncrWIndx (rngId)
521 U32 rngId;
522 #endif
523 {
524    U32 wrIndex;
525    /* Retrive Buffer from Id*/
526    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
527    wrIndex = ring->write + 1;
528    ring->write = (wrIndex == ring->size)?0:wrIndex;
529    /* Update Statistics */
530    SsRngInfoTbl[rngId].n_write++;
531 }
532
533 #ifdef ANSI
534 PUBLIC Void SRngIncrRIndx
535 (
536 U32 rngId
537 )
538 #else
539 PUBLIC Void SRngIncrRIndx (rngId)
540 U32 rngId;
541 #endif
542 {
543    U32 rdIndex;
544    /* Retrive Buffer from Id*/
545    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
546    rdIndex = ring->read + 1;
547    ring->read = (rdIndex == ring->size)?0:rdIndex;
548    /* Update Statistics */
549    SsRngInfoTbl[rngId].n_read++;
550 }
551 #ifdef XEON_SPECIFIC_CHANGES
552 #if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF))
553 S16 mtAddBufToRing(SsRngBufId ringId,void *bufPtr,U8 freeType)
554 {
555    S16 ret1 = ROK;
556    
557    Void *elem = NULLP;
558
559    RgKwFreeInfo *bufFreeInfo = NULLP;
560    elem = SRngGetWIndx(ringId);
561
562    if (NULLP != elem)
563    {
564       bufFreeInfo = (RgKwFreeInfo *) elem;
565
566       bufFreeInfo->bufToFree = bufPtr;
567       bufFreeInfo->freeType  = freeType;
568
569       SRngIncrWIndx(ringId);
570
571       SsRngInfoTbl[ringId].pktRate++;
572    }   
573    else
574    {
575       printf("Free Ring FULL id %d!!! \n",ringId);
576       SsRngInfoTbl[ringId].pktDrop++;
577       ret1 = RFAILED;
578    }
579    RETVALUE(ret1);
580 }
581 #endif
582 #endif
583
584
585
586 #if 0
587 int main(int argc, char **argv) 
588 {
589     SCreateSRngBuf(1,sizeof(SsRngBuf), 10);
590     rngElem* buf; 
591     /* Fill buffer with test elements 3 times */
592     buf = (SsRngBuf*)malloc(sizeof(rngBuf));
593     buf->ptr = 1;
594     SEnqSRngBuf(1, buf);
595     buf = (SsRngBuf*)malloc(sizeof(rngBuf));
596     buf->ptr = 2;
597     SEnqSRngBuf(1, buf);
598     buf = (SsRngBuf*)malloc(sizeof(rngBuf));
599     buf->ptr = 3;
600     SEnqSRngBuf(1, buf);
601
602    SDeqSRngBuf(1,buf);
603    printf("buf 1 = %d",buf->ptr);
604    SDeqSRngBuf(1,buf);
605    printf("buf 2 = %d",buf->ptr);
606    SDeqSRngBuf(1,buf);
607    printf("buf 3 = %d",buf->ptr);
608  
609     return 0;
610 }
611 #endif
612
613 /**********************************************************************
614          End of file
615 **********************************************************************/