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