1/****************************************************************************
2**+-----------------------------------------------------------------------+**
3**|                                                                       |**
4**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
5**| All rights reserved.                                                  |**
6**|                                                                       |**
7**| Redistribution and use in source and binary forms, with or without    |**
8**| modification, are permitted provided that the following conditions    |**
9**| are met:                                                              |**
10**|                                                                       |**
11**|  * Redistributions of source code must retain the above copyright     |**
12**|    notice, this list of conditions and the following disclaimer.      |**
13**|  * Redistributions in binary form must reproduce the above copyright  |**
14**|    notice, this list of conditions and the following disclaimer in    |**
15**|    the documentation and/or other materials provided with the         |**
16**|    distribution.                                                      |**
17**|  * Neither the name Texas Instruments nor the names of its            |**
18**|    contributors may be used to endorse or promote products derived    |**
19**|    from this software without specific prior written permission.      |**
20**|                                                                       |**
21**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
22**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
23**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
24**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
25**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
26**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
27**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
28**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
29**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
30**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
31**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
32**|                                                                       |**
33**+-----------------------------------------------------------------------+**
34****************************************************************************/
35
36/**************************************************************************/
37/*                                                                        */
38/*  MODULE:  memMngr.c                                                */
39/*  PURPOSE: manage the SDRAM buffers for MSDU Data Buffers allocations   */
40/*                                                                        */
41/**************************************************************************/
42
43#include "memMngrEx.h"
44#include "osApi.h"
45#include "report.h"
46
47
48/*************************************************************************
49*                        wlan_memMngrInit                                *
50**************************************************************************
51* DESCRIPTION:  Init of the Memory Manager module. This function allocated
52*               all memroy resources needed for the MemMngr. It tallocate
53*               a pool of Msdu structure, pool of Bd structure, and
54*               number of pools of data buffers.
55*
56* INPUT:        hOs - handle to Os abstraction layer
57*
58* OUTPUT:
59*
60* RETURN:       Handle to the allocated MemMngr control block
61**************************************************************************/
62TI_HANDLE wlan_memMngrInit(TI_HANDLE hOs)
63{
64    memMngr_t   *pMemMngr;
65    UINT32      count,i;
66    memMngrInit_t pMemMngrInit;
67
68    if( hOs  == NULL )
69    {
70        WLAN_OS_REPORT(("wlan_memMngrInit() : FATAL ERROR: OS handle Error - Aborting\n"));
71        return NULL;
72    }
73
74    /* structures for initialization of Memory manager */
75    pMemMngrInit.numOfPools = DEF_NUMBER_OF_BUF_POOLS;
76    pMemMngrInit.bufPoolInit[0].buffersSize = DEF_BUFFER_LENGTH_POOL_1;
77    pMemMngrInit.bufPoolInit[0].numOfbuffers = DEF_NUMBER_OF_BUFFERS_IN_POOL_1;
78    pMemMngrInit.bufPoolInit[1].buffersSize = DEF_BUFFER_LENGTH_POOL_2;
79    pMemMngrInit.bufPoolInit[1].numOfbuffers = DEF_NUMBER_OF_BUFFERS_IN_POOL_2;
80    pMemMngrInit.bufPoolInit[2].buffersSize = DEF_BUFFER_LENGTH_POOL_3;
81    pMemMngrInit.bufPoolInit[2].numOfbuffers = DEF_NUMBER_OF_BUFFERS_IN_POOL_3;
82
83    for( count = 0 ; count  < pMemMngrInit.numOfPools ; count++ )
84    {
85        if( pMemMngrInit.bufPoolInit[count].buffersSize > MAX_BUFFER_LENGTH ||
86            pMemMngrInit.bufPoolInit[count].buffersSize < MIN_BUFFER_LENGTH)
87        {
88            WLAN_OS_REPORT(("wlan_memMngrInit() : FATAL ERROR: Buffer length out of range - Aborting\n"));
89            return NULL;
90        }
91        if( count != 0 )
92        {
93            if(pMemMngrInit.bufPoolInit[count].buffersSize < pMemMngrInit.bufPoolInit[count-1].buffersSize )
94            {
95                WLAN_OS_REPORT(("wlan_memMngrInit() : FATAL ERROR: Buffer length's out of order - Aborting\n"));
96                return NULL;
97            }
98        }
99    }
100
101    /* alocate MemMngr module control block */
102    pMemMngr = os_memoryAlloc(hOs, (sizeof(memMngr_t)));
103    if(!pMemMngr) {
104        WLAN_OS_REPORT(("FATAL ERROR: Could not allocate pMemMngr - Aborting\n"));
105        return NULL;
106    }
107
108    os_memoryZero(hOs, pMemMngr, sizeof(memMngr_t));
109
110    pMemMngr->hOs = hOs;
111
112    pMemMngr->msduMaxNumber = DEF_NUMBER_OF_MSDUS;
113    pMemMngr->bdMaxNumber = DEF_NUMBER_OF_BDS;
114    pMemMngr->numFreeMSDU = pMemMngr->msduMaxNumber;
115    pMemMngr->numFreeBD = pMemMngr->bdMaxNumber;
116
117    pMemMngr->msduPool = (mem_MSDU_T*)os_memoryCAlloc(hOs, pMemMngr->msduMaxNumber, sizeof(mem_MSDU_T));
118    os_profile (hOs, 8, pMemMngr->msduMaxNumber * sizeof(mem_MSDU_T));
119
120    if (pMemMngr->msduPool == NULL)
121    {
122        wlan_memMngrDestroy(pMemMngr);
123        WLAN_OS_REPORT(("FATAL ERROR: Could not allocate memory for MEM MNGR - Aborting\n"));
124        return NULL;
125    }
126
127    pMemMngr->bdPool = (mem_BD_T*)os_memoryCAlloc(hOs, pMemMngr->bdMaxNumber, sizeof(mem_BD_T));
128    os_profile (hOs, 8, pMemMngr->bdMaxNumber * sizeof(mem_BD_T));
129
130    if (pMemMngr->bdPool == NULL)
131    {
132        wlan_memMngrDestroy(pMemMngr);
133        WLAN_OS_REPORT(("FATAL ERROR: Could not allocate memory for MEM MNGR - Aborting\n"));
134        return NULL;
135    }
136
137    /* initialize buffer pools objects */
138    pMemMngr->currentNumberOfPools = pMemMngrInit.numOfPools;
139    for( count = 0 ; count  < pMemMngr->currentNumberOfPools  ; count++ )
140    {
141        pMemMngr->buffersPool[count].buffersSize = pMemMngrInit.bufPoolInit[count].buffersSize;
142
143        pMemMngr->buffersPool[count].numFreeDataBuf = pMemMngrInit.bufPoolInit[count].numOfbuffers;
144
145        pMemMngr->buffersPool[count].dataBufMaxNumber = pMemMngrInit.bufPoolInit[count].numOfbuffers;
146
147        if((pMemMngr->buffersPool[count].dataBufPool = (mem_DataBuf_T*)os_memoryCAlloc(hOs,
148            pMemMngr->buffersPool[count].dataBufMaxNumber, sizeof(mem_DataBuf_T))) == NULL)
149        {
150            wlan_memMngrDestroy(pMemMngr);
151            WLAN_OS_REPORT(("FATAL ERROR: Could not allocate buffer pools  for MEM MNGR - Aborting\n"));
152            return NULL;
153        }
154        os_profile (hOs, 8, pMemMngr->buffersPool[count].dataBufMaxNumber * sizeof(mem_DataBuf_T));
155
156        pMemMngr->buffersPool[count].firstFreeDataBuf = pMemMngr->buffersPool[count].dataBufPool;
157
158        os_memoryZero(hOs, pMemMngr->buffersPool[count].dataBufPool,
159            (pMemMngr->buffersPool[count].numFreeDataBuf * sizeof(mem_DataBuf_T)));
160
161#ifdef TNETW_MASTER_MODE
162        if((pMemMngr->buffersPool[count].dataBufPoolPtr = (UINT8 *)os_memorySharedAlloc(hOs,
163            pMemMngr->buffersPool[count].buffersSize * pMemMngr->buffersPool[count].dataBufMaxNumber,
164            (void *)&pMemMngr->buffersPool[count].physicalDataBufPoolPtr)) == NULL)
165        {
166            wlan_memMngrDestroy(pMemMngr);
167            WLAN_OS_REPORT(("FATAL ERROR: Could not allocate buffers for MEM MNGR (count=%d / %d, size=%d) - Aborting\n",
168                count, pMemMngr->currentNumberOfPools,
169                pMemMngr->buffersPool[count].buffersSize * pMemMngr->buffersPool[count].dataBufMaxNumber));
170            return NULL;
171        }
172#else
173        if((pMemMngr->buffersPool[count].dataBufPoolPtr = (UINT8 *)os_memoryPreAlloc(hOs, count,
174            pMemMngr->buffersPool[count].buffersSize * pMemMngr->buffersPool[count].dataBufMaxNumber)) == NULL)
175        {
176            wlan_memMngrDestroy(pMemMngr);
177            WLAN_OS_REPORT(("FATAL ERROR: Could not allocate buffers for MEM MNGR - Aborting\n"));
178            return NULL;
179        }
180#endif
181        os_profile (hOs, 8, pMemMngr->buffersPool[count].buffersSize * pMemMngr->buffersPool[count].dataBufMaxNumber);
182
183	/* alocate the buffers */
184        for (i = 0; i < pMemMngr->buffersPool[count].dataBufMaxNumber; ++i)
185        {
186#ifdef TNETW_MASTER_MODE
187            pMemMngr->buffersPool[count].dataBufPool[i].data = (UINT8 *)
188                (pMemMngr->buffersPool[count].dataBufPoolPtr
189                + i*pMemMngr->buffersPool[count].buffersSize);
190
191            pMemMngr->buffersPool[count].dataBufPool[i].data_physical.u.LowPart = (ULONG)
192                (pMemMngr->buffersPool[count].physicalDataBufPoolPtr.u.LowPart + i*pMemMngr->buffersPool[count].buffersSize);
193#else
194
195            pMemMngr->buffersPool[count].dataBufPool[i].data = (UINT8 *)
196                (pMemMngr->buffersPool[count].dataBufPoolPtr
197                + i*pMemMngr->buffersPool[count].buffersSize);
198
199#endif
200
201            pMemMngr->buffersPool[count].dataBufPool[i].poolIndex = count;
202        }
203    }
204
205    /* chain the items in each list */
206    for (count = 0; count < pMemMngr->msduMaxNumber; ++count) {
207        pMemMngr->msduPool[count].handle = count;
208        if (count < pMemMngr->msduMaxNumber-1)  /* update next pointer except of the last one */
209            pMemMngr->msduPool[count].nextFreeMSDU = &(pMemMngr->msduPool[count+1]);
210    }
211    for (count = 0; count < pMemMngr->bdMaxNumber; ++count) {
212        pMemMngr->bdPool[count].handle = count;
213        if (count < pMemMngr->bdMaxNumber-1)    /* update next pointer except of the last one */
214            pMemMngr->bdPool[count].nextBDPtr = &(pMemMngr->bdPool[count+1]);
215    }
216    for (i = 0; i < pMemMngr->currentNumberOfPools; ++i) {
217        for (count = 0; count < pMemMngr->buffersPool[i].dataBufMaxNumber; ++count) {
218            pMemMngr->buffersPool[i].dataBufPool[count].handle = count;
219            if (count < pMemMngr->buffersPool[i].dataBufMaxNumber-1)        /* update next pointer except of the last one */
220                pMemMngr->buffersPool[i].dataBufPool[count].nextDataBuf = &(pMemMngr->buffersPool[i].dataBufPool[count+1]);
221        }
222    }
223
224    /* assign a pointer for the start of each list */
225    pMemMngr->firstFreeMSDU = pMemMngr->msduPool;
226    pMemMngr->firstFreeBD = pMemMngr->bdPool;
227
228    for(count=0 ; count < MAX_NUMBER_OF_MODULE; count++)
229        pMemMngr->moduleAllocCount[count] = 0;
230
231    if(( pMemMngr->hCriticalSectionProtect = os_protectCreate(hOs)) == NULL)
232    {
233        wlan_memMngrDestroy(pMemMngr);
234        WLAN_OS_REPORT(("FATAL ERROR: Could not Create Critical Section Protection for MEM MNGR - Aborting\n"));
235        return NULL;
236    }
237
238    return pMemMngr;
239}
240/***************************************************************************
241*                       wlan_memMngrConfigure                              *
242****************************************************************************
243* DESCRIPTION:  This function configures MemMngr module
244*
245* INPUTS:       hMemMngr - The object
246*               hOs - Handle to the Os Abstraction Layer
247*               hReport - Handle to the Report object
248* OUTPUT:
249*
250* RETURNS:      OK - Configuration succesfull
251*               NOK - Configuration unsuccesfull
252***************************************************************************/
253TI_STATUS wlan_memMngrConfigure(TI_HANDLE hMemMngr, TI_HANDLE hOs, TI_HANDLE hReport)
254{
255    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
256
257    pMemMngr->hReport = hReport;
258
259    WLAN_REPORT_INIT(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
260        (".....MemMngr configured successfully\n"));
261
262    return OK;
263}
264/***************************************************************************
265*                           wlan_memMngrDestroy                            *
266****************************************************************************
267* DESCRIPTION:  This function unload the tMemMngr module. It first free
268*               the msdu pool, bd pool, data buffers pools and
269*               then free the tMemMngr control block
270*
271* INPUTS:       hMemMngr - the object
272*
273* OUTPUT:
274*
275* RETURNS:      OK - Unload succesfull
276*               NOK - Unload unsuccesfull
277***************************************************************************/
278
279TI_STATUS wlan_memMngrDestroy(TI_HANDLE hMemMngr)
280{
281    UINT32 count;
282    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
283
284    /* Free Msdu pool */
285    if(pMemMngr->msduPool)
286    {
287        os_memoryFree(pMemMngr->hOs, pMemMngr->msduPool,
288            sizeof(mem_MSDU_T)*pMemMngr->msduMaxNumber);
289    }
290    /* Free Bd pool */
291    if(pMemMngr->bdPool)
292    {
293        os_memoryFree(pMemMngr->hOs, pMemMngr->bdPool,
294            sizeof(mem_BD_T)*pMemMngr->bdMaxNumber);
295    }
296
297    /* free data buf pools according to the number of pools */
298    for( count = 0 ; count  < pMemMngr->currentNumberOfPools  ; count++ )
299    {
300#ifdef TNETW_MASTER_MODE
301        if(pMemMngr->buffersPool[count].dataBufPoolPtr)
302        {
303            os_memorySharedFree(pMemMngr->hOs,pMemMngr->buffersPool[count].dataBufPoolPtr,
304                pMemMngr->buffersPool[count].buffersSize*pMemMngr->buffersPool[count].dataBufMaxNumber,
305                pMemMngr->buffersPool[count].physicalDataBufPoolPtr);
306        }
307#else
308        if(pMemMngr->buffersPool[count].dataBufPoolPtr)
309        {
310            os_memoryFree(pMemMngr->hOs,pMemMngr->buffersPool[count].dataBufPoolPtr,
311                pMemMngr->buffersPool[count].buffersSize*pMemMngr->buffersPool[count].dataBufMaxNumber);
312        }
313#endif
314
315        if(pMemMngr->buffersPool[count].dataBufPool)
316        {
317            os_memoryFree(pMemMngr->hOs, pMemMngr->buffersPool[count].dataBufPool,
318                sizeof(mem_DataBuf_T)*pMemMngr->buffersPool[count].dataBufMaxNumber);
319        }
320    }
321
322    /* free os_protect resources */
323    if(pMemMngr->hCriticalSectionProtect)
324        os_protectDestroy(pMemMngr->hOs,pMemMngr->hCriticalSectionProtect);
325
326    /* free the MemMngr control block */
327    os_memoryFree(pMemMngr->hOs, pMemMngr,sizeof(memMngr_t));
328
329    return OK;
330}
331
332/*************************************************************************
333*                        wlan_memMngrAllocDataBuf                        *
334**************************************************************************
335* DESCRIPTION:  This function allocates BDs and Data Buffers according
336*               to the required length. The memory manager will allocate
337*               the Data Buffers, update the buffer pointer in the BD
338*               structure and link the BDs when more than one Data
339*               Buffer is required. The Buffer length is selected that
340*               minimum beffer len will allocted.
341*
342* INPUT:        hMemMngr - the object
343*               len - the length of the required data buffer
344*
345* OUTPUT:       BDPtr - a pointer in which this function will return
346*                   to the allocated BD
347*
348*RETURN:        OK/NOK
349**************************************************************************/
350TI_STATUS wlan_memMngrAllocDataBuf(TI_HANDLE hMemMngr, mem_BD_T** bdPtr, UINT32 len)
351{
352    UINT32          poolIndex,count,dataBufNum;
353    mem_BD_T*       allocBdTmp;         /* pointer to the current allocated BD in the new list */
354    mem_DataBuf_T*  allocDataBufTmp;    /* pointer to the current allocated Data Buf */
355    buffersPool_t*  tempBuffersPool;
356
357    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
358
359    /* calculate the length and the number of Data Buffers we need allocate */
360    for (poolIndex = 0; poolIndex < pMemMngr->currentNumberOfPools-1; poolIndex++)
361    {
362        if(len < pMemMngr->buffersPool[poolIndex].buffersSize)
363            break;
364    }
365
366    /* the selected buffer pool */
367    tempBuffersPool = &pMemMngr->buffersPool[poolIndex];
368
369    /* calculate the number of buffers needed */
370    dataBufNum = (len / tempBuffersPool->buffersSize) + 1;
371
372    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
373
374    allocBdTmp = pMemMngr->firstFreeBD;
375    *bdPtr = pMemMngr->firstFreeBD;
376
377    allocDataBufTmp = tempBuffersPool->firstFreeDataBuf;
378
379    /* check if we have enough memory - Data buffers (in the selected pool) and Bds */
380    if ((pMemMngr->numFreeBD < dataBufNum) || (tempBuffersPool->numFreeDataBuf < dataBufNum))
381    {
382    	os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* END OF CRITICAL SECTION */
383        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
384            ("DB: mem_allocDataBuf: not enough memory numFreeBD=%d numFreeDataBuf=%d in Pool number=%d req DataBufs=%d\n",
385                pMemMngr->numFreeBD, tempBuffersPool->numFreeDataBuf,poolIndex, dataBufNum));
386        *bdPtr = NULL;
387        return NOK;
388    }
389
390    /* update the pointers to the head of the list */
391    for (count = 0 ; count < dataBufNum ; ++count)
392    {
393        allocBdTmp->refCount = 1;
394        allocBdTmp->dataBuf = allocDataBufTmp;
395        allocBdTmp->data = (char*)(allocDataBufTmp->data);
396#ifdef TNETW_MASTER_MODE
397        allocBdTmp->data_physical_low = os_memoryGetPhysicalLow(allocDataBufTmp->data_physical);
398#endif
399        allocDataBufTmp->refCount = 1;
400        allocBdTmp->length = tempBuffersPool->buffersSize;
401        if (count == (dataBufNum-1))
402        {
403            /* the last BD in the allocated list */
404            pMemMngr->firstFreeBD = allocBdTmp->nextBDPtr;
405            tempBuffersPool->firstFreeDataBuf = allocDataBufTmp->nextDataBuf;
406            allocBdTmp->nextBDPtr = NULL;
407            allocDataBufTmp->nextDataBuf = NULL;
408        }
409        else
410        {
411            allocBdTmp = allocBdTmp->nextBDPtr;
412            allocDataBufTmp = allocDataBufTmp->nextDataBuf;
413        }
414    }
415
416    /* update counter of free Bds and Data buffers */
417    pMemMngr->numFreeBD -= dataBufNum;
418    tempBuffersPool->numFreeDataBuf -= dataBufNum;
419
420    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* END OF CRITICAL SECTION */
421
422    return OK;
423}
424
425
426/*************************************************************************
427*                         wlan_memMngrAllocBDs                           *
428**************************************************************************
429* DESCRIPTION:  This function allocates and returns a pointer to a link
430*               list of BDs. This function allocates only Bds structure
431*               and does not allocate any memory buffers.
432*
433* INPUT:        hMemMngr - The object
434*               bdNumber - number of required BDs
435*
436* OUTPUT:       bdPtr - a pointer in which this function will return
437*                    to the first Bd in the allocated list
438*
439* RETURN:     OK/NOK
440**************************************************************************/
441TI_STATUS wlan_memMngrAllocBDs(TI_HANDLE hMemMngr, UINT32 bdNumber, mem_BD_T** bdPtr)
442{
443    UINT32          count;
444    mem_BD_T*       allocBdTmp; /* pointer to the current allocated BD in the new list */
445
446    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
447
448    if (bdNumber == 0)
449    {
450        *bdPtr = NULL;
451        return NOK;
452    }
453
454    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
455    allocBdTmp = pMemMngr->firstFreeBD;
456    *bdPtr = pMemMngr->firstFreeBD;
457
458    /* check if we have enough Bds */
459    if (pMemMngr->numFreeBD < bdNumber)
460    {
461        os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* END OF CRITICAL SECTION */
462        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
463            ("DB: wlan_memMngrAllocBDs: not enough memory\n"));
464        *bdPtr = NULL;
465        return NOK;
466    }
467
468    /* update the pointers to the head of the list */
469    for (count = 0 ; count < bdNumber ; ++count)
470    {
471        allocBdTmp->refCount = 1;
472        if (count == (bdNumber-1))
473        {
474            /* the last bd in the allocated list */
475            pMemMngr->firstFreeBD = allocBdTmp->nextBDPtr;
476            allocBdTmp->nextBDPtr = NULL;
477        }
478        else
479        {
480            allocBdTmp = allocBdTmp->nextBDPtr;
481        }
482    }
483
484    /* update counter of free Bds  */
485    pMemMngr->numFreeBD -= bdNumber;
486
487    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
488
489    return OK;
490}
491
492
493/*************************************************************************
494*                        wlan_memMngrAllocMSDU                           *
495**************************************************************************
496* DESCRIPTION:  This function allocates MSDU structure with a number of
497*               BDs and Data Buffers as required by 'len'.
498*
499* INPUT:        hMemMngr - The object
500*               len - the length of the required data buffer
501*                   if len=0, than only MSDU buffer will be allocated
502*               module - the module that allocate this Msdu
503*
504* OUTPUT:       MSDUPtr - a pointer in which this function will
505*                   return to the allocated MSDU structure
506*
507* RETURN:     OK/NOK
508**************************************************************************/
509TI_STATUS wlan_memMngrAllocMSDU (TI_HANDLE hMemMngr, mem_MSDU_T** MSDUPtr,
510                              UINT32 len, allocatingModule_e module)
511{
512    UINT32      rc;
513    mem_BD_T*   bdTmp;
514
515    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
516
517    if (pMemMngr->msduPool == NULL)
518    {
519        /* object not initiated yet (!!!) */
520        *MSDUPtr = NULL;
521        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
522            ("wlan_memMngrAllocMSDU: failed!\n"));
523        memMngrPrint(hMemMngr);
524        return NOK;
525    }
526
527    if (len > 0)
528    {
529        /* we need to allocate BD and Data Buffers */
530        rc = wlan_memMngrAllocDataBuf(hMemMngr,&bdTmp, len);
531        if (rc == NOK)
532        {
533            *MSDUPtr = NULL;
534            WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
535                ("wlan_memMngrAllocMSDU: failed! no data bufs\n"));
536            memMngrPrint(hMemMngr);
537            return NOK;
538        }
539    }
540    else
541    {
542        /* len = 0 - need to allocate msdu structure only */
543        rc = wlan_memMngrAllocMSDUBufferOnly(hMemMngr, MSDUPtr, module);
544        if (rc == NOK)
545        {
546            *MSDUPtr = NULL;
547            WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
548                ("wlan_memMngrAllocMSDU: failed to alloc buffer only!\n"));
549            memMngrPrint(hMemMngr);
550            return NOK;
551        }
552        return OK;
553
554    }
555
556    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* START OF CRITICAL SECTION */
557
558    /* check if we have enough free Msdu's */
559     if (pMemMngr->firstFreeMSDU == NULL)
560    {
561        /* no free MSDU buffers */
562        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
563                ("wlan_memMngrAllocMSDU no free MSDU in MemMngr !!!\n"));
564    	os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
565        memMngrPrint(hMemMngr);
566
567        /* In case we dont have free msdu - free the allocated Bds */
568        wlan_memMngrFreeBD(hMemMngr,bdTmp->handle);
569        *MSDUPtr = NULL;
570        return NOK;
571    }
572
573    *MSDUPtr = pMemMngr->firstFreeMSDU;
574    pMemMngr->firstFreeMSDU = pMemMngr->firstFreeMSDU->nextFreeMSDU;
575    pMemMngr->moduleAllocCount[module]++;
576
577    /* update counter of free msdu's  */
578    pMemMngr->numFreeMSDU--;
579
580    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
581
582    (*MSDUPtr)->nextFreeMSDU = NULL;
583    (*MSDUPtr)->freeFunc = NULL;
584    (*MSDUPtr)->firstBDPtr = bdTmp;
585    (*MSDUPtr)->lastBDPtr = bdTmp;
586    (*MSDUPtr)->dataLen = len;
587    (*MSDUPtr)->nextMSDUinList = NULL;
588    (*MSDUPtr)->prevMSDUinList = NULL;
589    (*MSDUPtr)->txFlags = 0;
590    (*MSDUPtr)->txCompleteFlags = 0;
591    (*MSDUPtr)->module = module;
592  #ifdef TI_DBG
593    (*MSDUPtr)->timeStampNum = 0;
594  #endif
595
596    return OK;
597}
598
599/*************************************************************************
600*                 wlan_memMngrAllocMSDUBufferOnly                        *
601**************************************************************************
602* DESCRIPTION:  This function allocates MSDU structure - without
603*                   Bds and Data Buffers
604*
605* INPUT:        hMemMngr - The object
606*
607* OUTPUT:       MSDUPtr - a pointer in which this function will return
608*                     to the allocated MSDU structure
609*               module - the module that allocate this Msdu
610*
611* RETURN:       OK/NOK
612**************************************************************************/
613TI_STATUS wlan_memMngrAllocMSDUBufferOnly(TI_HANDLE hMemMngr, mem_MSDU_T** MSDUPtr, allocatingModule_e module)
614{
615    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
616
617    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
618
619    if (pMemMngr->firstFreeMSDU == NULL)
620    {
621        /* no free MSDU buffers */
622        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
623                ("wlan_memMngrAllocMSDUBufferOnly no free MSDU in MemMngr !!!\n"));
624        os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
625        *MSDUPtr = NULL;
626        return NOK;
627    }
628
629    *MSDUPtr = pMemMngr->firstFreeMSDU;
630    pMemMngr->firstFreeMSDU = pMemMngr->firstFreeMSDU->nextFreeMSDU;
631    pMemMngr->moduleAllocCount[module]++;
632
633    /* update counter of free msdu's  */
634    pMemMngr->numFreeMSDU--;
635
636    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* END OF CRITICAL SECTION */
637
638    (*MSDUPtr)->nextFreeMSDU = NULL;
639    (*MSDUPtr)->freeFunc = NULL;
640    (*MSDUPtr)->firstBDPtr = NULL;
641    (*MSDUPtr)->lastBDPtr = NULL;
642    (*MSDUPtr)->dataLen = 0;
643    (*MSDUPtr)->nextMSDUinList = NULL;
644    (*MSDUPtr)->prevMSDUinList = NULL;
645    (*MSDUPtr)->txFlags = 0;
646    (*MSDUPtr)->txCompleteFlags = 0;
647    (*MSDUPtr)->module = module;
648  #ifdef TI_DBG
649    (*MSDUPtr)->timeStampNum = 0;
650  #endif
651
652    return OK;
653}
654
655/*************************************************************************
656*                     wlan_memMngrFreeListOfMSDU                         *
657**************************************************************************
658* DESCRIPTION:  Free list of MSDUs structure. This function will run
659*               over the MSDU list (if exist) and free all MSDU's with
660*               all BDs and Data Buffers that are bind to this MSDU.
661*
662* INPUT:        hMemMngr - The object
663*               handle - handle to the first MSDU in the list
664*
665* OUTPUT:
666*
667* RETURN:       OK/NOK
668**************************************************************************/
669TI_STATUS wlan_memMngrFreeListOfMSDU(TI_HANDLE hMemMngr, UINT32 handle)
670{
671    mem_MSDU_T          *msduTmp,*nextTmpMsdu;
672
673    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
674
675    msduTmp = &(pMemMngr->msduPool[handle]);
676
677    while (msduTmp != NULL)
678    {
679        nextTmpMsdu = msduTmp->nextMSDUinList;
680        if(wlan_memMngrFreeMSDU(hMemMngr,memMgr_MsduHandle(msduTmp)) != OK)
681        {
682            WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
683                ("wlan_memMngrFreeListOfMSDU This MSDU is already free\n"));
684		    //os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
685            return NOK;
686        }
687        msduTmp = nextTmpMsdu;
688    }
689
690    return OK;
691}
692
693/*************************************************************************
694*                        wlan_memMngrFreeMSDU                            *
695**************************************************************************
696* DESCRIPTION:  Free ONE MSDU structure. This function will free all
697*               BDs and Data Buffers that are bind to this MSDU.
698*
699* INPUT:        hMemMngr - The object
700*               handle - handle of the MSDU
701*
702* OUTPUT:
703*
704* RETURN:       OK/NOK
705**************************************************************************/
706TI_STATUS wlan_memMngrFreeMSDU(TI_HANDLE hMemMngr, UINT32 handle)
707{
708    UINT32 freeFlag;
709    ap_FreeMemFunc      freeFunc = NULL;        /* pointer to the Data Buffer free function */
710    UINT32              freeArgs[NUM_OF_FREE_ARGS]; /* arguments to be send with the free function */
711    int i;
712
713    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
714
715    if( handle == WLAN_DRV_NULL_MEM_HANDLE )
716        return OK;
717
718    /* check if the msdu is already free */
719    if(pMemMngr->msduPool[handle].module == MODULE_FREE_MSDU)
720    {
721        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
722                ("wlan_memMngrFreeMSDU This MSDU is already free\n"));
723        return NOK;
724
725    }
726
727    if (pMemMngr->msduPool[handle].firstBDPtr != NULL)
728    {
729        /* free all BDs and Data Buffers */
730        freeFlag = wlan_memMngrFreeBD(hMemMngr, pMemMngr->msduPool[handle].firstBDPtr->handle);
731
732        if ((freeFlag == TRUE) && (pMemMngr->msduPool[handle].freeFunc != NULL))
733        {
734            /* save the free parameters to do it at the end of the function */
735            freeFunc = pMemMngr->msduPool[handle].freeFunc;
736            for (i=0; i<NUM_OF_FREE_ARGS; i++)
737                freeArgs[i] = pMemMngr->msduPool[handle].freeArgs[i];
738        }
739    }
740
741    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* START OF CRITICAL SECTION */
742
743    /* reset the fields of the MSDU buffer */
744    pMemMngr->msduPool[handle].firstBDPtr = NULL;
745    pMemMngr->msduPool[handle].freeFunc = NULL;
746    pMemMngr->msduPool[handle].freeArgs[0] = 0;
747    pMemMngr->msduPool[handle].freeArgs[1] = 0;
748    pMemMngr->msduPool[handle].freeArgs[2] = 0;
749    pMemMngr->msduPool[handle].dataLen = 0;
750    pMemMngr->msduPool[handle].headerLen = 0;
751    pMemMngr->msduPool[handle].txFlags = 0;
752    pMemMngr->msduPool[handle].txCompleteFlags = 0;
753    pMemMngr->msduPool[handle].nextMSDUinList = 0;
754    pMemMngr->msduPool[handle].prevMSDUinList = 0;
755    pMemMngr->numFreeMSDU++;
756
757    pMemMngr->moduleAllocCount[pMemMngr->msduPool[handle].module]--;
758
759    pMemMngr->msduPool[handle].module = MODULE_FREE_MSDU;
760
761    /* add the MSDU to the free MSDU list */
762    pMemMngr->msduPool[handle].nextFreeMSDU = pMemMngr->firstFreeMSDU;
763    pMemMngr->firstFreeMSDU = &(pMemMngr->msduPool[handle]);
764
765    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
766
767    /* !!!!!!!! The free should be only after os_protectUnlock !!!!!!!! */
768    if (freeFunc != NULL)
769    {
770        /* call free function */
771        freeFunc((TI_HANDLE)(freeArgs[0]),
772                 (TI_HANDLE)(freeArgs[1]),
773                 (TI_STATUS)(freeArgs[2]));
774    }
775
776    return OK;
777}
778
779
780/*************************************************************************
781*                            allocDataBuf                                *
782**************************************************************************
783* DESCRIPTION:  Allocate Data Buffer
784*
785* INPUT:        hMemMngr - The object
786*               dataBuf - pointer to the new allocated Data Buffer
787*               poolIndex - The index of the pool to allocate from
788*
789* OUTPUT:
790*
791* RETURN:       OK/NOK
792**************************************************************************/
793#if 0
794static TI_STATUS allocDataBuf(TI_HANDLE hMemMngr, mem_DataBuf_T* dataBuf, UINT32 poolIndex)
795{
796    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
797
798    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
799    if (pMemMngr->buffersPool[poolIndex].firstFreeDataBuf == NULL) {
800        os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
801        return NOK;
802    }
803    dataBuf = pMemMngr->buffersPool[poolIndex].firstFreeDataBuf;
804    pMemMngr->buffersPool[poolIndex].firstFreeDataBuf = pMemMngr->buffersPool[poolIndex].firstFreeDataBuf->nextDataBuf;
805    pMemMngr->buffersPool[poolIndex].numFreeDataBuf--;
806    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
807
808    return OK;
809}
810#endif
811
812
813/*************************************************************************
814*                          freeDataBuf                                   *
815**************************************************************************
816* DESCRIPTION:  Free Data Buffer.
817*
818* INPUT:        hMemMngr - The object
819*               dataBuf - pointer to the Data Buffer
820*
821* OUTPUT:
822*
823* RETURN:       OK/NOK
824**************************************************************************/
825static TI_STATUS freeDataBuf(TI_HANDLE hMemMngr, mem_DataBuf_T* dataBuf)
826{
827    buffersPool_t   *tempBuffersPool;
828    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
829
830    if (dataBuf->refCount == 0) {
831        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
832            ("DB: freeDataBuf FATAL ERROR: dataBuf->refCount < 0\n"));
833        return NOK;
834    }
835
836    if (--(dataBuf->refCount) == 0) {
837        tempBuffersPool = &pMemMngr->buffersPool[dataBuf->poolIndex];
838        /* add this Data Buffer to the free list of the correct pool*/
839        dataBuf->nextDataBuf = tempBuffersPool->firstFreeDataBuf;
840        tempBuffersPool->firstFreeDataBuf = dataBuf;
841        tempBuffersPool->numFreeDataBuf++;
842    }
843
844    return OK;
845}
846
847
848/*************************************************************************
849*                        wlan_memMngrFreeBD                              *
850**************************************************************************
851* DESCRIPTION:  Free BD structure. This function will free a list of BD
852*               structures and the Data Buffer that is being pointed by
853*               these BD if any.
854*
855* INPUT:        hMemMngr - The object
856*               handle - handle of this BD
857* OUTPUT:
858* RETURN:       freeFlag - return TRUE if this BD list was freed
859*                   return FALSE if this BD list was not freed (refCount>0)
860**************************************************************************/
861UINT32 wlan_memMngrFreeBD(TI_HANDLE hMemMngr, UINT32 handle)
862{
863    UINT32              rc = FALSE;
864    mem_DataBuf_T*      dataBuf;
865    mem_BD_T*           bdTmp;     /* pointer to the current BD we need to free */
866    mem_BD_T*           nextBdTmp; /* pointer to the next BD we need to free    */
867
868    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
869
870    bdTmp = &(pMemMngr->bdPool[handle]);
871
872    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
873
874    while (bdTmp != NULL)
875    {
876        dataBuf = bdTmp->dataBuf;
877        nextBdTmp = bdTmp->nextBDPtr;
878        if (bdTmp->refCount == 0)
879        {
880            WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
881                ("DB: wlan_memMngrFreeBD FATAL ERROR: bdTmp->refCount < 0\n"));
882            os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
883            return FALSE;
884        }
885        if (dataBuf != NULL)
886        {
887            freeDataBuf(hMemMngr, dataBuf);
888        }
889
890#ifdef TNETW_MASTER_MODE
891        if( bdTmp->freeFunc != NULL)
892        {
893            bdTmp->freeFunc(  bdTmp->freeArgs[0], bdTmp->freeArgs[1], bdTmp->freeArgs[2],
894                              bdTmp->freeArgs[3], bdTmp->freeArgs[4]);
895        }
896#endif
897
898        if (--(bdTmp->refCount) == 0)
899        {
900            bdTmp->dataBuf = NULL;
901            bdTmp->data = NULL;
902
903#ifdef TNETW_MASTER_MODE
904            bdTmp->data_physical_low = 0;
905            bdTmp->freeFunc     = NULL;
906            os_memoryZero(pMemMngr->hOs, bdTmp->freeArgs, sizeof(UINT32)*NUM_OF_FREE_ARGS);
907#endif
908            bdTmp->dataOffset = 0;
909            bdTmp->length = 0;
910            /* adding the free BD to the free BD list */
911            bdTmp->nextBDPtr = pMemMngr->firstFreeBD;
912            pMemMngr->firstFreeBD = bdTmp;
913            pMemMngr->numFreeBD++;
914        }
915        if (nextBdTmp == NULL)
916        {
917            if (bdTmp->refCount <= 0)
918            {
919                rc = TRUE;
920            }
921        }
922        bdTmp = nextBdTmp;
923    }
924
925    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
926    return rc;
927}
928
929
930/*************************************************************************
931*                wlan_memMngrFreeAllOsAlocatesBuffer                     *
932**************************************************************************
933* DESCRIPTION:  This function run over the all msdus in the MemMngr
934*               and call the free function of the os allocated buffers
935*
936* INPUT:        hMemMngr - The object
937*
938* OUTPUT:
939*
940* RETURN:       OK
941**************************************************************************/
942
943TI_STATUS wlan_memMngrFreeAllOsAlocatesBuffer(TI_HANDLE hMemMngr)
944{
945    UINT32 count;
946
947    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
948
949    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* START OF CRITICAL SECTION */
950
951    for(count = 0 ; count < pMemMngr->msduMaxNumber ; count++)
952    {
953        if (pMemMngr->msduPool[count].freeFunc)
954        {
955            WLAN_OS_REPORT(("wlan_memMngrFreeAllOsAlocatesBuffer() - Call Os free func */*/*/**/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/ :\n"));
956#ifndef TNETW_MASTER_MODE
957            pMemMngr->msduPool[count].freeArgs[2] = NOK;
958#endif
959            /* call free function */
960            pMemMngr->msduPool[count].freeFunc((TI_HANDLE)(pMemMngr->msduPool[count].freeArgs[0]),
961                                                (TI_HANDLE)(pMemMngr->msduPool[count].freeArgs[1]),
962                                                (TI_STATUS)(pMemMngr->msduPool[count].freeArgs[2]));
963
964            pMemMngr->msduPool[count].freeFunc = NULL;
965            pMemMngr->msduPool[count].freeArgs[0] = 0;
966            pMemMngr->msduPool[count].freeArgs[1] = 0;
967            pMemMngr->msduPool[count].freeArgs[2] = 0;
968        }
969    }
970
971    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
972
973    return OK;
974}
975
976/*************************************************************************
977*                 wlan_memMngrCopyMsduFreeFunc                           *
978**************************************************************************
979* DESCRIPTION:  Copy The free function and the free arguments from on
980*               Msdu to another
981*
982* INPUT:        hMemMngr - The object
983*               destMsduHandle - the handle of the destination msdu
984*               sourceMsduHandle - the handle of the source msdu
985*
986* OUTPUT:
987*
988* RETURN:       OK
989**************************************************************************/
990
991TI_STATUS wlan_memMngrCopyMsduFreeFunc(TI_HANDLE hMemMngr, UINT32 destMsduHandle, UINT32 sourceMsduHandle)
992{
993    mem_MSDU_T*             sourceMsdu;
994    mem_MSDU_T*             destMsdu;
995
996    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
997
998     if( destMsduHandle == WLAN_DRV_NULL_MEM_HANDLE || sourceMsduHandle == WLAN_DRV_NULL_MEM_HANDLE )
999         return NOK;
1000
1001    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* START OF CRITICAL SECTION */
1002
1003    sourceMsdu = &(pMemMngr->msduPool[sourceMsduHandle]);
1004    destMsdu = &(pMemMngr->msduPool[destMsduHandle]);
1005
1006    destMsdu->freeFunc = sourceMsdu->freeFunc;
1007
1008    os_memoryCopy(pMemMngr->hOs, (void *)destMsdu->freeArgs, (void *)sourceMsdu->freeArgs,(NUM_OF_FREE_ARGS*sizeof(UINT32)));
1009
1010    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
1011
1012    return OK;
1013}
1014
1015/*************************************************************************
1016*                 wlan_memMngrChangeMsduOwner                            *
1017**************************************************************************
1018* DESCRIPTION:  the function changes the msdu module owner.
1019*
1020* INPUT:        hMemMngr - The object
1021*               newModule - msdu new module owner
1022*               pMsdu - the msdu to be changed
1023*
1024* OUTPUT:
1025*
1026* RETURN:       OK
1027**************************************************************************/
1028
1029TI_STATUS wlan_memMngrChangeMsduOwner(TI_HANDLE hMemMngr,allocatingModule_e newModule,mem_MSDU_T *pMsdu)
1030{
1031    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1032    allocatingModule_e oldModule;
1033
1034    if(pMsdu == NULL)
1035    {
1036        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
1037            ("wlan_memMngrChangeMsduOwner: pMsdu == NULL\n"));
1038        return NOK;
1039
1040    }
1041
1042    oldModule = pMsdu->module;
1043
1044    if(pMemMngr->moduleAllocCount[oldModule] > 0)
1045    {
1046        pMemMngr->moduleAllocCount[oldModule]--;
1047    }
1048    else
1049    {
1050        WLAN_REPORT_ERROR(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
1051                            ("wlan_memMngrChangeMsduOwner: oldModule %d  AllocCount < 0 ,newModule %d\n", oldModule,newModule));
1052        return NOK;
1053    }
1054
1055
1056    pMemMngr->moduleAllocCount[newModule]++;
1057
1058    pMsdu->module = newModule;
1059
1060    WLAN_REPORT_INFORMATION(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
1061                        ("wlan_memMngrChangeMsduOwner: oldModule: %d , newModule: %d\n", oldModule, newModule));
1062
1063
1064    return OK;
1065
1066
1067
1068
1069
1070
1071}
1072
1073
1074/*************************************************************************
1075*                 wlan_memMngrSwapMsdu                                  *
1076**************************************************************************
1077* DESCRIPTION:  Swap two Msdu, only the MSDU descriptor and not all fields
1078*
1079* INPUT:
1080*
1081* OUTPUT:
1082*
1083* RETURN:       OK
1084**************************************************************************/
1085TI_STATUS wlan_memMngrSwapMsdu(TI_HANDLE hMemMngr, mem_MSDU_T *pMsdu_1, mem_MSDU_T *pMsdu_2)
1086{
1087    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1088    mem_MSDU_T Msdu_tmp;
1089
1090    os_protectLock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);  /* START OF CRITICAL SECTION */
1091
1092    /* copy msdu 1 to Temporary msdu */
1093    Msdu_tmp.freeFunc = pMsdu_1->freeFunc;
1094    os_memoryCopy(pMemMngr->hOs, (void *)Msdu_tmp.freeArgs, (void *)pMsdu_1->freeArgs,(NUM_OF_FREE_ARGS*sizeof(UINT32)));
1095    Msdu_tmp.dataLen = pMsdu_1->dataLen;
1096    Msdu_tmp.headerLen = pMsdu_1->headerLen;
1097    Msdu_tmp.firstBDPtr = pMsdu_1->firstBDPtr;
1098    Msdu_tmp.lastBDPtr  = pMsdu_1->lastBDPtr;
1099
1100    /* copy msdu 2 to msdu 1 */
1101    pMsdu_1->freeFunc = pMsdu_2->freeFunc;
1102    os_memoryCopy(pMemMngr->hOs, (void *)pMsdu_1->freeArgs, (void *)pMsdu_2->freeArgs,(NUM_OF_FREE_ARGS*sizeof(UINT32)));
1103    pMsdu_1->dataLen = pMsdu_2->dataLen;
1104    pMsdu_1->headerLen = pMsdu_2->headerLen;
1105    pMsdu_1->firstBDPtr = pMsdu_2->firstBDPtr;
1106    pMsdu_1->lastBDPtr  = pMsdu_2->lastBDPtr;
1107
1108    /* copy Temporary msdu to msdu 2 */
1109    pMsdu_2->freeFunc = Msdu_tmp.freeFunc;
1110    os_memoryCopy(pMemMngr->hOs, (void *)pMsdu_2->freeArgs, (void *)Msdu_tmp.freeArgs,(NUM_OF_FREE_ARGS*sizeof(UINT32)));
1111    pMsdu_2->dataLen = Msdu_tmp.dataLen;
1112    pMsdu_2->headerLen = Msdu_tmp.headerLen;
1113    pMsdu_2->firstBDPtr = Msdu_tmp.firstBDPtr;
1114    pMsdu_2->lastBDPtr  = Msdu_tmp.lastBDPtr;
1115
1116    os_protectUnlock(pMemMngr->hOs, pMemMngr->hCriticalSectionProtect);/* END OF CRITICAL SECTION */
1117
1118    return OK;
1119}
1120
1121TI_STATUS wlan_memMngrGetMemMgrResources(TI_HANDLE hMemMngr, memMgrResources_t* memMgrResources)
1122{
1123    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1124
1125    memMgrResources->numOfFreeBDs = pMemMngr->numFreeBD;
1126    memMgrResources->numOfFreeMsdu = pMemMngr->numFreeMSDU;
1127    memMgrResources->numOfFreeBufPool1 = pMemMngr->buffersPool[0].numFreeDataBuf;
1128    memMgrResources->numOfFreeBufPool2 = pMemMngr->buffersPool[1].numFreeDataBuf;
1129    memMgrResources->numOfFreeBufPool3 = pMemMngr->buffersPool[2].numFreeDataBuf;
1130
1131    return OK;
1132}
1133
1134
1135TI_STATUS wlan_memMngrAddTimeStamp (TI_HANDLE hMemMngr, mem_MSDU_T *pMsdu)
1136{
1137  #ifdef TI_DBG
1138    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1139
1140    if (pMsdu->timeStampNum < MAX_NUM_OF_TIME_STAMPS)
1141        pMsdu->timeStamp[pMsdu->timeStampNum ++] =
1142            os_timeStampUs (pMemMngr->hOs);
1143  #endif
1144
1145    return OK;
1146}
1147
1148
1149/*************************************************************************
1150**************************************************************************
1151*                                                                        *
1152*                            TEST FUNCTIONS                              *
1153*                                                                        *
1154**************************************************************************
1155**************************************************************************/
1156
1157void memMngrPrintMSDU(mem_MSDU_T* pMsdu )
1158{
1159    WLAN_OS_REPORT(("\nPrinting MSDU :\n"));
1160    WLAN_OS_REPORT(("handle          = %X\n",pMsdu->handle));
1161    WLAN_OS_REPORT(("nextFreeMSDU	   = %X\n",pMsdu->nextFreeMSDU));
1162    WLAN_OS_REPORT(("headerLen       = %d\n",pMsdu->headerLen));
1163    WLAN_OS_REPORT(("firstBDPtr      = %X\n",pMsdu->firstBDPtr));
1164    WLAN_OS_REPORT(("lastBDPtr       = %X\n",pMsdu->lastBDPtr));
1165    WLAN_OS_REPORT(("freeFunc        = %X\n",pMsdu->freeFunc));
1166    WLAN_OS_REPORT(("freeArgs[0]     = %X\n",pMsdu->freeArgs[0]));
1167    WLAN_OS_REPORT(("freeArgs[1]     = %X\n",pMsdu->freeArgs[1]));
1168    WLAN_OS_REPORT(("freeArgs[2]     = %X\n",pMsdu->freeArgs[2]));
1169    WLAN_OS_REPORT(("freeArgs[3]     = %X\n",pMsdu->freeArgs[3]));
1170    WLAN_OS_REPORT(("freeArgs[4]     = %X\n",pMsdu->freeArgs[4]));
1171    WLAN_OS_REPORT(("dataLen         = %d\n",pMsdu->dataLen));
1172    WLAN_OS_REPORT(("module          = %d\n",pMsdu->module));
1173    WLAN_OS_REPORT(("nextMSDUinList  = %X\n",pMsdu->nextMSDUinList));
1174    WLAN_OS_REPORT(("prevMSDUinList  = %X\n",pMsdu->prevMSDUinList));
1175    WLAN_OS_REPORT(("txFlags         = %X\n",pMsdu->txFlags));
1176    WLAN_OS_REPORT(("txCompleteFlags = %X\n",pMsdu->txCompleteFlags));
1177
1178}
1179
1180void memMngrPrintBD(mem_BD_T * pBd )
1181{
1182    WLAN_OS_REPORT(("\nPrinting BD \n"));
1183    WLAN_OS_REPORT(("handle           = %X\n",pBd->handle));
1184    WLAN_OS_REPORT(("refCount         = %d\n",pBd->refCount));
1185    WLAN_OS_REPORT(("dataBuf          = %X\n",pBd->dataBuf));
1186    WLAN_OS_REPORT(("data             = %X\n",pBd->data));
1187    WLAN_OS_REPORT(("dataOffset       = %d\n",pBd->dataOffset));
1188    WLAN_OS_REPORT(("length           = %d\n",pBd->length));
1189    WLAN_OS_REPORT(("nextBDPtr        = %X\n",pBd->nextBDPtr));
1190#ifdef TNETW_MASTER_MODE
1191    WLAN_OS_REPORT(("data_physical_low = %X\n",pBd->data_physical_low));
1192#endif
1193}
1194
1195void memMngrPrintDataBuf(mem_DataBuf_T* pDataBuf )
1196{
1197    WLAN_OS_REPORT(("\nPrinting DataBuf \n"));
1198    WLAN_OS_REPORT(("handle      = %X\n",pDataBuf->handle));
1199    WLAN_OS_REPORT(("nextDataBuf = %X\n",pDataBuf->nextDataBuf));
1200    WLAN_OS_REPORT(("refCount    = %d\n",pDataBuf->refCount));
1201    WLAN_OS_REPORT(("poolIndex	= %X\n",pDataBuf->poolIndex));
1202    WLAN_OS_REPORT(("data		= %d\n",pDataBuf->data));
1203}
1204
1205void memMngrPrintMSDUWithItsBds(mem_MSDU_T* pMsdu )
1206{
1207    mem_BD_T *bdTmp = pMsdu->firstBDPtr;
1208
1209    memMngrPrintMSDU(pMsdu);
1210
1211    while(bdTmp != NULL)
1212    {
1213        memMngrPrintBD(bdTmp);
1214        bdTmp = bdTmp->nextBDPtr;
1215    }
1216}
1217
1218void memMngrPrintHandle(TI_HANDLE hMemMngr, UINT32 handle)
1219{
1220    mem_BD_T*       tmpBD;
1221
1222    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1223
1224    WLAN_REPORT_INFORMATION(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
1225        ("MSDU handle = %d firstBDPtr=%X length=%d\n", handle,
1226                            pMemMngr->msduPool[handle].firstBDPtr,
1227                            pMemMngr->msduPool[handle].dataLen));
1228
1229    tmpBD = pMemMngr->msduPool[handle].firstBDPtr;
1230    while (tmpBD != NULL) {
1231        WLAN_REPORT_INFORMATION(pMemMngr->hReport, MEM_MGR_MODULE_LOG,
1232            ("MSDU BD=%X handle=%d refCount=%d\n", tmpBD, tmpBD->handle, tmpBD->refCount));
1233        tmpBD = tmpBD->nextBDPtr;
1234    }
1235
1236}
1237
1238void memMngrFullPrint(TI_HANDLE hMemMngr)
1239{
1240    mem_MSDU_T*     tmpMSDU;
1241    mem_BD_T*       tmpBD;
1242    mem_DataBuf_T*  tmpDataBuf;
1243    UINT32  j,i=0;
1244
1245    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1246
1247    WLAN_OS_REPORT(("memMngrPrint\n"));
1248    WLAN_OS_REPORT(("numFreeMSDU %d numFreeBD %d  \n", pMemMngr->numFreeMSDU, pMemMngr->numFreeBD));
1249    for(j = 0 ;j < pMemMngr->currentNumberOfPools; j++)
1250        WLAN_OS_REPORT(("Pool Num %d   buffer length %d   numFreeDataBuf %d \n",
1251        j, pMemMngr->buffersPool[j].buffersSize, pMemMngr->buffersPool[j].numFreeDataBuf));
1252
1253    WLAN_OS_REPORT(("\nAllocated by modules : MLME=%d, OS_ABS=%d,  RSN=%d,  HAL_RX=%d\n",
1254        pMemMngr->moduleAllocCount[MLME_MODULE],pMemMngr->moduleAllocCount[OS_ABS_TX_MODULE],
1255        pMemMngr->moduleAllocCount[RSN_MODULE],pMemMngr->moduleAllocCount[HAL_RX_MODULE]));
1256
1257
1258    WLAN_OS_REPORT(("\nfirstFreeMSDU=%X\n",pMemMngr->firstFreeMSDU));
1259    tmpMSDU = pMemMngr->firstFreeMSDU;
1260    while (++i, tmpMSDU != NULL) {
1261        WLAN_OS_REPORT(("tmpMSDU %d = %X handle=%d tmpMSDU->nextMSDU=%X\n",
1262            i, tmpMSDU, tmpMSDU->handle, tmpMSDU->nextFreeMSDU));
1263        tmpMSDU = tmpMSDU->nextFreeMSDU;
1264    }
1265
1266    WLAN_OS_REPORT(("\nfirstFreeBD=%X\n",pMemMngr->firstFreeBD));
1267    i = 0;
1268    tmpBD = pMemMngr->firstFreeBD;
1269    while (++i, tmpBD != NULL) {
1270        WLAN_OS_REPORT(("tmpBD %d = %X handle=%d tmpBD->nextBDPtr=%X\n",
1271            i, tmpBD, tmpBD->handle, tmpBD->nextBDPtr));
1272        tmpBD = tmpBD->nextBDPtr;
1273    }
1274    WLAN_OS_REPORT(("\n"));
1275
1276    for(j = 0 ;j < pMemMngr->currentNumberOfPools; j++) {
1277        i = 0;
1278        tmpDataBuf = pMemMngr->buffersPool[j].firstFreeDataBuf;
1279        WLAN_OS_REPORT(("\npoolIndex=%d  firstFreeDataBuf=%X\n",j,pMemMngr->buffersPool[j].firstFreeDataBuf));
1280        while (++i, tmpDataBuf != NULL) {
1281            WLAN_OS_REPORT(("Buf %d = %X handle=%d  next=%X poolIndex=%d pData=%X\n", i, tmpDataBuf,
1282                tmpDataBuf->handle,tmpDataBuf->nextDataBuf, tmpDataBuf->poolIndex, tmpDataBuf->data));
1283            tmpDataBuf = tmpDataBuf->nextDataBuf;
1284        }
1285        WLAN_OS_REPORT(("\n"));
1286    }
1287    WLAN_OS_REPORT(("\n"));
1288}
1289
1290
1291void memMngrPrint(TI_HANDLE hMemMngr)
1292{
1293#if 0
1294    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1295
1296    WLAN_OS_REPORT(("memMngrPrint\n"));
1297    WLAN_OS_REPORT(("numFreeMSDU %d numFreeBD %d  \n", pMemMngr->numFreeMSDU, pMemMngr->numFreeBD));
1298    for(j = 0 ;j < pMemMngr->currentNumberOfPools; j++)
1299        WLAN_OS_REPORT(("Pool Num %d   buffer length %d   numFreeDataBuf %d \n", j,
1300            pMemMngr->buffersPool[j].buffersSize, pMemMngr->buffersPool[j].numFreeDataBuf));
1301
1302    WLAN_OS_REPORT(("\nAllocated by modules on Tx\n"));
1303
1304
1305    WLAN_OS_REPORT(("\nAllocated by modules : MLME=%d, OS_ABS=%d,  RSN=%d  \n",
1306                                            pMemMngr->moduleAllocCount[MLME_MODULE],
1307                                            pMemMngr->moduleAllocCount[OS_ABS_TX_MODULE],
1308                                            pMemMngr->moduleAllocCount[RSN_MODULE]));
1309
1310    WLAN_OS_REPORT(("\nAllocated by modules : HAL_TX=%d, CONCAT=%d,  DE_CONCAT=%d,  TX=%d\n",
1311                                            pMemMngr->moduleAllocCount[HAL_TX_MODULE],
1312                                            pMemMngr->moduleAllocCount[CONCAT_MODULE],
1313                                            pMemMngr->moduleAllocCount[DE_CONCAT_MODULE],
1314                                            pMemMngr->moduleAllocCount[TX_MODULE]));
1315
1316    WLAN_OS_REPORT(("\nAllocated by modules : ACK_EMUL=%d, MEASUREMENT=%d,  SITE_MGR=%d,  EXC_MANAGER=%d\n",
1317                                            pMemMngr->moduleAllocCount[ACK_EMUL_MODULE],
1318                                            pMemMngr->moduleAllocCount[MEASUREMENT_MODULE],
1319                                            pMemMngr->moduleAllocCount[SITE_MGR_MODULE],
1320                                            pMemMngr->moduleAllocCount[EXC_MANAGER_MODULE]));
1321
1322    WLAN_OS_REPORT(("\nAllocated by modules on Rx\n"));
1323
1324    WLAN_OS_REPORT(("\nAllocated by modules : HAL_RX=%d, CORE_RX=%d,  MLME_RX=%d,  OS_ABS_RX=%d\n",
1325                                            pMemMngr->moduleAllocCount[HAL_RX_MODULE],
1326                                            pMemMngr->moduleAllocCount[CORE_RX_MODULE],
1327                                            pMemMngr->moduleAllocCount[MLME_RX_MODULE],
1328                                            pMemMngr->moduleAllocCount[OS_ABS_RX_MODULE]));
1329
1330    WLAN_OS_REPORT(("\nAllocated by modules : RSN_RX=%d, MEASUREMENT_RX=%d,  SITE_MGR_RX=%d,  EXC_MANAGER_RX=%d\n",
1331                                            pMemMngr->moduleAllocCount[RSN_RX_MODULE],
1332                                            pMemMngr->moduleAllocCount[MEASUREMENT_RX_MODULE],
1333                                            pMemMngr->moduleAllocCount[SITE_MGR_RX_MODULE],
1334                                            pMemMngr->moduleAllocCount[EXC_MANAGER_RX_MODULE]));
1335
1336
1337
1338    WLAN_OS_REPORT(("\nAllocated by modules : HAL_WEP1_RX=%d, HAL_WEP2_RX=%d, HAL_DEFRAG_RX=%d,  HAL_DUPLICA_RX=%d\n",
1339                                            pMemMngr->moduleAllocCount[HAL_WEP1_RX],
1340                                            pMemMngr->moduleAllocCount[HAL_WEP2_RX],
1341                                            pMemMngr->moduleAllocCount[HAL_DEFRAG_RX],
1342                                            pMemMngr->moduleAllocCount[HAL_DUPLICA_RX]));
1343
1344
1345
1346
1347    WLAN_OS_REPORT(("\nAllocated by modules : FREE_MSDU=%d\n",
1348                                        pMemMngr->moduleAllocCount[MODULE_FREE_MSDU]));
1349
1350#endif
1351}
1352
1353void print_MsduDataHeader(TI_HANDLE hMemMngr, mem_MSDU_T *pMsdu)
1354{
1355    mem_BD_T            *pBd;
1356    UINT8               tempBuffer[40],*pTempBuffer;
1357    UINT32              lengthToPrint = 40;
1358    UINT32              i;
1359
1360    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1361
1362    pTempBuffer = tempBuffer;
1363    pBd =  pMsdu->firstBDPtr;
1364
1365    while (lengthToPrint != 0)
1366    {
1367        if (pBd->length < lengthToPrint)
1368        {
1369            os_memoryCopy(pMemMngr->hOs, (void *)pTempBuffer, (void *)pBd->data, pBd->length);
1370            lengthToPrint -= pBd->length;
1371            pTempBuffer += pBd->length;
1372            pBd = pBd->nextBDPtr;
1373        }
1374        else                            /* enough place in current BD*/
1375        {
1376            os_memoryCopy(pMemMngr->hOs, (void *)pTempBuffer, (void *)pBd->data, lengthToPrint);
1377            lengthToPrint = 0;
1378        }
1379    }
1380    WLAN_OS_REPORT(("\n"));
1381    for(i = 0 ; i < 60 ; i++)
1382    {
1383        WLAN_OS_REPORT(("%02X ",tempBuffer[i]));
1384    }
1385    WLAN_OS_REPORT(("\n\n"));
1386}
1387/*void DumpMemory(char* data, int size)
1388{
1389    char NumStr[60], CharStr[20], ResStr[81];
1390    int bank, i, space;
1391
1392    bank = 0;
1393
1394    for(i=0; i<size; i++) {
1395
1396        sprintf(&NumStr[bank*3], "%02X ", (UCHAR)data[i]);
1397        CharStr[bank] = (data[i]>=0x20 && data[i]<=0x7E) ? data[i] : '.';
1398
1399        if(++bank == 16) {
1400            CharStr[bank] = 0;
1401            sprintf(ResStr, "%s        %s", NumStr, CharStr);
1402            printf("%s\n",ResStr);
1403            bank = 0;
1404        }
1405
1406    }
1407
1408    if(bank) {
1409        CharStr[bank] = 0;
1410        printf("%s", NumStr);
1411        if(size < 16)
1412            space = 6;
1413        else
1414            space = 56-strlen(NumStr);
1415        for(i=0; i<space; i++)
1416            printf(" ");
1417        printf("%s\n",CharStr);
1418    }
1419
1420}
1421*/
1422
1423TI_STATUS txDataSTUB_txSendMsdu(TI_HANDLE hMemMngr, mem_MSDU_T *pMsdu)
1424{
1425    TI_STATUS status;
1426    memMngr_t *pMemMngr = (memMngr_t *)hMemMngr;
1427
1428    status = wlan_memMngrFreeMSDU(pMemMngr, memMgr_MsduHandle(pMsdu));
1429    if(status != OK)
1430        return NOK;
1431
1432    return OK;
1433}
1434
1435