• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &currentMsduPtr )) != 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, &currentMsduPtr )) != 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