summaryrefslogtreecommitdiff
path: root/network/wlan/WDI/COMMON/TSGen.c
diff options
context:
space:
mode:
Diffstat (limited to 'network/wlan/WDI/COMMON/TSGen.c')
-rw-r--r--network/wlan/WDI/COMMON/TSGen.c735
1 files changed, 735 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/TSGen.c b/network/wlan/WDI/COMMON/TSGen.c
new file mode 100644
index 00000000..36543f4b
--- /dev/null
+++ b/network/wlan/WDI/COMMON/TSGen.c
@@ -0,0 +1,735 @@
+#include "Mp_Precomp.h"
+
+#if WPP_SOFTWARE_TRACE
+#include "TSGen.tmh"
+#endif
+
+VOID
+TsAddBaProcess(
+ PRT_TIMER pTimer
+ )
+{
+ PADAPTER Adapter = (PADAPTER)pTimer->Adapter;
+ PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTimer->Context;
+
+ TsInitAddBA(Adapter, pTxTs, BA_POLICY_IMMEDIATE, FALSE);
+ RT_TRACE(COMP_QOS, DBG_LOUD, ("TsAddBaProcess(): ADDBA Req is started!! \n"));
+}
+
+
+VOID
+ResetTsCommonInfo(
+ PTS_COMMON_INFO pTsCommonInfo
+ )
+{
+ PlatformZeroMemory(pTsCommonInfo->Addr, 6);
+ PlatformZeroMemory(&pTsCommonInfo->TSpec, WMM_TSPEC_BODY_LENGTH);
+ PlatformZeroMemory(&pTsCommonInfo->TClass, sizeof(QOS_TCLAS)*TCLAS_NUM);
+ pTsCommonInfo->TClasProc = 0;
+ pTsCommonInfo->TClasNum = 0;
+}
+
+VOID
+ResetTxTsEntry(
+ PTX_TS_RECORD pTS
+ )
+{
+ ResetTsCommonInfo(&pTS->TsCommonInfo);
+ pTS->TxCurSeq = 0;
+ pTS->bAddBaReqInProgress = FALSE;
+ pTS->bAddBaReqDelayed = FALSE;
+ pTS->bUsingBa = FALSE;
+ ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
+ ResetBaEntry(&pTS->TxPendingBARecord);
+}
+
+VOID
+ResetRxTsEntry(
+ PRX_TS_RECORD pTS
+ )
+{
+ ResetTsCommonInfo(&pTS->TsCommonInfo);
+ pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
+ pTS->RxIndicateState = 0; // Reset indicate state!!
+ ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recepient
+
+ //Init it for avoid drop first packet.
+ pTS->RxLastFragNum = 0xff;
+ pTS->RxLastSeqNum = 0xffff;
+}
+
+VOID
+TSInitialize(
+ PADAPTER Adapter
+ )
+{
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+ PTX_TS_RECORD pTxTS = pMgntInfo->TxTsRecord;
+ PRX_TS_RECORD pRxTS = pMgntInfo->RxTsRecord;
+ PRX_REORDER_ENTRY pRxReorderEntry = pMgntInfo->RxReorderEntry;
+ u2Byte count = 0;
+
+ RT_TRACE(COMP_QOS, DBG_LOUD, ("===>TSInitialize()\r\n"));
+
+ // Initialize Tx TS related info.
+ RTInitializeListHead(&pMgntInfo->Tx_TS_Admit_List);
+ RTInitializeListHead(&pMgntInfo->Tx_TS_Pending_List);
+ RTInitializeListHead(&pMgntInfo->Tx_TS_Unused_List);
+ for(count = 0; count < TOTAL_TS_NUM; count++)
+ {
+ //
+ // The timers for the operation of Traffic Stream and Block Ack.
+ // DLS related timer will be add here in the future!!
+ //
+ PlatformInitializeTimer(
+ Adapter,
+ &pTxTS->TsAddBaTimer,
+ (RT_TIMER_CALL_BACK)TsAddBaProcess,
+ (PVOID)pTxTS,
+ "TxTsAddBaTimer" );
+
+ PlatformInitializeTimer(
+ Adapter,
+ &pTxTS->TxPendingBARecord.Timer,
+ (RT_TIMER_CALL_BACK)BaSetupTimeOut,
+ (PVOID)pTxTS,
+ "TxPendingBARecordTimer");
+
+ PlatformInitializeTimer(
+ Adapter,
+ &pTxTS->TxAdmittedBARecord.Timer,
+ (RT_TIMER_CALL_BACK)TxBaInactTimeout,
+ (PVOID) pTxTS,
+ "TxAdmittedBARecordTimer" );
+
+ ResetTxTsEntry(pTxTS);
+ RTInsertTailList(&pMgntInfo->Tx_TS_Unused_List, &pTxTS->TsCommonInfo.List);
+ pTxTS++;
+ }
+
+ // Initialize Rx TS related info.
+ RTInitializeListHead(&pMgntInfo->Rx_TS_Admit_List);
+ RTInitializeListHead(&pMgntInfo->Rx_TS_Pending_List);
+ RTInitializeListHead(&pMgntInfo->Rx_TS_Unused_List);
+ for(count = 0; count < TOTAL_TS_NUM; count++)
+ {
+ RTInitializeListHead(&pRxTS->RxPendingPktList);
+
+ PlatformInitializeTimer(
+ Adapter,
+ &pRxTS->RxAdmittedBARecord.Timer,
+ (RT_TIMER_CALL_BACK)RxBaInactTimeout,
+ (PVOID)pRxTS,
+ "RxAdmittedBARecordTimer");
+
+ PlatformInitializeTimer(
+ Adapter,
+ &pRxTS->RxPktPendingTimer,
+ (RT_TIMER_CALL_BACK)RxPktPendingTimeout,
+ (PVOID)pRxTS,
+ "RxPktPendingTimer");
+
+ ResetRxTsEntry(pRxTS);
+ RTInsertTailList(&pMgntInfo->Rx_TS_Unused_List, &pRxTS->TsCommonInfo.List);
+ pRxTS++;
+ }
+
+ // Initialize unused Rx Reorder List.
+ RTInitializeListHead(&pMgntInfo->RxReorder_Unused_List);
+ for(count = 0; count < REORDER_ENTRY_NUM; count++)
+ {
+ RTInsertTailList(&pMgntInfo->RxReorder_Unused_List, &pRxReorderEntry->List);
+ pRxReorderEntry++;
+ }
+}
+
+VOID
+AdmitTS(
+ PADAPTER Adapter,
+ PTS_COMMON_INFO pTsCommonInfo,
+ u4Byte InactTime
+ )
+{
+}
+
+VOID
+ExtendRxTS(
+ PADAPTER Adapter,
+ PRX_TS_RECORD pRxTS
+ )
+{
+ // TS part needs to be implemented in the future.
+}
+
+PRT_LIST_ENTRY
+SearchTSList(
+ PRT_LIST_ENTRY pTSList,
+ pu1Byte Addr,
+ u1Byte TID,
+ DIRECTION_VALUE Dir
+ )
+{
+ BOOLEAN bIsFound = FALSE;
+ PTS_COMMON_INFO pTS_Record = (PTS_COMMON_INFO) RTGetHeadList(pTSList);
+
+ while(&pTS_Record->List != pTSList)
+ {
+ if( PlatformCompareMemory(pTS_Record->Addr, Addr, 6) == 0 )
+ {
+ if(GET_TSPEC_BODY_TSINFO_TSID(pTS_Record->TSpec) == TID)
+ {
+ if(GET_TSPEC_BODY_TSINFO_DIRECTION(pTS_Record->TSpec) == Dir)
+ {
+ bIsFound = TRUE;
+ break;
+ }
+ }
+ }
+ pTS_Record = (PTS_COMMON_INFO)RTNextEntryList(&pTS_Record->List);
+ }
+
+ if(bIsFound)
+ return &pTS_Record->List;
+ else
+ return NULL;
+}
+
+
+PTS_COMMON_INFO
+SearchAdmitTRStream(
+ PMGNT_INFO pMgntInfo,
+ pu1Byte Addr,
+ u1Byte TID,
+ TR_SELECT TxRxSelect //Tx:0, Rx:1
+)
+{
+ //DIRECTION_VALUE dir;
+ u1Byte dir;
+ BOOLEAN search_dir[4] = {0, 0, 0, 0};
+ PRT_LIST_ENTRY psearch_list = NULL;
+ PTS_COMMON_INFO pRet=NULL;
+
+ if(pMgntInfo->ApType > 0)
+ {
+ if(TxRxSelect == TX_DIR)
+ {
+ search_dir[DIR_DOWN] = TRUE;
+ search_dir[DIR_BI_DIR]= TRUE;
+ }
+ else
+ {
+ search_dir[DIR_UP] = TRUE;
+ search_dir[DIR_BI_DIR]= TRUE;
+ }
+ }
+ else if(pMgntInfo->mIbss)
+ {
+ if(TxRxSelect == TX_DIR)
+ search_dir[DIR_UP] = TRUE;
+ else
+ search_dir[DIR_DOWN] = TRUE;
+ }
+ else
+ {
+ if(TxRxSelect == TX_DIR)
+ {
+ search_dir[DIR_UP] = TRUE;
+ search_dir[DIR_BI_DIR]= TRUE;
+ search_dir[DIR_DIRECT]= TRUE;
+ }
+ else
+ {
+ search_dir[DIR_DOWN] = TRUE;
+ search_dir[DIR_BI_DIR]= TRUE;
+ search_dir[DIR_DIRECT]= TRUE;
+ }
+ }
+
+ if(TxRxSelect == TX_DIR)
+ psearch_list = &pMgntInfo->Tx_TS_Admit_List;
+ else
+ psearch_list = &pMgntInfo->Rx_TS_Admit_List;
+
+ //for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
+ for(dir = 0; dir <= DIR_BI_DIR; dir++)
+ {
+ if(search_dir[dir] ==FALSE )
+ continue;
+
+ pRet = (PTS_COMMON_INFO)SearchTSList(psearch_list, Addr, TID, (DIRECTION_VALUE)dir);
+
+ if(pRet != NULL)
+ break;
+ }
+
+ if(pRet != NULL)
+ return pRet ;
+ else
+ return NULL;
+}
+
+VOID
+MakeTSEntry(
+ OUT PTS_COMMON_INFO pTsCommonInfo,
+ IN pu1Byte Addr,
+ IN pu1Byte pTSPEC,
+ IN PQOS_TCLAS pTCLAS,
+ IN u1Byte TCLAS_Num,
+ IN u1Byte TCLAS_Proc
+ )
+{
+ u1Byte count;
+
+ if(pTsCommonInfo == NULL)
+ return;
+
+ PlatformMoveMemory(pTsCommonInfo->Addr, Addr, 6);
+
+ if(pTSPEC != NULL)
+ PlatformMoveMemory((pu1Byte)(&(pTsCommonInfo->TSpec)), (pu1Byte)pTSPEC, WMM_TSPEC_BODY_LENGTH);
+
+ for(count = 0; count < TCLAS_Num; count++)
+ PlatformMoveMemory((pu1Byte)(&(pTsCommonInfo->TClass[count])), (pu1Byte)pTCLAS, sizeof(QOS_TCLAS));
+
+ pTsCommonInfo->TClasProc = TCLAS_Proc;
+ pTsCommonInfo->TClasNum = TCLAS_Num;
+}
+
+
+BOOLEAN
+GetTs(
+ PADAPTER Adapter,
+ PTS_COMMON_INFO *ppTS,
+ pu1Byte Addr,
+ u1Byte TID,
+ TR_SELECT TxRxSelect, //Rx:1, Tx:0
+ BOOLEAN bAddNewTs
+ )
+{
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+ u1Byte UP=0;
+
+ //
+ // We do not build any TS for Broadcast or Multicast stream.
+ // So reject these kinds of search here.
+ //
+ if(MacAddr_isBcst(Addr) || MacAddr_isMulticast(Addr))
+ {
+ RT_TRACE(COMP_QOS, DBG_LOUD, ("Broad or multicast return\r\n"));
+ return FALSE;
+ }
+
+ if(pMgntInfo->pStaQos->CurrentQosMode == QOS_DISABLE)
+ {//only use one TS
+ UP = 0;
+ }
+ else if(pMgntInfo->pStaQos->CurrentQosMode & QOS_WMM)
+ {
+ // In WMM case: we use 4 TID only
+
+ //
+ // <Roger_Notes> We use 7 TIDs to fit differentiated service from IP layer
+ // to meet different implementation of APs.
+ // 2008.12.18.
+ //
+ UP = TID;
+ }
+
+ *ppTS = SearchAdmitTRStream(
+ pMgntInfo,
+ Addr,
+ UP,
+ TxRxSelect);
+
+ if(*ppTS != NULL)
+ {
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("SearchAdmitTRStream get ppTS\r\n"));
+ return TRUE;
+ }
+ else
+ {
+ if(bAddNewTs == FALSE)
+ {
+ RT_TRACE(COMP_QOS, DBG_LOUD, ("bAddNewTs == FALSE\r\n"));
+ return FALSE;
+ }
+ else
+ {
+ //
+ // Create a new Traffic stream for current Tx/Rx
+ // This is for EDCA and WMM to add a new TS.
+ // For HCCA or WMMSA, TS cannot be addmit without negotiation.
+ //
+ u1Byte TSpec[WMM_TSPEC_BODY_LENGTH]={0};
+
+ pu1Byte pTSInfo= TSpec;
+ PRT_LIST_ENTRY pUnusedList =
+ (TxRxSelect == TX_DIR)?
+ (&pMgntInfo->Tx_TS_Unused_List):
+ (&pMgntInfo->Rx_TS_Unused_List);
+
+ PRT_LIST_ENTRY pAddmitList =
+ (TxRxSelect == TX_DIR)?
+ (&pMgntInfo->Tx_TS_Admit_List):
+ (&pMgntInfo->Rx_TS_Admit_List);
+
+ DIRECTION_VALUE Dir =
+ (ACTING_AS_AP(Adapter))?
+ ((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
+ ((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("GetTs(): Add New TS %s Entry.\n", TxRxSelect?"Rx":"Tx"));
+ RT_PRINT_ADDR(COMP_QOS, DBG_TRACE, "PeerAddress:", Addr);
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("UserPriority: %d\n", UP));
+ if(!RTIsListEmpty(pUnusedList))
+ {
+ (*ppTS) = (PTS_COMMON_INFO)RTRemoveHeadList(pUnusedList);
+
+ if(TxRxSelect==TX_DIR)
+ ResetTxTsEntry((PTX_TS_RECORD) *ppTS);
+ else
+ ResetRxTsEntry((PRX_TS_RECORD) *ppTS);
+
+ // Prepare TS Info releated field
+ SET_TSPEC_BODY_TSINFO_TRAFFIC_TYPE(pTSInfo, 0); // Traffic type: WMM is reserved in this field
+ SET_TSPEC_BODY_TSINFO_TSID(pTSInfo, UP); // TSID
+ SET_TSPEC_BODY_TSINFO_DIRECTION(pTSInfo, Dir); // Direction: if there is DirectLink, this need additional consideration.
+ SET_TSPEC_BODY_TSINFO_ACCESS_POLICY(pTSInfo, 1); // Access policy
+ SET_TSPEC_BODY_TSINFO_AGGREGATION(pTSInfo, 0); // Aggregation
+ SET_TSPEC_BODY_TSINFO_PSB(pTSInfo, 0); // Aggregation
+ SET_TSPEC_BODY_TSINFO_UP(pTSInfo, UP); // User priority
+ SET_TSPEC_BODY_TSINFO_ACK_POLICY(pTSInfo, 0); // Ack policy
+ SET_TSPEC_BODY_TSINFO_SCHEDULE(pTSInfo, 0); // Schedule
+
+ MakeTSEntry(*ppTS, Addr, TSpec, NULL, 0, 0);
+ AdmitTS(Adapter, *ppTS, 0);
+ RTInsertTailList(pAddmitList, &((*ppTS)->List));
+
+ // if there is DirectLink, we need to do additional operation here!!
+
+
+ return TRUE;
+ }
+ else
+ {
+ RT_ASSERT(FALSE, ("ManageTSInformation(): There is not enough TS record to be used!!"));
+ return FALSE;
+ }
+ }
+ }
+
+}
+
+VOID
+RemoveTsEntry(
+ PADAPTER Adapter,
+ PTS_COMMON_INFO pTs,
+ TR_SELECT TxRxSelect
+ )
+{
+ BOOLEAN bInRxProgress = FALSE;
+
+ TsInitDelBA(Adapter, pTs, TxRxSelect);
+
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("RemoveTsEntry(): Remove %s Entry.\n", TxRxSelect?"Rx":"Tx"));
+ RT_PRINT_ADDR(COMP_QOS, DBG_TRACE, "PeerAddress:", pTs->Addr);
+
+ if(TxRxSelect == RX_DIR)
+ {
+ PRX_REORDER_ENTRY pRxReorderEntry;
+ PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs;
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+
+ if( PlatformCancelTimer(Adapter, &pRxTS->RxPktPendingTimer) == FALSE )
+ {
+ pRxTS->RxIndicateState = RXTS_INDICATE_IDLE;
+ }
+
+ if(!GetDefaultAdapter(Adapter)->bRemoveTsInRxPath)
+ PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+ else
+ bInRxProgress = TRUE;
+
+ while(!RTIsListEmpty(&pRxTS->RxPendingPktList))
+ {
+ pRxReorderEntry = (PRX_REORDER_ENTRY)RTRemoveHeadList(&pRxTS->RxPendingPktList);
+ pRxTS->RxBatchCount--;
+ ReturnRFDList(Adapter, pRxReorderEntry->pRfd);
+ RTInsertTailList(&pMgntInfo->RxReorder_Unused_List, &pRxReorderEntry->List);
+ }
+
+ if(!bInRxProgress)
+ PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+ }
+ else
+ {
+ PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
+ PlatformCancelTimer(Adapter, &pTxTS->TsAddBaTimer);
+ }
+}
+
+VOID
+RemovePeerTS(
+ PADAPTER Adapter,
+ pu1Byte Addr
+ )
+{
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+ PTS_COMMON_INFO pTS, pTmpTS;
+
+ pTS = (PTS_COMMON_INFO)RTGetHeadList(&pMgntInfo->Tx_TS_Pending_List);
+ while(&pTS->List != &pMgntInfo->Tx_TS_Pending_List)
+ {
+ if(PlatformCompareMemory(pTS->Addr, Addr, 6) == 0)
+ {
+ pTmpTS = pTS;
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ RTRemoveEntryList(&pTmpTS->List);
+ RemoveTsEntry(Adapter, pTmpTS, TX_DIR);
+// RemoveMAEntry(Adapter, &pTmpTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Tx_TS_Unused_List, &pTmpTS->List);
+ }
+ else
+ {
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ }
+ }
+
+ pTS = (PTS_COMMON_INFO)RTGetHeadList(&pMgntInfo->Tx_TS_Admit_List);
+ while(&pTS->List != &pMgntInfo->Tx_TS_Admit_List)
+ {
+ if(PlatformCompareMemory(pTS->Addr, Addr, 6) == 0)
+ {
+ pTmpTS = pTS;
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ RTRemoveEntryList(&pTmpTS->List);
+ RemoveTsEntry(Adapter, pTmpTS, TX_DIR);
+// RemoveMAEntry(Adapter, &pTmpTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Tx_TS_Unused_List, &pTmpTS->List);
+ }
+ else
+ {
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ }
+ }
+
+ pTS = (PTS_COMMON_INFO)RTGetHeadList(&pMgntInfo->Rx_TS_Pending_List);
+ while(&pTS->List != &pMgntInfo->Rx_TS_Pending_List)
+ {
+ if(PlatformCompareMemory(pTS->Addr, Addr, 6) == 0)
+ {
+ pTmpTS = pTS;
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ RTRemoveEntryList(&pTmpTS->List);
+ RemoveTsEntry(Adapter, pTmpTS, RX_DIR);
+// RemoveMAEntry(Adapter, &pTmpTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Rx_TS_Unused_List, &pTmpTS->List);
+ }
+ else
+ {
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ }
+ }
+
+ pTS = (PTS_COMMON_INFO)RTGetHeadList(&pMgntInfo->Rx_TS_Admit_List);
+ while(&pTS->List != &pMgntInfo->Rx_TS_Admit_List)
+ {
+ if(PlatformCompareMemory(pTS->Addr, Addr, 6) == 0)
+ {
+ pTmpTS = pTS;
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ RTRemoveEntryList(&pTmpTS->List);
+ RemoveTsEntry(Adapter, pTmpTS, RX_DIR);
+// RemoveMAEntry(Adapter, &pTmpTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Rx_TS_Unused_List, &pTmpTS->List);
+ }
+ else
+ {
+ pTS = (PTS_COMMON_INFO)RTNextEntryList(&pTS->List);
+ }
+ }
+}
+
+VOID
+ReleaseAllTSTimer(
+ PADAPTER Adapter)
+{
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+ PTX_TS_RECORD pTxTS = pMgntInfo->TxTsRecord;
+ PRX_TS_RECORD pRxTS = pMgntInfo->RxTsRecord;
+ u1Byte count = 0;
+
+ for(count = 0; count < TOTAL_TS_NUM; count++)
+ {
+ //
+ // The timers for the operation of Traffic Stream and Block Ack.
+ // DLS related timer will be add here in the future!!
+ //
+ PlatformReleaseTimer(
+ Adapter,
+ &pTxTS->TsAddBaTimer);
+
+ PlatformReleaseTimer(
+ Adapter,
+ &pTxTS->TxPendingBARecord.Timer);
+
+ PlatformReleaseTimer(
+ Adapter,
+ &pTxTS->TxAdmittedBARecord.Timer);
+
+ pTxTS++;
+ }
+
+ for(count = 0; count < TOTAL_TS_NUM; count++)
+ {
+ PlatformReleaseTimer(
+ Adapter,
+ &pRxTS->RxAdmittedBARecord.Timer);
+
+ PlatformReleaseTimer(
+ Adapter,
+ &pRxTS->RxPktPendingTimer);
+
+ pRxTS++;
+ }
+}
+
+
+
+VOID
+RemoveAllTS(
+ PADAPTER Adapter
+ )
+{
+ PMGNT_INFO pMgntInfo = &Adapter->MgntInfo;
+ PTS_COMMON_INFO pTS;
+
+ while(!RTIsListEmpty(&pMgntInfo->Tx_TS_Pending_List))
+ {
+ pTS = (PTS_COMMON_INFO)RTRemoveHeadList(&pMgntInfo->Tx_TS_Pending_List);
+ RemoveTsEntry(Adapter, pTS, TX_DIR);
+// RemoveMAEntry(Adapter, &pTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Tx_TS_Unused_List, &pTS->List);
+ }
+
+ while(!RTIsListEmpty(&pMgntInfo->Tx_TS_Admit_List))
+ {
+ pTS = (PTS_COMMON_INFO)RTRemoveHeadList(&pMgntInfo->Tx_TS_Admit_List);
+ RemoveTsEntry(Adapter, pTS, TX_DIR);
+// RemoveMAEntry(Adapter, &pTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Tx_TS_Unused_List, &pTS->List);
+ }
+
+ while(!RTIsListEmpty(&pMgntInfo->Rx_TS_Pending_List))
+ {
+ pTS = (PTS_COMMON_INFO)RTRemoveHeadList(&pMgntInfo->Rx_TS_Pending_List);
+ RemoveTsEntry(Adapter, pTS, RX_DIR);
+// RemoveMAEntry(Adapter, &pTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Rx_TS_Unused_List, &pTS->List);
+ }
+
+ while(!RTIsListEmpty(&pMgntInfo->Rx_TS_Admit_List))
+ {
+ pTS = (PTS_COMMON_INFO)RTRemoveHeadList(&pMgntInfo->Rx_TS_Admit_List);
+ RemoveTsEntry(Adapter, pTS, RX_DIR);
+// RemoveMAEntry(Adapter, &pTS->Ts_MAInfo);
+ RTInsertTailList(&pMgntInfo->Rx_TS_Unused_List, &pTS->List);
+ }
+}
+
+VOID
+TsStartAddBaProcess(
+ PADAPTER Adapter,
+ PTX_TS_RECORD pTxTS
+ )
+{
+ if(Adapter->MgntInfo.SafeModeEnabled)
+ {
+ RT_TRACE(COMP_MLME, DBG_LOUD, ("TsStartAddBaProcess ABORT becuase SafeModeEnable\n"));
+ return;
+ }
+
+ if(pTxTS->bAddBaReqInProgress == FALSE)
+ {
+ pTxTS->bAddBaReqInProgress = TRUE;
+
+ if(pTxTS->bAddBaReqDelayed)
+ {
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"));
+ PlatformSetTimer(Adapter, &pTxTS->TsAddBaTimer, TS_ADDBA_DELAY);
+ }
+ else
+ {
+ RT_TRACE(COMP_QOS, DBG_TRACE, ("TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"));
+ PlatformSetTimer(Adapter, &pTxTS->TsAddBaTimer, 0);
+ }
+ }
+}
+
+VOID
+RxTSIndicate(
+ PADAPTER Adapter,
+ PRT_RFD pRfd
+ )
+{
+ OCTET_STRING frame;
+ u1Byte tid;
+ u2Byte SeqNum;
+
+ frame.Octet = pRfd->Buffer.VirtualAddress;
+ frame.Length = pRfd->PacketLength;
+ tid = Frame_QoSTID(frame, sMacHdrLng);
+ SeqNum = Frame_SeqNum(frame);
+
+ if(GetTs(
+ Adapter,
+ (PTS_COMMON_INFO*) &(pRfd->Status.pRxTS),
+ Frame_Addr2(frame),
+ tid,
+ RX_DIR,
+ TRUE))
+ {
+ ExtendRxTS(Adapter, pRfd->Status.pRxTS);
+
+ if(pRfd->Status.bIsAMPDU)
+ ExtendBAEntry(Adapter, &(pRfd->Status.pRxTS->RxAdmittedBARecord));
+
+ // Reserve for later usage by RxReorder.
+ pRfd->Status.Seq_Num = SeqNum;
+
+ // For 819X series turbo mode!!
+ // 2012/09/13 MH This should move to HAL layer.
+ // 2012/09/14 MH IN a special case, TPLINK WR741ND Atheros AR9341 AP.
+ // When tested in win7 OS, every 45-50s, AP will send a TID=6 packet to
+ // NIC for 3 times(6 sec). Then RTWLANU will disable EDCA turbo mode temporarily
+ // So the throughput will downgrade. We need to ignore the special case.
+ {
+ if(tid!=0 && tid!=3)
+ {
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
+ if (Adapter->MgntInfo.bWiFiConfg)
+ {
+ pHalData->bIsAnyNonBEPkts = TRUE;
+ }
+ else
+ {
+ //
+ // How to Judge,? In busy trafic and then BE packets > VI/VO more than 90%.
+ // Then in busy traffic and VI/VO > 1M??
+ //
+ }
+ Adapter->MgntInfo.NumNonBePkt++;
+ }
+ else
+ {
+ Adapter->MgntInfo.NumBePkt++;
+ }
+ }
+ }
+ else
+ {
+ pRfd->Status.pRxTS = NULL;
+
+ RT_TRACE(COMP_RECV, DBG_LOUD, ("RxTSIndicate(): No TS!! Skip the check!!\n"));
+ RT_ASSERT(FALSE, ("RxTSIndicate(): No TS allocated!!"));
+ }
+}