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