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
deConcat_create(TI_HANDLE hOs)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 ***************************************************************************/
deConcat_config(deConcatenator_t * pDeConcatenator,TI_HANDLE hOs,TI_HANDLE hReport,TI_HANDLE hMemMngr)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
deConcat_destroy(deConcatenator_t * pDeConcatenator)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 ************************************************************************/
deConcat_deConcatMsdu(deConcatenator_t * pDeConcatenator,mem_MSDU_T ** MsduPtr)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