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: envList.c */
39 /* PURPOSE: Envelope list implementation */
40 /* */
41 /***************************************************************************/
42
43 #include "MsduList.h"
44 #include "osTIType.h"
45 #include "paramIn.h"
46 #include "osApi.h"
47
48 /*************************************************************************
49 * msduList_CreateNewMsduList *
50 *************************************************************************
51 DESCRIPTION: This function creates new Msdu list.
52
53 INPUT: maxNumOfElements : The maximum number of elements allowd
54 pOs : Pointer to os abstraction layer
55
56 OUTPUT:
57
58 RETURN: MsduList_T
59 *************************************************************************/
msduList_CreateNewMsduList(TI_HANDLE hOs)60 MsduList_t* msduList_CreateNewMsduList( TI_HANDLE hOs )
61 {
62
63 MsduList_t* msduList = (MsduList_t*) os_memoryAlloc(hOs,sizeof(MsduList_t));
64 if( msduList == NULL )
65 return NULL;
66
67 if(( msduList->hCriticalSectionProtect = os_protectCreate(hOs)) == NULL)
68 {
69 WLAN_OS_REPORT(("FATAL ERROR: Could not Create Critical Section Protection for Msdu List - Aborting\n"));
70
71 /* free Msdu List Control Block */
72 os_memoryFree(hOs, msduList, sizeof(MsduList_t));
73
74 return NULL;
75 }
76
77 msduList->hOs = hOs;
78
79 msduList->first = NULL;
80 msduList->last = NULL;
81 msduList->maxNumOfMsdu = 0;
82 msduList->CurrNumOfMsdu = 0;
83 msduList->ovFlowPolicy = DROP_NEW_PACKET;
84 msduList->numOfOverFlow = 0;
85 msduList->maxCurrOfMsdu =0;
86
87 return msduList;
88 }
89
90 /*************************************************************************
91 * msduList_ConfigMsduList *
92 *************************************************************************
93 DESCRIPTION: This function configure the Msdu list.
94
95 INPUT: *this : A pointer to the list to configure
96 msduListConfig : Pointer to the Msdu list configuration
97 structure.
98
99 OUTPUT:
100
101 RETURN: TI_STATUS: OK/NOK
102 *************************************************************************/
msduList_ConfigMsduList(MsduList_t * this,TI_HANDLE hMemMgr,TI_HANDLE hReport,TI_HANDLE hOs,INT16 maxNumOfElements)103 TI_STATUS msduList_ConfigMsduList( MsduList_t* this, TI_HANDLE hMemMgr,
104 TI_HANDLE hReport, TI_HANDLE hOs,INT16 maxNumOfElements)
105 {
106 if( hOs == NULL || hReport == NULL ||
107 this == NULL || hMemMgr == NULL)
108 return NOK;
109
110 this->hReport = hReport;
111 this->hMemMgr = hMemMgr;
112 this->hOs = hOs;
113 this->maxNumOfMsdu = maxNumOfElements;
114
115 this->useAdmissionAlgo = FALSE;
116 this->credit = 0;
117 this->enableTransmissionTime = 0;
118 this->lastTimeStamp = 0;
119 this->mediumTime = 0;
120 this->totalUsedTime = 0;
121
122 this->highMediumUsageThreshold = 0;
123 this->lowMediumUsageThreshold = 0;
124
125
126 return OK;
127
128 }
129
130 /*************************************************************************
131 * msduList_SetMsduListNumOfElements *
132 *************************************************************************
133 DESCRIPTION: This function configure the Msdu list max num of elements.
134
135 INPUT: *this : A pointer to the list to configure
136 maxNumOfElements: max num of elements.
137 OUTPUT:
138
139 RETURN: TI_STATUS: OK/NOK
140 *************************************************************************/
141
msduList_SetMsduListNumOfElements(MsduList_t * this,UINT16 maxNumOfElements)142 TI_STATUS msduList_SetMsduListNumOfElements( MsduList_t* this, UINT16 maxNumOfElements)
143 {
144 if(this == NULL)
145 return NOK;
146
147 this->maxNumOfMsdu = maxNumOfElements;
148
149 return OK;
150
151 }
152
153 /*************************************************************************
154 * msduList_SetMsduListOverFlowPolicy *
155 *************************************************************************
156 DESCRIPTION: This function configure the Msdu list policy in case of over flow .
157
158 INPUT: *this : A pointer to the list to configure
159 QueueOvFlowPolicy: over flow polict - new packet drop or old packet drop.
160 OUTPUT:
161
162 RETURN: TI_STATUS: OK/NOK
163 *************************************************************************/
164
msduList_SetMsduListOverFlowPolicy(MsduList_t * this,qOvFlowPolicy_e QueueOvFlowPolicy)165 TI_STATUS msduList_SetMsduListOverFlowPolicy( MsduList_t* this, qOvFlowPolicy_e QueueOvFlowPolicy)
166 {
167 if(this == NULL)
168 return NOK;
169
170 this->ovFlowPolicy = QueueOvFlowPolicy;
171
172 return OK;
173
174 }
175
176
177 /*************************************************************************
178 * msduList_FreeMsduList *
179 *************************************************************************
180 DESCRIPTION: This function free the Msdu list.
181
182 INPUT: *this : A pointer to the list to free
183 pOs : Pointer to os abstraction layer
184
185 OUTPUT:
186
187 RETURN: TI_STATUS: OK/NOK
188 *************************************************************************/
msduList_FreeMsduList(MsduList_t * this)189 TI_STATUS msduList_FreeMsduList( MsduList_t* this)
190 {
191 if( this->CurrNumOfMsdu != 0 )
192 {
193 if( msduList_EmptyMsduList( this ) != OK )
194 {
195 WLAN_REPORT_ERROR(this->hReport, TX_DATA_MODULE_LOG,
196 (" msduList_FreeMsduList() : failed \n"));
197 return NOK;
198 }
199 }
200
201 /* free protection */
202 os_protectDestroy(this->hOs,this->hCriticalSectionProtect);
203
204 /* free msdu control block */
205 os_memoryFree(this->hOs, this, sizeof(MsduList_t));
206
207 return OK;
208
209 }
210
211 /*************************************************************************
212 * msduList_EmptyMsduList *
213 *************************************************************************
214 DESCRIPTION: This function free all the MSDUs from the Msdu list.
215
216 INPUT: *this : A pointer to the list to empty
217 pOs : Pointer to os abstraction layer
218
219 OUTPUT:
220
221 RETURN: TI_STATUS: OK/NOK
222 *************************************************************************/
msduList_EmptyMsduList(MsduList_t * this)223 TI_STATUS msduList_EmptyMsduList( MsduList_t* this)
224 {
225 UINT32 count;
226 mem_MSDU_T* pTempMsdu;
227
228 os_protectLock(this->hOs, this->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
229 if( this->CurrNumOfMsdu == 0 )
230 {
231 WLAN_REPORT_INFORMATION(this->hReport, TX_DATA_MODULE_LOG,
232 (" msduList_EmptyMsduList() : List is empty \n"));
233 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
234 return OK;
235 }
236
237 /* update Tx status to NOK for all msdu in list */
238 pTempMsdu = this->first;
239 for(count = 0 ; count < this->CurrNumOfMsdu ; count++)
240 {
241 memMgr_MsduFreeArg2Get(pTempMsdu) = NOK;
242 pTempMsdu = pTempMsdu->nextMSDUinList;
243 }
244
245 os_protectUnlock(this->hOs, this->hCriticalSectionProtect);
246 /* free all msdu back to the memMngr */
247 if ((wlan_memMngrFreeListOfMSDU(this->hMemMgr, memMgr_MsduHandle( this->first))) != OK)
248 {
249 WLAN_REPORT_ERROR(this->hReport, TX_DATA_MODULE_LOG,
250 (" msduList_EmptyMsduList() : Msdu free failed \n"));
251 }
252
253 os_protectLock(this->hOs, this->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
254 this->first = NULL;
255 this->last = NULL;
256 this->CurrNumOfMsdu = 0;
257 this->numOfOverFlow = 0;
258 this->maxCurrOfMsdu = 0;
259
260 this->useAdmissionAlgo = FALSE;
261 this->credit = 0;
262 this->enableTransmissionTime = 0;
263 this->lastTimeStamp = 0;
264 this->mediumTime = 0;
265 this->totalUsedTime = 0;
266
267 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
268
269 return OK;
270 }
271
272 /*************************************************************************
273 * msduList_MsduListIns *
274 *************************************************************************
275 DESCRIPTION: This function insert MSDU to the list pointed by this.
276
277 INPUT: *this : A pointer to the list to insert.
278 *pMsdu : Pointer to the MSDU to insert, the MSDU
279 is inserted to be the last in the list. If the
280 list is full the first MSDU will be taken
281 out and will be returned in this pointer.
282
283 OUTPUT: *pMsdu : In case the list is full,this poiter will hold
284 the dropt MSDU's.
285
286 RETURN: OK : The MSDU has been inserted, there was enough
287 place in the list.
288 NOK: The list was full, the first MSDU is dropt, and
289 returned by *pMsdu.
290 ************************************************************************/
msduList_Insert(MsduList_t * this,mem_MSDU_T ** pMsdu)291 TI_STATUS msduList_Insert( MsduList_t* this , mem_MSDU_T **pMsdu )
292 {
293
294 os_protectLock(this->hOs, this->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
295
296 if( this->CurrNumOfMsdu == 0 )
297 {
298 this->last = *pMsdu;
299 this->first = *pMsdu;
300 (*pMsdu)->nextMSDUinList = NULL;
301 (*pMsdu)->prevMSDUinList = NULL;
302 this->CurrNumOfMsdu++;
303 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
304
305 /* for debug */
306 if( this->CurrNumOfMsdu > this->maxCurrOfMsdu )
307 this->maxCurrOfMsdu = this->CurrNumOfMsdu;
308
309 return OK;
310 }
311 else
312 {
313 if( this->CurrNumOfMsdu == this->maxNumOfMsdu )
314 {
315 this->numOfOverFlow++;
316
317 if(this->ovFlowPolicy == DROP_NEW_PACKET)
318 {
319 /* The list is full, remove the new coming msdu*/
320 WLAN_REPORT_INFORMATION(this->hReport, TX_DATA_MODULE_LOG,
321 (" msduList_MsduListIns() : New Msdu has to be removed \n"));
322 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
323
324 /* for debug */
325 if( this->CurrNumOfMsdu > this->maxCurrOfMsdu )
326 this->maxCurrOfMsdu = this->CurrNumOfMsdu;
327
328 return NOK;
329
330 }else
331 {
332 /* The list is full, insert the new msdu and remove the first msdu*/
333 this->last->nextMSDUinList = *pMsdu;
334 (*pMsdu)->prevMSDUinList = this->last;
335 (*pMsdu)->nextMSDUinList = NULL;
336 this->last = *pMsdu;
337
338 /* remove the first msdu from list */
339 (*pMsdu) = this->first;
340 this->first = this->first->nextMSDUinList;
341 this->first->prevMSDUinList = NULL;
342 (*pMsdu)->nextMSDUinList = NULL;
343
344 WLAN_REPORT_INFORMATION(this->hReport, TX_DATA_MODULE_LOG,
345 (" msduList_MsduListIns() : First Msdu was removed \n"));
346 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
347 /* indicate that the first msdu has removed */
348
349 /* for debug */
350 if( this->CurrNumOfMsdu > this->maxCurrOfMsdu )
351 this->maxCurrOfMsdu = this->CurrNumOfMsdu;
352
353 return NOK;
354
355 }
356 }
357 else
358 { /* insert the MSDU to be the last. */
359 this->last->nextMSDUinList = *pMsdu;
360 (*pMsdu)->prevMSDUinList = this->last;
361 (*pMsdu)->nextMSDUinList = NULL;
362 this->last = *pMsdu;
363 }
364
365 this->CurrNumOfMsdu++;
366
367 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
368
369 /* for debug */
370 if( this->CurrNumOfMsdu > this->maxCurrOfMsdu )
371 this->maxCurrOfMsdu = this->CurrNumOfMsdu;
372
373 return OK;
374 }
375 }
376
377
378 /*************************************************************************
379 * msduList_MsduListGetFirst *
380 *************************************************************************
381 DESCRIPTION: This function get MSDU to the list pointed by this.
382
383 INPUT: *this : A pointer to the list to get.
384
385 OUTPUT: *pMsdu : A pointer to the first MSDU in the list.
386
387 RETURN: OK : There was an MSDU in the list, and it is assigned
388 to the *pMsdu.
389 NOK: The list was empty, *pMsdu is trush.
390 ************************************************************************/
msduList_GetFirst(MsduList_t * this,mem_MSDU_T ** pMsdu)391 TI_STATUS msduList_GetFirst( MsduList_t *this, mem_MSDU_T **pMsdu)
392 {
393
394 os_protectLock(this->hOs, this->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
395
396 if( this->CurrNumOfMsdu == 0 )
397 {
398 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
399 return NOK;
400 }
401
402 *pMsdu = this->first;
403 this->first = this->first->nextMSDUinList;
404 if (this->first != NULL)
405 this->first->prevMSDUinList = NULL;
406 this->CurrNumOfMsdu--;
407 (*pMsdu)->nextMSDUinList = NULL;
408
409 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
410
411 return OK;
412 }
413
414 /*************************************************************************
415 * msduList_MsduListWatchFirst *
416 *************************************************************************
417 DESCRIPTION: This function watch at the first SDU in the list. The
418 MSDU is not removed yet from the list.
419
420 INPUT: *this : A pointer to the list to watch.
421
422 OUTPUT: *pMsdu : A pointer to the first MSDU in the list.
423
424 RETURN: OK : There was an MSDU in the list, and it is assigned
425 to the *pMsdu.
426 NOK: The list was empty, *pMsdu is trush.
427 ************************************************************************/
msduList_WatchFirst(MsduList_t * this,mem_MSDU_T ** pMsdu)428 TI_STATUS msduList_WatchFirst( MsduList_t *this, mem_MSDU_T **pMsdu)
429 {
430 os_protectLock(this->hOs, this->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
431
432 if( this->CurrNumOfMsdu == 0 )
433 {
434 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
435 return NOK;
436 }
437
438 *pMsdu = this->first;
439
440 os_protectUnlock(this->hOs, this->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
441
442 return OK;
443 }
444
msduList_getCurrNumOfMsdu(MsduList_t * this)445 UINT32 msduList_getCurrNumOfMsdu(MsduList_t *this)
446 {
447 return this->CurrNumOfMsdu;
448 }
449
450
451 /* Debug functions */
452 /*-----------------*/
printMsduList(MsduList_t * this)453 void printMsduList(MsduList_t *this)
454 {
455 WLAN_OS_REPORT(("Msdu List : \n"));
456
457 WLAN_OS_REPORT(("first = %X\n", this->first));
458 WLAN_OS_REPORT(("last = %X\n", this->last));
459 WLAN_OS_REPORT(("maxNumOfMsdu = %d\n", this->maxNumOfMsdu));
460 WLAN_OS_REPORT(("CurrNumOfMsdu = %d\n", this->CurrNumOfMsdu));
461 WLAN_OS_REPORT(("numOfOverFlow = %d\n", this->numOfOverFlow));
462 WLAN_OS_REPORT(("maxCurrOfMsdu = %d\n", this->maxCurrOfMsdu));
463
464 WLAN_OS_REPORT(("useAdmissionAlgo = %d\n", this->useAdmissionAlgo));
465 WLAN_OS_REPORT(("credit = %d\n", this->credit));
466 WLAN_OS_REPORT(("enableTransmissionTime = %d\n", this->enableTransmissionTime));
467 WLAN_OS_REPORT(("lastTimeStamp = %d\n", this->lastTimeStamp));
468 WLAN_OS_REPORT(("mediumTime = %d\n", this->mediumTime));
469 WLAN_OS_REPORT(("totalUsedTime = %d\n", this->totalUsedTime));
470
471 }
472
printFullMsduList(MsduList_t * this)473 void printFullMsduList(MsduList_t *this)
474 {
475 mem_MSDU_T* tmpMSDU;
476 UINT32 i=0;
477
478 printMsduList(this);
479
480 tmpMSDU = this->first;
481 while (++i, tmpMSDU != NULL)
482 {
483 WLAN_OS_REPORT(("tmpMSDU %d = %X handle=%d tmpMSDU->nextMSDU=%X\n", i, tmpMSDU, tmpMSDU->handle, tmpMSDU->nextMSDUinList));
484 tmpMSDU = tmpMSDU->nextMSDUinList;
485 }
486
487 }
488