aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rt2870/common/ba_action.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rt2870/common/ba_action.c')
-rw-r--r--drivers/staging/rt2870/common/ba_action.c1799
1 files changed, 1 insertions, 1798 deletions
diff --git a/drivers/staging/rt2870/common/ba_action.c b/drivers/staging/rt2870/common/ba_action.c
index d9f738177e2b..a9e6a09d994f 100644
--- a/drivers/staging/rt2870/common/ba_action.c
+++ b/drivers/staging/rt2870/common/ba_action.c
@@ -1,1798 +1 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- *************************************************************************
- */
-
-
-#ifdef DOT11_N_SUPPORT
-
-#include "../rt_config.h"
-
-
-
-#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
-
-#define ORI_SESSION_MAX_RETRY 8
-#define ORI_BA_SESSION_TIMEOUT (2000) // ms
-#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
-
-#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
-#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
-
-#define RESET_RCV_SEQ (0xFFFF)
-
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
-
-
-BA_ORI_ENTRY *BATableAllocOriEntry(
- IN PRTMP_ADAPTER pAd,
- OUT USHORT *Idx);
-
-BA_REC_ENTRY *BATableAllocRecEntry(
- IN PRTMP_ADAPTER pAd,
- OUT USHORT *Idx);
-
-VOID BAOriSessionSetupTimeout(
- IN PVOID SystemSpecific1,
- IN PVOID FunctionContext,
- IN PVOID SystemSpecific2,
- IN PVOID SystemSpecific3);
-
-VOID BARecSessionIdleTimeout(
- IN PVOID SystemSpecific1,
- IN PVOID FunctionContext,
- IN PVOID SystemSpecific2,
- IN PVOID SystemSpecific3);
-
-
-BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
-BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
-
-#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
- Announce_Reordering_Packet(_pAd, _mpdu_blk);
-
-VOID BA_MaxWinSizeReasign(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntryPeer,
- OUT UCHAR *pWinSize)
-{
- UCHAR MaxSize;
-
-
- if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
- {
- if (pAd->MACVersion >= RALINK_3070_VERSION)
- {
- if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
- MaxSize = 7; // for non-open mode
- else
- MaxSize = 13;
- }
- else
- MaxSize = 31;
- }
- else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
- {
- if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
- MaxSize = 7; // for non-open mode
- else
- MaxSize = 13;
- }
- else
- MaxSize = 7;
-
- DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
- *pWinSize, MaxSize));
-
- if ((*pWinSize) > MaxSize)
- {
- DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
- *pWinSize, MaxSize));
-
- *pWinSize = MaxSize;
- }
-}
-
-void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
- IN struct reordering_mpdu *mpdu)
-{
- PNDIS_PACKET pPacket;
-
- pPacket = mpdu->pPacket;
-
- if (mpdu->bAMSDU)
- {
- ASSERT(0);
- BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
- }
- else
- {
- //
- // pass this 802.3 packet to upper layer or forward this packet to WM directly
- //
-
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
-#endif // CONFIG_STA_SUPPORT //
- }
-}
-
-/*
- * Insert a reordering mpdu into sorted linked list by sequence no.
- */
-BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
-{
-
- struct reordering_mpdu **ppScan = &list->next;
-
- while (*ppScan != NULL)
- {
- if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
- {
- ppScan = &(*ppScan)->next;
- }
- else if ((*ppScan)->Sequence == mpdu->Sequence)
- {
- /* give up this duplicated frame */
- return(FALSE);
- }
- else
- {
- /* find position */
- break;
- }
- }
-
- mpdu->next = *ppScan;
- *ppScan = mpdu;
- list->qlen++;
- return TRUE;
-}
-
-
-/*
- * caller lock critical section if necessary
- */
-static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
-{
- list->qlen++;
- mpdu_blk->next = list->next;
- list->next = mpdu_blk;
-}
-
-/*
- * caller lock critical section if necessary
- */
-static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
-{
- struct reordering_mpdu *mpdu_blk = NULL;
-
- ASSERT(list);
-
- if (list->qlen)
- {
- list->qlen--;
- mpdu_blk = list->next;
- if (mpdu_blk)
- {
- list->next = mpdu_blk->next;
- mpdu_blk->next = NULL;
- }
- }
- return mpdu_blk;
-}
-
-
-static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
-{
- return(ba_dequeue(list));
-}
-
-
-static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
- {
- ASSERT(list);
-
- return(list->next);
- }
-
-
-/*
- * free all resource for reordering mechanism
- */
-void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
-{
- BA_TABLE *Tab;
- PBA_REC_ENTRY pBAEntry;
- struct reordering_mpdu *mpdu_blk;
- int i;
-
- Tab = &pAd->BATable;
-
- /* I. release all pending reordering packet */
- NdisAcquireSpinLock(&pAd->BATabLock);
- for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
- {
- pBAEntry = &Tab->BARecEntry[i];
- if (pBAEntry->REC_BA_Status != Recipient_NONE)
- {
- while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
- {
- ASSERT(mpdu_blk->pPacket);
- RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
- ba_mpdu_blk_free(pAd, mpdu_blk);
- }
- }
- }
- NdisReleaseSpinLock(&pAd->BATabLock);
-
- ASSERT(pBAEntry->list.qlen == 0);
- /* II. free memory of reordering mpdu table */
- NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
- os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
- NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-
-
-/*
- * Allocate all resource for reordering mechanism
- */
-BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
-{
- int i;
- PUCHAR mem;
- struct reordering_mpdu *mpdu_blk;
- struct reordering_list *freelist;
-
- /* allocate spinlock */
- NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
-
- /* initialize freelist */
- freelist = &pAd->mpdu_blk_pool.freelist;
- freelist->next = NULL;
- freelist->qlen = 0;
-
- DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
-
- /* allocate number of mpdu_blk memory */
- os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
-
- pAd->mpdu_blk_pool.mem = mem;
-
- if (mem == NULL)
- {
- DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
- return(FALSE);
- }
-
- /* build mpdu_blk free list */
- for (i=0; i<num; i++)
- {
- /* get mpdu_blk */
- mpdu_blk = (struct reordering_mpdu *) mem;
- /* initial mpdu_blk */
- NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
- /* next mpdu_blk */
- mem += sizeof(struct reordering_mpdu);
- /* insert mpdu_blk into freelist */
- ba_enqueue(freelist, mpdu_blk);
- }
-
- return(TRUE);
-}
-
-//static int blk_count=0; // sample take off, no use
-
-static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
-{
- struct reordering_mpdu *mpdu_blk;
-
- NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
- mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
- if (mpdu_blk)
- {
-// blk_count++;
- /* reset mpdu_blk */
- NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
- }
- NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
- return mpdu_blk;
-}
-
-static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
-{
- ASSERT(mpdu_blk);
-
- NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-// blk_count--;
- ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
- NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-
-static USHORT ba_indicate_reordering_mpdus_in_order(
- IN PRTMP_ADAPTER pAd,
- IN PBA_REC_ENTRY pBAEntry,
- IN USHORT StartSeq)
-{
- struct reordering_mpdu *mpdu_blk;
- USHORT LastIndSeq = RESET_RCV_SEQ;
-
- NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
- while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
- {
- /* find in-order frame */
- if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
- {
- break;
- }
- /* dequeue in-order frame from reodering list */
- mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
- /* pass this frame up */
- ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
- /* move to next sequence */
- StartSeq = mpdu_blk->Sequence;
- LastIndSeq = StartSeq;
- /* free mpdu_blk */
- ba_mpdu_blk_free(pAd, mpdu_blk);
- }
-
- NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-
- /* update last indicated sequence */
- return LastIndSeq;
-}
-
-static void ba_indicate_reordering_mpdus_le_seq(
- IN PRTMP_ADAPTER pAd,
- IN PBA_REC_ENTRY pBAEntry,
- IN USHORT Sequence)
-{
- struct reordering_mpdu *mpdu_blk;
-
- NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
- while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
- {
- /* find in-order frame */
- if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
- {
- /* dequeue in-order frame from reodering list */
- mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
- /* pass this frame up */
- ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
- /* free mpdu_blk */
- ba_mpdu_blk_free(pAd, mpdu_blk);
- }
- else
- {
- break;
- }
- }
- NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-
-static void ba_refresh_reordering_mpdus(
- IN PRTMP_ADAPTER pAd,
- PBA_REC_ENTRY pBAEntry)
-{
- struct reordering_mpdu *mpdu_blk;
-
- NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
- /* dequeue in-order frame from reodering list */
- while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
- {
- /* pass this frame up */
- ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-
- pBAEntry->LastIndSeq = mpdu_blk->Sequence;
- ba_mpdu_blk_free(pAd, mpdu_blk);
-
- /* update last indicated sequence */
- }
- ASSERT(pBAEntry->list.qlen == 0);
- pBAEntry->LastIndSeq = RESET_RCV_SEQ;
- NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-
-//static
-void ba_flush_reordering_timeout_mpdus(
- IN PRTMP_ADAPTER pAd,
- IN PBA_REC_ENTRY pBAEntry,
- IN ULONG Now32)
-
-{
- USHORT Sequence;
-
-// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
-// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
-// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
-// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
- if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
- &&(pBAEntry->list.qlen > 1)
- )
- {
- DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
- (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
- pBAEntry->LastIndSeq));
- ba_refresh_reordering_mpdus(pAd, pBAEntry);
- pBAEntry->LastIndSeqAtTimer = Now32;
- }
- else
- if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
- && (pBAEntry->list.qlen > 0)
- )
- {
- //
- // force LastIndSeq to shift to LastIndSeq+1
- //
- Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
- ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
- pBAEntry->LastIndSeqAtTimer = Now32;
- pBAEntry->LastIndSeq = Sequence;
- //
- // indicate in-order mpdus
- //
- Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
- if (Sequence != RESET_RCV_SEQ)
- {
- pBAEntry->LastIndSeq = Sequence;
- }
-
- }
-#if 0
- else if (
- (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT))) &&
- (pBAEntry->list.qlen > 1))
- )
- {
- DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%lx-%lx = %d > %d): %x\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
- (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
- pBAEntry->LastIndSeq));
- ba_refresh_reordering_mpdus(pAd, pBAEntry);
- pBAEntry->LastIndSeqAtTimer = Now32;
- }
-#endif
-}
-
-
-/*
- * generate ADDBA request to
- * set up BA agreement
- */
-VOID BAOriSessionSetUp(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntry,
- IN UCHAR TID,
- IN USHORT TimeOut,
- IN ULONG DelayTime,
- IN BOOLEAN isForced)
-
-{
- //MLME_ADDBA_REQ_STRUCT AddbaReq;
- BA_ORI_ENTRY *pBAEntry = NULL;
- USHORT Idx;
- BOOLEAN Cancelled;
-
- if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
- return;
-
- // if this entry is limited to use legacy tx mode, it doesn't generate BA.
- if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
- return;
-
- if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
- {
- // try again after 3 secs
- DelayTime = 3000;
-// printk("DeCline BA from Peer\n");
-// return;
- }
-
-
- Idx = pEntry->BAOriWcidArray[TID];
- if (Idx == 0)
- {
- // allocate a BA session
- pBAEntry = BATableAllocOriEntry(pAd, &Idx);
- if (pBAEntry == NULL)
- {
- DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
- return;
- }
- }
- else
- {
- pBAEntry =&pAd->BATable.BAOriEntry[Idx];
- }
-
- if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
- {
- return;
- }
-
- pEntry->BAOriWcidArray[TID] = Idx;
-
- // Initialize BA session
- pBAEntry->ORI_BA_Status = Originator_WaitRes;
- pBAEntry->Wcid = pEntry->Aid;
- pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
- pBAEntry->Sequence = BA_ORI_INIT_SEQ;
- pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
- pBAEntry->TID = TID;
- pBAEntry->TimeOutValue = TimeOut;
- pBAEntry->pAdapter = pAd;
-
- if (!(pEntry->TXBAbitmap & (1<<TID)))
- {
- RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
- }
- else
- RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
- // set timer to send ADDBA request
- RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
-}
-
-VOID BAOriSessionAdd(
- IN PRTMP_ADAPTER pAd,
- IN MAC_TABLE_ENTRY *pEntry,
- IN PFRAME_ADDBA_RSP pFrame)
-{
- BA_ORI_ENTRY *pBAEntry = NULL;
- BOOLEAN Cancelled;
- UCHAR TID;
- USHORT Idx;
- PUCHAR pOutBuffer2 = NULL;
- NDIS_STATUS NStatus;
- ULONG FrameLen;
- FRAME_BAR FrameBar;
-
- TID = pFrame->BaParm.TID;
- Idx = pEntry->BAOriWcidArray[TID];
- pBAEntry =&pAd->BATable.BAOriEntry[Idx];
-
- // Start fill in parameters.
- if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
- {
- pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
- BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
-
- pBAEntry->TimeOutValue = pFrame->TimeOutValue;
- pBAEntry->ORI_BA_Status = Originator_Done;
- // reset sequence number
- pBAEntry->Sequence = BA_ORI_INIT_SEQ;
- // Set Bitmap flag.
- pEntry->TXBAbitmap |= (1<<TID);
- RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
- pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
-
- DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __func__, pEntry->TXBAbitmap,
- pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
-
- // SEND BAR ;
- NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- {
- DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
- return;
- }
-
-
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
-#endif // CONFIG_STA_SUPPORT //
-
- FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
- FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
- FrameBar.BarControl.TID = pBAEntry->TID; // 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(pAd, pOutBuffer2);
-
-
- 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;
- //UINT32 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", __func__, 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);
- }
-
-#if 0 // for debugging
- RTMPSetTimer(&pBAEntry->RECBATimer, REC_BA_SESSION_IDLE_TIMEOUT);
-#endif
-
- // Set Bitmap flag.
- pEntry->RXBAbitmap |= (1<<TID);
- pEntry->BARecWcidArray[TID] = Idx;
-
- pEntry->BADeclineBitmap &= ~(1<<TID);
-
- // Set BA session mask in WCID table.
- RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
-
- 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, ("BATableFreeOriEntry 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;
- MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
- NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
- NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
- COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
- DelbaReq.Wcid = Wcid;
- DelbaReq.TID = TID;
- DelbaReq.Initiator = ORIGINATOR;
-#if 1
- Elem->MsgLen = sizeof(DelbaReq);
- NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
- MlmeDELBAAction(pAd, Elem);
- kfree(Elem);
-#else
- MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
- RT28XX_MLME_HANDLER(pAd);
-#endif
- }
-
- return;
- }
-
- DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __func__, 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;
- MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
- NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
- NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
- COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
- DelbaReq.Wcid = Wcid;
- DelbaReq.TID = pBAEntry->TID;
- DelbaReq.Initiator = ORIGINATOR;
-#if 1
- Elem->MsgLen = sizeof(DelbaReq);
- NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
- MlmeDELBAAction(pAd, Elem);
- kfree(Elem);
-#else
- MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
- RT28XX_MLME_HANDLER(pAd);
-#endif
- }
- 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", __func__, 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;
- BOOLEAN Cancelled;
- MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
- //ULONG offset;
- //UINT32 VALUE;
-
- RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-
- //
- // 1. Send DELBA Action Frame
- //
- if (bPassive == FALSE)
- {
- NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
- NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
-
- COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
- DelbaReq.Wcid = Wcid;
- DelbaReq.TID = TID;
- DelbaReq.Initiator = RECIPIENT;
-#if 1
- Elem->MsgLen = sizeof(DelbaReq);
- NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
- MlmeDELBAAction(pAd, Elem);
- kfree(Elem);
-#else
- MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
- RT28XX_MLME_HANDLER(pAd);
-#endif
- }
-
-
- //
- // 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;
-
- RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
-
- NdisReleaseSpinLock(&pAd->BATabLock);
-
- }
-
- BATableFreeRecEntry(pAd, Idx);
-}
-
-VOID BASessionTearDownALL(
- IN OUT PRTMP_ADAPTER pAd,
- IN UCHAR Wcid)
-{
- int i;
-
- for (i=0; i<NUM_OF_TID; 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
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- {
- // 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 (ATE_ON(pAd))
- 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);
- RT28XX_MLME_HANDLER(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", __func__, 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);
- if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
- Status = 0;
- else
- Status = 38; // more parameters have invalid values
- }
- else
- {
- Status = 37; // the request has been declined.
- }
- }
-
- if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
- ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
-
- pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
- // 2. Always send back ADDBA Response
- NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- {
- DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
- return;
- }
-
- NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
- // 2-1. Prepare ADDBA Response frame.
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- {
- if (ADHOC_ON(pAd))
- ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
- else
-#ifdef QOS_DLS_SUPPORT
- if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls)
- ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
- else
-#endif // QOS_DLS_SUPPORT //
- ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
- }
-#endif // CONFIG_STA_SUPPORT //
- ADDframe.Category = CATEGORY_BA;
- ADDframe.Action = ADDBA_RESP;
- ADDframe.Token = pAddreqFrame->Token;
- // What is the Status code?? need to check.
- ADDframe.StatusCode = Status;
- ADDframe.BaParm.BAPolicy = IMMED_BA;
- ADDframe.BaParm.AMSDUSupported = 0;
- ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
- ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
- if (ADDframe.BaParm.BufSize == 0)
- {
- ADDframe.BaParm.BufSize = 64;
- }
- ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
-
- *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
- ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
- ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
-
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- sizeof(FRAME_ADDBA_RSP), &ADDframe,
- END_OF_ARGS);
- MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
- MlmeFreeMemory(pAd, pOutBuffer);
-
- DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid, ADDframe.BaParm.TID,
- ADDframe.BaParm.BufSize));
-}
-
-
-VOID PeerAddBARspAction(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- //UCHAR Idx, i;
- //PUCHAR pOutBuffer = NULL;
- PFRAME_ADDBA_RSP pFrame = NULL;
- //PBA_ORI_ENTRY pBAEntry;
-
- //ADDBA Response from unknown peer, ignore this.
- if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
- return;
-
- DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __func__, Elem->Wcid));
-
- //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
-
- if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
- {
- pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
-
- DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
- switch (pFrame->StatusCode)
- {
- case 0:
- // I want a BAsession with this peer as an originator.
- BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
- break;
- default:
- // check status == USED ???
- BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
- break;
- }
- // Rcv Decline StatusCode
- if ((pFrame->StatusCode == 37)
-#ifdef CONFIG_STA_SUPPORT
- || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
-#endif // CONFIG_STA_SUPPORT //
- )
- {
- pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
- }
- }
-}
-
-VOID PeerDelBAAction(
- IN PRTMP_ADAPTER pAd,
- IN MLME_QUEUE_ELEM *Elem)
-
-{
- //UCHAR Idx;
- //PUCHAR pOutBuffer = NULL;
- PFRAME_DELBA_REQ pDelFrame = NULL;
-
- DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __func__));
- //DELBA Request from unknown peer, ignore this.
- if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
- {
- pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
- if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
- {
- DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
- BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
- }
- else
- {
- DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
- //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
- BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
- }
- }
-}
-
-
-BOOLEAN CntlEnqueueForRecv(
- IN PRTMP_ADAPTER pAd,
- IN ULONG Wcid,
- IN ULONG MsgLen,
- IN PFRAME_BA_REQ pMsg)
-{
- PFRAME_BA_REQ pFrame = pMsg;
- //PRTMP_REORDERBUF pBuffer;
- //PRTMP_REORDERBUF pDmaBuf;
- PBA_REC_ENTRY pBAEntry;
- //BOOLEAN Result;
- ULONG Idx;
- //UCHAR NumRxPkt;
- UCHAR TID;//, i;
-
- TID = (UCHAR)pFrame->BARControl.TID;
-
- DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
- //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
- // Do nothing if the driver is starting halt state.
- // This might happen when timer already been fired before cancel timer with mlmehalt
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
- return FALSE;
-
- // First check the size, it MUST not exceed the mlme queue size
- if (MsgLen > MGMT_DMA_BUFFER_SIZE)
- {
- DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
- return FALSE;
- }
- else if (MsgLen != sizeof(FRAME_BA_REQ))
- {
- DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
- return FALSE;
- }
- else if (MsgLen != sizeof(FRAME_BA_REQ))
- {
- DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
- return FALSE;
- }
-
- if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
- {
- // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
- Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
- pBAEntry = &pAd->BATable.BARecEntry[Idx];
- }
- else
- {
- return FALSE;
- }
-
- DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
-
- if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
- {
- //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
- ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
- pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
- }
- //ba_refresh_reordering_mpdus(pAd, pBAEntry);
- return TRUE;
-}
-
-/*
-Description : Send PSMP Action frame If PSMP mode switches.
-*/
-VOID SendPSMPAction(
- IN PRTMP_ADAPTER pAd,
- IN UCHAR Wcid,
- IN UCHAR Psmp)
-{
- PUCHAR pOutBuffer = NULL;
- NDIS_STATUS NStatus;
- //ULONG Idx;
- FRAME_PSMP_ACTION Frame;
- ULONG FrameLen;
-
- NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
- if (NStatus != NDIS_STATUS_SUCCESS)
- {
- DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
- return;
- }
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
-#endif // CONFIG_STA_SUPPORT //
-
- Frame.Category = CATEGORY_HT;
- Frame.Action = SMPS_ACTION;
- switch (Psmp)
- {
- case MMPS_ENABLE:
- Frame.Psmp = 0;
- break;
- case MMPS_DYNAMIC:
- Frame.Psmp = 3;
- break;
- case MMPS_STATIC:
- Frame.Psmp = 1;
- break;
- }
- MakeOutgoingFrame(pOutBuffer, &FrameLen,
- sizeof(FRAME_PSMP_ACTION), &Frame,
- END_OF_ARGS);
- MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
- MlmeFreeMemory(pAd, pOutBuffer);
- DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
-}
-
-
-#define RADIO_MEASUREMENT_REQUEST_ACTION 0
-
-typedef struct PACKED
-{
- UCHAR RegulatoryClass;
- UCHAR ChannelNumber;
- USHORT RandomInterval;
- USHORT MeasurementDuration;
- UCHAR MeasurementMode;
- UCHAR BSSID[MAC_ADDR_LEN];
- UCHAR ReportingCondition;
- UCHAR Threshold;
- UCHAR SSIDIE[2]; // 2 byte
-} BEACON_REQUEST;
-
-typedef struct PACKED
-{
- UCHAR ID;
- UCHAR Length;
- UCHAR Token;
- UCHAR RequestMode;
- UCHAR Type;
-} MEASUREMENT_REQ;
-
-
-
-
-void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
- IN PRTMP_ADAPTER pAd,
- IN RX_BLK *pRxBlk,
- IN UCHAR FromWhichBSSID)
-{
- PNDIS_PACKET pRxPkt;
- UCHAR Header802_3[LENGTH_802_3];
-
- // 1. get 802.3 Header
- // 2. remove LLC
- // a. pointer pRxBlk->pData to payload
- // b. modify pRxBlk->DataSize
-
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-#endif // CONFIG_STA_SUPPORT //
-
- ASSERT(pRxBlk->pRxPacket);
- pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
- RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
- RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
- RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
- RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
-
- //
- // copy 802.3 header, if necessary
- //
- if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
- {
-
-#ifdef CONFIG_STA_SUPPORT
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- {
-#ifdef LINUX
- NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
-#endif
-#ifdef UCOS
- NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
-#endif
- }
-#endif // CONFIG_STA_SUPPORT //
- }
-}
-
-
-#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
- do \
- { \
- if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
- { \
- Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
- } \
- else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
- { \
- Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
- } \
- else \
- { \
- Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
- } \
- } while (0);
-
-
-
-static VOID ba_enqueue_reordering_packet(
- IN PRTMP_ADAPTER pAd,
- IN PBA_REC_ENTRY pBAEntry,
- IN RX_BLK *pRxBlk,
- IN UCHAR FromWhichBSSID)
-{
- struct reordering_mpdu *mpdu_blk;
- UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
-
- mpdu_blk = ba_mpdu_blk_alloc(pAd);
- if (mpdu_blk != NULL)
- {
- // Write RxD buffer address & allocated buffer length
- NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
- mpdu_blk->Sequence = Sequence;
-
- mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
-
- convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
-
- STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
-
- //
- // it is necessary for reordering packet to record
- // which BSS it come from
- //
- RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-
- mpdu_blk->pPacket = pRxBlk->pRxPacket;
-
- if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
- {
- // had been already within reordering list
- // don't indicate
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
- ba_mpdu_blk_free(pAd, mpdu_blk);
- }
-
- ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
- NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
- }
- else
- {
-#if 0
- DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d:%d) Can't allocate reordering mpdu blk\n",
- blk_count, pBAEntry->list.qlen));
-#else
- DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
- pBAEntry->list.qlen));
-#endif
- /*
- * flush all pending reordering mpdus
- * and receving mpdu to upper layer
- * make tcp/ip to take care reordering mechanism
- */
- //ba_refresh_reordering_mpdus(pAd, pBAEntry);
- ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-
- pBAEntry->LastIndSeq = Sequence;
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- }
-}
-
-
-/*
- ==========================================================================
- Description:
- Indicate this packet to upper layer or put it into reordering buffer
-
- Parametrs:
- pRxBlk : carry necessary packet info 802.11 format
- FromWhichBSSID : the packet received from which BSS
-
- Return :
- none
-
- Note :
- the packet queued into reordering buffer need to cover to 802.3 format
- or pre_AMSDU format
- ==========================================================================
- */
-
-VOID Indicate_AMPDU_Packet(
- IN PRTMP_ADAPTER pAd,
- IN RX_BLK *pRxBlk,
- IN UCHAR FromWhichBSSID)
-{
- USHORT Idx;
- PBA_REC_ENTRY pBAEntry = NULL;
- UINT16 Sequence = pRxBlk->pHeader->Sequence;
- ULONG Now32;
- UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
- UCHAR TID = pRxBlk->pRxWI->TID;
-
-
- if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
- {
-#if 0 // sample take off, no use
- static int err_size;
-
- err_size++;
- if (err_size > 20) {
- printk("AMPDU DataSize = %d\n", pRxBlk->DataSize);
- hex_dump("802.11 Header", (UCHAR *)pRxBlk->pHeader, 24);
- hex_dump("Payload", pRxBlk->pData, 64);
- err_size = 0;
- }
-#endif
- // release packet
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
- return;
- }
-
-
-#if 0 // test
- /* Rec BA Session had been torn down */
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- return;
-#endif
-
- if (Wcid < MAX_LEN_OF_MAC_TABLE)
- {
- Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
- if (Idx == 0)
- {
- /* Rec BA Session had been torn down */
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- return;
- }
- pBAEntry = &pAd->BATable.BARecEntry[Idx];
- }
- else
- {
- // impossible !!!
- ASSERT(0);
- // release packet
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
- return;
- }
-
- ASSERT(pBAEntry);
-
- // update last rx time
- NdisGetSystemUpTime(&Now32);
-
- pBAEntry->rcvSeq = Sequence;
-
-
- ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
- pBAEntry->LastIndSeqAtTimer = Now32;
-
- //
- // Reset Last Indicate Sequence
- //
- if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
- {
- ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
-
- // reset rcv sequence of BA session
- pBAEntry->LastIndSeq = Sequence;
- pBAEntry->LastIndSeqAtTimer = Now32;
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- return;
- }
-
-
- //
- // I. Check if in order.
- //
- if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
- {
- USHORT LastIndSeq;
-
- pBAEntry->LastIndSeq = Sequence;
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
- LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
- if (LastIndSeq != RESET_RCV_SEQ)
- {
- pBAEntry->LastIndSeq = LastIndSeq;
- }
- pBAEntry->LastIndSeqAtTimer = Now32;
- }
- //
- // II. Drop Duplicated Packet
- //
- else if (Sequence == pBAEntry->LastIndSeq)
- {
-
- // drop and release packet
- pBAEntry->nDropPacket++;
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
- }
- //
- // III. Drop Old Received Packet
- //
- else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
- {
-
- // drop and release packet
- pBAEntry->nDropPacket++;
- RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
- }
- //
- // IV. Receive Sequence within Window Size
- //
- else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
- {
- ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
- }
- //
- // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
- //
- else
- {
-#if 0
- ba_refresh_reordering_mpdus(pAd, pBAEntry);
- INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-#else
- LONG WinStartSeq, TmpSeq;
-
-
- TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
- if (TmpSeq < 0)
- {
- TmpSeq = (MAXSEQ+1) + TmpSeq;
- }
- WinStartSeq = (TmpSeq+1) & MAXSEQ;
- ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
- pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
-
- pBAEntry->LastIndSeqAtTimer = Now32;
-
- ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
-
- TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
- if (TmpSeq != RESET_RCV_SEQ)
- {
- pBAEntry->LastIndSeq = TmpSeq;
- }
-#endif
- }
-}
-
-#endif // DOT11_N_SUPPORT //
-
+#include "../../rt2860/common/ba_action.c"