Home | History | Annotate | Download | only in 4X
      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 /*		MODULE:													   */
     38 /*		PURPOSE:		 						   */
     39 /*																		   */
     40 /***************************************************************************/
     41 #include "DeConcatenator.h"
     42 #include "report.h"
     43 #include "osApi.h"
     44 #include "utils.h"
     45 #include "802_11Defs.h"
     46 
     47 #define MAX_DECONACT_LEN  1600 /* Maximum length of real ip packet inside concatination packet */
     48 
     49 /*************************************************************************
     50 *                        concat_create                                 *
     51 **************************************************************************
     52 * DESCRIPTION:	This function initializes the Ctrl data module.
     53 *
     54 * INPUT:		hOs - handle to Os Abstraction Layer
     55 *
     56 * OUTPUT:		TxCmplt_CB - call back function that return to configMngr
     57 *				in order to register in the Hal
     58 *
     59 * RETURN:		Handle to the allocated Ctrl data control block
     60 ************************************************************************/
     61 
     62 deConcatenator_t* deConcat_create(TI_HANDLE hOs)
     63 {
     64 	deConcatenator_t* pDeConcatenator;
     65 
     66 	if( hOs  == NULL )
     67 	{
     68 	    WLAN_OS_REPORT(("FATAL ERROR: deConcat_create(): OS handle Error - Aborting\n"));
     69 		return NULL;
     70 	}
     71 
     72 	/* alocate concatenator block */
     73 	pDeConcatenator = os_memoryAlloc(hOs, (sizeof(deConcatenator_t)));
     74 
     75 
     76 	if (!pDeConcatenator)
     77 	{
     78 		utils_nullMemoryFree(hOs, pDeConcatenator, sizeof(deConcatenator_t));
     79 	    WLAN_OS_REPORT(("FATAL ERROR: deConcat_create(): Error Creating DeConcatenator module- Aborting\n"));
     80 		return(NULL);
     81 	}
     82 
     83 	/* reset control module control block */
     84 	os_memoryZero(hOs, pDeConcatenator, (sizeof(deConcatenator_t)));
     85 
     86 	pDeConcatenator->hOs = hOs;
     87 
     88 	return(pDeConcatenator);
     89 }
     90 
     91 /***************************************************************************
     92 *							ctrlData_config				                   *
     93 ****************************************************************************
     94 * DESCRIPTION:	This function configures the Ctrl Data module
     95 *
     96 * INPUTS:		hCtrlData - The object
     97 *				hOs - Handle to the Os Abstraction Layer
     98 *				hReport - Handle to the Report object
     99 * 				ctrlDataInitParams - pointer to Ctrl module init parameters
    100 * OUTPUT:
    101 *
    102 * RETURNS:		OK - Configuration succesfull
    103 *				NOK - Configuration unsuccesfull
    104 ***************************************************************************/
    105 TI_STATUS deConcat_config(deConcatenator_t*	pDeConcatenator,
    106 						  TI_HANDLE			hOs,
    107 						  TI_HANDLE			hReport,
    108 						  TI_HANDLE			hMemMngr)
    109 {
    110 	/* check parameters validity */
    111 	if( pDeConcatenator == NULL || hOs == NULL ||
    112 		hReport == NULL || hMemMngr == NULL)
    113 	{
    114 	    WLAN_OS_REPORT(("FATAL ERROR: deConcat_config(): Parameters Error - Aborting\n"));
    115 		return NOK;
    116 	}
    117 
    118 	/* set objects handles */
    119 	pDeConcatenator->hOs = hOs;
    120 	pDeConcatenator->hReport = hReport;
    121 	pDeConcatenator->hMemMngr = hMemMngr;
    122 
    123 	WLAN_REPORT_INIT(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    124 		(".....DeConcatenator configured successfully\n"));
    125 
    126 	return OK;
    127 }
    128 
    129 /***************************************************************************
    130 *							ctrlData_unLoad				                   *
    131 ****************************************************************************
    132 * DESCRIPTION:	This function unload the Ctrl data module.
    133 *
    134 * INPUTS:		hCtrlData - the object
    135 *
    136 * OUTPUT:
    137 *
    138 * RETURNS:		OK - Unload succesfull
    139 *				NOK - Unload unsuccesfull
    140 ***************************************************************************/
    141 
    142 TI_STATUS deConcat_destroy(deConcatenator_t*	pDeConcatenator)
    143 {
    144 	/* free control module controll block */
    145 	os_memoryFree(pDeConcatenator->hOs, pDeConcatenator, sizeof(deConcatenator_t));
    146 
    147 	return OK;
    148 }
    149 
    150 
    151 /*************************************************************************
    152  *                        wdrv_rxDeConcatMsdu                            *
    153  *************************************************************************
    154 DESCRIPTION: This function de concatenates number of MSDUs froma single
    155              MPDU.
    156 
    157 INPUT:       msduPtr     - Pointer to the first MSDU.
    158 
    159 
    160 OUTPUT:
    161 
    162 RETURN:      OK : Deconcatenation OK.
    163              NOK: Deconcatenation Faild.
    164 ************************************************************************/
    165 TI_STATUS deConcat_deConcatMsdu(deConcatenator_t*	pDeConcatenator,
    166 								mem_MSDU_T**		MsduPtr)
    167 {
    168 
    169     Wdrv4xConcatHeader_t	*concatHdrPtr;
    170     dot114xMsdu_t			*pdot11fourXHeader;
    171 	mem_MSDU_T				*firstMsduPtr = NULL;
    172     UINT8					*currPtr;
    173     UINT8					*newDot11HeaderPtr;
    174 	UINT16					currentLength;
    175     UINT32					concatLength;
    176     UINT32					rc = OK;
    177     UINT32					parsedLen;
    178 	UINT32					msduNum = 0;
    179 	BOOL					firsdMsduInList = TRUE;
    180 	mem_MSDU_T				*NextMsduPtr;
    181     mem_MSDU_T				*PrevMsduPtr = NULL;
    182 
    183 	/*print_MsduDataHeader(pDeConcatenator->hMemMngr, *MsduPtr);*/
    184 
    185 
    186    /*
    187 	* The 802.11 header is located in the beggining of the concat frame.
    188 	*/
    189     pdot11fourXHeader = (dot114xMsdu_t*)memMgr_BufData((*MsduPtr)->firstBDPtr);
    190 
    191     concatLength =  (*MsduPtr)->dataLen;
    192 
    193    /*
    194 	* The parsed size is currently the wlan snap and 4x headers.
    195 	*/
    196     parsedLen =  sizeof( dot114xMsdu_t );
    197     currPtr =  (UINT8*) pdot11fourXHeader + sizeof(dot114xMsdu_t);
    198 
    199     /*
    200 	* Start parsing the concatenated MPDU and create an MSDUs.
    201 	*/
    202 
    203 	if(parsedLen + sizeof(Wdrv4xConcatHeader_t) >= concatLength)
    204 	{
    205 		WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    206 				("deConcat_deConcatMsdu: Error Parsing Deconcat Packet: concatLength = %d ",concatLength));
    207 		firstMsduPtr = NULL;
    208 		rc = NOK;
    209 	}
    210 
    211     while ( parsedLen + sizeof(Wdrv4xConcatHeader_t) < concatLength )
    212 	{
    213 
    214 		UINT8		numOfPadBytes;
    215 		mem_MSDU_T* CurrentMsduPtr;
    216 
    217 		msduNum++;
    218 
    219 		concatHdrPtr = (Wdrv4xConcatHeader_t*)currPtr;
    220 
    221 		currentLength = wlan_htons(concatHdrPtr->len);
    222 
    223 		if( currentLength > MAX_DECONACT_LEN)
    224 		{
    225 			WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    226 				("deConcat_deConcatMsdu: Error Parsing Deconcat Packet Len  %d ",currentLength));
    227             rc = NOK;
    228 			break;
    229 		}
    230 
    231 		currPtr += sizeof(Wdrv4xConcatHeader_t);
    232 
    233        /*
    234 		*  Zero Padding checking.
    235 		*/
    236 		numOfPadBytes = (currentLength+ 2) % 4;
    237 
    238 		if( numOfPadBytes )
    239 			numOfPadBytes = 4 - numOfPadBytes;
    240 
    241 	   /*
    242 		* Create MSDU with one buffer for the wlan header.
    243 		* and copy the 802.11 header from the MSDU to it.
    244 		*/
    245 #if 1
    246 		/*******************************************************************/
    247 		/*     Deconcatenation with COPY Solution                          */
    248 		/*******************************************************************/
    249 
    250 		if( wlan_memMngrAllocMSDU(pDeConcatenator->hMemMngr,
    251 								  &CurrentMsduPtr,
    252 								  WLAN_HDR_LEN + currentLength - sizeof(macAddress_t),
    253 								  DE_CONCAT_MODULE ) != OK)
    254 		{
    255 			WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    256 				("fail to allocate msdu \n"));
    257 			rc = NOK;
    258 			break; /* fail to allocate - abort deconcatenation */
    259 		}
    260 
    261 		if(firsdMsduInList == TRUE)
    262 		{
    263 			firstMsduPtr = CurrentMsduPtr;
    264 			firstMsduPtr->prevMSDUinList = NULL;
    265 			firsdMsduInList = FALSE;
    266 		}
    267 		else
    268 		{
    269 			CurrentMsduPtr->prevMSDUinList = PrevMsduPtr;
    270 			PrevMsduPtr->nextMSDUinList = CurrentMsduPtr;
    271 		}
    272 
    273 
    274 		CurrentMsduPtr->headerLen = WLAN_HDR_LEN;
    275 		newDot11HeaderPtr =  (UINT8 *)memMgr_BufData(CurrentMsduPtr->firstBDPtr);
    276 
    277 		os_memoryCopy(NULL, newDot11HeaderPtr, (char*)pdot11fourXHeader, WLAN_HDR_LEN );
    278 
    279 	   /*
    280 		*  Copy the SA from the concatenated MSDU to the header.
    281 		*/
    282 		os_memoryCopy(NULL, (void*)&(((dot11_header_t*)newDot11HeaderPtr)->address3),
    283 			(void*)&(concatHdrPtr->SaDa),sizeof(macAddress_t) );
    284 
    285 	   /*
    286 		* Reading the concatenation More bit, if it is exists, set it in each MSDU's
    287 		* order bit. (Used by the Ack emulation)
    288 		*/
    289 		if( pdot11fourXHeader->header4x.txFlags == wlan_htons(WLAN_4X_CONCAT_MORE_BIT) )
    290 			((dot11_header_t*)newDot11HeaderPtr)->fc |= DOT11_FC_ORDER;
    291 		else
    292             ((dot11_header_t*)newDot11HeaderPtr)->fc &= ~DOT11_FC_ORDER;
    293 
    294 	   /*
    295         *  Copy the SNAP + Payload length to the new data buffer.
    296         *  ( 2 copies solution ).
    297 		*/
    298 
    299 		os_memoryCopy(NULL, (void*)((UINT32)(newDot11HeaderPtr)+WLAN_HDR_LEN ),
    300 			currPtr, currentLength - sizeof(macAddress_t)  );
    301 
    302 
    303 		currPtr+= currentLength - sizeof(macAddress_t) + numOfPadBytes;
    304 
    305         CurrentMsduPtr->firstBDPtr->length = currentLength - sizeof(macAddress_t) + WLAN_HDR_LEN ;
    306 		CurrentMsduPtr->dataLen =  CurrentMsduPtr->firstBDPtr->length;
    307 		CurrentMsduPtr->firstBDPtr->dataOffset = 0;
    308 		CurrentMsduPtr->firstBDPtr->nextBDPtr = NULL;
    309 
    310 
    311 #else
    312 		/*******************************************************************/
    313 		/*     Deconcatenation with NO COPY Solution                       */
    314 		/*******************************************************************/
    315 		if( wlan_memMngrAllocMSDU(pDeConcatenator->hMemMngr, &buildMsduPtr,
    316 			sizeof(dot11_header_t),DE_CONCAT_MODULE )==NOK)
    317 		{
    318 			WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    319 				("fail to allocate msdu \n"));
    320 			return NOK;
    321 		}
    322 
    323 	   /*
    324 		*  Copy the 802.11 header to the first buffer. (BssBridge needs the 802.11
    325 		*  and the SNAP in the same buffer for Ethernet header translation.
    326 		*/
    327 		newDot11HeaderPtr =  memMgr_BufData(buildMsduPtr->firstBDPtr);
    328 		os_memoryCopy(NULL, newDot11HeaderPtr, (char*)pdot11Header, sizeof(dot11_header_t));
    329 
    330 	   /*
    331 		*  Copy the SA from the concatenated MSDU to the header.
    332 		*/
    333 		os_memoryCopy(NULL, (void*)&(((dot11_header_t*)newDot11HeaderPtr)->address3),
    334 			(void*)&(concatHdrPtr->SaDa),sizeof(macAddress_t) );
    335 
    336 			/*
    337 			* Reading the concatenation More bit, if it is exists, set it in each MSDU's
    338 			* order bit. (Used by the Ack emulation)
    339 		*/
    340 		if( pdot11Header->header4x.txFlags == WLAN_4X_CONCAT_MORE_BIT )
    341 			((dot11_header_t*)newDot11HeaderPtr)->fc |= DOT11_FC_ORDER;
    342 		else
    343             ((dot11_header_t*)newDot11HeaderPtr)->fc &= ~DOT11_FC_ORDER;
    344 
    345 	   /*
    346 		*  Copy the SNAP header to the first buffer. (BssBridge needs the 802.11
    347 		*  and the SNAP in the same buffer for Ethernet header translation.
    348 		*/
    349 		os_memoryCopy(NULL, (void*)((UINT32)(newDot11HeaderPtr)+sizeof(dot11_header_t)),
    350 			currPtr, sizeof(Wlan_LlcHeader_T) );
    351 
    352 		currPtr+= sizeof(Wlan_LlcHeader_T);
    353 
    354 		buildMsduPtr->firstBDPtr->length = sizeof( dot11_header_t ) + sizeof(Wlan_LlcHeader_T);
    355 
    356 		/*
    357 		* Create a new BD, link it concatenated to the data buffer's SNAP header.
    358 		*/
    359 		if( wlan_memMngrAllocBDs(pDeConcatenator->hMemMngr, 1, &payloadBdPtr) == NOK)
    360 		{
    361 			WLAN_REPORT_ERROR(pDeConcatenator->hReport, DE_CONCATENATOR_MODULE_LOG,
    362 				("fail to allocate BD \n"));
    363 			return NOK;
    364 		}
    365 		payloadBdPtr->dataBuf = MsduPtr->firstBDPtr->dataBuf;
    366 		payloadBdPtr->data = currPtr;
    367 		payloadBdPtr->length = currentLength - sizeof(macAddress_t) - sizeof(Wlan_LlcHeader_T);
    368 		payloadBdPtr->dataOffset = 0;
    369 		payloadBdPtr->nextBDPtr = NULL;
    370 
    371 		/*
    372 		*  Link the MSDU first BD (wlan header) to the second one (snap+payload)
    373 		*  creating a complete MSDU.
    374 		*/
    375 		buildMsduPtr->firstBDPtr->nextBDPtr =  payloadBdPtr;
    376 		payloadBdPtr->dataBuf->refCount++;
    377 		buildMsduPtr->dataLen =  buildMsduPtr->firstBDPtr->length + payloadBdPtr->length;
    378 
    379 		currPtr += currentLength - sizeof(macAddress_t) - sizeof(Wlan_LlcHeader_T) + numOfPadBytes;;
    380 #endif
    381 
    382 		PrevMsduPtr = CurrentMsduPtr;
    383 		parsedLen += currentLength + 2 + numOfPadBytes;
    384 
    385     } /* while ( parsedLen < concatLength ) */
    386 
    387 	  /*
    388 	  *  Free the c MSDU.
    389 	  */
    390 	if(rc == OK)
    391 	{
    392 		wlan_memMngrFreeMSDU(pDeConcatenator->hMemMngr, (*MsduPtr)->handle);
    393 		/* update the return msdu */
    394 		*MsduPtr = firstMsduPtr;
    395 	}
    396 	else /* free all allocated MSDUs in case of failure */
    397 	{
    398 		while(firstMsduPtr)
    399 		{
    400 			/* Save the next msdu in the list before free the current msdu */
    401 			NextMsduPtr = firstMsduPtr->nextMSDUinList;
    402 			wlan_memMngrFreeMSDU(pDeConcatenator->hMemMngr, firstMsduPtr->handle);
    403 			firstMsduPtr = NextMsduPtr;
    404 		}
    405 	}
    406 
    407 	return (TI_STATUS)rc;
    408 }
    409 
    410