📄 dls.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: dls.c Abstract: Handle WMM-DLS state machine Revision History: Who When What -------- ---------- ---------------------------------------------- Rory Chen 02-14-2006 Arvin Tai 06-03-2008 Modified for RT28xx */#include "rt_config.h"/* ========================================================================== Description: dls state machine init, including state transition and timer init Parameters: Sm - pointer to the dls state machine Note: The state machine looks like this DLS_IDLE MT2_MLME_DLS_REQUEST MlmeDlsReqAction MT2_PEER_DLS_REQUEST PeerDlsReqAction MT2_PEER_DLS_RESPONSE PeerDlsRspAction MT2_MLME_DLS_TEARDOWN MlmeTearDownAction MT2_PEER_DLS_TEARDOWN PeerTearDownAction IRQL = PASSIVE_LEVEL ========================================================================== */void DlsStateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *Sm, OUT STATE_MACHINE_FUNC Trans[]) { UCHAR i; StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE); // the first column StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction); StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction); StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction); StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction); StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction); for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++) { pAd->StaCfg.DLSEntry[i].pAd = pAd; RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE); }}/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */VOID MlmeDlsReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; HEADER_802_11 DlsReqHdr; PRT_802_11_DLS pDLS = NULL; UCHAR Category = CATEGORY_DLS; UCHAR Action = ACTION_DLS_REQUEST; ULONG tmp; USHORT reason; ULONG Timeout; BOOLEAN TimerCancelled; if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason)) return; DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n")); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n")); return; } ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); // Build basic frame first MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DlsReqHdr, 1, &Category, 1, &Action, 6, &pDLS->MacAddr, 6, pAd->CurrentAddress, 2, &pAd->StaActive.CapabilityInfo, 2, &pDLS->TimeOut, 1, &SupRateIe, 1, &pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, END_OF_ARGS); if (pAd->MlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; }#ifdef DOT11_N_SUPPORT if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { UCHAR HtLen;#ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp;#endif // add HT Capability IE HtLen = sizeof(HT_CAPABILITY_IE);#ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS);#else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS);#endif FrameLen = FrameLen + tmp; }#endif // DOT11_N_SUPPORT // RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); Timeout = DLS_TIMEOUT; RTMPSetTimer(&pDLS->Timer, Timeout); MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer);}/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */VOID PeerDlsReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; USHORT StatusCode = MLME_SUCCESS; HEADER_802_11 DlsRspHdr; UCHAR Category = CATEGORY_DLS; UCHAR Action = ACTION_DLS_RESPONSE; ULONG tmp; USHORT CapabilityInfo; UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; USHORT DLSTimeOut; SHORT i; ULONG Timeout; BOOLEAN TimerCancelled; PRT_802_11_DLS pDLS = NULL; UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR SupportedRatesLen; UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR HtCapabilityLen; HT_CAPABILITY_IE HtCapability; if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut, &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) return; // supported rates array may not be sorted. sort it and find the maximum rate for (i = 0; i < SupportedRatesLen; i++) { if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f)) MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f; } DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n")); return; } if (!INFRA_ON(pAd)) { StatusCode = MLME_REQUEST_DECLINED; } else if (!pAd->CommonCfg.bWmmCapable) { StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA; } else if (!pAd->CommonCfg.bDLSCapable) { StatusCode = MLME_REQUEST_DECLINED; } else { // find table to update parameters for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--) { if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) { if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; else { RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; } pAd->StaCfg.DLSEntry[i].Sequence = 0; pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut; pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut; if (HtCapabilityLen != 0) pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; else pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; pDLS = &pAd->StaCfg.DLSEntry[i]; break; } } // can not find in table, create a new one if (i < 0) { DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n")); for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--) { if (!pAd->StaCfg.DLSEntry[i].Valid) { MAC_TABLE_ENTRY *pEntry; UCHAR MaxSupportedRate = RATE_11; if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; } else { RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; } pAd->StaCfg.DLSEntry[i].Sequence = 0; pAd->StaCfg.DLSEntry[i].Valid = TRUE; pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut; pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut; NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN); if (HtCapabilityLen != 0) pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; else pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; pDLS = &pAd->StaCfg.DLSEntry[i]; pEntry = MacTableInsertDlsEntry(pAd, SA, i); switch (MaxSupportedRateIn500Kbps) { case 108: MaxSupportedRate = RATE_54; break; case 96: MaxSupportedRate = RATE_48; break; case 72: MaxSupportedRate = RATE_36; break; case 48: MaxSupportedRate = RATE_24; break; case 36: MaxSupportedRate = RATE_18; break; case 24: MaxSupportedRate = RATE_12; break; case 18: MaxSupportedRate = RATE_9; break; case 12: MaxSupportedRate = RATE_6; break; case 22: MaxSupportedRate = RATE_11; break; case 11: MaxSupportedRate = RATE_5_5; break; case 4: MaxSupportedRate = RATE_2; break; case 2: MaxSupportedRate = RATE_1; break; default: MaxSupportedRate = RATE_11; break; } pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) { pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate; pEntry->MinHTPhyMode.field.MODE = MODE_CCK; pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate; pEntry->HTPhyMode.field.MODE = MODE_CCK; pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; } else { pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; pEntry->HTPhyMode.field.MODE = MODE_OFDM; pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; } pEntry->MaxHTPhyMode.field.BW = BW_20; pEntry->MinHTPhyMode.field.BW = BW_20;#ifdef DOT11_N_SUPPORT pEntry->HTCapability.MCSSet[0] = 0; pEntry->HTCapability.MCSSet[1] = 0; // If this Entry supports 802.11n, upgrade to HT rate. if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { UCHAR j, bitmask; //k,bitmask; CHAR ii; DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) { pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -