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
concat_create(TI_HANDLE hOs)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 ***************************************************************************/
concat_config(concatenator_t * pConcatenator,TI_HANDLE hOs,TI_HANDLE hReport,TI_HANDLE hMemMngr)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
concat_destroy(concatenator_t * pConcatenator)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 ************************************************************************/
concat_concatMsduList(concatenator_t * pConcatenator,mem_MSDU_T * pFirstMsduPtr,mem_MSDU_T ** pReturnMsduPtr,UINT16 concatFlags)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 ************************************************************************/
concat_replaceWlanHeader(concatenator_t * pConcatenator,mem_MSDU_T * msduPtr)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