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 "Concatenator.h"
     42 #include "report.h"
     43 #include "osApi.h"
     44 #include "utils.h"
     45 #include "802_11Defs.h"
     46 #include "whalBus_Defs.h"
     47 #include "TNETW_Driver_api.h"
     48 
     49 
     50 static TI_STATUS concat_replaceWlanHeader(concatenator_t* pConcatenator,
     51 										  mem_MSDU_T *msduPtr);
     52 
     53 
     54 /*************************************************************************
     55 *                        concat_create                                 *
     56 **************************************************************************
     57 * DESCRIPTION:	This function initializes the Ctrl data module.
     58 *
     59 * INPUT:		hOs - handle to Os Abstraction Layer
     60 *
     61 * OUTPUT:		TxCmplt_CB - call back function that return to configMngr
     62 *				in order to register in the Hal
     63 *
     64 * RETURN:		Handle to the allocated Ctrl data control block
     65 ************************************************************************/
     66 
     67 concatenator_t* concat_create(TI_HANDLE hOs)
     68 {
     69 	concatenator_t* pConcatenator;
     70 
     71 	if( hOs  == NULL )
     72 	{
     73 	    WLAN_OS_REPORT(("FATAL ERROR: concat_create(): OS handle Error - Aborting\n"));
     74 		return NULL;
     75 	}
     76 
     77 	/* alocate concatenator block */
     78 	pConcatenator = os_memoryAlloc(hOs, (sizeof(concatenator_t)));
     79 
     80 
     81 	if (!pConcatenator)
     82 	{
     83 		utils_nullMemoryFree(hOs, pConcatenator, sizeof(concatenator_t));
     84 	    WLAN_OS_REPORT(("FATAL ERROR: concat_create(): Error Creating Concatenator module- Aborting\n"));
     85 		return(NULL);
     86 	}
     87 
     88 	/* reset control module control block */
     89 	os_memoryZero(hOs, pConcatenator, (sizeof(concatenator_t)));
     90 
     91 	pConcatenator->hOs = hOs;
     92 
     93 	return(pConcatenator);
     94 }
     95 
     96 /***************************************************************************
     97 *							concat_config				                   *
     98 ****************************************************************************
     99 * DESCRIPTION:	This function configures the Ctrl Data module
    100 *
    101 * INPUTS:		hCtrlData - The object
    102 *				hOs - Handle to the Os Abstraction Layer
    103 *				hReport - Handle to the Report object
    104 * 				ctrlDataInitParams - pointer to Ctrl module init parameters
    105 * OUTPUT:
    106 *
    107 * RETURNS:		OK - Configuration succesfull
    108 *				NOK - Configuration unsuccesfull
    109 ***************************************************************************/
    110 TI_STATUS concat_config(concatenator_t*		pConcatenator,
    111 						TI_HANDLE			hOs,
    112 						TI_HANDLE			hReport,
    113 						TI_HANDLE			hMemMngr
    114 						/*concatInitParams_t* concatInitParams*/)
    115 {
    116 	/* check parameters validity */
    117 	if( pConcatenator == NULL || hOs == NULL ||
    118 		hReport == NULL || hMemMngr == NULL /*||  concatInitParams == NULL*/)
    119 	{
    120 	    WLAN_OS_REPORT(("FATAL ERROR: concat_config(): Parameters Error - Aborting\n"));
    121 		return NOK;
    122 	}
    123 
    124 	/* set objects handles */
    125 	pConcatenator->hOs = hOs;
    126 	pConcatenator->hReport = hReport;
    127 	pConcatenator->hMemMngr = hMemMngr;
    128 
    129 	WLAN_REPORT_INIT(pConcatenator->hReport, CONCATENATOR_MODULE_LOG,
    130 		(".....Concatenator configured successfully\n"));
    131 
    132 	return OK;
    133 }
    134 
    135 /***************************************************************************
    136 *							ctrlData_unLoad				                   *
    137 ****************************************************************************
    138 * DESCRIPTION:	This function unload the Ctrl data module.
    139 *
    140 * INPUTS:		hCtrlData - the object
    141 *
    142 * OUTPUT:
    143 *
    144 * RETURNS:		OK - Unload succesfull
    145 *				NOK - Unload unsuccesfull
    146 ***************************************************************************/
    147 
    148 TI_STATUS concat_destroy(concatenator_t* pConcatenator)
    149 {
    150 	/* free control module controll block */
    151 	os_memoryFree(pConcatenator->hOs, pConcatenator, sizeof(concatenator_t));
    152 
    153 	return OK;
    154 }
    155 
    156 
    157 /*************************************************************************
    158  *                        wdrv_txConcatMsduList                          *
    159  *************************************************************************
    160 DESCRIPTION: This function get a list of MSDUs (The first MSDU points
    161              on the others) and concatenate them into one MPDU by linking the
    162              buffers BDs. In return only the first MSDU struct is in use,
    163              and it contains the entire concatenated MPDU.
    164 
    165 INPUT:       msduPtr     - Pointer to the first MSDU.
    166              concatFlags - Concatenation flags.
    167 
    168 
    169 OUTPUT:      By reference to the msduPtr.
    170 
    171 RETURN:      OK : Initiation successful.
    172              NOK: Initiation unsuccessful.
    173 ************************************************************************/
    174 TI_STATUS concat_concatMsduList(concatenator_t*	pConcatenator,
    175 								mem_MSDU_T*		pFirstMsduPtr,
    176 								mem_MSDU_T**	pReturnMsduPtr,
    177 								UINT16			concatFlags)
    178 {
    179 	mem_MSDU_T     *currMsduPtr;
    180 	mem_MSDU_T     *prevMsduPtr;
    181 	/*mem_MSDU_T     *buildMsduPtr; */
    182 	UINT8          *srcDataPtr;
    183 	UINT8          *buildDataPtr;
    184     Wdrv4xHeader_t *w4xHeaderPtr;
    185 	UINT8			tiSnapDataArray[8] = {0xAA,0xAA,0x03,0x08,0x00,0x28,0x60,0xD0};
    186 
    187 	/* Allocate MSDU and a BD for the concatenatetion header. */
    188 	if(wlan_memMngrAllocMSDU(pConcatenator->hMemMngr, pReturnMsduPtr,
    189 							  WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN +WLAN_4X_CONCAT_HDR_LEN + sizeof(DbTescriptor),
    190 							  CONCAT_MODULE) == NOK)
    191 	{
    192 		WLAN_REPORT_ERROR(pConcatenator->hReport, CONCATENATOR_MODULE_LOG,
    193 			("concat_concatMsduList: no MemMngre resources, free the MsduList to concat\n"));
    194 
    195 		wlan_memMngrFreeListOfMSDU(pConcatenator->hMemMngr, memMgr_MsduHandle(pFirstMsduPtr));
    196 		return NOK;
    197 	}
    198 
    199 	(*pReturnMsduPtr)->txFlags = pFirstMsduPtr->txFlags;
    200 
    201 	/* Create the first BD.(contains 802.11 header, TI wlan SNAP & Concat headr) */
    202 	srcDataPtr = (UINT8 *)memMgr_MsduHdrAddr(pFirstMsduPtr);
    203 	buildDataPtr = (UINT8 *)memMgr_MsduHdrAddr(*pReturnMsduPtr);
    204 
    205 	/* Copy the 802.11 header. */
    206 	os_memoryCopy(pConcatenator->hOs, buildDataPtr, srcDataPtr, WLAN_HDR_LEN );
    207 
    208 	/* We send the frame from the STA so the AP */
    209 	os_memoryCopy(pConcatenator->hOs, buildDataPtr+WLAN_DA_FIELD_OFFSET, srcDataPtr+WLAN_BSSID_FIELD_OFFSET, 6 );
    210 
    211 	buildDataPtr += WLAN_HDR_LEN;
    212 
    213 	/* create a TI WLAN SNAP */
    214 	os_memoryCopy(pConcatenator->hOs, buildDataPtr ,tiSnapDataArray, WLAN_SNAP_HDR_LEN );
    215 	buildDataPtr += WLAN_SNAP_HDR_LEN;
    216 
    217 	/* create 4X header.   */
    218     w4xHeaderPtr = (Wdrv4xHeader_t*)buildDataPtr;
    219     w4xHeaderPtr->type = WLAN_HEADER_TYPE_CONCATENATION;
    220     w4xHeaderPtr->headerLen = WLAN_CONCAT_HEADER_LEN;
    221     w4xHeaderPtr->txFlags = wlan_htons(concatFlags);
    222 
    223 	(*pReturnMsduPtr)->firstBDPtr->length = WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN +
    224 										WLAN_4X_CONCAT_HDR_LEN;
    225 
    226     (*pReturnMsduPtr)->dataLen =  WLAN_HDR_LEN + WLAN_SNAP_HDR_LEN +
    227 										WLAN_4X_CONCAT_HDR_LEN;
    228 
    229 
    230     (*pReturnMsduPtr)->headerLen = WLAN_HDR_LEN;
    231 
    232 
    233     /*buildMsduPtr->nextMSDUinList = (*pMsduPtr);*/
    234 
    235 
    236 	/* Link the new MSDU to the first MSDU to imitate the MSDU list format.     */
    237 	(*pReturnMsduPtr)->firstBDPtr->nextBDPtr = pFirstMsduPtr->firstBDPtr;
    238 
    239 	/* Start Concatenating the MSDUs, payload is copied from the SNAP to       */
    240 	/* payload  end.                                                           */
    241 	currMsduPtr = pFirstMsduPtr;
    242 	while( currMsduPtr != NULL )
    243 	{
    244         concat_replaceWlanHeader(pConcatenator, currMsduPtr );
    245 
    246         /* Update the size of the concatenated MSDU. */
    247         (*pReturnMsduPtr)->dataLen += currMsduPtr->dataLen;
    248 
    249 
    250         if(  currMsduPtr->nextMSDUinList != NULL )
    251         {
    252             /* Link last BD of the current MSDU to the first BD of the next MSDU.*/
    253              currMsduPtr->lastBDPtr->nextBDPtr = currMsduPtr->nextMSDUinList->firstBDPtr;
    254 
    255             /* Jump for the next MSDU */
    256             prevMsduPtr = currMsduPtr;
    257 			currMsduPtr = currMsduPtr->nextMSDUinList;
    258 			prevMsduPtr->firstBDPtr = NULL;
    259 			prevMsduPtr->nextMSDUinList = NULL;
    260 			wlan_memMngrFreeMSDU(pConcatenator->hMemMngr, memMgr_MsduHandle(prevMsduPtr));
    261 
    262 
    263         }
    264         else
    265 		{
    266             /* Last MSDU */
    267             prevMsduPtr = currMsduPtr;
    268 			prevMsduPtr->firstBDPtr = NULL;
    269 			prevMsduPtr->nextMSDUinList = NULL;
    270 			wlan_memMngrFreeMSDU(pConcatenator->hMemMngr, memMgr_MsduHandle(prevMsduPtr));
    271 
    272             currMsduPtr = NULL;
    273 
    274         }
    275 
    276 
    277 	} /* While( currMsduPtr != NULL ) */
    278 
    279 
    280 	return OK;
    281 }
    282 
    283 
    284 /*************************************************************************
    285  *                        wdrv_txReplaceWlanHeader                       *
    286  *************************************************************************
    287 DESCRIPTION: This function replaces the 802.11 header with length + SA as
    288              prefix to the concatenated MSDU.
    289 
    290 INPUT:       msduPtr     - Pointer to the first MSDU.
    291 
    292 
    293 
    294 RETURN:      OK : Initiation succesfull.
    295              NOK: Initiation unsuccesfull.
    296 ************************************************************************/
    297 static TI_STATUS concat_replaceWlanHeader(concatenator_t* pConcatenator,
    298 										  mem_MSDU_T *msduPtr)
    299 {
    300     UINT8   *firstDataBuf;
    301     UINT8    numOfPadBytes;
    302     UINT8   *tmpPtr;
    303 	UINT8	tmpMacAddr[WLAN_DA_FIELD_LEN];
    304     int i;
    305 
    306 
    307 	/* Replace the 802.11 header with 2 length bytes and 6 DA . */
    308 	firstDataBuf = (UINT8 *)(msduPtr->firstBDPtr->data +
    309 							msduPtr->firstBDPtr->dataOffset);
    310 
    311 	/*
    312 	 * Use temporary buffer to prevent overwrite on the same data
    313 	 */
    314 	os_memoryCopy(pConcatenator->hOs,
    315 				  tmpMacAddr,
    316 				  firstDataBuf+WLAN_DA_FIELD_OFFSET, WLAN_DA_FIELD_LEN);
    317 	os_memoryCopy(pConcatenator->hOs,
    318 				  firstDataBuf+ WLAN_HDR_LEN - WLAN_DA_FIELD_LEN,
    319 				  tmpMacAddr, WLAN_DA_FIELD_LEN);
    320 
    321 	msduPtr->firstBDPtr->dataOffset += WLAN_CONCAT_HDR_OFFSET;
    322 	msduPtr->firstBDPtr->length -= WLAN_CONCAT_HDR_OFFSET;
    323 	msduPtr->dataLen -= WLAN_CONCAT_HDR_OFFSET;
    324 
    325 	/* Fill the length bytes.   */
    326 	(*(UINT16*)(firstDataBuf+ WLAN_CONCAT_HDR_OFFSET)) =
    327 			wlan_htons((UINT16)(msduPtr->dataLen - WLAN_4X_LEN_FIELD_LEN));
    328 
    329 	/* Padding the last buffer with zeros.*/
    330 	numOfPadBytes = msduPtr->dataLen % 4;
    331 
    332 	if( numOfPadBytes > 0 )
    333 	{
    334 #if 1
    335 	/*
    336 	* fixing the alignment bug.
    337 	       */
    338 		numOfPadBytes = 4 - numOfPadBytes;
    339 #endif
    340 		tmpPtr = (UINT8 *) ((UINT32)msduPtr->lastBDPtr->data + msduPtr->lastBDPtr->length +
    341 			msduPtr->lastBDPtr->dataOffset);
    342 		for( i=0; i<numOfPadBytes; i++)
    343 			tmpPtr[i] = 0x00;
    344 
    345 		msduPtr->lastBDPtr->length += numOfPadBytes;
    346 		msduPtr->dataLen += numOfPadBytes;
    347 	}
    348 
    349 	return OK;
    350 }
    351