1 /**
2  * @file IxOsalBufferMgt.c
3  *
4  * @brief Default buffer pool management and buffer management
5  *        Implementation.
6  *
7  * Design Notes:
8  *
9  * @par
10  * IXP400 SW Release version 2.0
11  *
12  * -- Copyright Notice --
13  *
14  * @par
15  * Copyright 2001-2005, Intel Corporation.
16  * All rights reserved.
17  *
18  * @par
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  * 3. Neither the name of the Intel Corporation nor the names of its contributors
28  *    may be used to endorse or promote products derived from this software
29  *    without specific prior written permission.
30  *
31  * @par
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
33  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  *
44  * @par
45  * -- End of Copyright Notice --
46  */
47 
48 /*
49  * OS may choose to use default bufferMgt by defining
50  * IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h
51  */
52 
53 #include "IxOsal.h"
54 
55 #define IX_OSAL_BUFFER_FREE_PROTECTION  /* Define this to enable Illegal MBuf Freed Protection*/
56 
57 /*
58  * The implementation is only used when the following
59  * is defined.
60  */
61 #ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT
62 
63 
64 #define IX_OSAL_MBUF_SYS_SIGNATURE				(0x8BADF00D)
65 #define IX_OSAL_MBUF_SYS_SIGNATURE_MASK				(0xEFFFFFFF)
66 #define IX_OSAL_MBUF_USED_FLAG					(0x10000000)
67 #define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr)        		IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE
68 
69 /*
70 *  This implementation is protect, the buffer pool management's  ixOsalMBufFree
71 *  against an invalid MBUF pointer argument that already has been freed earlier
72 *  or in other words resides in the free pool of MBUFs. This added feature,
73 *  checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed
74 *  back to the Buffer Pool.
75 *  Disable this feature for performance reasons by undef
76 *  IX_OSAL_BUFFER_FREE_PROTECTION macro.
77 */
78 #ifdef IX_OSAL_BUFFER_FREE_PROTECTION  /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
79 
80 #define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr)		(IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) )
81 #define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr)    do {																											\
82 																									IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\
83 														    									IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE;			\
84 																									}while(0)
85 
86 #define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr)   IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG
87 #define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG
88 #define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG)
89 
90 #else
91 
92 #define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr)	 IX_OSAL_MBUF_SIGNATURE (bufPtr)
93 #define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr)   IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE
94 
95 #endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/
96 /*
97  * Variable declarations global to this file only.  Externs are followed by
98  * static variables.
99  */
100 
101 /*
102  * A unit of 32, used to provide bit-shift for pool
103  * management. Needs some work if users want more than 32 pools.
104  */
105 #define IX_OSAL_BUFF_FREE_BITS 32
106 
107 PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS /
108     IX_OSAL_BUFF_FREE_BITS];
109 
110 PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS];
111 
112 static int ixOsalBuffPoolsInUse = 0;
113 
114 #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
115 PRIVATE IX_OSAL_MBUF *
116 ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
117                       UINT32 dataSizeAligned,
118                       IX_OSAL_MBUF_POOL *poolPtr);
119 #endif
120 
121 PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void);
122 
123 /*
124  * Function definition: ixOsalPoolAlloc
125  */
126 
127 /****************************/
128 
129 PRIVATE IX_OSAL_MBUF_POOL *
ixOsalPoolAlloc(void)130 ixOsalPoolAlloc (void)
131 {
132     register unsigned int i = 0;
133 
134     /*
135      * Scan for the first free buffer. Free buffers are indicated by 0
136      * on the corrsponding bit in ixOsalBuffFreePools.
137      */
138     if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS)
139     {
140         /*
141          * Fail to grab a ptr this time
142          */
143         return NULL;
144     }
145 
146     while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] &
147         (1 << (i % IX_OSAL_BUFF_FREE_BITS)))
148         i++;
149     /*
150      * Free buffer found. Mark it as busy and initialize.
151      */
152     ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |=
153         (1 << (i % IX_OSAL_BUFF_FREE_BITS));
154 
155     memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL));
156 
157     ixOsalBuffPools[i].poolIdx = i;
158     ixOsalBuffPoolsInUse++;
159 
160     return &ixOsalBuffPools[i];
161 }
162 
163 
164 #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
165 PRIVATE IX_OSAL_MBUF *
ixOsalBuffPoolMbufInit(UINT32 mbufSizeAligned,UINT32 dataSizeAligned,IX_OSAL_MBUF_POOL * poolPtr)166 ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned,
167                       UINT32 dataSizeAligned,
168                       IX_OSAL_MBUF_POOL *poolPtr)
169 {
170     UINT8 *dataPtr;
171     IX_OSAL_MBUF *realMbufPtr;
172     /* Allocate cache-aligned memory for mbuf header */
173     realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned);
174     IX_OSAL_ASSERT (realMbufPtr != NULL);
175     memset (realMbufPtr, 0, mbufSizeAligned);
176 
177     /* Allocate cache-aligned memory for mbuf data */
178     dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned);
179     IX_OSAL_ASSERT (dataPtr != NULL);
180     memset (dataPtr, 0, dataSizeAligned);
181 
182     /* Fill in mbuf header fields */
183     IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr;
184     IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr;
185 
186     IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned;
187     IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned;
188 
189     IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr;
190 
191     IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr);
192 
193     /* update some statistical information */
194     poolPtr->mbufMemSize += mbufSizeAligned;
195     poolPtr->dataMemSize += dataSizeAligned;
196 
197     return realMbufPtr;
198 }
199 #endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */
200 
201 /*
202  * Function definition: ixOsalBuffPoolInit
203  */
204 
205 PUBLIC IX_OSAL_MBUF_POOL *
ixOsalPoolInit(UINT32 count,UINT32 size,const char * name)206 ixOsalPoolInit (UINT32 count, UINT32 size, const char *name)
207 {
208 
209     /* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY
210      * is defined .
211      */
212 #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
213     UINT32 i, mbufSizeAligned, dataSizeAligned;
214     IX_OSAL_MBUF *currentMbufPtr = NULL;
215 #else
216     void *poolBufPtr;
217     void *poolDataPtr;
218     int mbufMemSize;
219     int dataMemSize;
220 #endif
221 
222     IX_OSAL_MBUF_POOL *poolPtr = NULL;
223 
224     if (count <= 0)
225     {
226         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
227             IX_OSAL_LOG_DEV_STDOUT,
228             "ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0);
229         return NULL;
230     }
231 
232     if (name == NULL)
233     {
234         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
235             IX_OSAL_LOG_DEV_STDOUT,
236             "ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0);
237         return NULL;
238     }
239 
240     if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
241     {
242         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
243             IX_OSAL_LOG_DEV_STDOUT,
244             "ixOsalPoolInit(): "
245             "ERROR - name length should be no greater than %d  \n",
246             IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
247         return NULL;
248     }
249 
250 /* OS can choose whether to allocate all buffers all together (if it
251  * can handle a huge single alloc request), or to allocate buffers
252  * separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY.
253  */
254 #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
255     /* Get a pool Ptr */
256     poolPtr = ixOsalPoolAlloc ();
257 
258     if (poolPtr == NULL)
259     {
260         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
261             IX_OSAL_LOG_DEV_STDOUT,
262             "ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0);
263         return NULL;
264     }
265 
266     mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
267     dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size);
268 
269     poolPtr->nextFreeBuf = NULL;
270     poolPtr->mbufMemPtr = NULL;
271     poolPtr->dataMemPtr = NULL;
272     poolPtr->bufDataSize = dataSizeAligned;
273     poolPtr->totalBufsInPool = count;
274     poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
275     strcpy (poolPtr->name, name);
276 
277 
278     for (i = 0; i < count; i++)
279     {
280 	    /* create an mbuf */
281 	    currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned,
282 					         dataSizeAligned,
283 					         poolPtr);
284 
285 #ifdef IX_OSAL_BUFFER_FREE_PROTECTION
286 /* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail.
287    ixOsalMbufFree used here is in a special case whereby, it's
288    used to add MBUF to the Pool. By specification, ixOsalMbufFree
289    deallocates an allocated MBUF from Pool.
290 */
291       IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr);
292 #endif
293 	    /* Add it to the pool */
294 	    ixOsalMbufFree (currentMbufPtr);
295 
296 	    /* flush the pool information to RAM */
297 	    IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned);
298     }
299 
300     /*
301      * update the number of free buffers in the pool
302      */
303     poolPtr->freeBufsInPool = count;
304 
305 #else
306 /* Otherwise allocate buffers in a continuous block fashion */
307     poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize);
308     IX_OSAL_ASSERT (poolBufPtr != NULL);
309     poolDataPtr =
310         IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize);
311     IX_OSAL_ASSERT (poolDataPtr != NULL);
312 
313     poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr,
314         count, size, name);
315     if (poolPtr == NULL)
316     {
317         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
318             IX_OSAL_LOG_DEV_STDOUT,
319             "ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0);
320         return NULL;
321     }
322 
323     poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC;
324 
325 #endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */
326     return poolPtr;
327 }
328 
329 PUBLIC IX_OSAL_MBUF_POOL *
ixOsalNoAllocPoolInit(void * poolBufPtr,void * poolDataPtr,UINT32 count,UINT32 size,const char * name)330 ixOsalNoAllocPoolInit (void *poolBufPtr,
331     void *poolDataPtr, UINT32 count, UINT32 size, const char *name)
332 {
333     UINT32 i,  mbufSizeAligned, sizeAligned;
334     IX_OSAL_MBUF *currentMbufPtr = NULL;
335     IX_OSAL_MBUF *nextMbufPtr = NULL;
336     IX_OSAL_MBUF_POOL *poolPtr = NULL;
337 
338     /*
339      * check parameters
340      */
341     if (poolBufPtr == NULL)
342     {
343         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
344             IX_OSAL_LOG_DEV_STDOUT,
345             "ixOsalNoAllocPoolInit(): "
346             "ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0);
347         return NULL;
348     }
349 
350     if (count <= 0)
351     {
352         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
353             IX_OSAL_LOG_DEV_STDOUT,
354             "ixOsalNoAllocPoolInit(): "
355             "ERROR - count must > 0   \n", 0, 0, 0, 0, 0, 0);
356         return NULL;
357     }
358 
359     if (name == NULL)
360     {
361         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
362             IX_OSAL_LOG_DEV_STDOUT,
363             "ixOsalNoAllocPoolInit(): "
364             "ERROR - NULL name ptr  \n", 0, 0, 0, 0, 0, 0);
365         return NULL;
366     }
367 
368     if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN)
369     {
370         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
371             IX_OSAL_LOG_DEV_STDOUT,
372             "ixOsalNoAllocPoolInit(): "
373             "ERROR - name length should be no greater than %d  \n",
374             IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0);
375         return NULL;
376     }
377 
378     poolPtr = ixOsalPoolAlloc ();
379 
380     if (poolPtr == NULL)
381     {
382         return NULL;
383     }
384 
385     /*
386      * Adjust sizes to ensure alignment on cache line boundaries
387      */
388     mbufSizeAligned =
389         IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
390     /*
391      * clear the mbuf memory area
392      */
393     memset (poolBufPtr, 0, mbufSizeAligned * count);
394 
395     if (poolDataPtr != NULL)
396     {
397         /*
398          * Adjust sizes to ensure alignment on cache line boundaries
399          */
400         sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
401         /*
402          * clear the data memory area
403          */
404         memset (poolDataPtr, 0, sizeAligned * count);
405     }
406     else
407     {
408         sizeAligned = 0;
409     }
410 
411     /*
412      * initialise pool fields
413      */
414     strcpy ((poolPtr)->name, name);
415 
416     poolPtr->dataMemPtr = poolDataPtr;
417     poolPtr->mbufMemPtr = poolBufPtr;
418     poolPtr->bufDataSize = sizeAligned;
419     poolPtr->totalBufsInPool = count;
420     poolPtr->mbufMemSize = mbufSizeAligned * count;
421     poolPtr->dataMemSize = sizeAligned * count;
422 
423     currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr;
424 
425     poolPtr->nextFreeBuf = currentMbufPtr;
426 
427     for (i = 0; i < count; i++)
428     {
429         if (i < (count - 1))
430         {
431             nextMbufPtr =
432                 (IX_OSAL_MBUF *) ((unsigned) currentMbufPtr +
433                 mbufSizeAligned);
434         }
435         else
436         {                       /* last mbuf in chain */
437             nextMbufPtr = NULL;
438         }
439         IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr;
440         IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr;
441 
442         IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr);
443 
444         if (poolDataPtr != NULL)
445         {
446             IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr;
447             IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr;
448 
449             IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned;
450             IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned;
451 
452             poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned);
453         }
454 
455         currentMbufPtr = nextMbufPtr;
456     }
457 
458     /*
459      * update the number of free buffers in the pool
460      */
461     poolPtr->freeBufsInPool = count;
462 
463     poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC;
464 
465     return poolPtr;
466 }
467 
468 /*
469  * Get a mbuf ptr from the pool
470  */
471 PUBLIC IX_OSAL_MBUF *
ixOsalMbufAlloc(IX_OSAL_MBUF_POOL * poolPtr)472 ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr)
473 {
474     int lock;
475     IX_OSAL_MBUF *newBufPtr = NULL;
476 
477     /*
478      * check parameters
479      */
480     if (poolPtr == NULL)
481     {
482         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
483             IX_OSAL_LOG_DEV_STDOUT,
484             "ixOsalMbufAlloc(): "
485             "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
486         return NULL;
487     }
488 
489     lock = ixOsalIrqLock ();
490 
491     newBufPtr = poolPtr->nextFreeBuf;
492     if (newBufPtr)
493     {
494         poolPtr->nextFreeBuf =
495             IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr);
496         IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL;
497 
498         /*
499          * update the number of free buffers in the pool
500          */
501         poolPtr->freeBufsInPool--;
502     }
503     else
504     {
505         /* Return NULL to indicate to caller that request is denied. */
506         ixOsalIrqUnlock (lock);
507 
508         return NULL;
509     }
510 
511 #ifdef IX_OSAL_BUFFER_FREE_PROTECTION
512 	/* Set Buffer Used Flag to indicate state.*/
513     IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr);
514 #endif
515 
516     ixOsalIrqUnlock (lock);
517 
518     return newBufPtr;
519 }
520 
521 PUBLIC IX_OSAL_MBUF *
ixOsalMbufFree(IX_OSAL_MBUF * bufPtr)522 ixOsalMbufFree (IX_OSAL_MBUF * bufPtr)
523 {
524     int lock;
525     IX_OSAL_MBUF_POOL *poolPtr;
526 
527     IX_OSAL_MBUF *nextBufPtr = NULL;
528 
529     /*
530      * check parameters
531      */
532     if (bufPtr == NULL)
533     {
534         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
535             IX_OSAL_LOG_DEV_STDOUT,
536             "ixOsalMbufFree(): "
537             "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
538         return NULL;
539     }
540 
541 
542 
543     lock = ixOsalIrqLock ();
544 
545 #ifdef IX_OSAL_BUFFER_FREE_PROTECTION
546 
547 	/* Prevention for Buffer freed more than once*/
548     if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr))
549     {
550    	return NULL;
551     }
552     IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr);
553 #endif
554 
555     poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr);
556 
557     /*
558      * check the mbuf wrapper signature (if mbuf wrapper was used)
559      */
560     if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
561     {
562         IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE),
563             "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature.");
564     }
565 
566     nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr);
567 
568     IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf;
569     poolPtr->nextFreeBuf = bufPtr;
570 
571     /*
572      * update the number of free buffers in the pool
573      */
574     poolPtr->freeBufsInPool++;
575 
576     ixOsalIrqUnlock (lock);
577 
578     return nextBufPtr;
579 }
580 
581 PUBLIC void
ixOsalMbufChainFree(IX_OSAL_MBUF * bufPtr)582 ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr)
583 {
584     while ((bufPtr = ixOsalMbufFree (bufPtr)));
585 }
586 
587 /*
588  * Function definition: ixOsalBuffPoolShow
589  */
590 PUBLIC void
ixOsalMbufPoolShow(IX_OSAL_MBUF_POOL * poolPtr)591 ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr)
592 {
593     IX_OSAL_MBUF *nextBufPtr;
594     int count = 0;
595     int lock;
596 
597     /*
598      * check parameters
599      */
600     if (poolPtr == NULL)
601     {
602         ixOsalLog (IX_OSAL_LOG_LVL_ERROR,
603             IX_OSAL_LOG_DEV_STDOUT,
604             "ixOsalBuffPoolShow(): "
605             "ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0);
606         /*
607          * return IX_FAIL;
608          */
609         return;
610     }
611 
612     lock = ixOsalIrqLock ();
613     count = poolPtr->freeBufsInPool;
614     nextBufPtr = poolPtr->nextFreeBuf;
615     ixOsalIrqUnlock (lock);
616 
617     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
618         IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0,
619         0, 0, 0);
620     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
621         "Pool Name:                   %s\n",
622         (unsigned int) poolPtr->name, 0, 0, 0, 0, 0);
623     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
624         "Pool Allocation Type:        %d\n",
625         (unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0);
626     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
627         "Pool Mbuf Mem Usage (bytes): %d\n",
628         (unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0);
629     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
630         "Pool Data Mem Usage (bytes): %d\n",
631         (unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0);
632     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
633         "Mbuf Data Capacity  (bytes): %d\n",
634         (unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0);
635     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
636         "Total Mbufs in Pool:         %d\n",
637         (unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0);
638     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
639         "Available Mbufs:             %d\n", (unsigned int) count, 0,
640         0, 0, 0, 0);
641     ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
642         "Next Available Mbuf:         %p\n", (unsigned int) nextBufPtr,
643         0, 0, 0, 0, 0);
644 
645     if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC)
646     {
647         ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,
648             IX_OSAL_LOG_DEV_STDOUT,
649             "Mbuf Mem Area Start address: %p\n",
650             (unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0);
651         ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT,
652             "Data Mem Area Start address: %p\n",
653             (unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0);
654     }
655 }
656 
657 PUBLIC void
ixOsalMbufDataPtrReset(IX_OSAL_MBUF * bufPtr)658 ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr)
659 {
660     IX_OSAL_MBUF_POOL *poolPtr;
661     UINT8 *poolDataPtr;
662 
663     if (bufPtr == NULL)
664     {
665         ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
666             "ixOsalBuffPoolBufDataPtrReset"
667             ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0);
668         return;
669     }
670 
671     poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr);
672     poolDataPtr = poolPtr->dataMemPtr;
673 
674     if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
675     {
676         if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE)
677         {
678             ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
679                 "ixOsalBuffPoolBufDataPtrReset"
680                 ": invalid mbuf, cannot reset mData pointer\n", 0, 0,
681                 0, 0, 0, 0);
682             return;
683         }
684         IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr);
685     }
686     else
687     {
688         if (poolDataPtr)
689         {
690             unsigned int bufSize = poolPtr->bufDataSize;
691             unsigned int bufDataAddr =
692                 (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr);
693             unsigned int poolDataAddr = (unsigned int) poolDataPtr;
694 
695             /*
696              * the pointer is still pointing somewhere in the mbuf payload.
697              * This operation moves the pointer to the beginning of the
698              * mbuf payload
699              */
700             bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize;
701             IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr];
702         }
703         else
704         {
705             ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT,
706                 "ixOsalBuffPoolBufDataPtrReset"
707                 ": cannot be used if user supplied NULL pointer for pool data area "
708                 "when pool was created\n", 0, 0, 0, 0, 0, 0);
709             return;
710         }
711     }
712 
713 }
714 
715 /*
716  * Function definition: ixOsalBuffPoolUninit
717  */
718 PUBLIC IX_STATUS
ixOsalBuffPoolUninit(IX_OSAL_MBUF_POOL * pool)719 ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool)
720 {
721     if (!pool)
722     {
723         ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
724             "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0);
725         return IX_FAIL;
726     }
727 
728     if (pool->freeBufsInPool != pool->totalBufsInPool)
729     {
730         ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,
731             "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n",
732             0, 0, 0, 0, 0, 0);
733         return IX_FAIL;
734     }
735 
736     if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC)
737     {
738 #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY
739 				UINT32 i;
740 				IX_OSAL_MBUF* pBuf;
741 
742 				pBuf = pool->nextFreeBuf;
743 				/* Freed the Buffer one by one till all the Memory is freed*/
744 				for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){
745 						IX_OSAL_MBUF* pBufTemp;
746 						pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf);
747 						/* Freed MBUF Data Memory area*/
748 						IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) );
749 						/* Freed MBUF Struct Memory area*/
750 						IX_OSAL_CACHE_DMA_FREE(pBuf);
751 						pBuf = pBufTemp;
752 				}
753 
754 #else
755         IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr);
756         IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr);
757 #endif
758     }
759 
760     ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &=
761         ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS));
762     ixOsalBuffPoolsInUse--;
763     return IX_SUCCESS;
764 }
765 
766 /*
767  * Function definition: ixOsalBuffPoolDataAreaSizeGet
768  */
769 PUBLIC UINT32
ixOsalBuffPoolDataAreaSizeGet(int count,int size)770 ixOsalBuffPoolDataAreaSizeGet (int count, int size)
771 {
772     UINT32 memorySize;
773     memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size);
774     return memorySize;
775 }
776 
777 /*
778  * Function definition: ixOsalBuffPoolMbufAreaSizeGet
779  */
780 PUBLIC UINT32
ixOsalBuffPoolMbufAreaSizeGet(int count)781 ixOsalBuffPoolMbufAreaSizeGet (int count)
782 {
783     UINT32 memorySize;
784     memorySize =
785         count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF));
786     return memorySize;
787 }
788 
789 /*
790  * Function definition: ixOsalBuffPoolFreeCountGet
791  */
ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)792 PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr)
793 
794 {
795 
796    return poolPtr->freeBufsInPool;
797 
798 }
799 
800 #endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */
801