PageRenderTime 70ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/common/src/core/data_ctrl/Tx/tx.c

https://bitbucket.org/cyanogenmod/cm-kernel
C | 4557 lines | 2530 code | 740 blank | 1287 comment | 393 complexity | 8704803afbf2a443c63ec0d0070266de MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  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: Tx.c */
  38. /* PURPOSE: Tx module functions */
  39. /* */
  40. /***************************************************************************/
  41. #include "osTIType.h"
  42. #include "paramIn.h"
  43. #include "paramOut.h"
  44. #include "osApi.h"
  45. #include "tx.h"
  46. #include "DataCtrl_Api.h"
  47. #include "siteMgrApi.h"
  48. #include "802_11Defs.h"
  49. #include "Ethernet.h"
  50. /* GWSI_LAYER */
  51. #include "Core_AdaptTx.h"
  52. #include "memMngrEx.h"
  53. #include "report.h"
  54. #include "utils.h"
  55. #include "measurementMgrApi.h"
  56. #include "TI_IPC_Api.h"
  57. #include "EvHandler.h"
  58. #include "qosMngr_API.h"
  59. #include "PowerMgr_API.h"
  60. #include "bufferPoolApi.h"
  61. #include "TNETW_Driver_api.h"
  62. /*
  63. This is an Ethernet Version 2 frame:
  64. +--------------+
  65. | | The destination address is a six byte Media Access
  66. | Destination | Control (MAC) address, usually burned into the
  67. | 6 bytes | ROM of the Ethernet card.
  68. +--------------+
  69. | | The source address is a six byte MAC address, and
  70. | Source | can signify a physical station or a broadcast.
  71. | 6 bytes |
  72. +--------------+
  73. | Type | The Type field it must be grater then 1500 dec.
  74. | 2 bytes |
  75. +--------------+
  76. | | Any higher layer information is placed in the
  77. | Data | data field, which could contain protocol
  78. | | information or user data.
  79. ~ ~
  80. ~ ~
  81. | 46 to 1500 |
  82. | bytes |
  83. | |
  84. +--------------+
  85. | FCS |
  86. | 4 bytes |
  87. +--------------+
  88. */
  89. /*
  90. 802.2 SNAP DATA Frame
  91. +----------------+
  92. | |
  93. | Destination |
  94. | 6 bytes |
  95. +----------------+
  96. | |
  97. | Source |
  98. | 6 bytes |
  99. +----------------+
  100. | Frame Length | Must be <= 1500 Dec.
  101. | 2 bytes |
  102. +----------------+
  103. | DSAP - 1 byte | = 0xAA ( SNAP )
  104. +----------------+
  105. | SSAP - 1 byte | = 0xAA ( SNAP )
  106. +----------------+
  107. |Control - 1 byte| = 0x03
  108. +----------------+
  109. | OUI - 3 bytes | = 0x0
  110. | |
  111. +----------------+
  112. | Type - 2 bytes | = Ethernet type (IP=0x0800)
  113. +----------------+
  114. | |
  115. | Data |
  116. | |
  117. ~ ~
  118. ~ ~
  119. | 46 to 1500 |
  120. | bytes |
  121. | |
  122. +----------------+
  123. | FCS |
  124. | 4 bytes |
  125. +----------------+
  126. 802.11 DATA Frame
  127. +----------------+
  128. | |
  129. | Frame Control |
  130. | 2 bytes |
  131. +----------------+
  132. | |
  133. | Duration ID |
  134. | 2 bytes |
  135. +----------------+
  136. | |
  137. | Address 1 |
  138. | 6 bytes |
  139. +----------------+
  140. | |
  141. | Address 2 |
  142. | 6 bytes |
  143. +----------------+
  144. | |
  145. | Address 3 |
  146. | 6 bytes |
  147. +----------------+
  148. | |
  149. | Sequence Cntrl |
  150. | 2 bytes |
  151. +----------------+
  152. | |
  153. | Address 4 |
  154. | 6 bytes |
  155. +----------------+
  156. | DSAP - 1 byte | = 0xAA ( SNAP )
  157. +----------------+
  158. | SSAP - 1 byte | = 0xAA ( SNAP )
  159. +----------------+
  160. |Control - 1 byte| = 0x03
  161. +----------------+
  162. | OUI - 3 bytes | = 0x0
  163. | |
  164. +----------------+
  165. | Type - 2 bytes | = Ethernet type (IP=0x0800)
  166. +----------------+
  167. | |
  168. | Data |
  169. | |
  170. ~ ~
  171. ~ ~
  172. | 46 to 1500 |
  173. | bytes |
  174. | |
  175. +----------------+
  176. | FCS |
  177. | 4 bytes |
  178. +----------------+
  179. */
  180. /* Tx queue selection definitions */
  181. #define Q_LEAST_WEIGHT 0xFFFFFFFF /* Use least possible weight as init value (highest value is lowest priority). */
  182. #define Q_SELECTION_HISTORY_LEVEL 5 /* Count down from this value if queue is selected to Tx. */
  183. #define MANAGEMENT_QUEUE_SIZE 16
  184. #define DEFAULT_QUEUE_TO_HAL 1
  185. #define EAPOL_PACKET 0x8E88
  186. /* defined in QosMngr.c - used to update QosControl (userPriority) of a given packet after it has been "downgraded" due to admission control */
  187. extern UINT8 wmeAcToUpIndex[MAX_NUM_OF_AC];
  188. /* defined in qosMngr.c - used to identify voice packets in NON QOS APs */
  189. extern int WMEQosTagToACTable[MAX_NUM_OF_802_1d_TAGS];
  190. /* this macro accesses the WME Tag-to-AC conversion array in order to enable identifying voice packets even on NON QOS APs */
  191. #define GET_WME_AC_TYPE_FROM_MSDU(pMsdu) (WMEQosTagToACTable[pMsdu->qosTag])
  192. #define GET_QUEUE_INDEX(pTxData,acIndex) (pTxData->txDataAcTrfcCtrl[acIndex].QueueIndex)
  193. #define ABS(a) (((int)(a) >= 0) ? (a) : -((int)(a)))
  194. static void txData_convertEthToWlanHeader (txData_t *pTxData, mem_MSDU_T *pMsdu);
  195. static TI_STATUS txData_schedulerSelectQueueToTransmitFrom( TI_HANDLE hTxData, MsduList_t** pMsduListPtr,UINT8 *selectedQueueIndex );
  196. static void txData_startTxSchedulerFromTimer(TI_HANDLE hTxData);
  197. static void txData_calcCreditFromTimer(TI_HANDLE hTxData);
  198. static void txData_UpdateTxCounters( TI_HANDLE hTxData, txCompleteAttr_t *pTxCompleteAttr );
  199. static void txData_SetTxDelayCounters( TI_HANDLE hTxData, UINT32 txQid, txCompleteAttr_t *pTxCompleteAttr, UINT32 driverDelay );
  200. static int txData_selectQueueAndUpdateUserPriority (txData_t *pTxData, mem_MSDU_T *pMsdu, int *selectedQueue, acTrfcType_e *selectedAc);
  201. static int txData_getHighestAdmittedAc(txData_t *pTxData, int startingAcIndex);
  202. static void txData_startVadTimer(TI_HANDLE hTxData, UINT16 voiceDuration);
  203. static void txData_stopVadTimer(TI_HANDLE hTxData);
  204. static void txData_setVadTimer(TI_HANDLE hTxData, BOOL vadEnabled, UINT16 duration);
  205. static void txData_resetVadTimer(TI_HANDLE hTxData);
  206. static void txData_vadTimeout(TI_HANDLE hTxData);
  207. #ifdef TI_DBG
  208. static void txData_printTxThroughputPerQueue(TI_HANDLE hTxData);
  209. static void txData_printTxAirThroughputPerQueue(TI_HANDLE hTxData);
  210. static void txData_printJitter(TI_HANDLE hTxData);
  211. #endif
  212. static BOOL txData_acVoPsPollMode(txData_t *pTxData);
  213. static UINT32 txDataTimeToMsduExpiry( TI_HANDLE htxData, mem_MSDU_T* pMsdu, UINT8 Qid);
  214. static UINT8 txData_GetAcIdFromQid(TI_HANDLE hTxData,UINT8 Qid);
  215. TI_STATUS txData_setMediumUsageThresholds(TI_HANDLE hTxData,
  216. UINT8 acID,
  217. INT32 highMediumUsageThreshold,
  218. INT32 lowMediumUsageThreshold);
  219. static void txData_SetQidToAcTable(TI_HANDLE hTxData,UINT8 QidStart, UINT8 QidEnd,UINT8 AcId);
  220. /* The TX delay histogram ranges start and end in msec. */
  221. static UINT32 txDelayRangeStart[TX_DELAY_RANGES_NUM] = { 0, 1, 10, 20, 40, 60, 80, 100, 200 };
  222. static UINT32 txDelayRangeEnd [TX_DELAY_RANGES_NUM] = { 1, 10, 20, 40, 60, 80, 100, 200, 0xFFFFFFFF };
  223. /*************************************************************************
  224. * txData_create *
  225. **************************************************************************
  226. * DESCRIPTION: This function initializes the Tx module.
  227. *
  228. * INPUT: hOs - handle to Os Abstraction Layer
  229. * txDataInitParams - Tx Data creation parameters
  230. * OUTPUT:
  231. *
  232. * RETURN: Handle to the allocated Tx data control block
  233. *************************************************************************/
  234. TI_HANDLE txData_create(txDataInitParams_t *txDataInitParams,
  235. TI_HANDLE hOs)
  236. {
  237. txData_t *hTxData;
  238. MsduList_t *mgmtMsduList;
  239. MsduList_t *dataMsduListArr[MAX_NUM_OF_TX_QUEUES];
  240. void* pTimer;
  241. #ifdef TI_DBG
  242. void* pThroughputTimer;
  243. void* pAirThroughputTimer;
  244. void* pJitterTimer;
  245. #endif
  246. void* pCreditTimer;
  247. void* pVadTimer;
  248. int queueIndex = 0;
  249. /* check parameters validity */
  250. if( txDataInitParams->txDataNumOfDataQueues > MAX_NUM_OF_TX_QUEUES ||
  251. txDataInitParams->txDataNumOfDataQueues <= 0 )
  252. {
  253. WLAN_OS_REPORT(("FATAL ERROR - UNABLE TO CREATE TX MODULE. Number of queues error = %d.",txDataInitParams->txDataNumOfDataQueues));
  254. return NULL;
  255. }
  256. /* allocate Tx module control block */
  257. hTxData = os_memoryAlloc(hOs, (sizeof(txData_t)));
  258. if(!hTxData)
  259. return NULL;
  260. /* reset tx control block */
  261. os_memoryZero(hOs, hTxData, (sizeof(txData_t)));
  262. /* allocate the buffer pool */
  263. hTxData->hBufferPool = bufferPool_create( hOs,
  264. HAL_CTRL_ACX_TX_DESC_DEF * MAX_NUM_OF_TX_QUEUES,
  265. sizeof(txPacketIdAttr_t) );
  266. if ( NULL == hTxData->hBufferPool )
  267. {
  268. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  269. return NULL;
  270. }
  271. /* allocate Timer to use for scheduler trigger */
  272. pTimer = os_timerCreate(hOs, txData_startTxSchedulerFromTimer, hTxData);
  273. if(!pTimer)
  274. {
  275. bufferPool_destroy( hTxData->hBufferPool );
  276. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  277. return NULL;
  278. }
  279. /* allocate Timer for vad operation */
  280. pVadTimer = os_timerCreate(hOs, txData_vadTimeout, hTxData);
  281. if(!pVadTimer)
  282. {
  283. bufferPool_destroy( hTxData->hBufferPool );
  284. utils_nullTimerDestroy (hOs, pTimer);
  285. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  286. return NULL;
  287. }
  288. #ifdef TI_DBG
  289. /* allocate timer for debug throughput per queue */
  290. pThroughputTimer = os_timerCreate(hOs, txData_printTxThroughputPerQueue, hTxData);
  291. if(!pThroughputTimer)
  292. {
  293. bufferPool_destroy( hTxData->hBufferPool );
  294. utils_nullTimerDestroy(hOs, pTimer);
  295. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  296. return NULL;
  297. }
  298. /* allocate timer for debug throughput per queue */
  299. pAirThroughputTimer = os_timerCreate (hOs, txData_printTxAirThroughputPerQueue, hTxData);
  300. if (!pAirThroughputTimer)
  301. {
  302. bufferPool_destroy (hTxData->hBufferPool);
  303. utils_nullTimerDestroy (hOs, pTimer);
  304. utils_nullTimerDestroy (hOs, pThroughputTimer);
  305. utils_nullMemoryFree (hOs, hTxData, sizeof(txData_t));
  306. return NULL;
  307. }
  308. /* allocate timer for debug throughput per queue */
  309. pJitterTimer = os_timerCreate (hOs, txData_printJitter, hTxData);
  310. if (!pJitterTimer)
  311. {
  312. bufferPool_destroy (hTxData->hBufferPool);
  313. utils_nullTimerDestroy (hOs, pTimer);
  314. utils_nullTimerDestroy (hOs, pThroughputTimer);
  315. utils_nullTimerDestroy (hOs, pAirThroughputTimer);
  316. utils_nullMemoryFree (hOs, hTxData, sizeof(txData_t));
  317. return NULL;
  318. }
  319. #endif
  320. /* allocate timer for credit calculation */
  321. pCreditTimer = os_timerCreate(hOs, txData_calcCreditFromTimer, hTxData);
  322. if(!pCreditTimer)
  323. {
  324. bufferPool_destroy( hTxData->hBufferPool );
  325. utils_nullTimerDestroy(hOs, pTimer);
  326. #ifdef TI_DBG
  327. utils_nullTimerDestroy(hOs, pThroughputTimer);
  328. utils_nullTimerDestroy(hOs, pAirThroughputTimer);
  329. utils_nullTimerDestroy(hOs, pJitterTimer);
  330. #endif
  331. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  332. return NULL;
  333. }
  334. /* initialize management queue */
  335. mgmtMsduList = msduList_CreateNewMsduList( hOs);
  336. if(!mgmtMsduList)
  337. {
  338. bufferPool_destroy( hTxData->hBufferPool );
  339. utils_nullTimerDestroy(hOs, pTimer);
  340. #ifdef TI_DBG
  341. utils_nullTimerDestroy(hOs, pThroughputTimer);
  342. utils_nullTimerDestroy(hOs, pAirThroughputTimer);
  343. utils_nullTimerDestroy(hOs, pJitterTimer);
  344. #endif
  345. utils_nullTimerDestroy(hOs, pCreditTimer);
  346. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  347. return NULL;
  348. }
  349. /* initialize tx data queues */
  350. for(queueIndex = 0 ; queueIndex < MAX_NUM_OF_TX_QUEUES ; queueIndex++)
  351. {
  352. dataMsduListArr[queueIndex] = msduList_CreateNewMsduList( hOs);
  353. if(!dataMsduListArr[queueIndex])
  354. {
  355. bufferPool_destroy( hTxData->hBufferPool );
  356. utils_nullTimerDestroy(hOs, pTimer);
  357. #ifdef TI_DBG
  358. utils_nullTimerDestroy(hOs, pThroughputTimer);
  359. utils_nullTimerDestroy(hOs, pAirThroughputTimer);
  360. utils_nullTimerDestroy(hOs, pJitterTimer);
  361. #endif
  362. utils_nullTimerDestroy(hOs, pCreditTimer);
  363. utils_nullMemoryFree(hOs, mgmtMsduList, sizeof(MsduList_t));
  364. queueIndex--;
  365. for(; queueIndex >= 0 ; queueIndex--)
  366. {
  367. utils_nullMemoryFree(hOs, dataMsduListArr[queueIndex], sizeof(MsduList_t));
  368. }
  369. utils_nullMemoryFree(hOs, hTxData, sizeof(txData_t));
  370. return NULL;
  371. }
  372. }
  373. hTxData->txDataNumOfQueues = txDataInitParams->txDataNumOfDataQueues;
  374. /* Threshold to decide whether we drop the packet, or sending it to Fw */
  375. /* example: value of 75 will drop any MSDU that stayed it the Driver */
  376. /* Queues for more than 75% of the time that was originally defined for it */
  377. hTxData->uFracOfLifeTimeToDrop = txDataInitParams->uFracOfLifeTimeToDrop;
  378. hTxData->TxEventDistributor = DistributorMgr_Create(hOs,MAX_TX_NOTIF_REQ_ELMENTS);
  379. hTxData->mngMsduList = mgmtMsduList;
  380. for(queueIndex = 0 ; queueIndex < MAX_NUM_OF_TX_QUEUES ; queueIndex++)
  381. {
  382. hTxData->dataMsduListArr[queueIndex] = dataMsduListArr[queueIndex];
  383. }
  384. hTxData->pSchedulerTimer = pTimer;
  385. hTxData->pVadTimer = pVadTimer;
  386. hTxData->bSchedulerTimerRunning = FALSE;
  387. #ifdef TI_DBG
  388. hTxData->pThroughputTimer = pThroughputTimer;
  389. hTxData->pAirThroughputTimer = pAirThroughputTimer;
  390. hTxData->pJitterTimer = pJitterTimer;
  391. #endif
  392. hTxData->pCreditTimer = pCreditTimer;
  393. hTxData->hOs = hOs;
  394. hTxData->bVadTimerEnabled = FALSE;
  395. hTxData->vadTimerDuration = 0;
  396. hTxData->creditCalculationTimeout = txDataInitParams->creditCalculationTimeout;
  397. hTxData->bCreditCalcTimerEnabled = txDataInitParams->bCreditCalcTimerEnabled;
  398. hTxData->admCtrlDelayDueToMediumTimeOverUsage = txDataInitParams->admCtrlDelayDueToMediumTimeOverUsage;
  399. hTxData->admissionDownGradeEnable = txDataInitParams->admissionDownGradeEnable;
  400. return(hTxData);
  401. }
  402. /***************************************************************************
  403. * txData_config *
  404. ****************************************************************************
  405. * DESCRIPTION: This function configures the Tx Data module
  406. *
  407. * INPUTS: hTxData - The object
  408. * hCtrlData - Handle to the Ctrl Data object
  409. * hOs - Handle to the Os Abstraction Layer
  410. * hReport - Handle to the Report object
  411. * hMemMngr - Handle to the Memory manager object
  412. * OUTPUT:
  413. *
  414. * RETURNS: OK - Configuration unsuccessful
  415. * NOK - Configuration unsuccessful
  416. ***************************************************************************/
  417. TI_STATUS txData_config(TI_HANDLE hTxData,
  418. TI_HANDLE hCtrlData,
  419. TI_HANDLE hTnetwDrv,
  420. TI_HANDLE hWhalCtrl,
  421. TI_HANDLE hOs,
  422. TI_HANDLE hReport,
  423. TI_HANDLE hMemMngr,
  424. TI_HANDLE hSiteMgr,
  425. TI_HANDLE hEvHandler,
  426. TI_HANDLE hQosMngr,
  427. TI_HANDLE hPowerMgr)
  428. {
  429. int qIndex;
  430. txData_t *pTxData = (txData_t *)hTxData;
  431. /* configure modules handles */
  432. pTxData->hCtrlData = hCtrlData;
  433. pTxData->hTnetwDrv = hTnetwDrv;
  434. pTxData->hWhalCtrl= hWhalCtrl;
  435. pTxData->hOs = hOs;
  436. pTxData->hReport = hReport;
  437. pTxData->hMemMngr = hMemMngr;
  438. pTxData->hSiteMgr = hSiteMgr;
  439. pTxData->hEvHandler = hEvHandler;
  440. pTxData->hQosMngr = hQosMngr;
  441. pTxData->hPowerMgr = hPowerMgr;
  442. /* set Tx parameters */
  443. pTxData->txDataPortStatus = DEF_TX_PORT_STATUS;
  444. pTxData->savePortStatus = DEF_TX_PORT_STATUS;
  445. pTxData->txDataCurrentPrivacyInvokedMode = DEF_CURRENT_PRIVACY_INVOKED_MODE;
  446. pTxData->saveTxDataCurrentPrivacyInvokedMode = DEF_CURRENT_PRIVACY_INVOKED_MODE;
  447. pTxData->txDataEapolEncryptionStatus = DEF_EAPOL_ENCRYPTION_STATUS;
  448. pTxData->saveTxDataEapolEncryptionStatus = DEF_EAPOL_ENCRYPTION_STATUS;
  449. pTxData->txDataIsSchedulerInWork = DEF_IS_SCHEDULER_IN_WORK;
  450. pTxData->txDataHalInterfaceStatus = DEF_HAL_INTERFACE_STATUS;
  451. /* Initialize the parameters related to GWSI and to Scheduler in Work */
  452. pTxData->txDataGwsiInterfaceStatus = GWSI_OPEN;
  453. pTxData->txDataIsSchedulerInWork = FALSE;
  454. pTxData->bCreditCalcTimerRunning = FALSE;
  455. /* encryption header size */
  456. pTxData->encryptionFieldSize = 0;
  457. pTxData->saveEncryptionFieldSize = 0;
  458. /* configure the packet ID buffer pool */
  459. bufferPool_config( pTxData->hBufferPool, hReport );
  460. /* configure the Tx queues (msdu lists) */
  461. /* num of elements is configured by qosMngr */
  462. for (qIndex = 0; qIndex < MAX_NUM_OF_TX_QUEUES; qIndex++)
  463. {
  464. if( (msduList_ConfigMsduList( pTxData->dataMsduListArr[qIndex], pTxData->hMemMngr,
  465. pTxData->hReport,pTxData->hOs,0 )) != OK )
  466. {
  467. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  468. ("Error configure DataMsduList num: %d\n",qIndex));
  469. }
  470. /*
  471. * Mark all queues available for TX
  472. */
  473. pTxData->txDataAvailableQueue[qIndex] = TRUE;
  474. }
  475. if( (msduList_ConfigMsduList( pTxData->mngMsduList, pTxData->hMemMngr,
  476. pTxData->hReport, pTxData->hOs,MANAGEMENT_QUEUE_SIZE )) != OK )
  477. {
  478. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  479. ("Error configure MgmtMsduList\n"));
  480. }
  481. /* reset counters */
  482. txData_resetCounters (pTxData);
  483. txData_resetDbgCounters (pTxData);
  484. WLAN_REPORT_INIT(pTxData->hReport, TX_DATA_MODULE_LOG,
  485. (".....Tx Data configured successfully\n"));
  486. #ifdef NO_COPY_NDIS_BUFFERS
  487. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  488. ("Driver configured to work in NO COPY MSDU BUFFERS."));
  489. #else
  490. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  491. ("Driver is configured to work in COPY MSDU BUFFERS."));
  492. #endif
  493. return OK;
  494. }
  495. /***************************************************************************
  496. * txData_unLoad *
  497. ****************************************************************************
  498. * DESCRIPTION: This function unload the tx data module. It first free the
  499. * MsduLists and then free the Tx data control block
  500. *
  501. * INPUTS: hTxData - the object
  502. *
  503. * OUTPUT:
  504. *
  505. * RETURNS: OK - Unload succesfull
  506. * NOK - Unload unsuccesfull
  507. ***************************************************************************/
  508. TI_STATUS txData_unLoad(TI_HANDLE hTxData)
  509. {
  510. txData_t *pTxData = (txData_t *)hTxData;
  511. TI_STATUS status = OK;
  512. int queueIndex;
  513. /* check parameters validity */
  514. if( pTxData == NULL )
  515. {
  516. return NOK;
  517. }
  518. /* free Data queue msdu list */
  519. for(queueIndex = 0;queueIndex < MAX_NUM_OF_TX_QUEUES; queueIndex++)
  520. {
  521. if (msduList_FreeMsduList( pTxData->dataMsduListArr[queueIndex]) != OK)
  522. {
  523. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  524. (" txData_unLoad() : fail to free Data MsduList number: %d\n",queueIndex));
  525. status = NOK;
  526. }
  527. }
  528. /* free Mgmt queue msdu list */
  529. if (msduList_FreeMsduList( pTxData->mngMsduList) != OK)
  530. {
  531. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  532. (" txData_unLoad() : fail to free Mgmt MsduList \n"));
  533. status = NOK;
  534. }
  535. DistributorMgr_Destroy(pTxData->TxEventDistributor);
  536. /* free Timer */
  537. utils_nullTimerDestroy(pTxData->hOs, pTxData->pSchedulerTimer);
  538. utils_nullTimerDestroy(pTxData->hOs, pTxData->pVadTimer);
  539. #ifdef TI_DBG
  540. utils_nullTimerDestroy(pTxData->hOs, pTxData->pThroughputTimer);
  541. utils_nullTimerDestroy(pTxData->hOs, pTxData->pAirThroughputTimer);
  542. utils_nullTimerDestroy(pTxData->hOs, pTxData->pJitterTimer);
  543. #endif
  544. utils_nullTimerDestroy(pTxData->hOs, pTxData->pCreditTimer);
  545. /* release the packet ID buffer pool */
  546. bufferPool_destroy( pTxData->hBufferPool );
  547. /* free Tx Data control block */
  548. os_memoryFree(pTxData->hOs, pTxData, sizeof(txData_t));
  549. return status;
  550. }
  551. /****************************************************************************
  552. * txData_stop *
  553. *****************************************************************************
  554. * DESCRIPTION: this function stop the tx data. It empties the tx queues (msdu
  555. * lists) from the msdu's and return all tx data parameters to
  556. * default values
  557. *
  558. * INPUTS: hTxData - the object
  559. *
  560. * OUTPUT:
  561. *
  562. * RETURNS: OK - stop successful
  563. * NOK - stop unsuccessful
  564. ****************************************************************************/
  565. TI_STATUS txData_stop(TI_HANDLE hTxData)
  566. {
  567. txData_t *pTxData = (txData_t *)hTxData;
  568. int queueIndex;
  569. pTxData->savePortStatus = pTxData->txDataPortStatus;
  570. /* stop scheduler timer trigger */
  571. if ( TRUE == pTxData->bSchedulerTimerRunning )
  572. {
  573. os_timerStop(pTxData->hOs, pTxData->pSchedulerTimer);
  574. }
  575. /* stop vad timer */
  576. if ( TRUE == pTxData->bVadTimerEnabled )
  577. {
  578. os_timerStop(pTxData->hOs, pTxData->pVadTimer);
  579. }
  580. /* stop throughput timer */
  581. if(pTxData->txThroughputTimerEnable == TRUE)
  582. {
  583. os_timerStop(pTxData->hOs, pTxData->pThroughputTimer);
  584. pTxData->txThroughputTimerEnable = FALSE;
  585. }
  586. /* stop throughput timer */
  587. if (pTxData->txAirThroughputTimerEnable)
  588. {
  589. os_timerStop (pTxData->hOs, pTxData->pAirThroughputTimer);
  590. pTxData->txAirThroughputTimerEnable = FALSE;
  591. }
  592. /* stop credit calculation timer */
  593. if ( pTxData->bCreditCalcTimerRunning )
  594. {
  595. os_timerStop(pTxData->hOs, pTxData->pCreditTimer);
  596. pTxData->bCreditCalcTimerRunning = FALSE;
  597. }
  598. /* empty Tx data queue from Msdus */
  599. for(queueIndex = 0;queueIndex < MAX_NUM_OF_TX_QUEUES; queueIndex++)
  600. {
  601. if( msduList_EmptyMsduList( pTxData->dataMsduListArr[queueIndex] ) != OK)
  602. {
  603. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  604. (" txData_stop() : fail to empty Data Msdu List number: %d\n",queueIndex));
  605. return NOK;
  606. }
  607. }
  608. /* empty Tx Mgmt queue from Msdus */
  609. if( msduList_EmptyMsduList( pTxData->mngMsduList ) != OK)
  610. {
  611. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  612. (" txData_stop() : fail to empty Mgmt Msdu List \n"));
  613. return NOK;
  614. }
  615. /* set Tx parameters to default values */
  616. pTxData->txDataPortStatus = DEF_TX_PORT_STATUS;
  617. pTxData->saveTxDataCurrentPrivacyInvokedMode = pTxData->txDataCurrentPrivacyInvokedMode;
  618. pTxData->saveTxDataEapolEncryptionStatus = pTxData->txDataEapolEncryptionStatus;
  619. pTxData->saveEncryptionFieldSize = pTxData->encryptionFieldSize;
  620. pTxData->txDataCurrentPrivacyInvokedMode = DEF_CURRENT_PRIVACY_INVOKED_MODE;
  621. pTxData->txDataEapolEncryptionStatus = DEF_EAPOL_ENCRYPTION_STATUS;
  622. pTxData->encryptionFieldSize = 0;
  623. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  624. (" txData_stop() : Succeeded.\n"));
  625. return OK;
  626. }
  627. /****************************************************************************
  628. * txData_start *
  629. *****************************************************************************
  630. * DESCRIPTION: this function start the tx data.
  631. *
  632. * INPUTS: hTxData - the object
  633. *
  634. * OUTPUT:
  635. *
  636. * RETURNS: OK - stop succesfull
  637. * NOK - stop unsuccesfull
  638. ****************************************************************************/
  639. TI_STATUS txData_start(TI_HANDLE hTxData)
  640. {
  641. txData_t *pTxData = (txData_t *)hTxData;
  642. /* check parameters validity */
  643. if( pTxData == NULL )
  644. {
  645. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  646. (" txData_start() : Illegal value for hTxData\n"));
  647. return NOK;
  648. }
  649. pTxData->txDataPortStatus = pTxData->savePortStatus;
  650. return OK;
  651. }
  652. /****************************************************************************
  653. * txData_recoveryIndication *
  654. *****************************************************************************
  655. * DESCRIPTION: this function clears information on recovery.
  656. *
  657. * INPUTS: hTxData - the object
  658. *
  659. * OUTPUT:
  660. *
  661. * RETURNS:
  662. ****************************************************************************/
  663. void txData_recoveryIndication (TI_HANDLE hTxData)
  664. {
  665. txData_t *pTxData = (txData_t *)hTxData;
  666. int queueIndex;
  667. /* Reinitializes packet ID buffer pool (mark all buffers as available) */
  668. bufferPool_reinit (pTxData->hBufferPool);
  669. /* Empty Tx data queue from Msdus */
  670. for (queueIndex = 0; queueIndex < MAX_NUM_OF_TX_QUEUES; queueIndex++)
  671. {
  672. if (msduList_EmptyMsduList (pTxData->dataMsduListArr[queueIndex]) != OK)
  673. {
  674. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  675. (" txData_stop() : fail to empty data MSDU list number: %d\n", queueIndex));
  676. }
  677. }
  678. /* Empty Tx management queue from MSDU's */
  679. if (msduList_EmptyMsduList (pTxData->mngMsduList) != OK)
  680. {
  681. WLAN_REPORT_ERROR (pTxData->hReport, TX_DATA_MODULE_LOG,
  682. (" txData_stop() : fail to empty management MSDU list\n"));
  683. }
  684. /*
  685. * Set GWSI interfaces status as 'opened'
  686. * because it can be undefined upon recovery
  687. */
  688. pTxData->txDataGwsiInterfaceStatus = GWSI_OPEN;
  689. for (queueIndex = 0; queueIndex < MAX_NUM_OF_TX_QUEUES; queueIndex++)
  690. {
  691. /*
  692. * Mark all queues available for TX
  693. */
  694. pTxData->txDataAvailableQueue[queueIndex] = TRUE;
  695. }
  696. }
  697. /***************************************************************************
  698. * txData_checkQueueSize *
  699. ****************************************************************************
  700. * DESCRIPTION: Check the Tx Queue size
  701. *
  702. * INPUTS: hTxData - the object
  703. *
  704. * OUTPUT:
  705. *
  706. * RETURNS: OK
  707. * NOK - The queue is full
  708. ***************************************************************************/
  709. TI_STATUS txData_checkQueueSize(TI_HANDLE hTxData,UINT8 qIndex)
  710. {
  711. txData_t *pTxData = (txData_t *)hTxData;
  712. TI_STATUS Status = OK;
  713. txData_startTxScheduler(pTxData);
  714. if (pTxData->dataMsduListArr[qIndex]->CurrNumOfMsdu == pTxData->dataMsduListArr[qIndex]->maxNumOfMsdu)
  715. Status = NOK;
  716. return Status;
  717. }
  718. /***************************************************************************
  719. * txData_copyPacketToMsdu *
  720. ****************************************************************************
  721. * DESCRIPTION:
  722. *
  723. * INPUTS: hTxData - the object
  724. *
  725. * OUTPUT:
  726. *
  727. * RETURNS: OK
  728. * NOK - The queue is full
  729. ***************************************************************************/
  730. TI_STATUS txData_copyPacketToMsdu(TI_HANDLE hTxData,mem_MSDU_T **pMsdu, int FreeOldMsdu)
  731. {
  732. #ifdef NO_COPY_NDIS_BUFFERS
  733. txData_t *pTxData = (txData_t *)hTxData;
  734. TI_STATUS Status = OK;
  735. mem_BD_T *pCurrBd;
  736. mem_MSDU_T *tempMsdu;
  737. UINT8 *pMsduData;
  738. UINT8 *pCurrBufData;
  739. dot11_header_t *pdot11Header;
  740. /*
  741. * Allocate MSDU+BD+BUFFER+TX_DESCRIPTOR_SIZE to copy to !!
  742. */
  743. if(wlan_memMngrAllocMSDU(pTxData->hMemMngr,&tempMsdu,(*pMsdu)->dataLen+TX_TOTAL_OFFSET_BEFORE_DATA,TX_MODULE) != OK)
  744. {
  745. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  746. (" txData_copyPacketToMsdu() : No Memory in MemMgr \n"));
  747. return NOK;
  748. }
  749. tempMsdu->dataLen = 0;
  750. tempMsdu->firstBDPtr->length = 0;
  751. tempMsdu->txFlags = (*pMsdu)->txFlags;
  752. pCurrBd = (*pMsdu)->firstBDPtr;
  753. pMsduData = tempMsdu->firstBDPtr->data + TX_TOTAL_OFFSET_BEFORE_DATA;
  754. while(pCurrBd)
  755. {
  756. pCurrBufData = pCurrBd->data + pCurrBd->dataOffset;
  757. /* Copy the packet */
  758. os_memoryCopy(pTxData->hOs, pMsduData, pCurrBufData, pCurrBd->length);
  759. tempMsdu->dataLen += pCurrBd->length - TNETWIF_WRITE_OFFSET_BYTES;
  760. tempMsdu->firstBDPtr->length += pCurrBd->length;
  761. pMsduData += pCurrBd->length;
  762. pCurrBd = pCurrBd->nextBDPtr;
  763. }
  764. tempMsdu->headerLen = (*pMsdu)->headerLen;
  765. txData_convertEthToWlanHeader( pTxData, tempMsdu );
  766. /* set wep bit if needed */
  767. if((tempMsdu->txFlags & TX_DATA_DATA_MSDU) && (pTxData->txDataCurrentPrivacyInvokedMode))
  768. {
  769. pdot11Header = (dot11_header_t*)(memMgr_BufData(pMsdu->firstBDPtr) + memMgr_BufOffset(pMsdu->firstBDPtr));
  770. pdot11Header->fc |= DOT11_FC_WEP;
  771. }
  772. else if ((tempMsdu->txFlags & TX_DATA_EAPOL_MSDU ) && (pTxData->txDataEapolEncryptionStatus))
  773. {
  774. pdot11Header = (dot11_header_t*)(memMgr_BufData(pMsdu->firstBDPtr) + memMgr_BufOffset(pMsdu->firstBDPtr));
  775. pdot11Header->fc |= DOT11_FC_WEP;
  776. }
  777. if (FreeOldMsdu)
  778. wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle((*pMsdu)));
  779. (*pMsdu) = tempMsdu;
  780. #endif
  781. return OK;
  782. }
  783. /***************************************************************************
  784. * txData_sendPktToWlan *
  785. ****************************************************************************
  786. * DESCRIPTION: This function is called by the Os Abstraction Layer in order
  787. * to send packet to the wireless LAN. It calls the header
  788. * conversion function and passes the to sendMsdu function.
  789. *
  790. * INPUTS: hTxData - the object
  791. * pMsdu - pointer the packet in 802.3 format
  792. *
  793. * OUTPUT:
  794. *
  795. * RETURNS: OK
  796. * NOK
  797. ***************************************************************************/
  798. TI_STATUS txData_sendPktToWlan(TI_HANDLE hTxData, mem_MSDU_T *pMsdu, UINT8 pkt_DTag)
  799. {
  800. EthernetHeader_t *pEthHeader;
  801. UINT16 TypeLength;
  802. TI_STATUS Status;
  803. mem_BD_T* tempBd;
  804. BOOL UseConvertHeader = TRUE;
  805. txData_t *pTxData = (txData_t *)hTxData;
  806. /* check parameters validity */
  807. if( pTxData == NULL || pMsdu == NULL )
  808. {
  809. return NOK;
  810. }
  811. pEthHeader = (EthernetHeader_t*)(memMgr_BufData(pMsdu->firstBDPtr)+memMgr_BufOffset(pMsdu->firstBDPtr));
  812. /* check if the frame is multicast/broadcast - need for the transmission rate */
  813. if(IsMacAddressGroup( &pEthHeader->DstAddr ))
  814. pMsdu->txFlags |= TX_DATA_MULTICAST_FRAME;
  815. TypeLength = pEthHeader->TypeLength;
  816. /* Call the Classify function in the Control Module to set the qosTag of the MSDU */
  817. if (ctrlData_ClsfrClassifyTxMSDU(pTxData->hCtrlData, pMsdu, pkt_DTag) != OK)
  818. {
  819. WLAN_REPORT_DEBUG_TX(pTxData->hReport,
  820. (" txData_sendPktToWlan(): No matching classifier found\n"));
  821. }
  822. /* filter MSDU according to Tx Port Status and the Eth Type */
  823. if ( pTxData->txDataPortStatus != OPEN )
  824. {
  825. int queueIndex;
  826. int acIndex;
  827. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  828. (" txData_sendPktToWlan() : try to transmit Msdu while port is not open (txDataPortStatus = 0x%x)\n", pTxData->txDataPortStatus));
  829. /* Find AC and Tx-queue in order to update the correct Queue measurements */
  830. acIndex = GET_WME_AC_TYPE_FROM_MSDU(pMsdu);
  831. queueIndex = GET_QUEUE_INDEX(pTxData,acIndex);
  832. /* updating the measurements - dropped packet counter */
  833. pTxData->txDataReportedCounters[queueIndex].OtherFailCounter++;
  834. pTxData->txDataReportedCounters[queueIndex].NumPackets++;
  835. if((pTxData->txDataPortStatus == CLOSE) || (pTxData->txDataPortStatus == OPEN_NOTIFY) )
  836. {
  837. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  838. (" txData_sendPktToWlan() : try to transmit Msdu while port is not open (txDataPortStatus = 0x%x)\n", pTxData->txDataPortStatus));
  839. /* In case the function return status is NOK, no need to call Os free function */
  840. /* Set freefunc in the msdu to null. In this case the MemMngr will not call */
  841. /* the Os free function */
  842. memMgr_MsduFreeFuncGet(pMsdu) = NULL;
  843. /* free MSDU */
  844. if( (wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle(pMsdu))) != OK )
  845. {
  846. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  847. (" txData_sendPktToWlan() : free msdu failed \n"));
  848. }
  849. return NOK;
  850. }
  851. /* filter Data frames while port is open only for Eapol's */
  852. if( (pTxData->txDataPortStatus == OPEN_EAPOL) && (TypeLength != EAPOL_PACKET) )
  853. {
  854. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  855. (" txData_sendPktToWlan() : try to transmit Non Eapol packet while port is open for eapols only\n"));
  856. /* In case the function return status is NOK, no need to call Os free function. */
  857. /* Set freefunc in the msdu to null. In this case the MemMngr will not call */
  858. /* the Os free function - because the return staus to the Os is NOK the buffer */
  859. /* free by the Os */
  860. memMgr_MsduFreeFuncGet(pMsdu) = NULL;
  861. /* frre MSDU */
  862. if ((wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle(pMsdu))) != OK)
  863. {
  864. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  865. (" txData_sendPktToWlan() : free msdu failed \n"));
  866. }
  867. return NOK;
  868. }
  869. }
  870. /* PORT IS OPEN */
  871. #ifdef CORE_TX_DBG
  872. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  873. (" txData_sendPktToWlan: port is open \n"));
  874. #endif
  875. if( TypeLength != EAPOL_PACKET )
  876. {
  877. pMsdu->txFlags |= TX_DATA_DATA_MSDU;
  878. }
  879. else
  880. {
  881. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  882. (" txData_sendPktToWlan() : Tx an EAPOL frame tranferred to HAL\n"));
  883. /* because EAPOL is sent from Mgmt queue */
  884. pMsdu->txFlags |= TX_DATA_EAPOL_MSDU;
  885. }
  886. UseConvertHeader = TRUE; /* a patch for WinCe */
  887. #ifdef NO_COPY_NDIS_BUFFERS
  888. if (pMsdu->txFlags & TX_DATA_FROM_OS)
  889. UseConvertHeader = FALSE; /* don't convert on external (OS) packets */
  890. #endif
  891. if (UseConvertHeader == TRUE)
  892. {
  893. /* Header conversion from Ethernet to 802.11 */
  894. txData_convertEthToWlanHeader( pTxData, pMsdu );
  895. }
  896. /* update last BD */
  897. tempBd = pMsdu->firstBDPtr;
  898. while(tempBd->nextBDPtr)
  899. {
  900. tempBd = tempBd->nextBDPtr;
  901. }
  902. pMsdu->lastBDPtr = tempBd;
  903. Status = txData_txSendMsdu( pTxData, pMsdu );
  904. if( Status == NOK )
  905. {
  906. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  907. (" txData_sendPktToWlan() : txData_txSendMsdu failed \n"));
  908. }
  909. if ((OK == Status) && (GET_WME_AC_TYPE_FROM_MSDU(pMsdu) == QOS_AC_VO))
  910. {
  911. txData_resetVadTimer(pTxData);
  912. }
  913. return Status;
  914. }
  915. /***************************************************************************
  916. * txData_txSendMsdu *
  917. ****************************************************************************
  918. * DESCRIPTION: This function is insert the MSDU to transmit to the proper
  919. * tx queue and give a trigger to the scheduler to start
  920. * transmission to the wireless LAN.
  921. *
  922. * INPUTS: hTxData - the object
  923. * pMsdu - pointer the MSDU in 802.11 format
  924. *
  925. * OUTPUT:
  926. *
  927. * RETURNS: OK
  928. * NOK
  929. ***************************************************************************/
  930. TI_STATUS txData_txSendMsdu(TI_HANDLE hTxData, mem_MSDU_T *pMsdu )
  931. {
  932. dot11_header_t *pdot11Header;
  933. TI_STATUS Status = OK;
  934. int queueIndex;
  935. acTrfcType_e acIndex;
  936. txData_t *pTxData = (txData_t *)hTxData;
  937. /* ctrlData_txMsdu(pTxData->hCtrlData,&pMsdu); 4x related */
  938. if(pMsdu == NULL)
  939. {
  940. WLAN_REPORT_INFORMATION(pTxData->hReport, TX_DATA_MODULE_LOG,
  941. (" txData_txSendMsdu() : DISCARD Packet...... \n"));
  942. txData_startTxScheduler(pTxData);
  943. return NOK;
  944. }
  945. #ifndef NO_COPY_NDIS_BUFFERS /* buffers are copied by OAL*/
  946. /* set wep bit if needed */
  947. if((pMsdu->txFlags & TX_DATA_DATA_MSDU) && (pTxData->txDataCurrentPrivacyInvokedMode))
  948. {
  949. /* update offset of header */
  950. pdot11Header = (dot11_header_t*)(memMgr_BufData(pMsdu->firstBDPtr) + memMgr_BufOffset(pMsdu->firstBDPtr));
  951. pdot11Header->fc |= DOT11_FC_WEP;
  952. }
  953. else if ((pMsdu->txFlags & TX_DATA_EAPOL_MSDU ) && (pTxData->txDataEapolEncryptionStatus))
  954. {
  955. /* update offset of header */
  956. pdot11Header = (dot11_header_t*)(memMgr_BufData(pMsdu->firstBDPtr) + memMgr_BufOffset(pMsdu->firstBDPtr));
  957. pdot11Header->fc |= DOT11_FC_WEP;
  958. }
  959. #endif /*NO_COPY_NDIS_BUFFERS*/
  960. #ifdef EXC_MODULE_INCLUDED
  961. if ((pMsdu->txFlags & TX_DATA_IAPP_MSDU) && (pTxData->txDataCurrentPrivacyInvokedMode))
  962. {
  963. /* update offset of header */
  964. pdot11Header = (dot11_header_t*)(memMgr_BufData(pMsdu->firstBDPtr) + memMgr_BufOffset(pMsdu->firstBDPtr));
  965. pdot11Header->fc |= DOT11_FC_WEP;
  966. }
  967. #endif
  968. WLAN_REPORT_DEBUG_TX(pTxData->hReport,
  969. (" txData_txSendMsdu() : Sending PAcket pMsdu %x pMsdu->txFlags %x \n",pMsdu,pMsdu->txFlags));
  970. /* insert the msdu to the the appropriate queue */
  971. if( (pMsdu->txFlags & TX_DATA_DATA_MSDU) || (pMsdu->txFlags & TX_DATA_NULL_MSDU) )
  972. {
  973. /* Find Tx-queue and AC to use for Tx, and if downgraded from original one update the UP. */
  974. txData_selectQueueAndUpdateUserPriority (pTxData, pMsdu, &queueIndex, &acIndex);
  975. /* set insertion time for further expiry timeout calculation */
  976. pMsdu->insertionTime = os_timeStampUs (pTxData->hOs);
  977. /* see if the frame is tagged VO. */
  978. /* Note: Check actual tag even if current not working in WME, to support voice anyway. */
  979. if( GET_WME_AC_TYPE_FROM_MSDU(pMsdu) == QOS_AC_VO)
  980. {
  981. /*
  982. * If the frame is tagged VO and power save is on, send psPoll before the VO frame.
  983. */
  984. if(txData_acVoPsPollMode(pTxData) == TRUE)
  985. {
  986. mem_MSDU_T *pMsduPsPoll;
  987. if(txData_getPsPollFrame(pTxData,&pMsduPsPoll) == OK)
  988. {
  989. /* increment debug counters */
  990. pTxData->txDataDbgCounters.dbgInsertToMsduListBytes[queueIndex] += pMsduPsPoll->dataLen;
  991. pTxData->txDataDbgCounters.dbgInsertToMsduListPackets[queueIndex]++;
  992. /* set insertion time for further expiry timeout calculation */
  993. pMsduPsPoll->insertionTime = os_timeStampUs (pTxData->hOs);
  994. /* insert to queueIndex queue */
  995. if( msduList_Insert( pTxData->dataMsduListArr[queueIndex] , &pMsduPsPoll ) != OK )
  996. {
  997. pTxData->txDataDbgCounters.dbgDropedFromMsduListPackets[queueIndex]++;
  998. /* the first msdu in list has removed and the new one has inserted */
  999. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  1000. (" txData_sendPktToWlan() : Msdu List num %d was full \n",queueIndex));
  1001. /* free the msdu which removed from the list (returned in pMsdu) */
  1002. /*---------------------------------------------------------------*/
  1003. /* set msdu tx status to Fail (this status is used by OS) */
  1004. memMgr_MsduFreeArg2Get(pMsduPsPoll) = NOK;
  1005. /* free the msdu */
  1006. wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle(pMsduPsPoll));
  1007. pTxData->txDataDbgCounters.dbgDropedPacketsCounter++;
  1008. }/*msduList_Insert*/
  1009. }/*txData_getPsPollFrame*/
  1010. }/*txData_acVoPsPollMode*/
  1011. }
  1012. /* insert to data queue */
  1013. /* if we didn't succeed to insert psPolls exclude VO packet also */
  1014. if( msduList_Insert( pTxData->dataMsduListArr[queueIndex] , &pMsdu ) != OK )
  1015. {
  1016. pTxData->txDataDbgCounters.dbgDropedFromMsduListPackets[queueIndex]++;
  1017. /* the first msdu in list has removed and the new one has inserted */
  1018. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  1019. (" txData_txSendMsdu() : Data Msdu [%d] List was full \n",queueIndex));
  1020. /* free the msdu which removed from the list (returned in pMsdu) */
  1021. /*---------------------------------------------------------------*/
  1022. /* set msdu tx status to Fail (this status is used by OS) */
  1023. memMgr_MsduFreeArg2Get(pMsdu) = NOK;
  1024. /* free the msdu */
  1025. wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle(pMsdu));
  1026. pTxData->txDataDbgCounters.dbgDropedPacketsCounter++;
  1027. pTxData->txDataReportedCounters[queueIndex].NumPackets++;
  1028. pTxData->txDataReportedCounters[queueIndex].OtherFailCounter++;
  1029. return OK;
  1030. }
  1031. /* increament debug counters */
  1032. pTxData->txDataDbgCounters.dbgInsertToMsduListBytes[queueIndex] += pMsdu->dataLen;
  1033. pTxData->txDataDbgCounters.dbgInsertToMsduListPackets[queueIndex]++;
  1034. WLAN_REPORT_DEBUG_TX(pTxData->hReport,
  1035. (" txData_txSendMsdu() : insert data packet to queue # %d \n",queueIndex));
  1036. }
  1037. else
  1038. {
  1039. /* Management frame, Eapol and null frame (for measuring a non serving channel)
  1040. are also sent from the mgmt queue */
  1041. /* set insertion time for further expiry timeout calculation */
  1042. pMsdu->insertionTime = os_timeStampUs (pTxData->hOs);
  1043. WLAN_REPORT_DEBUG_TX(pTxData->hReport,
  1044. (" txData_txSendMsdu() : insert mngt packet to Management queue pMsdu %x \n",pMsdu));
  1045. if( msduList_Insert( pTxData->mngMsduList , &pMsdu ) != OK )
  1046. {
  1047. /* the first msdu in list has removed and the new one has inserted */
  1048. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  1049. (" txData_txSendMsdu() : Mgmt Msdu List was full \n"));
  1050. /* free the msdu which removed from the list (returned in pMsdu) */
  1051. /*---------------------------------------------------------------*/
  1052. /* set msdu tx status to Fail (this status is used by OS) */
  1053. memMgr_MsduFreeArg2Get(pMsdu) = NOK;
  1054. /* free the msdu */
  1055. wlan_memMngrFreeMSDU(pTxData->hMemMngr, memMgr_MsduHandle(pMsdu));
  1056. pTxData->txDataDbgCounters.dbgDropedPacketsCounter++;
  1057. }
  1058. }
  1059. {
  1060. /* call the scheduler in order to transmit the frame to the Hal */
  1061. Status = txData_startTxScheduler(pTxData);
  1062. if ( Status == NOK )
  1063. {
  1064. WLAN_REPORT_ERROR(pTxData->hReport, TX_DATA_MODULE_LOG,
  1065. (" txData_txSendMsdu() : txData_startTxScheduler error \n"));
  1066. }
  1067. }
  1068. /* this is the status of the current Msdu */
  1069. return OK;
  1070. }
  1071. /***************************************************************************
  1072. * txData_startTxScheduler *
  1073. ****************************************************************************
  1074. * DESCRIPTION: This function start the transmission process.
  1075. * It select msdu to transmit from the tx queues and send
  1076. * it to the Hal
  1077. *
  1078. * INPUTS: hTxData - the object
  1079. *
  1080. * OUTPUT:
  1081. *
  1082. * RETURNS: OK
  1083. * NOK
  1084. ***************************************************************************/
  1085. TI_STATUS txData_startTxScheduler(TI_HANDLE hTxData)
  1086. {
  1087. txData_t *pTxData = (txData_t *)hTxData;
  1088. mem_MSDU_T *pMsdu;
  1089. MsduList_t *pMsduList = NULL;
  1090. txData_attr_t txAttr;
  1091. UINT8 count, selectedQueueIndex;
  1092. TI_STATUS txStatus;
  1093. txPacketIdAttr_t *pPacketId;
  1094. dot11_header_t *pDot11Header;
  1095. bssType_e currBssType;
  1096. macAddress_t currBssId;
  1097. UINT32 msduTimeToExpiry;
  1098. #ifdef SUPPORT_4X
  1099. hwTxInformation_t hwTxInformation;
  1100. BOOL fourXEnable;
  1101. #endif
  1102. /* check if HAL is open now - used for recovery only!!! */
  1103. if ( pTxData->txDataHalInterfaceStatus == TX_DATA_CLOSED )
  1104. {
  1105. return OK; /* TODO ronen: doesn't seem to be used any more, remove */
  1106. }
  1107. /* Checking if Tx is now disabled */
  1108. if(pTxData->txDisable == DISABLE_IMMEDIATELY)
  1109. {
  1110. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  1111. (" txData_startTxScheduler() : Tx Disabled!!! \n"));
  1112. /* start scheduler timer */
  1113. if ( FALSE == pTxData->bSchedulerTimerRunning )
  1114. {
  1115. os_timerStart( pTxData->hOs, pTxData->pSchedulerTimer, SCHEDULER_TIMER, FALSE );
  1116. pTxData->bSchedulerTimerRunning = TRUE;
  1117. }
  1118. pTxData->txDataIsSchedulerInWork = FALSE;
  1119. return OK;
  1120. }
  1121. /*
  1122. * in case of non serialized system no need to
  1123. * run the scheduler if it is already in work
  1124. */
  1125. if(pTxData->txDataIsSchedulerInWork == TRUE)
  1126. {
  1127. WLAN_REPORT_WARNING(pTxData->hReport, TX_DATA_MODULE_LOG,
  1128. (" txData_startTxScheduler() : Scheduler already in work...........!!!! \n"));
  1129. return OK;
  1130. }
  1131. else
  1132. {
  1133. pTxData->txDataIsSch

Large files files are truncated, but you can click here to view the full file