提交 371abf6d 编写于 作者: B Bartlomiej Zolnierkiewicz 提交者: Greg Kroah-Hartman

Staging: rt28[67]0: merge rt28[67]0/common/*.[ch]

Signed-off-by: NBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 59fe2d89
/*
*************************************************************************
* 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.
{
#ifndef RT30xx
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
#endif
#ifdef RT30xx
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
#endif
}
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 "../../rt2860/common/action.c"
/*
*************************************************************************
* 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:
aironet.h
Abstract:
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Name Date Modification logs
Paul Lin 04-06-15 Initial
*/
#ifndef __ACTION_H__
#define __ACTION_H__
typedef struct PACKED __HT_INFO_OCTET
{
UCHAR Request:1;
UCHAR Forty_MHz_Intolerant:1;
UCHAR STA_Channel_Width:1;
UCHAR Reserved:5;
} HT_INFORMATION_OCTET;
typedef struct PACKED __FRAME_HT_INFO
{
HEADER_802_11 Hdr;
UCHAR Category;
UCHAR Action;
HT_INFORMATION_OCTET HT_Info;
} FRAME_HT_INFO, *PFRAME_HT_INFO;
#endif /* __ACTION_H__ */
#include "../../rt2860/common/action.h"
/*
*************************************************************************
* 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 "../../rt2860/common/dfs.c"
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册