U8, U16, U32 data type changes
[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 uint32_t ssRngBufStatus = 0;
43
44 /* Global Ring Loop Up Table */
45 SsRngBufTbl SsRngInfoTbl[SS_RNG_BUF_MAX];
46
47
48 Void SsRngBufEnable(Void)
49 {
50   ssRngBufStatus = TRUE;
51 }
52
53
54 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 S16 SCreateSRngBuf
67 (
68 uint32_t id,  
69 Region region,
70 Pool pool,
71 uint32_t elmSize,
72 uint32_t rngSize
73 )
74 #else
75 S16 SCreateSRngBuf (id, region, pool, elmSize, rngSize)
76 uint32_t id; 
77 Region region;
78 Pool pool;
79 uint32_t elmSize;
80 uint32_t 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       return 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       return 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       return 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       return 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     return 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 S16 SAttachSRngBuf
154 (
155 uint32_t id,  
156 uint32_t ent,
157 uint32_t txRx
158 )
159 #else
160 S16 SAttachSRngBuf (id, ent, txRx)
161 uint32_t id;
162 uint32_t ent;
163 uint32_t 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        return 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        return 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     return ROK;
200 }
201 /* 
202 Func: SConnectSRngBuf
203 Desc: Establish a pipe between producer and consumer
204
205 */
206 #ifdef ANSI
207 S16 SConnectSRngBuf
208 (
209 uint32_t id,  
210 uint32_t rxEnt
211 )
212 #else
213 S16 SConnectSRngBuf (id, rxEnt)
214 uint32_t id;
215 uint32_t rxEnt;
216 #endif
217 {
218    /* Send to Reciever ENT*/ 
219    return 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 1
229    if((rBuf->write+1) == rBuf->read)
230    {
231      return 1;
232    }
233    if((rBuf->write+1) == (rBuf->read + rBuf->size))
234    {
235      return 1;
236    }
237    if((rBuf->write + 1) > rBuf->size )
238    {
239      return 1;
240    }
241    return 0;
242 #endif
243
244 /*
245 Func: IsEmpty
246 Desc: Checks if ring is empty
247 */
248 inline static S16 IsEmpty(SsRngBuf* rBuf)
249 {
250    /* write == read implies Buffer is empty*/
251    return (rBuf->write == rBuf->read); 
252 }
253
254 S16 isRngEmpty(uint32_t id)
255 {
256    return (IsEmpty(SsRngInfoTbl[id].r_addr));
257 }
258 /*
259 Func: SEnqSRngBuf
260 Desc: Perform Queue operation on Ring bufer
261 */
262 #ifdef ANSI
263 S16 SEnqSRngBuf 
264 (
265 uint32_t id, 
266 Void* elem
267 )
268 #else
269 S16 SEnqSRngBuf(id,elem) 
270 uint32_t id;
271 Void* elem;
272 #endif
273 {
274    uint8_t* w_ptr;
275    uint8_t i=0;
276    uint8_t *element = (uint8_t *)elem;
277    uint32_t wrIndex;
278    /* TBD To replace id with ring addr when SAttachSRngBuf is used*/
279    /* Retrive Buffer from Id */
280    SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
281    if (IsFull(ring))
282    {
283         SsRngInfoTbl[id].nWriteFail++;
284         return RFAILED;
285    }
286    /* TBD Avoid multiplication for optimisation */
287    w_ptr = (uint8_t*)ring->elem + (ring->write * ring->type);
288    /* TBD Avoid for loop - use memcpy */
289    for( i=0; i < ring->type; i++)
290    {
291       *(uint8_t*)w_ptr = *(uint8_t*)element;
292       w_ptr++;
293       (uint8_t*)element++;
294    }
295    /* Increment write index */
296     wrIndex = ring->write + 1 ;
297     ring->write = (wrIndex == ring->size)?0: wrIndex;
298    /* Update Statistics */
299    SsRngInfoTbl[id].n_write++;
300    return ROK;
301 }
302
303 #ifdef ANSI
304 S16 SGetNumElemInRng
305 (
306 uint32_t id
307 )
308 #else
309 S16 SGetNumElemInRng (id)
310 uint32_t id;
311 #endif
312 {
313
314    S16 freeDist = (SsRngInfoTbl[id].n_write- SsRngInfoTbl[id].n_read);
315
316         return (freeDist);
317 }
318 /*
319 Func: SDeqSRngBuf
320 Desc: Perform DeQueue operation on Ring bufer
321 */
322 #ifdef ANSI
323 S16 SDeqSRngBuf
324 (
325 uint32_t id,
326 Void *elem
327 )
328 #else
329 S16 SDeqSRngBuf (id,elem)
330 uint8_t id;
331 Void *elem;
332 #endif
333 {
334    uint8_t* r_ptr;
335    uint8_t i=0;
336    uint8_t *element = (uint8_t *)elem;
337    uint32_t rdIndex;
338    /* Retrive Buffer from Id*/
339    SsRngBuf* ring  = SsRngInfoTbl[id].r_addr;
340    if(IsEmpty(ring))
341    {  
342        SsRngInfoTbl[id].nReadFail++;
343        return RFAILED;
344    }
345    r_ptr = (uint8_t*)ring->elem + (ring->read * ring->type);
346    for(i=0; i<ring->type; i++)
347    {
348       *(uint8_t*)element = *r_ptr;
349       (uint8_t*)element++;
350       r_ptr++;
351    }
352    // Avoiding % operation for wrap around
353    rdIndex= ring->read + 1;
354    ring->read = (rdIndex == ring->size)?0:rdIndex;
355    SsRngInfoTbl[id].n_read++;
356    return ROK;
357 }
358
359 #ifdef ANSI
360 S16 SDestroySRngBuf 
361 (
362 uint32_t id,
363 Region region,
364 Pool pool
365 )
366 #else
367 S16 SDestroySRngBuf(id, region, pool)
368 uint32_t id;
369 Region region;
370 Pool pool;
371 #endif
372 {
373    /* Retrive Buffer from Id */
374    SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
375    if(ring)
376    {   
377       //SPutSBuf(region, pool, (Data *)ring->elem, (ring->size * ring->type));
378       //SPutSBuf(region, pool, (Data *)ring, sizeof(SsRngBuf));
379       
380       free(ring->elem); /* OK if null */ 
381       free(ring); /* OK if null */ 
382
383       /* Update Global Info  table */
384       SsRngInfoTbl[id].rngState = SS_RNG_DESTROYED;
385       SsRngInfoTbl[id].r_addr = 0;
386    }
387    return ROK;
388 }
389
390 #ifdef ANSI
391 S16 SPrintSRngStats
392 (
393 Void
394 )
395 #else
396 S16 SPrintSRngStats ()
397 Void;
398 #endif
399 {
400 uint32_t i; 
401
402    Txt   prntBuf[100];
403
404 #ifdef RGL_SPECIFIC_CHANGES
405    return ROK;
406 #endif
407    for(i=0; i< SS_RNG_BUF_MAX;i++)
408    {
409       if(SsRngInfoTbl[i].r_addr != 0 )
410       {
411 #ifndef ALIGN_64BIT
412          sprintf(prntBuf,"\n=======Ring %ld Stats========\n",i);
413          SDisplay(0, prntBuf);
414          sprintf(prntBuf,"r_addr      = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
415          SDisplay(0, prntBuf);
416          sprintf(prntBuf,"txEnt       = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
417          SDisplay(0, prntBuf);
418          sprintf(prntBuf,"rxEnt       = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
419          SDisplay(0, prntBuf);
420          sprintf(prntBuf,"n_write     = %lu\n", SsRngInfoTbl[i].n_write);
421          SDisplay(0, prntBuf);
422          sprintf(prntBuf,"n_read      = %lu\n", SsRngInfoTbl[i].n_read);
423          SDisplay(0, prntBuf);
424          sprintf(prntBuf,"nWriteFail  = %lu\n", SsRngInfoTbl[i].nWriteFail);
425          SDisplay(0, prntBuf);
426          sprintf(prntBuf,"nReadFail   = %lu\n", SsRngInfoTbl[i].nReadFail);
427          SDisplay(0, prntBuf);
428          sprintf(prntBuf,"pktDrop     = %lu\n", SsRngInfoTbl[i].pktDrop);
429          SDisplay(0, prntBuf);
430          sprintf(prntBuf,"State       = %lu\n\n", SsRngInfoTbl[i].rngState);
431          SDisplay(0, prntBuf);
432          sprintf(prntBuf,"nPktProc    = %lu\n\n", SsRngInfoTbl[i].nPktProc);
433          SDisplay(0, prntBuf);
434 #else
435          sprintf(prntBuf,"\n=======Ring %d Stats========\n",i);
436          SDisplay(0, prntBuf);
437          sprintf(prntBuf,"r_addr      = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
438          SDisplay(0, prntBuf);
439          sprintf(prntBuf,"txEnt       = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
440          SDisplay(0, prntBuf);
441          sprintf(prntBuf,"rxEnt       = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
442          SDisplay(0, prntBuf);
443          sprintf(prntBuf,"n_write     = %u\n", SsRngInfoTbl[i].n_write);
444          SDisplay(0, prntBuf);
445          sprintf(prntBuf,"n_read      = %u\n", SsRngInfoTbl[i].n_read);
446          SDisplay(0, prntBuf);
447          sprintf(prntBuf,"nWriteFail  = %u\n", SsRngInfoTbl[i].nWriteFail);
448          SDisplay(0, prntBuf);
449          sprintf(prntBuf,"nReadFail   = %u\n", SsRngInfoTbl[i].nReadFail);
450          SDisplay(0, prntBuf);
451          sprintf(prntBuf,"pktDrop     = %u\n", SsRngInfoTbl[i].pktDrop);
452          SDisplay(0, prntBuf);
453          sprintf(prntBuf,"State       = %u\n\n", SsRngInfoTbl[i].rngState);
454          SDisplay(0, prntBuf);
455          sprintf(prntBuf,"nPktProc    = %u\n\n", SsRngInfoTbl[i].nPktProc);
456          SDisplay(0, prntBuf);
457
458 #endif
459       }
460    }
461    return ROK; 
462 }
463
464 #ifdef ANSI
465 Void* SRngGetWIndx
466 (
467 uint32_t rngId
468 )
469 #else
470 Void* SRngGetWIndx (rngId)
471 uint32_t rngId;
472 #endif
473 {
474    /* Retrive Buffer from Id*/
475    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
476    if (IsFull(ring))
477    {
478       SsRngInfoTbl[rngId].nWriteFail++;
479       return (NULLP);
480    }
481    else
482    {
483       return (((uint8_t *)ring->elem) + (ring->type * ring->write));
484    }
485 }
486
487 #ifdef ANSI
488 Void* SRngGetRIndx
489 (
490 uint32_t rngId
491 )
492 #else
493 Void* SRngGetRIndx (rngId)
494 uint32_t rngId;
495 #endif
496 {
497    /* Retrive Buffer from Id*/
498    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
499    if(IsEmpty(ring))
500    {
501       SsRngInfoTbl[rngId].nReadFail++;
502       return (NULLP);
503    }
504    else
505    {
506       return (((uint8_t *)ring->elem) + (ring->type * ring->read));
507    }
508 }
509
510 #ifdef ANSI
511 Void SRngIncrWIndx
512 (
513 uint32_t rngId
514 )
515 #else
516 Void SRngIncrWIndx (rngId)
517 uint32_t rngId;
518 #endif
519 {
520    uint32_t wrIndex;
521    /* Retrive Buffer from Id*/
522    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
523    wrIndex = ring->write + 1;
524    ring->write = (wrIndex == ring->size)?0:wrIndex;
525    /* Update Statistics */
526    SsRngInfoTbl[rngId].n_write++;
527 }
528
529 #ifdef ANSI
530 Void SRngIncrRIndx
531 (
532 uint32_t rngId
533 )
534 #else
535 Void SRngIncrRIndx (rngId)
536 uint32_t rngId;
537 #endif
538 {
539    uint32_t rdIndex;
540    /* Retrive Buffer from Id*/
541    SsRngBuf* ring  = SsRngInfoTbl[rngId].r_addr;
542    rdIndex = ring->read + 1;
543    ring->read = (rdIndex == ring->size)?0:rdIndex;
544    /* Update Statistics */
545    SsRngInfoTbl[rngId].n_read++;
546 }
547 #ifdef XEON_SPECIFIC_CHANGES
548 #if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF))
549 S16 mtAddBufToRing(SsRngBufId ringId,void *bufPtr,uint8_t freeType)
550 {
551    S16 ret1 = ROK;
552    
553    Void *elem = NULLP;
554
555    RgKwFreeInfo *bufFreeInfo = NULLP;
556    elem = SRngGetWIndx(ringId);
557
558    if (NULLP != elem)
559    {
560       bufFreeInfo = (RgKwFreeInfo *) elem;
561
562       bufFreeInfo->bufToFree = bufPtr;
563       bufFreeInfo->freeType  = freeType;
564
565       SRngIncrWIndx(ringId);
566
567       SsRngInfoTbl[ringId].pktRate++;
568    }   
569    else
570    {
571       printf("Free Ring FULL id %d!!! \n",ringId);
572       SsRngInfoTbl[ringId].pktDrop++;
573       ret1 = RFAILED;
574    }
575    return (ret1);
576 }
577 #endif
578 #endif
579
580
581
582 /**********************************************************************
583          End of file
584 **********************************************************************/