PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/common/src/core/data_ctrl/Ctrl/4X/fourX.c

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