Home | History | Annotate | Download | only in Tx
      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 *************************************************************************/
     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 *************************************************************************/
    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 
    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 
    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 *************************************************************************/
    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 *************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 ************************************************************************/
    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 
    445 UINT32 msduList_getCurrNumOfMsdu(MsduList_t *this)
    446 {
    447 	return this->CurrNumOfMsdu;
    448 }
    449 
    450 
    451 /* Debug functions */
    452 /*-----------------*/
    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 
    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