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 uint32_t ssRngBufStatus = 0;
44 /* Global Ring Loop Up Table */
45 SsRngBufTbl SsRngInfoTbl[SS_RNG_BUF_MAX];
48 Void SsRngBufEnable(Void)
50 ssRngBufStatus = TRUE;
54 Void SsRngBufDisable(Void)
56 ssRngBufStatus = FALSE;
61 Desc: Creates Ring Buffer for the given Id.
62 Ring Structure is allocated from given
77 if(id >= SS_RNG_BUF_MAX)
79 #if (ERRCLASS & ERRCLS_DEBUG)
80 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
84 if(SsRngInfoTbl[id].r_addr != 0)
86 #if (ERRCLASS & ERRCLS_DEBUG)
87 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id,
88 "Failed to Create Ring Buffer Id Ring already exist");
92 /* Get Element Size */
95 /* Allocate memory for Ring structure */
96 ring = (SsRngBuf* )malloc(sizeof(SsRngBuf));
99 #if (ERRCLASS & ERRCLS_DEBUG)
100 SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring Failed!!!")
104 #if (ERRCLASS & ERRCLS_DEBUG)
105 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, ring,
106 "Failed to Create Ring Buffer Id Ring already exist");
109 ring->size = rngSize; /* No empty elem */
112 ring->type = elmSize;
114 /* Allocate elements memory */
115 ring->elem = calloc(ring->size, ring->type);
116 if(ring->elem == NULLP)
118 #if (ERRCLASS & ERRCLS_DEBUG)
119 SSLOGERROR(ERRCLS_INT_PAR, ESSXXX, ERRZERO, "Allocating Ring Failed!!!")
124 /* Update Buffer Id Table */
125 SsRngInfoTbl[id].r_addr = ring;
126 SsRngInfoTbl[id].rngState = SS_RNG_CREATED;
127 SsRngInfoTbl[id].n_write = 0;
128 SsRngInfoTbl[id].n_read = 0;
131 printf("\nRing Buffer Created with id =%ld rSize:%ld eSize:%ld %lx\n",id,ring->size,ring->type,(PTR)ring);
133 printf("\nRing Buffer Created with id =%d rSize:%d eSize:%d %lx\n",id,ring->size,ring->type,(PTR)ring);
140 Desc: Attach the calling Entity to a ring buffer
141 as consumer(Rx) or producer (Tx)
150 /* Retrive Buffer from Global Info Table */
151 if( id >= SS_RNG_BUF_MAX)
153 #if (ERRCLASS & ERRCLS_DEBUG)
154 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id, "Invalid RBUF ID");
158 if(SsRngInfoTbl[id].rngState < SS_RNG_CREATED)
160 #if (ERRCLASS & ERRCLS_DEBUG)
161 SSLOGERROR(ERRCLS_DEBUG, ESSXXX, id,
162 "Attach Request in Invalid Ring ID");
165 printf("\nAttach Request in Invalid Ring State %ld id%ld \n",
166 SsRngInfoTbl[id].rngState,id);
168 printf("\nAttach Request in Invalid Ring State %d id%d \n",
169 SsRngInfoTbl[id].rngState,id);
173 if(txRx == SS_RNG_TX)
175 SsRngInfoTbl[id].txEnt = ent;
176 SsRngInfoTbl[id].rngState = SS_RNG_TX_ATTACHED;
178 else if(txRx == SS_RNG_RX)
180 SsRngInfoTbl[id].rxEnt = ent;
181 SsRngInfoTbl[id].rngState = SS_RNG_RX_ATTACHED;
186 Func: SConnectSRngBuf
187 Desc: Establish a pipe between producer and consumer
196 /* Send to Reciever ENT*/
202 Desc: Checks if Ring is full
204 inline static S16 IsFull(SsRngBuf* rBuf)
207 if((rBuf->write+1) == rBuf->read)
211 if((rBuf->write+1) == (rBuf->read + rBuf->size))
215 if((rBuf->write + 1) > rBuf->size )
224 Desc: Checks if ring is empty
226 inline static S16 IsEmpty(SsRngBuf* rBuf)
228 /* write == read implies Buffer is empty*/
229 return (rBuf->write == rBuf->read);
232 S16 isRngEmpty(uint32_t id)
234 return (IsEmpty(SsRngInfoTbl[id].r_addr));
238 Desc: Perform Queue operation on Ring bufer
248 uint8_t *element = (uint8_t *)elem;
250 /* TBD To replace id with ring addr when SAttachSRngBuf is used*/
251 /* Retrive Buffer from Id */
252 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
255 SsRngInfoTbl[id].nWriteFail++;
258 /* TBD Avoid multiplication for optimisation */
259 w_ptr = (uint8_t*)ring->elem + (ring->write * ring->type);
260 /* TBD Avoid for loop - use memcpy */
261 for( i=0; i < ring->type; i++)
263 *(uint8_t*)w_ptr = *(uint8_t*)element;
267 /* Increment write index */
268 wrIndex = ring->write + 1 ;
269 ring->write = (wrIndex == ring->size)?0: wrIndex;
270 /* Update Statistics */
271 SsRngInfoTbl[id].n_write++;
275 S16 SGetNumElemInRng(uint32_t id)
278 S16 freeDist = (SsRngInfoTbl[id].n_write- SsRngInfoTbl[id].n_read);
284 Desc: Perform DeQueue operation on Ring bufer
286 S16 SDeqSRngBuf(uint32_t id,Void *elem)
290 uint8_t *element = (uint8_t *)elem;
292 /* Retrive Buffer from Id*/
293 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
296 SsRngInfoTbl[id].nReadFail++;
299 r_ptr = (uint8_t*)ring->elem + (ring->read * ring->type);
300 for(i=0; i<ring->type; i++)
302 *(uint8_t*)element = *r_ptr;
306 // Avoiding % operation for wrap around
307 rdIndex= ring->read + 1;
308 ring->read = (rdIndex == ring->size)?0:rdIndex;
309 SsRngInfoTbl[id].n_read++;
320 /* Retrive Buffer from Id */
321 SsRngBuf* ring = SsRngInfoTbl[id].r_addr;
324 //SPutSBuf(region, pool, (Data *)ring->elem, (ring->size * ring->type));
325 //SPutSBuf(region, pool, (Data *)ring, sizeof(SsRngBuf));
327 free(ring->elem); /* OK if null */
328 free(ring); /* OK if null */
330 /* Update Global Info table */
331 SsRngInfoTbl[id].rngState = SS_RNG_DESTROYED;
332 SsRngInfoTbl[id].r_addr = 0;
337 S16 SPrintSRngStats(Void)
343 #ifdef RGL_SPECIFIC_CHANGES
346 for(i=0; i< SS_RNG_BUF_MAX;i++)
348 if(SsRngInfoTbl[i].r_addr != 0 )
351 sprintf(prntBuf,"\n=======Ring %ld Stats========\n",i);
352 SDisplay(0, prntBuf);
353 sprintf(prntBuf,"r_addr = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
354 SDisplay(0, prntBuf);
355 sprintf(prntBuf,"txEnt = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
356 SDisplay(0, prntBuf);
357 sprintf(prntBuf,"rxEnt = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
358 SDisplay(0, prntBuf);
359 sprintf(prntBuf,"n_write = %lu\n", SsRngInfoTbl[i].n_write);
360 SDisplay(0, prntBuf);
361 sprintf(prntBuf,"n_read = %lu\n", SsRngInfoTbl[i].n_read);
362 SDisplay(0, prntBuf);
363 sprintf(prntBuf,"nWriteFail = %lu\n", SsRngInfoTbl[i].nWriteFail);
364 SDisplay(0, prntBuf);
365 sprintf(prntBuf,"nReadFail = %lu\n", SsRngInfoTbl[i].nReadFail);
366 SDisplay(0, prntBuf);
367 sprintf(prntBuf,"pktDrop = %lu\n", SsRngInfoTbl[i].pktDrop);
368 SDisplay(0, prntBuf);
369 sprintf(prntBuf,"State = %lu\n\n", SsRngInfoTbl[i].rngState);
370 SDisplay(0, prntBuf);
371 sprintf(prntBuf,"nPktProc = %lu\n\n", SsRngInfoTbl[i].nPktProc);
372 SDisplay(0, prntBuf);
374 sprintf(prntBuf,"\n=======Ring %d Stats========\n",i);
375 SDisplay(0, prntBuf);
376 sprintf(prntBuf,"r_addr = %lx\n", (PTR)SsRngInfoTbl[i].r_addr);
377 SDisplay(0, prntBuf);
378 sprintf(prntBuf,"txEnt = %lx\n", (PTR)SsRngInfoTbl[i].txEnt);
379 SDisplay(0, prntBuf);
380 sprintf(prntBuf,"rxEnt = %lx\n", (PTR)SsRngInfoTbl[i].rxEnt);
381 SDisplay(0, prntBuf);
382 sprintf(prntBuf,"n_write = %u\n", SsRngInfoTbl[i].n_write);
383 SDisplay(0, prntBuf);
384 sprintf(prntBuf,"n_read = %u\n", SsRngInfoTbl[i].n_read);
385 SDisplay(0, prntBuf);
386 sprintf(prntBuf,"nWriteFail = %u\n", SsRngInfoTbl[i].nWriteFail);
387 SDisplay(0, prntBuf);
388 sprintf(prntBuf,"nReadFail = %u\n", SsRngInfoTbl[i].nReadFail);
389 SDisplay(0, prntBuf);
390 sprintf(prntBuf,"pktDrop = %u\n", SsRngInfoTbl[i].pktDrop);
391 SDisplay(0, prntBuf);
392 sprintf(prntBuf,"State = %u\n\n", SsRngInfoTbl[i].rngState);
393 SDisplay(0, prntBuf);
394 sprintf(prntBuf,"nPktProc = %u\n\n", SsRngInfoTbl[i].nPktProc);
395 SDisplay(0, prntBuf);
403 Void* SRngGetWIndx(uint32_t rngId)
405 /* Retrive Buffer from Id*/
406 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
409 SsRngInfoTbl[rngId].nWriteFail++;
414 return (((uint8_t *)ring->elem) + (ring->type * ring->write));
418 Void* SRngGetRIndx(uint32_t rngId)
420 /* Retrive Buffer from Id*/
421 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
424 SsRngInfoTbl[rngId].nReadFail++;
429 return (((uint8_t *)ring->elem) + (ring->type * ring->read));
433 Void SRngIncrWIndx(uint32_t rngId)
436 /* Retrive Buffer from Id*/
437 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
438 wrIndex = ring->write + 1;
439 ring->write = (wrIndex == ring->size)?0:wrIndex;
440 /* Update Statistics */
441 SsRngInfoTbl[rngId].n_write++;
444 Void SRngIncrRIndx(uint32_t rngId)
447 /* Retrive Buffer from Id*/
448 SsRngBuf* ring = SsRngInfoTbl[rngId].r_addr;
449 rdIndex = ring->read + 1;
450 ring->read = (rdIndex == ring->size)?0:rdIndex;
451 /* Update Statistics */
452 SsRngInfoTbl[rngId].n_read++;
454 #ifdef XEON_SPECIFIC_CHANGES
455 #if (defined (MAC_FREE_RING_BUF) || defined (RLC_FREE_RING_BUF))
456 S16 mtAddBufToRing(SsRngBufId ringId,void *bufPtr,uint8_t freeType)
462 RgKwFreeInfo *bufFreeInfo = NULLP;
463 elem = SRngGetWIndx(ringId);
467 bufFreeInfo = (RgKwFreeInfo *) elem;
469 bufFreeInfo->bufToFree = bufPtr;
470 bufFreeInfo->freeType = freeType;
472 SRngIncrWIndx(ringId);
474 SsRngInfoTbl[ringId].pktRate++;
478 printf("\nFree Ring FULL id %d!!! \n",ringId);
479 SsRngInfoTbl[ringId].pktDrop++;
489 /**********************************************************************
491 **********************************************************************/