1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
20 Steps to Add a new Ring Buffer
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
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 */
37 #include "gen.x" /* general layer */
38 #include "ssi.x" /* system services */
42 U32 ssRngBufStatus = 0;
44 /* Global Ring Loop Up Table */
45 SsRngBufTbl SsRngInfoTbl[SS_RNG_BUF_MAX];
48 PUBLIC Void SsRngBufEnable(Void)
50 ssRngBufStatus = TRUE;
54 PUBLIC Void SsRngBufDisable(Void)
56 ssRngBufStatus = FALSE;
61 Desc: Creates Ring Buffer for the given Id.
62 Ring Structure is allocated from given
66 PUBLIC S16 SCreateSRngBuf
75 PUBLIC S16 SCreateSRngBuf (id, region, pool, elmSize, rngSize)
86 if(id >= SS_RNG_BUF_MAX)
88 #if (ERRCLASS & ERRCLS_DEBUG)
89 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
93 if(SsRngInfoTbl[id].r_addr != 0)
95 #if (ERRCLASS & ERRCLS_DEBUG)
96 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id,
97 "Failed to Create Ring Buffer Id Ring already exist");
101 /* Get Element Size */
104 /* Allocate memory for Ring structure */
105 ring = (SsRngBuf* )malloc(sizeof(SsRngBuf));
108 #if (ERRCLASS & ERRCLS_DEBUG)
109 SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring Failed!!!")
113 #if (ERRCLASS & ERRCLS_DEBUG)
114 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ring,
115 "Failed to Create Ring Buffer Id Ring already exist");
118 ring->size = rngSize; /* No empty elem */
121 ring->type = elmSize;
123 /* Allocate elements memory */
124 ring->elem = calloc(ring->size, ring->type);
125 if(ring->elem == NULLP)
127 #if (ERRCLASS & ERRCLS_DEBUG)
128 SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring Failed!!!")
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;
140 printf("Ring Buffer Created with id =%ld rSize:%ld eSize:%ld %lx\n",id,ring->size,ring->type,(PTR)ring);
142 printf("Ring Buffer Created with id =%d rSize:%d eSize:%d %lx\n",id,ring->size,ring->type,(PTR)ring);
149 Desc: Attach the calling Entity to a ring buffer
150 as consumer(Rx) or producer (Tx)
153 PUBLIC S16 SAttachSRngBuf
160 PUBLIC S16 SAttachSRngBuf (id, ent, txRx)
166 /* Retrive Buffer from Global Info Table */
167 if( id >= SS_RNG_BUF_MAX)
169 #if (ERRCLASS & ERRCLS_DEBUG)
170 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
174 if(SsRngInfoTbl[id].rngState < SS_RNG_CREATED)
176 #if (ERRCLASS & ERRCLS_DEBUG)
177 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id,
178 "Attach Request in Invalid Ring ID");
181 printf("Attach Request in Invalid Ring State %ld id%ld \n",
182 SsRngInfoTbl[id].rngState,id);
184 printf("Attach Request in Invalid Ring State %d id%d \n",
185 SsRngInfoTbl[id].rngState,id);
189 if(txRx == SS_RNG_TX)
191 SsRngInfoTbl[id].txEnt = ent;
192 SsRngInfoTbl[id].rngState = SS_RNG_TX_ATTACHED;
194 else if(txRx == SS_RNG_RX)
196 SsRngInfoTbl[id].rxEnt = ent;
197 SsRngInfoTbl[id].rngState = SS_RNG_RX_ATTACHED;
202 Func: SConnectSRngBuf
203 Desc: Establish a pipe between producer and consumer
207 PUBLIC S16 SConnectSRngBuf
213 PUBLIC S16 SConnectSRngBuf (id, rxEnt)
218 /* Send to Reciever ENT*/
224 Desc: Checks if Ring is full
226 inline static S16 IsFull(SsRngBuf* rBuf)
229 if((rBuf->write+1) == rBuf->read)
233 if((rBuf->write+1) == (rBuf->read + rBuf->size))
237 if((rBuf->write + 1) > rBuf->size )
246 Desc: Checks if ring is empty
248 inline static S16 IsEmpty(SsRngBuf* rBuf)
250 /* write == read implies Buffer is empty*/
251 return (rBuf->write == rBuf->read);
254 PUBLIC S16 isRngEmpty(U32 id)
256 return (IsEmpty(SsRngInfoTbl[id].r_addr));
260 Desc: Perform Queue operation on Ring bufer
263 PUBLIC S16 SEnqSRngBuf
269 PUBLIC S16 SEnqSRngBuf(id,elem)
276 U8 *element = (U8 *)elem;
278 /* TBD To replace id with ring addr when SAttachSRngBuf is used*/
279 /* Retrive Buffer from Id */
280 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
283 SsRngInfoTbl[id].nWriteFail++;
286 /* TBD Avoid multiplication for optimisation */
287 w_ptr = (U8*)ring->elem + (ring->write * ring->type);
288 /* TBD Avoid for loop - use memcpy */
289 for( i=0; i < ring->type; i++)
291 *(U8*)w_ptr = *(U8*)element;
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++;
304 PUBLIC S16 SGetNumElemInRng
309 PUBLIC S16 SGetNumElemInRng (id)
314 S16 freeDist = (SsRngInfoTbl[id].n_write- SsRngInfoTbl[id].n_read);
320 Desc: Perform DeQueue operation on Ring bufer
323 PUBLIC S16 SDeqSRngBuf
329 PUBLIC S16 SDeqSRngBuf (id,elem)
336 U8 *element = (U8 *)elem;
338 /* Retrive Buffer from Id*/
339 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
342 SsRngInfoTbl[id].nReadFail++;
345 r_ptr = (U8*)ring->elem + (ring->read * ring->type);
346 for(i=0; i<ring->type; i++)
348 *(U8*)element = *r_ptr;
352 // Avoiding % operation for wrap around
353 rdIndex= ring->read + 1;
354 ring->read = (rdIndex == ring->size)?0:rdIndex;
355 SsRngInfoTbl[id].n_read++;
360 PUBLIC S16 SDestroySRngBuf
367 PUBLIC S16 SDestroySRngBuf(id, region, pool)
373 /* Retrive Buffer from Id */
374 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
377 //SPutSBuf(region, pool, (Data *)ring->elem, (ring->size * ring->type));
378 //SPutSBuf(region, pool, (Data *)ring, sizeof(SsRngBuf));
380 free(ring->elem); /* OK if null */
381 free(ring); /* OK if null */
383 /* Update Global Info table */
384 SsRngInfoTbl[id].rngState = SS_RNG_DESTROYED;
385 SsRngInfoTbl[id].r_addr = 0;
391 PUBLIC S16 SPrintSRngStats
396 PUBLIC S16 SPrintSRngStats ()
404 #ifdef RGL_SPECIFIC_CHANGES
407 for(i=0; i< SS_RNG_BUF_MAX;i++)
409 if(SsRngInfoTbl[i].r_addr != 0 )
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);
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);
465 PUBLIC Void* SRngGetWIndx
470 PUBLIC Void* SRngGetWIndx (rngId)
474 /* Retrive Buffer from Id*/
475 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
478 SsRngInfoTbl[rngId].nWriteFail++;
483 RETVALUE(((U8 *)ring->elem) + (ring->type * ring->write));
488 PUBLIC Void* SRngGetRIndx
493 PUBLIC Void* SRngGetRIndx (rngId)
497 /* Retrive Buffer from Id*/
498 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
501 SsRngInfoTbl[rngId].nReadFail++;
506 RETVALUE(((U8 *)ring->elem) + (ring->type * ring->read));
511 PUBLIC Void SRngIncrWIndx
516 PUBLIC Void SRngIncrWIndx (rngId)
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++;
530 PUBLIC Void SRngIncrRIndx
535 PUBLIC Void SRngIncrRIndx (rngId)
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++;
547 #ifdef XEON_SPECIFIC_CHANGES
548 #if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF))
549 S16 mtAddBufToRing(SsRngBufId ringId,void *bufPtr,U8 freeType)
555 RgKwFreeInfo *bufFreeInfo = NULLP;
556 elem = SRngGetWIndx(ringId);
560 bufFreeInfo = (RgKwFreeInfo *) elem;
562 bufFreeInfo->bufToFree = bufPtr;
563 bufFreeInfo->freeType = freeType;
565 SRngIncrWIndx(ringId);
567 SsRngInfoTbl[ringId].pktRate++;
571 printf("Free Ring FULL id %d!!! \n",ringId);
572 SsRngInfoTbl[ringId].pktDrop++;
582 /**********************************************************************
584 **********************************************************************/