📄 ba_action.c
字号:
if (pBAEntry->ORIBATimer.TimerValue) RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec }}BOOLEAN BARecSessionAdd( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry, IN PFRAME_ADDBA_REQ pFrame){ BA_REC_ENTRY *pBAEntry = NULL; BOOLEAN Status = TRUE; BOOLEAN Cancelled; USHORT Idx; UCHAR TID; UCHAR BAWinSize; UINT Value; UINT offset; ASSERT(pEntry); // find TID TID = pFrame->BaParm.TID; BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit); // Intel patch if (BAWinSize == 0) { BAWinSize = 64; } Idx = pEntry->BARecWcidArray[TID]; if (Idx == 0) { pBAEntry = BATableAllocRecEntry(pAd, &Idx); } else { pBAEntry = &pAd->BATable.BARecEntry[Idx]; // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); } DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize, BAWinSize)); // Start fill in parameters. if (pBAEntry != NULL) { ASSERT(pBAEntry->list.qlen == 0); pBAEntry->REC_BA_Status = Recipient_HandleRes; pBAEntry->BAWinSize = BAWinSize; pBAEntry->Wcid = pEntry->Aid; pBAEntry->TID = TID; pBAEntry->TimeOutValue = pFrame->TimeOutValue; pBAEntry->REC_BA_Status = Recipient_Accept; // initial sequence number pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq; printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq); if (pEntry->RXBAbitmap & (1<<TID)) { RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); } else { RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE); } // Set Bitmap flag. pEntry->RXBAbitmap |= (1<<TID); pEntry->BARecWcidArray[TID] = Idx; // Set BA session mask in WCID table. offset = MAC_WCID_BASE + pEntry->Aid * HW_WCID_ENTRY_SIZE + 4; RTMP_IO_READ32(pAd, offset, &Value); Value |= (0x10000<<TID); RTMP_IO_WRITE32(pAd, offset, Value); DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID])); } else { Status = FALSE; DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n", PRINT_MAC(pEntry->Addr), TID)); } return(Status);}BA_REC_ENTRY *BATableAllocRecEntry( IN PRTMP_ADAPTER pAd, OUT USHORT *Idx){ int i; BA_REC_ENTRY *pBAEntry = NULL; NdisAcquireSpinLock(&pAd->BATabLock); if (pAd->BATable.numAsRecipient >= Max_BARECI_SESSION) { printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient, Max_BARECI_SESSION); goto done; } // reserve idx 0 to identify BAWcidArray[TID] as empty for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++) { pBAEntry =&pAd->BATable.BARecEntry[i]; if ((pBAEntry->REC_BA_Status == Recipient_NONE)) { // get one pAd->BATable.numAsRecipient++; pBAEntry->REC_BA_Status = Recipient_USED; *Idx = i; break; } } done: NdisReleaseSpinLock(&pAd->BATabLock); return pBAEntry;}BA_ORI_ENTRY *BATableAllocOriEntry( IN PRTMP_ADAPTER pAd, OUT USHORT *Idx){ int i; BA_ORI_ENTRY *pBAEntry = NULL; NdisAcquireSpinLock(&pAd->BATabLock); if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE)) { goto done; } // reserve idx 0 to identify BAWcidArray[TID] as empty for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++) { pBAEntry =&pAd->BATable.BAOriEntry[i]; if ((pBAEntry->ORI_BA_Status == Originator_NONE)) { // get one pAd->BATable.numAsOriginator++; pBAEntry->ORI_BA_Status = Originator_USED; pBAEntry->pAdapter = pAd; *Idx = i; break; } } done: NdisReleaseSpinLock(&pAd->BATabLock); return pBAEntry;}VOID BATableFreeOriEntry( IN PRTMP_ADAPTER pAd, IN ULONG Idx){ BA_ORI_ENTRY *pBAEntry = NULL; MAC_TABLE_ENTRY *pEntry; if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) return; pBAEntry =&pAd->BATable.BAOriEntry[Idx]; if (pBAEntry->ORI_BA_Status != Originator_NONE) { pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; pEntry->BAOriWcidArray[pBAEntry->TID] = 0; NdisAcquireSpinLock(&pAd->BATabLock); if (pBAEntry->ORI_BA_Status == Originator_Done) { pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) )); DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); // Erase Bitmap flag. } ASSERT(pAd->BATable.numAsOriginator != 0); pAd->BATable.numAsOriginator -= 1; pBAEntry->ORI_BA_Status = Originator_NONE; pBAEntry->Token = 0; NdisReleaseSpinLock(&pAd->BATabLock); }}VOID BATableFreeRecEntry( IN PRTMP_ADAPTER pAd, IN ULONG Idx){ BA_REC_ENTRY *pBAEntry = NULL; MAC_TABLE_ENTRY *pEntry; if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE)) return; pBAEntry =&pAd->BATable.BARecEntry[Idx]; if (pBAEntry->REC_BA_Status != Recipient_NONE) { pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; pEntry->BARecWcidArray[pBAEntry->TID] = 0; NdisAcquireSpinLock(&pAd->BATabLock); ASSERT(pAd->BATable.numAsRecipient != 0); pAd->BATable.numAsRecipient -= 1; pBAEntry->REC_BA_Status = Recipient_NONE; NdisReleaseSpinLock(&pAd->BATabLock); }}VOID BAOriSessionTearDown( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR TID, IN BOOLEAN bPassive, IN BOOLEAN bForceSend){ ULONG Idx = 0; BA_ORI_ENTRY *pBAEntry; BOOLEAN Cancelled; if (Wcid >= MAX_LEN_OF_MAC_TABLE) { return; } // // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). // Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID]; if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) { if (bForceSend == TRUE) { // force send specified TID DelBA MLME_DELBA_REQ_STRUCT DelbaReq; NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = ORIGINATOR; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); MlmeHandler(pAd); } return; } DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BAOriEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done)) { MLME_DELBA_REQ_STRUCT DelbaReq; NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = pBAEntry->TID; DelbaReq.Initiator = ORIGINATOR; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); MlmeHandler(pAd); } RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); BATableFreeOriEntry(pAd, Idx); if (bPassive) { //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); }}VOID BARecSessionTearDown( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR TID, IN BOOLEAN bPassive){ ULONG Idx = 0; BA_REC_ENTRY *pBAEntry; if (Wcid >= MAX_LEN_OF_MAC_TABLE) { return; } // // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). // Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; if (Idx == 0) return; DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BARecEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept)) { MLME_DELBA_REQ_STRUCT DelbaReq; ULONG offset; ULONG VALUE; BOOLEAN Cancelled; RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); // // 1. Send DELBA Action Frame // if (bPassive == FALSE) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = RECIPIENT; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); MlmeHandler(pAd); } // // 2. Free resource of BA session // // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); NdisAcquireSpinLock(&pAd->BATabLock); // Erase Bitmap flag. pBAEntry->LastIndSeq = RESET_RCV_SEQ; pBAEntry->BAWinSize = 0; // Erase Bitmap flag at software mactable pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; offset = MAC_WCID_BASE + (pBAEntry->Wcid) * HW_WCID_ENTRY_SIZE + 4; RTMP_IO_READ32(pAd, offset, &VALUE); // bitmap field starts at 0x10000 in ASIC WCID table VALUE &= (~(0x10000 << pBAEntry->TID)); RTMP_IO_WRITE32(pAd, offset, VALUE); NdisReleaseSpinLock(&pAd->BATabLock); } BATableFreeRecEntry(pAd, Idx);}VOID BASessionTearDownALL( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid){ int i; for (i=0; i<=MAX_TID_NUM; i++) { BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE); BARecSessionTearDown(pAd, Wcid, i, FALSE); }}/* ========================================================================== Description: Retry sending ADDBA Reqest. IRQL = DISPATCH_LEVEL Parametrs: p8023Header: if this is already 802.3 format, p8023Header is NULL Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. FALSE , then continue indicaterx at this moment. ========================================================================== */VOID BAOriSessionSetupTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext; MAC_TABLE_ENTRY *pEntry; PRTMP_ADAPTER pAd; if (pBAEntry == NULL) return; pAd = pBAEntry->pAdapter;#ifdef CONFIG_STA_SUPPORT // Do nothing if monitor mode is on if (MONITOR_ON(pAd)) return;#endif // CONFIG_STA_SUPPORT // #ifdef RALINK_ATE // Nothing to do in ATE mode. if (pAd->ate.Mode != ATE_STOP) return;#endif // RALINK_ATE // pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) { MLME_ADDBA_REQ_STRUCT AddbaReq; NdisZeroMemory(&AddbaReq, sizeof(AddbaReq)); COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr); AddbaReq.Wcid = (UCHAR)(pEntry->Aid); AddbaReq.TID = pBAEntry->TID; AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit; AddbaReq.TimeOutValue = 0; AddbaReq.Token = pBAEntry->Token; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq); MlmeHandler(pAd); DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token)); pBAEntry->Token++; RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); } else { BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]); }}/* ========================================================================== Description: Retry sending ADDBA Reqest. IRQL = DISPATCH_LEVEL Parametrs: p8023Header: if this is already 802.3 format, p8023Header is NULL Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere. FALSE , then continue indicaterx at this moment. ========================================================================== */VOID BARecSessionIdleTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext; PRTMP_ADAPTER pAd; ULONG Now32; if (pBAEntry == NULL) return; if ((pBAEntry->REC_BA_Status == Recipient_Accept)) { NdisGetSystemUpTime(&Now32); if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT))) { pAd = pBAEntry->pAdapter; // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); printk("%ld: REC BA session Timeout\n", Now32); } }}VOID PeerAddBAReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { // 7.4.4.1 //ULONG Idx; UCHAR Status = 1; UCHAR pAddr[6]; FRAME_ADDBA_RSP ADDframe; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; PFRAME_ADDBA_REQ pAddreqFrame = NULL; //UCHAR BufSize; ULONG FrameLen; PULONG ptemp; PMAC_TABLE_ENTRY pMacEntry; DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid)); //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); //ADDBA Request from unknown peer, ignore this. if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) return; pMacEntry = &pAd->MacTab.Content[Elem->Wcid]; DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n")); ptemp = (PULONG)Elem->Msg; //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) { if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) { pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -