dect
/
linux-2.6
Archived
13
0
Fork 0

Staging: rt{28,30}70: merge rt{28,30}70/common/*.[ch]

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Bartlomiej Zolnierkiewicz 2009-04-26 16:06:23 +02:00 committed by Greg Kroah-Hartman
parent ffbc7b854e
commit d763794962
20 changed files with 20 additions and 37043 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,611 +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. *
* *
*************************************************************************
Module Name:
action.c
Abstract:
Handle association related requests either from WSTA or from local MLME
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan Lee 2006 created for rt2860
*/
#include "../rt_config.h"
#include "../action.h"
static VOID ReservedAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem);
/*
==========================================================================
Description:
association state machine init, including state transition and timer init
Parameters:
S - pointer to the association state machine
Note:
The state machine looks like the following
ASSOC_IDLE
MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
MT2_PEER_DISASSOC_REQ peer_disassoc_action
MT2_PEER_ASSOC_REQ drop
MT2_PEER_REASSOC_REQ drop
MT2_CLS3ERR cls3err_action
==========================================================================
*/
VOID ActionStateMachineInit(
IN PRTMP_ADAPTER pAd,
IN STATE_MACHINE *S,
OUT STATE_MACHINE_FUNC Trans[])
{
StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
}
VOID MlmeADDBAAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
MLME_ADDBA_REQ_STRUCT *pInfo;
UCHAR Addr[6];
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG Idx;
FRAME_ADDBA_REQ Frame;
ULONG FrameLen;
BA_ORI_ENTRY *pBAEntry = NULL;
pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
{
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if(NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
return;
}
// 1. find entry
Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
if (Idx == 0)
{
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
return;
}
else
{
pBAEntry =&pAd->BATable.BAOriEntry[Idx];
}
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
}
Frame.Category = CATEGORY_BA;
Frame.Action = ADDBA_REQ;
Frame.BaParm.AMSDUSupported = 0;
Frame.BaParm.BAPolicy = IMMED_BA;
Frame.BaParm.TID = pInfo->TID;
Frame.BaParm.BufSize = pInfo->BaBufSize;
Frame.Token = pInfo->Token;
Frame.TimeOutValue = pInfo->TimeOutValue;
Frame.BaStartSeq.field.FragNum = 0;
Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
*(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(FRAME_ADDBA_REQ), &Frame,
END_OF_ARGS);
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
}
}
/*
==========================================================================
Description:
send DELBA and delete BaEntry if any
Parametrs:
Elem - MLME message MLME_DELBA_REQ_STRUCT
IRQL = DISPATCH_LEVEL
==========================================================================
*/
VOID MlmeDELBAAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
MLME_DELBA_REQ_STRUCT *pInfo;
PUCHAR pOutBuffer = NULL;
PUCHAR pOutBuffer2 = NULL;
NDIS_STATUS NStatus;
ULONG Idx;
FRAME_DELBA_REQ Frame;
ULONG FrameLen;
FRAME_BAR FrameBar;
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))
{
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if(NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
return;
}
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
if(NStatus != 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.)
Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
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(pAd, pOutBuffer2);
DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
// SEND DELBA FRAME
FrameLen = 0;
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
}
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);
DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
}
}
VOID MlmeQOSAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
}
VOID MlmeDLSAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
}
VOID MlmeInvalidAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
//PUCHAR pOutBuffer = NULL;
//Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
}
VOID PeerQOSAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
}
VOID PeerBAAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Action = Elem->Msg[LENGTH_802_11+1];
switch(Action)
{
case ADDBA_REQ:
PeerAddBAReqAction(pAd,Elem);
break;
case ADDBA_RESP:
PeerAddBARspAction(pAd,Elem);
break;
case DELBA:
PeerDelBAAction(pAd,Elem);
break;
}
}
VOID PeerPublicAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
return;
}
static VOID ReservedAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Category;
if (Elem->MsgLen <= LENGTH_802_11)
{
return;
}
Category = Elem->Msg[LENGTH_802_11];
DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
}
VOID PeerRMAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
return;
}
static VOID respond_ht_information_exchange_action(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG FrameLen;
FRAME_HT_INFO HTINFOframe, *pFrame;
UCHAR *pAddr;
// 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 - respond_ht_information_exchange_action() allocate memory failed \n"));
return;
}
// get RA
pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
pAddr = pFrame->Hdr.Addr2;
NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
// 2-1. Prepare ADDBA Response frame.
{
if (ADHOC_ON(pAd))
ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
else
ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
}
HTINFOframe.Category = CATEGORY_HT;
HTINFOframe.Action = HT_INFO_EXCHANGE;
HTINFOframe.HT_Info.Request = 0;
HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(FRAME_HT_INFO), &HTINFOframe,
END_OF_ARGS);
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
VOID PeerHTAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Action = Elem->Msg[LENGTH_802_11+1];
if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
return;
switch(Action)
{
case NOTIFY_BW_ACTION:
DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
{
// Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
// sending BW_Notify Action frame, and cause us to linkup and linkdown.
// In legacy mode, don't need to parse HT action frame.
DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
Elem->Msg[LENGTH_802_11+2] ));
break;
}
if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
break;
case SMPS_ACTION:
// 7.3.1.25
DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
{
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
}
else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
{
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
}
else
{
pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
}
DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
// rt2860c : add something for smps change.
break;
case SETPCO_ACTION:
break;
case MIMO_CHA_MEASURE_ACTION:
break;
case HT_INFO_EXCHANGE:
{
HT_INFORMATION_OCTET *pHT_info;
pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
// 7.4.8.10
DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
if (pHT_info->Request)
{
respond_ht_information_exchange_action(pAd, Elem);
}
}
break;
}
}
/*
==========================================================================
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 ORIBATimerTimeout(
IN PRTMP_ADAPTER pAd)
{
MAC_TABLE_ENTRY *pEntry;
INT i, total;
UCHAR TID;
total = pAd->MacTab.Size * NUM_OF_TID;
for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
{
if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
{
pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
TID = pAd->BATable.BAOriEntry[i].TID;
ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
}
total --;
}
}
VOID SendRefreshBAR(
IN PRTMP_ADAPTER pAd,
IN MAC_TABLE_ENTRY *pEntry)
{
FRAME_BAR FrameBar;
ULONG FrameLen;
NDIS_STATUS NStatus;
PUCHAR pOutBuffer = NULL;
USHORT Sequence;
UCHAR i, TID;
USHORT idx;
BA_ORI_ENTRY *pBAEntry;
for (i = 0; i <NUM_OF_TID; i++)
{
idx = pEntry->BAOriWcidArray[i];
if (idx == 0)
{
continue;
}
pBAEntry = &pAd->BATable.BAOriEntry[idx];
if (pBAEntry->ORI_BA_Status == Originator_Done)
{
TID = pBAEntry->TID;
ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
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;
}
Sequence = pEntry->TxSeq[TID];
BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(FRAME_BAR), &FrameBar,
END_OF_ARGS);
if (1) // Now we always send BAR.
{
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
}
MlmeFreeMemory(pAd, pOutBuffer);
}
}
}
VOID ActHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN PUCHAR Addr1,
IN PUCHAR Addr2,
IN PUCHAR Addr3)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SUBTYPE_ACTION;
COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
}
VOID BarHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PFRAME_BAR pCntlBar,
IN PUCHAR pDA,
IN PUCHAR pSA)
{
NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
pCntlBar->FC.Type = BTYPE_CNTL;
pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
pCntlBar->BarControl.MTID = 0;
pCntlBar->BarControl.Compressed = 1;
pCntlBar->BarControl.ACKPolicy = 0;
pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
}
/*
==========================================================================
Description:
Insert Category and action code into the action frame.
Parametrs:
1. frame buffer pointer.
2. frame length.
3. category code of the frame.
4. action code of the frame.
Return : None.
==========================================================================
*/
VOID InsertActField(
IN PRTMP_ADAPTER pAd,
OUT PUCHAR pFrameBuf,
OUT PULONG pFrameLen,
IN UINT8 Category,
IN UINT8 ActCode)
{
ULONG TempLen;
MakeOutgoingFrame( pFrameBuf, &TempLen,
1, &Category,
1, &ActCode,
END_OF_ARGS);
*pFrameLen = *pFrameLen + TempLen;
return;
}
#include "../../rt2870/common/action.c"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,936 +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. *
* *
*************************************************************************
*/
/*
All functions in this file must be USB-depended, or you should out your function
in other files.
*/
#include "../rt_config.h"
/*
We can do copy the frame into pTxContext when match following conditions.
=>
=>
=>
*/
static inline NDIS_STATUS RtmpUSBCanDoWrite(
IN RTMP_ADAPTER *pAd,
IN UCHAR QueIdx,
IN HT_TX_CONTEXT *pHTTXContext)
{
NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
{
DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
}
else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
{
DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
}
else if (pHTTXContext->bCurWriting == TRUE)
{
DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
}
else
{
canWrite = NDIS_STATUS_SUCCESS;
}
return canWrite;
}
USHORT RtmpUSB_WriteSubTxResource(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN BOOLEAN bIsLast,
OUT USHORT *FreeNumber)
{
// Dummy function. Should be removed in the future.
return 0;
}
USHORT RtmpUSB_WriteFragTxResource(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN UCHAR fragNum,
OUT USHORT *FreeNumber)
{
HT_TX_CONTEXT *pHTTXContext;
USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
UINT32 fillOffset;
TXINFO_STRUC *pTxInfo;
TXWI_STRUC *pTxWI;
PUCHAR pWirelessPacket = NULL;
UCHAR QueIdx;
NDIS_STATUS Status;
unsigned long IrqFlags;
UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
BOOLEAN TxQLastRound = FALSE;
//
// get Tx Ring Resource & Dma Buffer address
//
QueIdx = pTxBlk->QueIdx;
pHTTXContext = &pAd->TxContext[QueIdx];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
pHTTXContext = &pAd->TxContext[QueIdx];
fillOffset = pHTTXContext->CurWritePosition;
if(fragNum == 0)
{
// Check if we have enough space for this bulk-out batch.
Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
if (Status == NDIS_STATUS_SUCCESS)
{
pHTTXContext->bCurWriting = TRUE;
// Reserve space for 8 bytes padding.
if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
{
pHTTXContext->ENextBulkOutPosition += 8;
pHTTXContext->CurWritePosition += 8;
fillOffset += 8;
}
pTxBlk->Priv = 0;
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
}
else
{
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
return(Status);
}
}
else
{
// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
if (Status == NDIS_STATUS_SUCCESS)
{
fillOffset += pTxBlk->Priv;
}
else
{
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
return(Status);
}
}
NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
// copy TXWI + WLAN Header + LLC into DMA Header Buffer
//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
// Build our URB for USBD
DMAHdrLen = TXWI_SIZE + hwHdrLen;
USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
USBDMApktLen += padding;
pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
if (fragNum == pTxBlk->TotalFragNum)
{
pTxInfo->USBDMATxburst = 0;
if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
{
pTxInfo->SwUseLastRound = 1;
TxQLastRound = TRUE;
}
}
else
{
pTxInfo->USBDMATxburst = 1;
}
NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
// Zero the last padding.
pWirelessPacket += pTxBlk->SrcBufLen;
NdisZeroMemory(pWirelessPacket, padding + 8);
if (fragNum == pTxBlk->TotalFragNum)
{
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
// Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
pHTTXContext->CurWritePosition += pTxBlk->Priv;
if (TxQLastRound == TRUE)
pHTTXContext->CurWritePosition = 8;
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
// Finally, set bCurWriting as FALSE
pHTTXContext->bCurWriting = FALSE;
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
// succeed and release the skb buffer
RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
}
return(Status);
}
USHORT RtmpUSB_WriteSingleTxResource(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN BOOLEAN bIsLast,
OUT USHORT *FreeNumber)
{
HT_TX_CONTEXT *pHTTXContext;
USHORT hwHdrLen;
UINT32 fillOffset;
TXINFO_STRUC *pTxInfo;
TXWI_STRUC *pTxWI;
PUCHAR pWirelessPacket;
UCHAR QueIdx;
unsigned long IrqFlags;
NDIS_STATUS Status;
UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
BOOLEAN bTxQLastRound = FALSE;
// For USB, didn't need PCI_MAP_SINGLE()
//SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
//
// get Tx Ring Resource & Dma Buffer address
//
QueIdx = pTxBlk->QueIdx;
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
pHTTXContext = &pAd->TxContext[QueIdx];
fillOffset = pHTTXContext->CurWritePosition;
// Check ring full.
Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
if(Status == NDIS_STATUS_SUCCESS)
{
pHTTXContext->bCurWriting = TRUE;
pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
// Reserve space for 8 bytes padding.
if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
{
pHTTXContext->ENextBulkOutPosition += 8;
pHTTXContext->CurWritePosition += 8;
fillOffset += 8;
}
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
// copy TXWI + WLAN Header + LLC into DMA Header Buffer
//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
// Build our URB for USBD
DMAHdrLen = TXWI_SIZE + hwHdrLen;
USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
USBDMApktLen += padding;
pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
{
pTxInfo->SwUseLastRound = 1;
bTxQLastRound = TRUE;
}
NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
// We unlock it here to prevent the first 8 bytes maybe over-writed issue.
// 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
// 2. An interrupt break our routine and handle bulk-out complete.
// 3. In the bulk-out compllete, it need to do another bulk-out,
// if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
// but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
// 4. Interrupt complete.
// 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
// 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
// and the packet will wrong.
pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
pWirelessPacket += pTxBlk->SrcBufLen;
NdisZeroMemory(pWirelessPacket, padding + 8);
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
pHTTXContext->CurWritePosition += pTxBlk->Priv;
if (bTxQLastRound)
pHTTXContext->CurWritePosition = 8;
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
pHTTXContext->bCurWriting = FALSE;
}
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
// succeed and release the skb buffer
RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
return(Status);
}
USHORT RtmpUSB_WriteMultiTxResource(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN UCHAR frameNum,
OUT USHORT *FreeNumber)
{
HT_TX_CONTEXT *pHTTXContext;
USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
UINT32 fillOffset;
TXINFO_STRUC *pTxInfo;
TXWI_STRUC *pTxWI;
PUCHAR pWirelessPacket = NULL;
UCHAR QueIdx;
NDIS_STATUS Status;
unsigned long IrqFlags;
//UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
//
// get Tx Ring Resource & Dma Buffer address
//
QueIdx = pTxBlk->QueIdx;
pHTTXContext = &pAd->TxContext[QueIdx];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
if(frameNum == 0)
{
// Check if we have enough space for this bulk-out batch.
Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
if (Status == NDIS_STATUS_SUCCESS)
{
pHTTXContext->bCurWriting = TRUE;
pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
// Reserve space for 8 bytes padding.
if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
{
pHTTXContext->CurWritePosition += 8;
pHTTXContext->ENextBulkOutPosition += 8;
}
fillOffset = pHTTXContext->CurWritePosition;
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
//
// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
//
if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
else
//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
// Update the pTxBlk->Priv.
pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
// pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
// Copy it.
NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
pWirelessPacket += pTxBlk->Priv;
}
}
else
{ // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
if (Status == NDIS_STATUS_SUCCESS)
{
fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
//hwHdrLen = pTxBlk->MpduHeaderLen;
NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
pWirelessPacket += (pTxBlk->MpduHeaderLen);
pTxBlk->Priv += pTxBlk->MpduHeaderLen;
}
else
{ // It should not happened now unless we are going to shutdown.
DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
Status = NDIS_STATUS_FAILURE;
}
}
// We unlock it here to prevent the first 8 bytes maybe over-write issue.
// 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
// 2. An interrupt break our routine and handle bulk-out complete.
// 3. In the bulk-out compllete, it need to do another bulk-out,
// if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
// but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
// 4. Interrupt complete.
// 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
// 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
// and the packet will wrong.
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
if (Status != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
goto done;
}
// Copy the frame content into DMA buffer and update the pTxBlk->Priv
NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
pWirelessPacket += pTxBlk->SrcBufLen;
pTxBlk->Priv += pTxBlk->SrcBufLen;
done:
// Release the skb buffer here
RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
return(Status);
}
VOID RtmpUSB_FinalWriteTxResource(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN USHORT totalMPDUSize,
IN USHORT TxIdx)
{
UCHAR QueIdx;
HT_TX_CONTEXT *pHTTXContext;
UINT32 fillOffset;
TXINFO_STRUC *pTxInfo;
TXWI_STRUC *pTxWI;
UINT32 USBDMApktLen, padding;
unsigned long IrqFlags;
PUCHAR pWirelessPacket;
QueIdx = pTxBlk->QueIdx;
pHTTXContext = &pAd->TxContext[QueIdx];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
if (pHTTXContext->bCurWriting == TRUE)
{
fillOffset = pHTTXContext->CurWritePosition;
if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
&& (pHTTXContext->bCopySavePad == TRUE))
pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
else
pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
//
// Update TxInfo->USBDMApktLen ,
// the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
//
pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
// Calculate the bulk-out padding
USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
USBDMApktLen += padding;
pTxInfo->USBDMATxPktLen = USBDMApktLen;
//
// Update TXWI->MPDUtotalByteCount ,
// the length = 802.11 header + payload_of_all_batch_frames
pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
pTxWI->MPDUtotalByteCount = totalMPDUSize;
//
// Update the pHTTXContext->CurWritePosition
//
pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
{ // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
pHTTXContext->CurWritePosition = 8;
pTxInfo->SwUseLastRound = 1;
}
pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
//
// Zero the last padding.
//
pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
NdisZeroMemory(pWirelessPacket, padding + 8);
// Finally, set bCurWriting as FALSE
pHTTXContext->bCurWriting = FALSE;
}
else
{ // It should not happened now unless we are going to shutdown.
DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
}
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
}
VOID RtmpUSBDataLastTxIdx(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN USHORT TxIdx)
{
// DO nothing for USB.
}
/*
When can do bulk-out:
1. TxSwFreeIdx < TX_RING_SIZE;
It means has at least one Ring entity is ready for bulk-out, kick it out.
2. If TxSwFreeIdx == TX_RING_SIZE
Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
*/
VOID RtmpUSBDataKickOut(
IN PRTMP_ADAPTER pAd,
IN TX_BLK *pTxBlk,
IN UCHAR QueIdx)
{
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
RTUSBKickBulkOut(pAd);
}
/*
Must be run in Interrupt context
This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
*/
int RtmpUSBMgmtKickOut(
IN RTMP_ADAPTER *pAd,
IN UCHAR QueIdx,
IN PNDIS_PACKET pPacket,
IN PUCHAR pSrcBufVA,
IN UINT SrcBufLen)
{
PTXINFO_STRUC pTxInfo;
ULONG BulkOutSize;
UCHAR padLen;
PUCHAR pDest;
ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
unsigned long IrqFlags;
pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
// Build our URB for USBD
BulkOutSize = SrcBufLen;
BulkOutSize = (BulkOutSize + 3) & (~3);
RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
BulkOutSize += 4; // Always add 4 extra bytes at every packet.
// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
BulkOutSize += 4;
padLen = BulkOutSize - SrcBufLen;
ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
// Now memzero all extra padding bytes.
pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
NdisZeroMemory(pDest, padLen);
RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
// Length in TxInfo should be 8 less than bulkout size.
pMLMEContext->BulkOutSize = BulkOutSize;
pMLMEContext->InUse = TRUE;
pMLMEContext->bWaitingBulkOut = TRUE;
//for debug
//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
//pAd->RalinkCounters.KickTxCount++;
//pAd->RalinkCounters.OneSecTxDoneCount++;
//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
// needKickOut = TRUE;
// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
pAd->MgmtRing.TxSwFreeIdx--;
INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
//if (needKickOut)
RTUSBKickBulkOut(pAd);
return 0;
}
VOID RtmpUSBNullFrameKickOut(
IN RTMP_ADAPTER *pAd,
IN UCHAR QueIdx,
IN UCHAR *pNullFrame,
IN UINT32 frameLen)
{
if (pAd->NullContext.InUse == FALSE)
{
PTX_CONTEXT pNullContext;
PTXINFO_STRUC pTxInfo;
PTXWI_STRUC pTxWI;
PUCHAR pWirelessPkt;
pNullContext = &(pAd->NullContext);
// Set the in use bit
pNullContext->InUse = TRUE;
pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
RTMPZeroMemory(&pWirelessPkt[0], 100);
pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
pTxInfo->QSEL = FIFO_EDCA;
pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
// Fill out frame length information for global Bulk out arbitor
//pNullContext->BulkOutSize = TransferBufferLength;
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
// Kick bulk out
RTUSBKickBulkOut(pAd);
}
}
/*
========================================================================
Routine Description:
Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
Arguments:
pRxD Pointer to the Rx descriptor
Return Value:
NDIS_STATUS_SUCCESS No err
NDIS_STATUS_FAILURE Error
Note:
========================================================================
*/
NDIS_STATUS RTMPCheckRxError(
IN PRTMP_ADAPTER pAd,
IN PHEADER_802_11 pHeader,
IN PRXWI_STRUC pRxWI,
IN PRT28XX_RXD_STRUC pRxINFO)
{
PCIPHER_KEY pWpaKey;
INT dBm;
if (pAd->bPromiscuous == TRUE)
return(NDIS_STATUS_SUCCESS);
if(pRxINFO == NULL)
return(NDIS_STATUS_FAILURE);
// Phy errors & CRC errors
if (pRxINFO->Crc)
{
// Check RSSI for Noise Hist statistic collection.
dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
if (dBm <= -87)
pAd->StaCfg.RPIDensity[0] += 1;
else if (dBm <= -82)
pAd->StaCfg.RPIDensity[1] += 1;
else if (dBm <= -77)
pAd->StaCfg.RPIDensity[2] += 1;
else if (dBm <= -72)
pAd->StaCfg.RPIDensity[3] += 1;
else if (dBm <= -67)
pAd->StaCfg.RPIDensity[4] += 1;
else if (dBm <= -62)
pAd->StaCfg.RPIDensity[5] += 1;
else if (dBm <= -57)
pAd->StaCfg.RPIDensity[6] += 1;
else if (dBm > -57)
pAd->StaCfg.RPIDensity[7] += 1;
return(NDIS_STATUS_FAILURE);
}
// Add Rx size to channel load counter, we should ignore error counts
pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
if (pHeader->FC.ToDs)
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
return NDIS_STATUS_FAILURE;
}
// Paul 04-03 for OFDM Rx length issue
if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
return NDIS_STATUS_FAILURE;
}
// Drop not U2M frames, cant's drop here because we will drop beacon in this case
// I am kind of doubting the U2M bit operation
// if (pRxD->U2M == 0)
// return(NDIS_STATUS_FAILURE);
// drop decyption fail frame
if (pRxINFO->Decrypted && pRxINFO->CipherErr)
{
//
// MIC Error
//
if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
{
pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
RTMPReportMicError(pAd, pWpaKey);
DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
}
if (pRxINFO->Decrypted &&
(pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
(pHeader->Sequence == pAd->FragFrame.Sequence))
{
//
// Acceptable since the First FragFrame no CipherErr problem.
//
return(NDIS_STATUS_SUCCESS);
}
return(NDIS_STATUS_FAILURE);
}
return(NDIS_STATUS_SUCCESS);
}
VOID RT28xxUsbStaAsicForceWakeup(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bFromTx)
{
AUTO_WAKEUP_STRUC AutoWakeupCfg;
AutoWakeupCfg.word = 0;
RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
}
VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
IN PRTMP_ADAPTER pAd,
IN USHORT TbttNumToNextWakeUp)
{
AUTO_WAKEUP_STRUC AutoWakeupCfg;
// we have decided to SLEEP, so at least do it for a BEACON period.
if (TbttNumToNextWakeUp == 0)
TbttNumToNextWakeUp = 1;
AutoWakeupCfg.word = 0;
RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
AutoWakeupCfg.field.EnableAutoWakeup = 1;
AutoWakeupCfg.field.AutoLeadTime = 5;
RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
}
VOID RT28xxUsbMlmeRadioOn(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
return;
AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
RTMPusecDelay(10000);
NICResetFromError(pAd);
// Enable Tx/Rx
RTMPEnableRxTx(pAd);
#ifdef RT3070
if (IS_RT3071(pAd))
{
RT30xxReverseRFSleepModeSetup(pAd);
}
#endif // RT3070 //
// Clear Radio off flag
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
RTUSBBulkReceive(pAd);
// Set LED
RTMPSetLED(pAd, LED_RADIO_ON);
}
VOID RT28xxUsbMlmeRadioOFF(
IN PRTMP_ADAPTER pAd)
{
WPDMA_GLO_CFG_STRUC GloCfg;
UINT32 Value, i;
DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
return;
// Set LED
RTMPSetLED(pAd, LED_RADIO_OFF);
// Set Radio off flag
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
{
// Link down first if any association exists
if (INFRA_ON(pAd) || ADHOC_ON(pAd))
LinkDown(pAd, FALSE);
RTMPusecDelay(10000);
//==========================================
// Clean up old bss table
BssTableInit(&pAd->ScanTab);
}
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
{
// Must using 40MHz.
AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
}
else
{
// Must using 20MHz.
AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
}
// Disable Tx/Rx DMA
RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
GloCfg.field.EnableTxDMA = 0;
GloCfg.field.EnableRxDMA = 0;
RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
// Waiting for DMA idle
i = 0;
do
{
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
break;
RTMPusecDelay(1000);
}while (i++ < 100);
// Disable MAC Tx/Rx
RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
Value &= (0xfffffff3);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
}
#include "../../rt2870/common/cmm_data_2870.c"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,617 +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. *
* *
*************************************************************************
Module Name:
sync.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Chang 2004-09-01 modified for rt2561/2661
*/
#include "../rt_config.h"
// 2.4 Ghz channel plan index in the TxPower arrays.
#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
#define BG_BAND_REGION_0_SIZE 11
#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_1_SIZE 13
#define BG_BAND_REGION_2_START 9 // 10,11
#define BG_BAND_REGION_2_SIZE 2
#define BG_BAND_REGION_3_START 9 // 10,11,12,13
#define BG_BAND_REGION_3_SIZE 4
#define BG_BAND_REGION_4_START 13 // 14
#define BG_BAND_REGION_4_SIZE 1
#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_5_SIZE 14
#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
#define BG_BAND_REGION_6_SIZE 7
#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
#define BG_BAND_REGION_7_SIZE 9
#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
#define BG_BAND_REGION_31_SIZE 14
// 5 Ghz channel plan index in the TxPower arrays.
UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
UCHAR BaSizeArray[4] = {8,16,32,64};
/*
==========================================================================
Description:
Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
and 3) PHY-mode user selected.
The outcome is used by driver when doing site survey.
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
==========================================================================
*/
VOID BuildChannelList(
IN PRTMP_ADAPTER pAd)
{
UCHAR i, j, index=0, num=0;
PUCHAR pChannelList = NULL;
NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
// if not 11a-only mode, channel list starts from 2.4Ghz band
if ((pAd->CommonCfg.PhyMode != PHY_11A)
&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
)
{
switch (pAd->CommonCfg.CountryRegion & 0x7f)
{
case REGION_0_BG_BAND: // 1 -11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
index += BG_BAND_REGION_0_SIZE;
break;
case REGION_1_BG_BAND: // 1 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
index += BG_BAND_REGION_1_SIZE;
break;
case REGION_2_BG_BAND: // 10 - 11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
index += BG_BAND_REGION_2_SIZE;
break;
case REGION_3_BG_BAND: // 10 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
index += BG_BAND_REGION_3_SIZE;
break;
case REGION_4_BG_BAND: // 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
index += BG_BAND_REGION_4_SIZE;
break;
case REGION_5_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
index += BG_BAND_REGION_5_SIZE;
break;
case REGION_6_BG_BAND: // 3 - 9
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
index += BG_BAND_REGION_6_SIZE;
break;
case REGION_7_BG_BAND: // 5 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
index += BG_BAND_REGION_7_SIZE;
break;
case REGION_31_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
index += BG_BAND_REGION_31_SIZE;
break;
default: // Error. should never happen
break;
}
for (i=0; i<index; i++)
pAd->ChannelList[i].MaxTxPwr = 20;
}
if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
)
{
switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
{
case REGION_0_A_BAND:
num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
break;
case REGION_1_A_BAND:
num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
break;
case REGION_2_A_BAND:
num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
break;
case REGION_3_A_BAND:
num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
break;
case REGION_4_A_BAND:
num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
break;
case REGION_5_A_BAND:
num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
break;
case REGION_6_A_BAND:
num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
break;
case REGION_7_A_BAND:
num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
break;
case REGION_8_A_BAND:
num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
break;
case REGION_9_A_BAND:
num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
break;
case REGION_10_A_BAND:
num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
break;
case REGION_11_A_BAND:
num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
break;
default: // Error. should never happen
DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
break;
}
if (num != 0)
{
UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
for (i=0; i<num; i++)
{
for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
{
if (pChannelList[i] == pAd->TxPower[j].Channel)
NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
}
for (j=0; j<15; j++)
{
if (pChannelList[i] == RadarCh[j])
pAd->ChannelList[index+i].DfsReq = TRUE;
}
pAd->ChannelList[index+i].MaxTxPwr = 20;
}
index += num;
}
}
pAd->ChannelListNum = index;
DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
#ifdef DBG
for (i=0;i<pAd->ChannelListNum;i++)
{
DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
}
#endif
}
/*
==========================================================================
Description:
This routine return the first channel number according to the country
code selection and RF IC selection (signal band or dual band). It is called
whenever driver need to start a site survey of all supported channels.
Return:
ch - the first channel number of current country code setting
IRQL = PASSIVE_LEVEL
==========================================================================
*/
UCHAR FirstChannel(
IN PRTMP_ADAPTER pAd)
{
return pAd->ChannelList[0].Channel;
}
/*
==========================================================================
Description:
This routine returns the next channel number. This routine is called
during driver need to start a site survey of all supported channels.
Return:
next_channel - the next channel number valid in current country code setting.
Note:
return 0 if no more next channel
==========================================================================
*/
UCHAR NextChannel(
IN PRTMP_ADAPTER pAd,
IN UCHAR channel)
{
int i;
UCHAR next_channel = 0;
for (i = 0; i < (pAd->ChannelListNum - 1); i++)
if (channel == pAd->ChannelList[i].Channel)
{
next_channel = pAd->ChannelList[i+1].Channel;
break;
}
return next_channel;
}
/*
==========================================================================
Description:
This routine is for Cisco Compatible Extensions 2.X
Spec31. AP Control of Client Transmit Power
Return:
None
Note:
Required by Aironet dBm(mW)
0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
17dBm(50mw), 20dBm(100mW)
We supported
3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
14dBm(75%), 15dBm(100%)
The client station's actual transmit power shall be within +/- 5dB of
the minimum value or next lower value.
==========================================================================
*/
VOID ChangeToCellPowerLimit(
IN PRTMP_ADAPTER pAd,
IN UCHAR AironetCellPowerLimit)
{
//valud 0xFF means that hasn't found power limit information
//from the AP's Beacon/Probe response.
if (AironetCellPowerLimit == 0xFF)
return;
if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
pAd->CommonCfg.TxPowerPercentage = 6;
else if (AironetCellPowerLimit < 9)
pAd->CommonCfg.TxPowerPercentage = 10;
else if (AironetCellPowerLimit < 12)
pAd->CommonCfg.TxPowerPercentage = 25;
else if (AironetCellPowerLimit < 14)
pAd->CommonCfg.TxPowerPercentage = 50;
else if (AironetCellPowerLimit < 15)
pAd->CommonCfg.TxPowerPercentage = 75;
else
pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
}
CHAR ConvertToRssi(
IN PRTMP_ADAPTER pAd,
IN CHAR Rssi,
IN UCHAR RssiNumber)
{
UCHAR RssiOffset, LNAGain;
// Rssi equals to zero should be an invalid value
if (Rssi == 0)
return -99;
LNAGain = GET_LNA_GAIN(pAd);
if (pAd->LatchRfRegs.Channel > 14)
{
if (RssiNumber == 0)
RssiOffset = pAd->ARssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->ARssiOffset1;
else
RssiOffset = pAd->ARssiOffset2;
}
else
{
if (RssiNumber == 0)
RssiOffset = pAd->BGRssiOffset0;
else if (RssiNumber == 1)
RssiOffset = pAd->BGRssiOffset1;
else
RssiOffset = pAd->BGRssiOffset2;
}
return (-12 - RssiOffset - LNAGain - Rssi);
}
/*
==========================================================================
Description:
Scan next channel
==========================================================================
*/
VOID ScanNextChannel(
IN PRTMP_ADAPTER pAd)
{
HEADER_802_11 Hdr80211;
PUCHAR pOutBuffer = NULL;
NDIS_STATUS NStatus;
ULONG FrameLen = 0;
UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
USHORT Status;
PHEADER_802_11 pHdr80211;
UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
if (MONITOR_ON(pAd))
return;
if (pAd->MlmeAux.Channel == 0)
{
if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
&& (INFRA_ON(pAd)
|| (pAd->OpMode == OPMODE_AP))
)
{
AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue &= (~0x18);
BBPValue |= 0x10;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
}
else
{
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
}
{
//
// To prevent data lost.
// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
//
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
{
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
if (NStatus == NDIS_STATUS_SUCCESS)
{
pHdr80211 = (PHEADER_802_11) pOutBuffer;
MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
pHdr80211->Duration = 0;
pHdr80211->FC.Type = BTYPE_DATA;
pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
// Send using priority queue
MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
MlmeFreeMemory(pAd, pOutBuffer);
RTMPusecDelay(5000);
}
}
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_SUCCESS;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}
#ifdef RT2870
else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
}
#endif // RT2870 //
else
{
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
AsicForceWakeup(pAd, TRUE);
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
MlmeSetPsmBit(pAd, PWR_ACTIVE);
}
AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
AsicLockChannel(pAd, pAd->MlmeAux.Channel);
{
if (pAd->MlmeAux.Channel > 14)
{
if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
{
ScanType = SCAN_PASSIVE;
ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
}
}
}
//Global country domain(ch1-11:active scan, ch12-14 passive scan)
if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
{
ScanType = SCAN_PASSIVE;
}
// We need to shorten active scan time in order for WZC connect issue
// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
if (ScanType == FAST_SCAN_ACTIVE)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
else if (((ScanType == SCAN_CISCO_ACTIVE) ||
(ScanType == SCAN_CISCO_PASSIVE) ||
(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
{
if (pAd->StaCfg.CCXScanTime < 25)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
}
else // must be SCAN_PASSIVE or SCAN_ACTIVE
{
if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
)
{
if (pAd->MlmeAux.Channel > 14)
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
}
else
RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
}
if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
(ScanType == SCAN_CISCO_ACTIVE))
{
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_FAIL_NO_RESOURCE;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
return;
}
// There is no need to send broadcast probe request if active scan is in effect.
if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
)
SsidLen = pAd->MlmeAux.SsidLen;
else
SsidLen = 0;
MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &Hdr80211,
1, &SsidIe,
1, &SsidLen,
SsidLen, pAd->MlmeAux.Ssid,
1, &SupRateIe,
1, &pAd->CommonCfg.SupRateLen,
pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
END_OF_ARGS);
if (pAd->CommonCfg.ExtRateLen)
{
ULONG Tmp;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &ExtRateIe,
1, &pAd->CommonCfg.ExtRateLen,
pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
END_OF_ARGS);
FrameLen += Tmp;
}
if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
{
ULONG Tmp;
UCHAR HtLen;
UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
if (pAd->bBroadComHT == TRUE)
{
HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &WpaIe,
1, &HtLen,
4, &BROADCOM[0],
pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
END_OF_ARGS);
}
else
{
HtLen = pAd->MlmeAux.HtCapabilityLen;
MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
1, &HtCapIe,
1, &HtLen,
HtLen, &pAd->CommonCfg.HtCapability,
END_OF_ARGS);
}
FrameLen += Tmp;
}
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
MlmeFreeMemory(pAd, pOutBuffer);
}
// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
}
}
VOID MgtProbReqMacHeaderInit(
IN PRTMP_ADAPTER pAd,
IN OUT PHEADER_802_11 pHdr80211,
IN UCHAR SubType,
IN UCHAR ToDs,
IN PUCHAR pDA,
IN PUCHAR pBssid)
{
NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
pHdr80211->FC.Type = BTYPE_MGMT;
pHdr80211->FC.SubType = SubType;
if (SubType == SUBTYPE_ACK)
pHdr80211->FC.Type = BTYPE_CNTL;
pHdr80211->FC.ToDs = ToDs;
COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
}
#include "../../rt2870/common/cmm_sync.c"

File diff suppressed because it is too large Load Diff

View File

@ -1,432 +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. *
* *
*************************************************************************
Module Name:
ap_dfs.c
Abstract:
Support DFS function.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Fonchi 03-12-2007 created
*/
#include "../rt_config.h"
typedef struct _RADAR_DURATION_TABLE
{
ULONG RDDurRegion;
ULONG RadarSignalDuration;
ULONG Tolerance;
} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
{
{9, 250, 250, 250}, // CE
{4, 250, 250, 250}, // FCC
{4, 250, 250, 250}, // JAP
{15, 250, 250, 250}, // JAP_W53
{4, 250, 250, 250} // JAP_W56
};
/*
========================================================================
Routine Description:
Bbp Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID BbpRadarDetectionStart(
IN PRTMP_ADAPTER pAd)
{
UINT8 RadarPeriod;
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
RadarDetectionStart(pAd, 0, RadarPeriod);
return;
}
/*
========================================================================
Routine Description:
Bbp Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID BbpRadarDetectionStop(
IN PRTMP_ADAPTER pAd)
{
RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
RadarDetectionStop(pAd);
return;
}
/*
========================================================================
Routine Description:
Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
========================================================================
*/
VOID RadarDetectionStart(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN CTSProtect,
IN UINT8 CTSPeriod)
{
UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
if (CTSProtect != 0)
{
switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
{
case FCC:
case JAP_W56:
CtsProtect = 0x03;
break;
case CE:
case JAP_W53:
default:
CtsProtect = 0x02;
break;
}
}
else
CtsProtect = 0x01;
// send start-RD with CTS protection command to MCU
// highbyte [7] reserve
// highbyte [6:5] 0x: stop Carrier/Radar detection
// highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
// highbyte [4:0] Radar/carrier detection duration. In 1ms.
// lowbyte [7:0] Radar/carrier detection period, in 1ms.
AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
//AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
return;
}
/*
========================================================================
Routine Description:
Radar detection routine
Arguments:
pAd Pointer to our adapter
Return Value:
TRUE Found radar signal
FALSE Not found radar signal
========================================================================
*/
VOID RadarDetectionStop(
IN PRTMP_ADAPTER pAd)
{
DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
return;
}
/*
========================================================================
Routine Description:
Radar channel check routine
Arguments:
pAd Pointer to our adapter
Return Value:
TRUE need to do radar detect
FALSE need not to do radar detect
========================================================================
*/
BOOLEAN RadarChannelCheck(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ch)
{
#if 1
INT i;
BOOLEAN result = FALSE;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (Ch == pAd->ChannelList[i].Channel)
{
result = pAd->ChannelList[i].DfsReq;
break;
}
}
return result;
#else
INT i;
UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
for (i=0; i<15; i++)
{
if (Ch == Channel[i])
{
break;
}
}
if (i != 15)
return TRUE;
else
return FALSE;
#endif
}
ULONG JapRadarType(
IN PRTMP_ADAPTER pAd)
{
ULONG i;
const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
{
return pAd->CommonCfg.RadarDetect.RDDurRegion;
}
for (i=0; i<15; i++)
{
if (pAd->CommonCfg.Channel == Channel[i])
{
break;
}
}
if (i < 4)
return JAP_W53;
else if (i < 15)
return JAP_W56;
else
return JAP; // W52
}
ULONG RTMPBbpReadRadarDuration(
IN PRTMP_ADAPTER pAd)
{
UINT8 byteValue = 0;
ULONG result;
BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
result = 0;
switch (byteValue)
{
case 1: // radar signal detected by pulse mode.
case 2: // radar signal detected by width mode.
result = RTMPReadRadarDuration(pAd);
break;
case 0: // No radar signal.
default:
result = 0;
break;
}
return result;
}
ULONG RTMPReadRadarDuration(
IN PRTMP_ADAPTER pAd)
{
ULONG result = 0;
return result;
}
VOID RTMPCleanRadarDuration(
IN PRTMP_ADAPTER pAd)
{
return;
}
/*
========================================================================
Routine Description:
Radar wave detection. The API should be invoke each second.
Arguments:
pAd - Adapter pointer
Return Value:
None
========================================================================
*/
VOID ApRadarDetectPeriodic(
IN PRTMP_ADAPTER pAd)
{
INT i;
pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
for (i=0; i<pAd->ChannelListNum; i++)
{
if (pAd->ChannelList[i].RemainingTimeForUse > 0)
{
pAd->ChannelList[i].RemainingTimeForUse --;
if ((pAd->Mlme.PeriodicRound%5) == 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
}
}
}
//radar detect
if ((pAd->CommonCfg.Channel > 14)
&& (pAd->CommonCfg.bIEEE80211H == 1)
&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
{
RadarDetectPeriodic(pAd);
}
return;
}
// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
// Before switch channel, driver needs doing channel switch announcement.
VOID RadarDetectPeriodic(
IN PRTMP_ADAPTER pAd)
{
// need to check channel availability, after switch channel
if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
return;
// channel availability check time is 60sec, use 65 for assurance
if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
{
DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
BbpRadarDetectionStop(pAd);
AsicEnableBssSync(pAd);
pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
return;
}
return;
}
/*
==========================================================================
Description:
change channel moving time for DFS testing.
Arguments:
pAdapter Pointer to our adapter
wrq Pointer to the ioctl argument
Return Value:
None
Note:
Usage:
1.) iwpriv ra0 set ChMovTime=[value]
==========================================================================
*/
INT Set_ChMovingTime_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
UINT8 Value;
Value = simple_strtol(arg, 0, 10);
pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
pAd->CommonCfg.RadarDetect.ChMovingTime));
return TRUE;
}
INT Set_LongPulseRadarTh_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
UINT8 Value;
Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __func__,
pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
return TRUE;
}
#include "../../rt2870/common/dfs.c"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,497 +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. *
* *
*************************************************************************
Module Name:
rtmp_wep.c
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Paul Wu 10-28-02 Initial
*/
#include "../rt_config.h"
UINT FCSTAB_32[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*
========================================================================
Routine Description:
Init WEP function.
Arguments:
pAd Pointer to our adapter
pKey Pointer to the WEP KEY
KeyId WEP Key ID
KeyLen the length of WEP KEY
pDest Pointer to the destination which Encryption data will store in.
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPInitWepEngine(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pKey,
IN UCHAR KeyId,
IN UCHAR KeyLen,
IN OUT PUCHAR pDest)
{
UINT i;
UCHAR WEPKEY[] = {
//IV
0x00, 0x11, 0x22,
//WEP KEY
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
};
pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
{
ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
}
else
{
NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
for(i = 0; i < 3; i++)
WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
}
*(pDest+3) = (KeyId << 6); //Append KEYID
}
/*
========================================================================
Routine Description:
Encrypt transimitted data
Arguments:
pAd Pointer to our adapter
pSrc Pointer to the transimitted source data that will be encrypt
pDest Pointer to the destination where entryption data will be store in.
Len Indicate the length of the source data
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID RTMPEncryptData(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pSrc,
IN PUCHAR pDest,
IN UINT Len)
{
pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
}
/*
========================================================================
Routine Description:
Decrypt received WEP data
Arguments:
pAdapter Pointer to our adapter
pSrc Pointer to the received data
Len the length of the received data
Return Value:
TRUE Decrypt WEP data success
FALSE Decrypt WEP data failed
Note:
========================================================================
*/
BOOLEAN RTMPSoftDecryptWEP(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN ULONG DataByteCnt,
IN PCIPHER_KEY pGroupKey)
{
UINT trailfcs;
UINT crc32;
UCHAR KeyIdx;
UCHAR WEPKEY[] = {
//IV
0x00, 0x11, 0x22,
//WEP KEY
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
};
UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
ULONG payload_len = DataByteCnt - LENGTH_802_11;
NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
if (pGroupKey[KeyIdx].KeyLen == 0)
return (FALSE);
NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
crc32 ^= 0xffffffff; /* complement */
if(crc32 != cpu2le32(trailfcs))
{
DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
return (FALSE);
}
return (TRUE);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pKey Pointer to the WEP KEY
KeyLen Indicate the length fo the WEP KEY
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID ARCFOUR_INIT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pKey,
IN UINT KeyLen)
{
UCHAR t, u;
UINT keyindex;
UINT stateindex;
PUCHAR state;
UINT counter;
state = Ctx->STATE;
Ctx->X = 0;
Ctx->Y = 0;
for (counter = 0; counter < 256; counter++)
state[counter] = (UCHAR)counter;
keyindex = 0;
stateindex = 0;
for (counter = 0; counter < 256; counter++)
{
t = state[counter];
stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
u = state[stateindex];
state[stateindex] = t;
state[counter] = u;
if (++keyindex >= KeyLen)
keyindex = 0;
}
}
/*
========================================================================
Routine Description:
Get bytes from ARCFOUR CONTEXT (S-BOX)
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
Return Value:
UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
Note:
========================================================================
*/
UCHAR ARCFOUR_BYTE(
IN PARCFOURCONTEXT Ctx)
{
UINT x;
UINT y;
UCHAR sx, sy;
PUCHAR state;
state = Ctx->STATE;
x = (Ctx->X + 1) & 0xff;
sx = state[x];
y = (sx + Ctx->Y) & 0xff;
sy = state[y];
Ctx->X = x;
Ctx->Y = y;
state[y] = sx;
state[x] = sy;
return(state[(sx + sy) & 0xff]);
}
/*
========================================================================
Routine Description:
The Stream Cipher Decryption Algorithm
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source data
Return Value:
None
Note:
========================================================================
*/
VOID ARCFOUR_DECRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source dta
Return Value:
None
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
VOID ARCFOUR_ENCRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
Arguments:
Ctx Pointer to ARCFOUR CONTEXT (SBOX)
pDest Pointer to the Destination
pSrc Pointer to the Source data
Len Indicate the length of the Source dta
========================================================================
*/
VOID WPAARCFOUR_ENCRYPT(
IN PARCFOURCONTEXT Ctx,
IN PUCHAR pDest,
IN PUCHAR pSrc,
IN UINT Len)
{
UINT i;
//discard first 256 bytes
for (i = 0; i < 256; i++)
ARCFOUR_BYTE(Ctx);
for (i = 0; i < Len; i++)
pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
}
/*
========================================================================
Routine Description:
Calculate a new FCS given the current FCS and the new data.
Arguments:
Fcs the original FCS value
Cp pointer to the data which will be calculate the FCS
Len the length of the data
Return Value:
UINT - FCS 32 bits
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
UINT RTMP_CALC_FCS32(
IN UINT Fcs,
IN PUCHAR Cp,
IN INT Len)
{
while (Len--)
Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
return (Fcs);
}
/*
========================================================================
Routine Description:
Get last FCS and encrypt it to the destination
Arguments:
pDest Pointer to the Destination
Return Value:
None
Note:
========================================================================
*/
VOID RTMPSetICV(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pDest)
{
pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
}
#include "../../rt2870/common/rtmp_wep.c"

File diff suppressed because it is too large Load Diff

View File

@ -1,218 +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. *
* *
*************************************************************************
Module Name:
rtusb_data.c
Abstract:
Ralink USB driver Tx/Rx functions.
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan 03-25-2006 created
*/
#include "../rt_config.h"
extern UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
extern UCHAR EpToQueue[];
VOID REPORT_AMSDU_FRAMES_TO_LLC(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN ULONG DataSize)
{
PNDIS_PACKET pPacket;
UINT nMSDU;
struct sk_buff *pSkb;
nMSDU = 0;
/* allocate a rx packet */
pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
if (pSkb)
{
/* convert 802.11 to 802.3 packet */
pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
}
else
{
DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
}
}
NDIS_STATUS RTUSBFreeDescriptorRequest(
IN PRTMP_ADAPTER pAd,
IN UCHAR BulkOutPipeId,
IN UINT32 NumberRequired)
{
// UCHAR FreeNumber = 0;
// UINT Index;
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
unsigned long IrqFlags;
HT_TX_CONTEXT *pHTTXContext;
pHTTXContext = &pAd->TxContext[BulkOutPipeId];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
{
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
}
else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
{
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
}
else if (pHTTXContext->bCurWriting == TRUE)
{
DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
}
else
{
Status = NDIS_STATUS_SUCCESS;
}
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
return (Status);
}
NDIS_STATUS RTUSBFreeDescriptorRelease(
IN RTMP_ADAPTER *pAd,
IN UCHAR BulkOutPipeId)
{
unsigned long IrqFlags;
HT_TX_CONTEXT *pHTTXContext;
pHTTXContext = &pAd->TxContext[BulkOutPipeId];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
pHTTXContext->bCurWriting = FALSE;
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
return (NDIS_STATUS_SUCCESS);
}
BOOLEAN RTUSBNeedQueueBackForAgg(
IN RTMP_ADAPTER *pAd,
IN UCHAR BulkOutPipeId)
{
unsigned long IrqFlags;
HT_TX_CONTEXT *pHTTXContext;
BOOLEAN needQueBack = FALSE;
pHTTXContext = &pAd->TxContext[BulkOutPipeId];
RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
{
if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
(((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
{
needQueBack = TRUE;
}
else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
{
needQueBack = TRUE;
}
}
RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
return needQueBack;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID RTUSBRejectPendingPackets(
IN PRTMP_ADAPTER pAd)
{
UCHAR Index;
PQUEUE_ENTRY pEntry;
PNDIS_PACKET pPacket;
PQUEUE_HEADER pQueue;
for (Index = 0; Index < 4; Index++)
{
NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
while (pAd->TxSwQueue[Index].Head != NULL)
{
pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
pEntry = RemoveHeadQueue(pQueue);
pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
}
NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
}
}
VOID RTMPWriteTxInfo(
IN PRTMP_ADAPTER pAd,
IN PTXINFO_STRUC pTxInfo,
IN USHORT USBDMApktLen,
IN BOOLEAN bWiv,
IN UCHAR QueueSel,
IN UCHAR NextValid,
IN UCHAR TxBurst)
{
pTxInfo->USBDMATxPktLen = USBDMApktLen;
pTxInfo->QSEL = QueueSel;
if (QueueSel != FIFO_EDCA)
DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
pTxInfo->USBDMANextVLD = FALSE; //NextValid; // Need to check with Jan about this.
pTxInfo->USBDMATxburst = TxBurst;
pTxInfo->WIV = bWiv;
pTxInfo->SwUseLastRound = 0;
pTxInfo->rsv = 0;
pTxInfo->rsv2 = 0;
}
#include "../../rt2870/common/rtusb_data.c"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff