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 /* */
38 /* MODULE: */
39 /* PURPOSE: */
40 /* */
41 /***************************************************************************/
42 #include "fourX.h"
43 #include "report.h"
44 #include "osApi.h"
45 #include "utils.h"
46 #include "802_11Defs.h"
47
48
49 static Wlan4XType_t fourX_parseRxFrame(fourX_t* pFourX, mem_MSDU_T* msduPtr);
50
51 static TI_STATUS fourX_MakeConcatDecision(fourX_t* pFourX,
52 MsduList_t* pMsduList,
53 hwTxInformation_t* pHwTxInformation,
54 UINT32 numOfReadyMsdu,
55 UINT16* concatFlags,
56 UINT32* numOfMsduToConcat);
57
58 static TI_STATUS fourX_prepareMsduListToConcat(fourX_t* pFourX,
59 mem_MSDU_T** returnMsduPtr,
60 MsduList_t* pMsduList,
61 UINT32 maxNumMsduToConcat);
62
63
64 /*************************************************************************
65 * concat_create *
66 **************************************************************************
67 * DESCRIPTION: This function initializes the Ctrl data module.
68 *
69 * INPUT: hOs - handle to Os Abstraction Layer
70 *
71 * OUTPUT: TxCmplt_CB - call back function that return to configMngr
72 * in order to register in the Hal
73 *
74 * RETURN: Handle to the allocated Ctrl data control block
75 ************************************************************************/
76
fourX_create(TI_HANDLE hOs)77 fourX_t* fourX_create(TI_HANDLE hOs)
78 {
79 fourX_t* pFourX;
80 deConcatenator_t* pDeConcatenator;
81 concatenator_t* pConcatenator;
82 ackEmul_t* pAckEmul;
83
84
85 if( hOs == NULL )
86 {
87 WLAN_OS_REPORT(("FATAL ERROR: fourX_create(): OS handle Error - Aborting\n"));
88 return NULL;
89 }
90
91 /* alocate concatenator block */
92 pFourX = os_memoryAlloc(hOs, (sizeof(fourX_t)));
93
94 /* create 4x sub moduls */
95 pConcatenator = concat_create(hOs);
96 pDeConcatenator = deConcat_create(hOs);
97 pAckEmul = ackEmul_create(hOs);
98
99
100 if ( (!pFourX) || (!pConcatenator) || (!pDeConcatenator) || (!pAckEmul))
101 {
102 utils_nullMemoryFree(hOs, pDeConcatenator, sizeof(deConcatenator_t));
103 utils_nullMemoryFree(hOs, pConcatenator, sizeof(concatenator_t));
104 utils_nullMemoryFree(hOs, pAckEmul, sizeof(ackEmul_t));
105 utils_nullMemoryFree(hOs, pFourX, sizeof(fourX_t));
106 WLAN_OS_REPORT(("FATAL ERROR: fourX_create(): Error Creating fourX module- Aborting\n"));
107 return(NULL);
108 }
109
110 /* reset control module control block */
111 os_memoryZero(hOs, pFourX, (sizeof(fourX_t)));
112
113 pFourX->pConcatenator = pConcatenator;
114 pFourX->pDeConcatenator = pDeConcatenator;
115 pFourX->pAckEmul = pAckEmul;
116
117 pFourX->hOs = hOs;
118
119 return(pFourX);
120 }
121
122 /***************************************************************************
123 * ctrlData_config *
124 ****************************************************************************
125 * DESCRIPTION: This function configures the Ctrl Data module
126 *
127 * INPUTS: hCtrlData - The object
128 * hOs - Handle to the Os Abstraction Layer
129 * hReport - Handle to the Report object
130 * ctrlDataInitParams - pointer to Ctrl module init parameters
131 * OUTPUT:
132 *
133 * RETURNS: OK - Configuration succesfull
134 * NOK - Configuration unsuccesfull
135 ***************************************************************************/
fourX_config(fourX_t * pFourX,TI_HANDLE hOs,TI_HANDLE hReport,TI_HANDLE hMemMngr,TI_HANDLE hWhalCtrl,TI_HANDLE hTxData,fourXInitParams_t * fourXInitParams)136 TI_STATUS fourX_config(fourX_t* pFourX,
137 TI_HANDLE hOs,
138 TI_HANDLE hReport,
139 TI_HANDLE hMemMngr,
140 TI_HANDLE hWhalCtrl,
141 TI_HANDLE hTxData,
142 fourXInitParams_t* fourXInitParams)
143 {
144 /* check parameters validity */
145 if( (pFourX == NULL) || (hOs == NULL) || (hReport == NULL) ||
146 (hMemMngr == NULL) || (hWhalCtrl == NULL) || (hTxData == NULL))
147 {
148 WLAN_OS_REPORT(("FATAL ERROR: fourX_config(): Parameters Error - Aborting\n"));
149 return NOK;
150 }
151
152 /* set objects handles */
153 pFourX->hOs = hOs;
154 pFourX->hReport = hReport;
155 pFourX->hMemMngr = hMemMngr;
156 pFourX->hWhalCtrl = hWhalCtrl;
157 pFourX->hTxData = hTxData;
158
159 /* configure 4x parameters - TODO USE fourXInitParams */
160 pFourX->desiredConcatenationEnable = DESIRED_CONCATENATION_ENABLE_DEF;
161 pFourX->desiredCWMinEnable = DESIRED_CWMIN_ENABLE_DEF;
162 pFourX->desiredCWComboEnable = DESIRED_CWCOMBO_ENABLE_DEF;
163 pFourX->desiredAckEmulationEnable = DESIRED_ACKEMULATION_ENABLE_DEF;
164 pFourX->desiredERP_ProtectionEnable = DESIRED_ERP_PROTECTION_ENABLE_DEF;
165 pFourX->desiredMaxConcatSize = MAX_CONCAT_SIZE_DEF;
166 pFourX->desiredCWMin = CW_MIN_DEF;
167 pFourX->desiredCWMax = CW_MAX_DEF;
168
169
170 /* configure 4x sub modules */
171 concat_config(pFourX->pConcatenator, hOs, hReport, hMemMngr);
172 deConcat_config(pFourX->pDeConcatenator, hOs, hReport, hMemMngr);
173 ackEmul_config(pFourX->pAckEmul,hWhalCtrl,hOs,hReport,hMemMngr);
174
175
176 WLAN_REPORT_INIT(pFourX->hReport, FOUR_X_MODULE_LOG,
177 (".....fouorX configured successfully\n"));
178
179 return OK;
180 }
181
182 /***************************************************************************
183 * ctrlData_unLoad *
184 ****************************************************************************
185 * DESCRIPTION: This function unload the Ctrl data module.
186 *
187 * INPUTS: hCtrlData - the object
188 *
189 * OUTPUT:
190 *
191 * RETURNS: OK - Unload succesfull
192 * NOK - Unload unsuccesfull
193 ***************************************************************************/
194
fourX_destroy(fourX_t * pFourX)195 TI_STATUS fourX_destroy(fourX_t* pFourX)
196 {
197 concat_destroy(pFourX->pConcatenator);
198 deConcat_destroy(pFourX->pDeConcatenator);
199 ackEmul_destroy(pFourX->pAckEmul);
200
201 /* free control module controll block */
202 os_memoryFree(pFourX->hOs, pFourX, sizeof(fourX_t));
203
204 return OK;
205 }
206
207
fourX_parseRxFrame(fourX_t * pFourX,mem_MSDU_T * msduPtr)208 static Wlan4XType_t fourX_parseRxFrame(fourX_t* pFourX, mem_MSDU_T* msduPtr)
209 {
210 dot114xMsdu_t* pdot114xHeader;
211 UINT8 tiSnapDataArray[8] = {0xAA,0xAA,0x03,0x08,0x00,0x28,0x60,0xD0};
212
213 /* Check frame len validity */
214 if(msduPtr->dataLen < sizeof(dot114xMsdu_t))
215 return NOT_4X_MSDU;
216
217 pdot114xHeader = (dot114xMsdu_t*)memMgr_BufData(msduPtr->firstBDPtr);
218
219 /*
220 Verify a TI SNAP header.
221 */
222 if( os_memoryCompare(pFourX->hOs,
223 (void*)&(pdot114xHeader->msduHeader.snapHeader),
224 tiSnapDataArray,
225 sizeof(Wlan_LlcHeader_T)) != 0)
226 {
227 return NOT_4X_MSDU;
228 }
229
230 switch (pdot114xHeader->header4x.type)
231 {
232
233 case CONCATENATION :
234 return CONCATENATION;
235 /* break; - unreachable*/
236
237 case MANAGMENT_4X :
238 return MANAGMENT_4X;
239 /* break; - unreachable*/
240
241 default:
242 return NOT_4X_MSDU;
243 /* break; - unreachable*/
244
245 }
246 }
247
fourX_rxMsdu(fourX_t * pFourX,mem_MSDU_T ** rxMsduPtr)248 TI_STATUS fourX_rxMsdu(fourX_t* pFourX, mem_MSDU_T** rxMsduPtr)
249 {
250 Wlan4XType_t type4xMsdu;
251 mem_MSDU_T* currMsduPtr;
252
253 type4xMsdu = fourX_parseRxFrame(pFourX, *rxMsduPtr);
254
255 switch (type4xMsdu)
256 {
257 case CONCATENATION :
258 /*
259 * Deconcatenate Msdu
260 */
261 WLAN_REPORT_INFORMATION(pFourX->hReport, FOUR_X_MODULE_LOG,
262 (" Received Concat msdu \n"));
263 if(deConcat_deConcatMsdu(pFourX->pDeConcatenator, rxMsduPtr) != OK)
264 {
265 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
266 (" Failed to deconcat packet \n"));
267
268 return NOK;
269 }
270 break;
271
272 case MANAGMENT_4X :
273 break;
274
275 default:
276 break;
277
278 }
279
280 if(pFourX->ackEmulationEnable)
281 {
282 /* call ack emulation for each packet */
283 currMsduPtr = *rxMsduPtr;
284 while(currMsduPtr)
285 {
286 wdrv_ackEmulationRxPacket(pFourX->pAckEmul, currMsduPtr);
287 currMsduPtr = currMsduPtr->nextMSDUinList;
288 }
289 }
290 return OK;
291
292 }
293
294 #define NUM_MSDU_TO_COPY 8
295
296 /***************************************************************************
297 * fourX_CopyReplace
298 ****************************************************************************
299 * DESCRIPTION: This function copy OS data blocks to local data blocks
300 * in the MSDU in order to release OS resources and to enable
301 * high stream of data from the OS
302 *
303 * INPUTS:
304 *
305 * OUTPUT:
306 *
307 * RETURNS:
308 ***************************************************************************/
fourX_CopyReplace(fourX_t * pFourX,mem_MSDU_T ** pMsdu,MsduList_t * pMsduList,mem_MSDU_T ** pNewMsdu)309 TI_STATUS fourX_CopyReplace(fourX_t* pFourX, mem_MSDU_T **pMsdu, MsduList_t *pMsduList, mem_MSDU_T **pNewMsdu)
310 {
311 mem_MSDU_T *pOrigMsdu;
312
313 pOrigMsdu = (*pMsdu);
314
315 /*
316 * The copy is to new msdu pointed by pMsdu
317 */
318 if(txData_copyPacketToMsdu(pFourX->hTxData, pMsdu, 0 /* dont FreeOldMsdu */) != OK)
319 {
320 /* no msdu to transmit */
321 WLAN_REPORT_INFORMATION(pFourX->hReport, FOUR_X_MODULE_LOG,
322 (" fourX_CopyReplace() : txData_copyPacketToMsdu FAILED \n"));
323
324 return NOK;
325 }
326
327 /*
328 * Still use the old Msdu with its pointers, so swap the BDs of the new and the orig Msdu
329 */
330 wlan_memMngrSwapMsdu(pFourX->hMemMngr, pOrigMsdu, (*pMsdu));
331
332 /* return the new msdu to free later */
333 (*pNewMsdu) = (*pMsdu);
334 /* use the orig Msdu */
335 (*pMsdu) = pOrigMsdu;
336
337 return OK;
338 }
339
340
341 /***************************************************************************
342 * fourX_CopyOsData
343 ****************************************************************************
344 * DESCRIPTION: This function scan the Msdu list and copy OS data blocks to
345 * local data blocks .
346 * in the MSDU in order to release OS resources and to enable
347 * high stream of data from the OS
348 *
349 * INPUTS:
350 *
351 * OUTPUT:
352 *
353 * RETURNS:
354 ***************************************************************************/
fourX_CopyOsData(fourX_t * pFourX,MsduList_t * pMsduList)355 UINT32 fourX_CopyOsData(fourX_t* pFourX, MsduList_t *pMsduList)
356 {
357 int NumMsduToCopy = 0;
358 mem_MSDU_T *pMsdu;
359 mem_MSDU_T *pNewMsdu=NULL;
360 mem_MSDU_T *pMsduFreeList=NULL;
361 mem_MSDU_T *pMsduFreeCurr=NULL;
362 mem_MSDU_T *pKeepNext=NULL;
363 int i;
364 int NumOfCopiedPackets=0;
365
366 os_protectLock(pMsduList->hOs, pMsduList->hCriticalSectionProtect); /* START OF CRITICAL SECTION */
367
368 if (pMsduList->CurrNumOfMsdu == 0)
369 {
370 pFourX->counters.count6 = 0;
371 pFourX->counters.count7 = 0;
372 os_protectUnlock(pMsduList->hOs, pMsduList->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
373 return 0;
374 }
375
376 /*
377 * Find how many msdu to copy
378 */
379 if (pMsduList->CurrNumOfMsdu <= NUM_MSDU_TO_COPY)
380 NumMsduToCopy = pMsduList->CurrNumOfMsdu;
381 else
382 NumMsduToCopy = NUM_MSDU_TO_COPY;
383
384 pMsdu=pMsduList->first;
385
386 /*
387 * Start the copy
388 */
389 for (i=0; (i<NumMsduToCopy) ; i++)
390 {
391 if (pMsdu == NULL)
392 {
393 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
394 (" fourX_CopyMsdu() : fourX_CopyReplace FAILED, pMsdu is NULL i=%d, Num=%d (Actual=%d) \n", i, NumMsduToCopy, pMsduList->CurrNumOfMsdu));
395
396 break;
397 }
398 /*
399 * Already copied - skip it
400 */
401 if (pMsdu->freeFunc == NULL)
402 {
403 pMsdu=pMsdu->nextMSDUinList;
404 NumOfCopiedPackets++;
405 continue;
406 }
407
408 WLAN_REPORT_INFORMATION(pFourX->hReport, FOUR_X_MODULE_LOG,
409 (" fourX_CopyMsdu() : i=%d, CopyReplace 0x%x\n", i , pMsdu));
410
411 /*
412 * Copy and replace in the list
413 */
414 if(fourX_CopyReplace(pFourX, &pMsdu, pMsduList, &pNewMsdu) != OK)
415 {
416 /* no msdu to transmit */
417 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
418 (" fourX_CopyMsdu() : fourX_CopyReplace FAILED \n"));
419
420 break;
421 }
422
423 /*
424 * Enter the new Msdu to the free list
425 */
426 if (pMsduFreeList == NULL)
427 {
428 pMsduFreeList = pNewMsdu;
429 }
430 else
431 {
432 pMsduFreeCurr = pMsduFreeList;
433 while (pMsduFreeCurr->nextMSDUinList != NULL)
434 pMsduFreeCurr = pMsduFreeCurr->nextMSDUinList;
435 pMsduFreeCurr->nextMSDUinList = pNewMsdu;
436 }
437 pNewMsdu->nextMSDUinList = NULL;
438
439 /* copy the next msdu */
440 pMsdu=pMsdu->nextMSDUinList;
441 NumOfCopiedPackets++;
442 }
443
444 pFourX->counters.count6 = pMsduList->CurrNumOfMsdu;
445 pFourX->counters.count7 = i;
446
447 /* !!!! This is the right place for the unlock */
448 os_protectUnlock(pMsduList->hOs, pMsduList->hCriticalSectionProtect); /* END OF CRITICAL SECTION */
449
450 /*
451 * free loop, do not call the free inside lock !!!
452 */
453 pMsduFreeCurr = pMsduFreeList;
454 while (pMsduFreeCurr != NULL)
455 {
456 pKeepNext = pMsduFreeCurr->nextMSDUinList;
457
458 wlan_memMngrFreeMSDU(pFourX->hMemMngr, memMgr_MsduHandle(pMsduFreeCurr));
459
460 pMsduFreeCurr=pKeepNext;
461 }
462
463 return NumOfCopiedPackets;
464 }
465
466
467
fourX_txMsduDeQueue(fourX_t * pFourX,mem_MSDU_T ** returnMsduPtr,MsduList_t * pMsduList,hwTxInformation_t * pHwTxInformation)468 TI_STATUS fourX_txMsduDeQueue(fourX_t* pFourX,
469 mem_MSDU_T** returnMsduPtr,
470 MsduList_t* pMsduList,
471 hwTxInformation_t* pHwTxInformation)
472 {
473 TI_STATUS status;
474 mem_MSDU_T* firstMsduPtr;
475 UINT16 concatFlags = 0;
476 UINT32 numOfMsduToConcat;
477 UINT32 numMsdu = 0;
478
479 *returnMsduPtr = NULL;
480
481
482 #ifdef NO_COPY_NDIS_BUFFERS
483 /*
484 * Scan the Msdu list and copy OS data blocks to local data blocks .
485 * in the MSDU in order to release OS resources and to enable
486 * high stream of data from the OS.
487 */
488 numMsdu = fourX_CopyOsData(pFourX, pMsduList);
489 /* This function copied up to 8 or numOfMsdu in list packets from OS to Shared memory
490 * As there is NDISfreeFunc after the copy, New un-copied packets can enter the msduList,
491 * but the scheduler was blocked from entering the send again.
492 */
493 #else
494
495 if (pMsduList->CurrNumOfMsdu < NUM_MSDU_TO_COPY )
496 numMsdu = pMsduList->CurrNumOfMsdu;
497 else
498 numMsdu = NUM_MSDU_TO_COPY;
499 #endif
500
501 /*if(pFourX->concatenationEnable != TRUE)*/
502 status = fourX_MakeConcatDecision(pFourX,pMsduList,pHwTxInformation,numMsdu,
503 &concatFlags,&numOfMsduToConcat);
504
505
506 switch(status)
507 {
508 case MAKE_CONCATENATION:
509
510 /*
511 * Make Concatenation
512 */
513
514 fourX_prepareMsduListToConcat(pFourX,
515 &firstMsduPtr,
516 pMsduList,
517 numOfMsduToConcat);
518
519 if(firstMsduPtr == NULL)
520 return NOK;
521
522
523 return concat_concatMsduList(pFourX->pConcatenator,
524 firstMsduPtr,
525 returnMsduPtr,
526 concatFlags);
527
528
529 case SEND_ONE_MSDU:
530
531 /*
532 * Send Only One Msdu
533 */
534
535 if((msduList_GetFirst( pMsduList, returnMsduPtr )) != OK)
536 {
537 /* msdu list is empty - should never reach here */
538 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
539 (" fourX_txMsduDeQueue:msduList_GetFirst() : No Msdu to get in list \n"));
540
541 return NOK;
542 }
543
544 return OK;
545
546 case DO_NOT_SEND_MSDU:
547
548 /*
549 * Don't Send any Msdu
550 */
551
552 return NOK;
553
554 default:
555 break;
556
557 }
558 return OK;
559 }
560
fourX_txMsduBeforInsertToQueue(fourX_t * pFourX,mem_MSDU_T ** msduPtr)561 TI_STATUS fourX_txMsduBeforInsertToQueue(fourX_t* pFourX,
562 mem_MSDU_T** msduPtr)
563 {
564 /* no ACK emulation !!!!!!!!!!!!!!!!!! */
565 #if 0
566 UINT32 discardPacket;
567 if(pFourX->ackEmulationEnable)
568 {
569 wdrv_ackEmulationTxPacket(pFourX->pAckEmul, *msduPtr, &discardPacket);
570 if (discardPacket == TRUE)
571 {
572 wlan_memMngrFreeMSDU(pFourX->hMemMngr, (*msduPtr)->handle);
573 (*msduPtr) = NULL;
574 return OK;
575 }
576 }
577 #endif
578 return OK;
579 }
580
fourX_prepareMsduListToConcat(fourX_t * pFourX,mem_MSDU_T ** returnMsduPtr,MsduList_t * pMsduList,UINT32 maxNumMsduToConcat)581 static TI_STATUS fourX_prepareMsduListToConcat(fourX_t* pFourX,
582 mem_MSDU_T** returnMsduPtr,
583 MsduList_t* pMsduList,
584 UINT32 maxNumMsduToConcat)
585 {
586 mem_MSDU_T* currentMsduPtr;
587 mem_MSDU_T* PrevMsduPtr=NULL;
588 UINT32 totalLen = 0;
589 BOOL firsdMsduInList = TRUE;
590 UINT32 numOfMsdu = 0;
591
592
593 *returnMsduPtr = NULL;
594
595 while(maxNumMsduToConcat--)
596 {
597 /* prepare a link list of msdu in the concatenator format */
598 if((msduList_WatchFirst( pMsduList, ¤tMsduPtr )) != OK)
599 {
600 /* msdu list is empty - can return now */
601 WLAN_REPORT_INFORMATION(pFourX->hReport, FOUR_X_MODULE_LOG,
602 (" fourX_txMsduDeQueue: msduList_WatchFirst() : No Msdu to watch \n"));
603 break;
604 }
605 totalLen += currentMsduPtr->dataLen;
606
607 if(totalLen > 4032/*pFourX->currentMaxConcatSize*/)
608 break;
609
610 if((msduList_GetFirst( pMsduList, ¤tMsduPtr )) != OK)
611 {
612 /* msdu list is empty - should never reach here */
613 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
614 (" fourX_txMsduDeQueue:msduList_GetFirst() : No Msdu to get in list \n"));
615 break;
616 }
617
618 /* In this phase, the free func should be NULL !!!!!!!!!!! */
619 if (currentMsduPtr->freeFunc)
620 {
621 WLAN_REPORT_ERROR(pFourX->hReport, FOUR_X_MODULE_LOG,
622 (" fourX_txMsduDeQueue:msduList_GetFirst() : fourX_prepareMsduListToConcat, free funct is not NULL !!!!!!!\n"));
623 }
624
625 numOfMsdu++;
626
627 if(firsdMsduInList == TRUE)
628 {
629 *returnMsduPtr = currentMsduPtr;
630 firsdMsduInList = FALSE;
631 }
632 else
633 {
634 PrevMsduPtr->nextMSDUinList = currentMsduPtr;
635 }
636
637 PrevMsduPtr = currentMsduPtr;
638 }
639
640 return OK;
641 }
642
fourX_MakeConcatDecision(fourX_t * pFourX,MsduList_t * pMsduList,hwTxInformation_t * pHwTxInformation,UINT32 numOfReadyMsdu,UINT16 * concatFlags,UINT32 * numOfMsduToConcat)643 static TI_STATUS fourX_MakeConcatDecision(fourX_t* pFourX,
644 MsduList_t* pMsduList,
645 hwTxInformation_t* pHwTxInformation,
646 UINT32 numOfReadyMsdu,
647 UINT16* concatFlags,
648 UINT32* numOfMsduToConcat)
649 {
650 memMgrResources_t memMgrResources;
651
652 #ifdef TNETW_MASTER_MODE
653 UINT32 limitResourcees;
654 #endif
655
656 *numOfMsduToConcat = 0;
657
658 /* get MemoryMgr resources for concatenation */
659 wlan_memMngrGetMemMgrResources(pFourX->hMemMngr, &memMgrResources);
660
661 #ifdef TNETW_MASTER_MODE
662 limitResourcees = MIN(memMgrResources.numOfFreeBufPool2 ,(MIN(memMgrResources.numOfFreeBufPool1-1 , pHwTxInformation->hwNumOfFreeBDs)));
663
664
665
666 /* No free space in HW to send */
667 if( (pHwTxInformation->hwNumOfFreeMsdu == 0) || (limitResourcees < 2) )
668 {
669 pFourX->counters.count1++;
670 return DO_NOT_SEND_MSDU;
671 }
672
673 /*
674 * Phase 1: At least 3 waiting msdu for concat (and enough space in HW)
675 * --------------------------------------------------------------------
676 * In case there are 2 msdu the decision will be later
677 * We have resources to send, decide if to concat, send single or wait.
678 */
679 if( numOfReadyMsdu >= 3 )
680 {
681 pFourX->counters.count2++;
682 /* We have enough msdus to concat. */
683 *concatFlags = *concatFlags | WLAN_4X_CONCAT_MORE_BIT;
684
685 /* not enough free bd to send or concat - need at least 2 msdu and 2 bd for each + concat header bd */
686 if (limitResourcees < 5)
687 return DO_NOT_SEND_MSDU;
688
689 /* minimum 2 bd for each msdu and one for cocat header */
690 *numOfMsduToConcat = MIN( (limitResourcees - 1)>>1, numOfReadyMsdu);
691
692 /* minimum 2 msdu to concat */
693 if (*numOfMsduToConcat < 2)
694 return SEND_ONE_MSDU;
695
696 return MAKE_CONCATENATION;
697 }
698
699
700 /*
701 * Phase 2: Less than 3 waiting msdu, and the HW already has Msdu to send
702 * ----------------------------------------------------------------------
703 * It is allowed to delay the msdu and continue queueing more MSDU
704 */
705 if(pHwTxInformation->hwNumOfBusyMsdu > 1)
706 {
707 pFourX->counters.count3++;
708 /*
709 * ACX has enough packets to send, delay the current sending.
710 */
711 return DO_NOT_SEND_MSDU;
712 }
713
714 /*
715 * Phase 3: Less than 3 waiting msdu, and the HW is free to send
716 * -------------------------------------------------------------
717 * It is NOT allowed to delay the msdu, so send it
718 */
719 else
720 {
721 /*
722 * Phase 4: There are 2 msdu to concat and the HW is free to send
723 * --------------------------------------------------------------
724 */
725 if( numOfReadyMsdu > 1 )
726 {
727 pFourX->counters.count4++;
728 /* We have enough msdus to concat. */
729 *concatFlags = *concatFlags | WLAN_4X_CONCAT_MORE_BIT;
730
731 /* not enough free bd to send or concat - need at least 2 msdu and 2 bd for each + concat header bd */
732 if (limitResourcees < 5)
733 return DO_NOT_SEND_MSDU;
734
735 /* minimum 2 bd for each msdu and one for cocat header */
736 *numOfMsduToConcat = MIN( (limitResourcees - 1)>>1, numOfReadyMsdu);
737
738 /* minimum 2 msdu to concat */
739 if (*numOfMsduToConcat < 2)
740 return SEND_ONE_MSDU;
741
742 return MAKE_CONCATENATION;
743 }
744 /*
745 * Phase 5: There are only one msdu to send, send it (no concatination)
746 * --------------------------------------------------------------------
747 */
748 else
749 {
750 pFourX->counters.count5++;
751 /*
752 * There space in HW and only one MSDU to send, send it as single.
753 */
754 return SEND_ONE_MSDU;
755 }
756 }
757
758
759 #else /* SLAVE_MODE */
760 if((pHwTxInformation->hwTotalAvailMem > 4095) && (numOfReadyMsdu > 1))
761 {
762 *concatFlags = *concatFlags | WLAN_4X_CONCAT_MORE_BIT;
763 return MAKE_CONCATENATION;
764 }
765 else
766 {
767 if(pHwTxInformation->hwTotalAvailMem > pMsduList->first->dataLen)
768 return SEND_ONE_MSDU;
769 else
770 return DO_NOT_SEND_MSDU;
771 }
772
773 #endif /* MASTER/SALVE modes */
774
775
776
777 }
778
779
780 /* debug functions */
fourX_printParams(fourX_t * pFourX)781 void fourX_printParams(fourX_t* pFourX)
782 {
783
784 WLAN_OS_REPORT((" FOUR X Parameters \n"));
785 WLAN_OS_REPORT(("-------------------------------------\n"));
786
787 WLAN_OS_REPORT(("hOs = 0x%X\n",pFourX->hOs ));
788 WLAN_OS_REPORT(("hReport = 0x%X\n",pFourX->hReport ));
789 WLAN_OS_REPORT(("hMemMngr = 0x%X\n\n",pFourX->hMemMngr ));
790
791 WLAN_OS_REPORT(("concatenationEnable = %d\n",pFourX->concatenationEnable ));
792 WLAN_OS_REPORT(("CWMinEnable = %d\n",pFourX->CWMinEnable ));
793 WLAN_OS_REPORT(("CWComboEnable = %d\n",pFourX->CWComboEnable ));
794 WLAN_OS_REPORT(("ackEmulationEnable = %d\n",pFourX->ackEmulationEnable ));
795 WLAN_OS_REPORT(("ERP_ProtectionEnable = %d\n\n",pFourX->ERP_ProtectionEnable ));
796
797 WLAN_OS_REPORT(("desiredConcatenationEnable = %d\n",pFourX->desiredConcatenationEnable ));
798 WLAN_OS_REPORT(("desiredCWMinEnable = %d\n",pFourX->desiredCWMinEnable ));
799 WLAN_OS_REPORT(("desiredCWComboEnable = %d\n",pFourX->desiredCWComboEnable ));
800 WLAN_OS_REPORT(("desiredAckEmulationEnable = %d\n",pFourX->desiredAckEmulationEnable ));
801 WLAN_OS_REPORT(("desiredERP_ProtectionEnable = %d\n\n",pFourX->desiredERP_ProtectionEnable ));
802
803 WLAN_OS_REPORT(("desiredMaxConcatSize = %d\n",pFourX->desiredMaxConcatSize ));
804 WLAN_OS_REPORT(("desiredCWMin = %d\n",pFourX->desiredCWMin ));
805 WLAN_OS_REPORT(("desiredCWMax = %d\n\n",pFourX->desiredCWMax ));
806
807
808 /* AP supported features */
809
810
811 /* 4x parameters */
812 WLAN_OS_REPORT(("currentMaxConcatSize = %d\n",pFourX->currentMaxConcatSize ));
813 WLAN_OS_REPORT(("currentCWMin = %d\n",pFourX->currentCWMin ));
814 WLAN_OS_REPORT(("currentCWMax = %d\n\n",pFourX->currentCWMax ));
815
816
817 WLAN_OS_REPORT(("ApFourX_Capabilities.fourXProtocolVersion = %d\n", pFourX->ApFourX_Capabilities.fourXProtocolVersion));
818 WLAN_OS_REPORT(("-------------------------------------------------\n"));
819
820 WLAN_OS_REPORT(("AP_Cap.concatenationParams.enableDisable = %d\n", pFourX->ApFourX_Capabilities.concatenationParams.enableDisable));
821 WLAN_OS_REPORT(("AP_Cap.concatenationParams.concatenationSize = %d\n", pFourX->ApFourX_Capabilities.concatenationParams.concatenationSize));
822
823 WLAN_OS_REPORT(("AP_Cap.contentionWindowParams.enableDisable = %d\n", pFourX->ApFourX_Capabilities.contentionWindowParams.enableDisable));
824 WLAN_OS_REPORT(("AP_Cap.contentionWindowParams.CWMin = %d\n", pFourX->ApFourX_Capabilities.contentionWindowParams.CWMin));
825 WLAN_OS_REPORT(("AP_Cap.contentionWindowParams.CWMax = %d\n", pFourX->ApFourX_Capabilities.contentionWindowParams.CWMax));
826
827 WLAN_OS_REPORT(("AP_Cap.CWCombParams.enableDisable = %d\n", pFourX->ApFourX_Capabilities.CWCombParams.enableDisable));
828 WLAN_OS_REPORT(("AP_Cap.CWCombParams.DIFS = %d\n", pFourX->ApFourX_Capabilities.CWCombParams.DIFS));
829 WLAN_OS_REPORT(("AP_Cap.CWCombParams.SLOT = %d\n", pFourX->ApFourX_Capabilities.CWCombParams.SLOT));
830 WLAN_OS_REPORT(("AP_Cap.CWCombParams.CWMin = %d\n", pFourX->ApFourX_Capabilities.CWCombParams.CWMin));
831
832 WLAN_OS_REPORT(("AP_Cap.ackEmulationParams.enableDisable = %d\n", pFourX->ApFourX_Capabilities.ackEmulationParams.enableDisable));
833
834 WLAN_OS_REPORT(("AP_Cap.ERP_ProtectionParams.enableDisable = %d\n", pFourX->ApFourX_Capabilities.ERP_ProtectionParams.enableDisable));
835
836 WLAN_OS_REPORT(("No Free Msdu in ACX = %d\n", pFourX->counters.count1));
837 WLAN_OS_REPORT(("Concat more than 2 = %d\n", pFourX->counters.count2));
838 WLAN_OS_REPORT(("Delay sending = %d\n", pFourX->counters.count3));
839 WLAN_OS_REPORT(("Concat less than 3 = %d\n", pFourX->counters.count4));
840 WLAN_OS_REPORT(("send one msdu = %d\n", pFourX->counters.count5));
841
842 WLAN_OS_REPORT(("Msdu in Queue Total = %d\n", pFourX->counters.count6));
843 WLAN_OS_REPORT(("Msdu in Queue Copied = %d\n", pFourX->counters.count7));
844
845 }
846