/* ========================================================================== Description: send DELBA and delete BaEntry if any Parametrs: Elem - MLME message MLME_DELBA_REQ_STRUCT IRQL = DISPATCH_LEVEL ========================================================================== */ void MlmeDELBAAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_DELBA_REQ_STRUCT *pInfo; PUCHAR pOutBuffer = NULL, pOutBuffer2 = NULL; ULONG Idx; FRAME_DELBA_REQ Frame; ULONG FrameLen; FRAME_BAR FrameBar; MAC_TABLE_ENTRY *pEntry = NULL; struct wifi_dev *wdev; pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; /* must send back DELBA */ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen) && VALID_WCID(pInfo->Wcid)) { pOutBuffer = MlmeAllocateMemory(); if (!pOutBuffer) { return; } pOutBuffer2 = MlmeAllocateMemory(); if (!pOutBuffer2) { MlmeFreeMemory(pOutBuffer); return; } /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ pEntry = &pAd->MacTab.Content[pInfo->Wcid]; if (!pEntry->wdev) { DBGPRINT(RT_DEBUG_ERROR, ("%s():No binding wdev for wcid(%d)\n", __FUNCTION__, pInfo->Wcid)); MlmeFreeMemory(pOutBuffer); MlmeFreeMemory(pOutBuffer2); return; } wdev = pEntry->wdev; Idx = pEntry->BAOriWcidArray[pInfo->TID]; #ifdef APCLI_SUPPORT #endif /* APCLI_SUPPORT */ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, wdev->if_addr); FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton.*/ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton.*/ MakeOutgoingFrame(pOutBuffer2, &FrameLen, sizeof(FRAME_BAR), &FrameBar, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen); MlmeFreeMemory(pOutBuffer2); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); /* SEND DELBA FRAME*/ FrameLen = 0; //CFG_TODO #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef APCLI_SUPPORT #endif /* APCLI_SUPPORT */ ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pEntry->wdev->if_addr, pEntry->wdev->bssid); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (ADHOC_ON(pAd)) ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pAd->StaCfg.wdev.if_addr, pAd->StaCfg.wdev.bssid); else ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, pAd->StaCfg.wdev.if_addr, pAd->StaCfg.wdev.bssid); } #endif /* CONFIG_STA_SUPPORT */ Frame.Category = CATEGORY_BA; Frame.Action = DELBA; Frame.DelbaParm.Initiator = pInfo->Initiator; Frame.DelbaParm.TID = pInfo->TID; Frame.ReasonCode = 39; /* Time Out*/ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); Frame.ReasonCode = cpu2le16(Frame.ReasonCode); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_DELBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); }
/* ========================================================================== Description: send DELBA and delete BaEntry if any Parametrs: Elem - MLME message MLME_DELBA_REQ_STRUCT IRQL = DISPATCH_LEVEL ========================================================================== */ VOID MlmeDELBAAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_DELBA_REQ_STRUCT *pInfo; PUCHAR pOutBuffer = NULL, pOutBuffer2 = NULL; //ULONG Idx; FRAME_DELBA_REQ Frame; ULONG FrameLen; #if defined(RTMP_MAC) || defined(RTL_MAC) FRAME_BAR FrameBar; #endif MAC_TABLE_ENTRY *pEntry = NULL; struct wifi_dev *wdev; UCHAR *src_addr = NULL; pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg; /* must send back DELBA */ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ)); DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator)); if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen) && VALID_WCID(pInfo->Wcid)) { if(MlmeAllocateMemory(pAd, &pOutBuffer) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n")); return; } if(MlmeAllocateMemory(pAd, &pOutBuffer2) != NDIS_STATUS_SUCCESS) { MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n")); return; } /* SEND BAR (Send BAR to refresh peer reordering buffer.) */ pEntry = &pAd->MacTab.Content[pInfo->Wcid]; if (!pEntry->wdev) { DBGPRINT(RT_DEBUG_ERROR, ("%s():No binding wdev for wcid(%d)\n", __FUNCTION__, pInfo->Wcid)); MlmeFreeMemory(pAd, pOutBuffer); MlmeFreeMemory(pAd, pOutBuffer2); return; } wdev = pEntry->wdev; //Idx = pEntry->BAOriWcidArray[pInfo->TID]; #ifdef APCLI_SUPPORT #ifdef MAC_REPEATER_SUPPORT if (IS_ENTRY_APCLI(pEntry) && pEntry->bReptCli) { UINT apidx = pEntry->func_tb_idx; src_addr = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[pEntry->MatchReptCliIdx].CurrentAddress[0]; } else #endif /* MAC_REPEATER_SUPPORT */ #endif /* APCLI_SUPPORT */ src_addr = wdev->if_addr; #if defined(RTMP_MAC) || defined(RTL_MAC) if ((pAd->chipCap.hif_type == HIF_RTMP) || (pAd->chipCap.hif_type == HIF_RLT)) { BarHeaderInit(pAd, &FrameBar, pEntry->Addr, src_addr); FrameBar.StartingSeq.field.FragNum = 0; /* make sure sequence not clear in DEL funciton.*/ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.tr_entry[pInfo->Wcid].TxSeq[pInfo->TID]; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.TID = pInfo->TID; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.ACKPolicy = IMMED_BA; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.Compressed = 1; /* make sure sequence not clear in DEL funciton.*/ FrameBar.BarControl.MTID = 0; /* make sure sequence not clear in DEL funciton.*/ MakeOutgoingFrame(pOutBuffer2, &FrameLen, sizeof(FRAME_BAR), &FrameBar, END_OF_ARGS); MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG & QID_AC_BE), pOutBuffer2, FrameLen); DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n")); } #endif /* SEND DELBA FRAME*/ FrameLen = 0; ActHeaderInit(pAd, &Frame.Hdr, pEntry->Addr, src_addr, pEntry->wdev->bssid); Frame.Category = CATEGORY_BA; Frame.Action = DELBA; Frame.DelbaParm.Initiator = pInfo->Initiator; Frame.DelbaParm.TID = pInfo->TID; Frame.ReasonCode = 39; /* Time Out*/ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm)); Frame.ReasonCode = cpu2le16(Frame.ReasonCode); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_DELBA_REQ), &Frame, END_OF_ARGS); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); MlmeFreeMemory(pAd, pOutBuffer2); DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator)); } }