• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 **************************************************************************/
wlan_memMngrInit(TI_HANDLE hOs)62 TI_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 ***************************************************************************/
wlan_memMngrConfigure(TI_HANDLE hMemMngr,TI_HANDLE hOs,TI_HANDLE hReport)253 TI_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 
wlan_memMngrDestroy(TI_HANDLE hMemMngr)279 TI_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 **************************************************************************/
wlan_memMngrAllocDataBuf(TI_HANDLE hMemMngr,mem_BD_T ** bdPtr,UINT32 len)350 TI_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 **************************************************************************/
wlan_memMngrAllocBDs(TI_HANDLE hMemMngr,UINT32 bdNumber,mem_BD_T ** bdPtr)441 TI_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 **************************************************************************/
wlan_memMngrAllocMSDU(TI_HANDLE hMemMngr,mem_MSDU_T ** MSDUPtr,UINT32 len,allocatingModule_e module)509 TI_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 **************************************************************************/
wlan_memMngrAllocMSDUBufferOnly(TI_HANDLE hMemMngr,mem_MSDU_T ** MSDUPtr,allocatingModule_e module)613 TI_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 **************************************************************************/
wlan_memMngrFreeListOfMSDU(TI_HANDLE hMemMngr,UINT32 handle)669 TI_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 **************************************************************************/
wlan_memMngrFreeMSDU(TI_HANDLE hMemMngr,UINT32 handle)706 TI_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
794 static 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 **************************************************************************/
freeDataBuf(TI_HANDLE hMemMngr,mem_DataBuf_T * dataBuf)825 static 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 **************************************************************************/
wlan_memMngrFreeBD(TI_HANDLE hMemMngr,UINT32 handle)861 UINT32 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 
wlan_memMngrFreeAllOsAlocatesBuffer(TI_HANDLE hMemMngr)943 TI_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 
wlan_memMngrCopyMsduFreeFunc(TI_HANDLE hMemMngr,UINT32 destMsduHandle,UINT32 sourceMsduHandle)991 TI_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 
wlan_memMngrChangeMsduOwner(TI_HANDLE hMemMngr,allocatingModule_e newModule,mem_MSDU_T * pMsdu)1029 TI_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 **************************************************************************/
wlan_memMngrSwapMsdu(TI_HANDLE hMemMngr,mem_MSDU_T * pMsdu_1,mem_MSDU_T * pMsdu_2)1085 TI_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 
wlan_memMngrGetMemMgrResources(TI_HANDLE hMemMngr,memMgrResources_t * memMgrResources)1121 TI_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 
wlan_memMngrAddTimeStamp(TI_HANDLE hMemMngr,mem_MSDU_T * pMsdu)1135 TI_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 
memMngrPrintMSDU(mem_MSDU_T * pMsdu)1157 void 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 
memMngrPrintBD(mem_BD_T * pBd)1180 void 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 
memMngrPrintDataBuf(mem_DataBuf_T * pDataBuf)1195 void 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 
memMngrPrintMSDUWithItsBds(mem_MSDU_T * pMsdu)1205 void 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 
memMngrPrintHandle(TI_HANDLE hMemMngr,UINT32 handle)1218 void 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 
memMngrFullPrint(TI_HANDLE hMemMngr)1238 void 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 
memMngrPrint(TI_HANDLE hMemMngr)1291 void 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 
print_MsduDataHeader(TI_HANDLE hMemMngr,mem_MSDU_T * pMsdu)1353 void 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 
txDataSTUB_txSendMsdu(TI_HANDLE hMemMngr,mem_MSDU_T * pMsdu)1423 TI_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