📄 sync.c
字号:
DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP forced to use LONG preamble\n");
}
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
(EdcaParm.bValid == TRUE) &&
(EdcaParm.EdcaUpdateCount != pAd->PortCfg.APEdcaParm.EdcaUpdateCount))
{
DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP change EDCA parameters(from %d to %d)\n",
pAd->PortCfg.APEdcaParm.EdcaUpdateCount,
EdcaParm.EdcaUpdateCount);
AsicSetEdcaParm(pAd, &EdcaParm);
}
// copy QOS related information
NdisMoveMemory(&pAd->PortCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
NdisMoveMemory(&pAd->PortCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
}
// only INFRASTRUCTURE mode support power-saving feature
if (INFRA_ON(pAd) && (pAd->PortCfg.Psm == PWR_SAVE))
{
// UCHAR FreeNumber;
// 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
// 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
// 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
// 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
// 5. otherwise, put PHY back to sleep to save battery.
if (MessageToMe)
{
DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP backlog unicast-to-me, stay AWAKE, send PSPOLL\n");
EnqueuePsPoll(pAd);
}
else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
{
DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP backlog broadcast/multicast, stay AWAKE\n");
}
#if 0
else if ((RTUSBFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
// (RTUSBFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
// (RTUSBFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
// (RTUSBFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
(RTUSBFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE, &FreeNumber) != NDIS_STATUS_SUCCESS))
{
// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
DBGPRINT(RT_DEBUG_TRACE, "SYNC - outgoing frame in TxRing/MgmtRing, stay AWAKE\n");
}
#endif
else
{
USHORT NextDtim = DtimCount;
if (NextDtim == 0)
NextDtim = DtimPeriod;
TbttNumToNextWakeUp = pAd->PortCfg.DefaultListenCount;
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
TbttNumToNextWakeUp = NextDtim;
DBGPRINT(RT_DEBUG_INFO, "SYNC - PHY sleeps for %d TBTT, Dtim=%d/%d\n", TbttNumToNextWakeUp, DtimCount, DtimPeriod);
AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
}
}
#ifndef SINGLE_ADHOC_LINKUP
// At least another peer in this IBSS, declare MediaState as CONNECTED
if (ADHOC_ON(pAd) &&
!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
// 2003/03/12 - john
// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
// "site survey" result should always include the current connected network.
//
Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
if (Bssidx == BSS_NOT_FOUND)
{
Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen,
BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo,
SupRate, SupRateLen, ExtRate, ExtRateLen, Channel, RealRssi + pAd->BbpRssiToDbmDelta, TimeStamp, CkipFlag,
&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
}
}
#endif
}
// not my BSSID, ignore it
}
// sanity check fail, ignore this frame
}
/*
==========================================================================
Description:
Receive PROBE REQ from remote peer when operating in IBSS mode
==========================================================================
*/
VOID PeerProbeReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Addr2[MAC_ADDR_LEN];
CHAR Ssid[MAX_LEN_OF_SSID];
UCHAR SsidLen;
HEADER_802_11 ProbeRspHdr;
PUCHAR pOutBuffer = NULL;
ULONG FrameLen = 0;
LARGE_INTEGER FakeTimestamp;
UCHAR DsLen = 1, IbssLen = 2;
UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
USHORT NStatus;
BOOLEAN Privacy;
USHORT CapabilityInfo;
if (! ADHOC_ON(pAd))
return;
if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
{
if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen))
{
#if 0
CSR15_STRUC Csr15;
// we should respond a ProbeRsp only when we're the last BEACON transmitter
// in this ADHOC network.
RTMP_IO_READ32(pAd, CSR15, &Csr15.word);
if (Csr15.field.BeaconSent == 0)
{
DBGPRINT(RT_DEBUG_INFO, "SYNC - NOT last BEACON sender, no PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n",
Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] );
return;
}
#endif
// allocate and send out ProbeReq frame
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
return;
//pAd->PortCfg.AtimWin = 0; // ??????
DBGPRINT(RT_DEBUG_TRACE, "SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n",
Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] );
MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->PortCfg.Bssid);
Privacy = (pAd->PortCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
(pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
(pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled);
CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->PortCfg.TxPreamble == Rt802_11PreambleShort), 0);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &ProbeRspHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &CapabilityInfo,
1, &SsidIe,
1, &pAd->PortCfg.SsidLen,
pAd->PortCfg.SsidLen, pAd->PortCfg.Ssid,
1, &SupRateIe,
1, &pAd->ActiveCfg.SupRateLen,
pAd->ActiveCfg.SupRateLen, pAd->ActiveCfg.SupRate,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
1, &IbssIe,
1, &IbssLen,
2, &pAd->ActiveCfg.AtimWin,
END_OF_ARGS);
if (pAd->ActiveCfg.ExtRateLen)
{
ULONG tmp;
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
3, LocalErpIe,
1, &ExtRateIe,
1, &pAd->ActiveCfg.ExtRateLen,
pAd->ActiveCfg.ExtRateLen, &pAd->ActiveCfg.ExtRate,
END_OF_ARGS);
FrameLen += tmp;
}
// If adhoc secruity is set for WPA-None, append the cipher suite IE
if (pAd->PortCfg.AuthMode == Ndis802_11AuthModeWPANone)
{
ULONG tmp;
if (pAd->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) // Tkip
{
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1, &WpaIe,
1, &CipherSuiteWpaNoneTkipLen,
CipherSuiteWpaNoneTkipLen, &CipherSuiteWpaNoneTkip[0],
END_OF_ARGS);
FrameLen += tmp;
}
else if (pAd->PortCfg.WepStatus == Ndis802_11Encryption3Enabled) // Aes
{
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1, &WpaIe,
1, &CipherSuiteWpaNoneAesLen,
CipherSuiteWpaNoneAesLen, &CipherSuiteWpaNoneAes[0],
END_OF_ARGS);
FrameLen += tmp;
}
}
MiniportMMRequest(pAd, pOutBuffer, FrameLen);
}
}
}
VOID BeaconTimeoutAtJoinAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "SYNC - BeaconTimeoutAtJoinAction\n");
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_REJ_TIMEOUT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
}
/*
==========================================================================
Description:
Scan timeout procedure. basically add channel index by 1 and rescan
==========================================================================
*/
VOID ScanTimeoutAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
// DBGPRINT(RT_DEBUG_TRACE,"SYNC - ScanTimeoutAction\n");
pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
ScanNextChannel(pAd); // this routine will stop if pAd->MlmeAux.Channel == 0
}
/*
==========================================================================
Description:
Scan next channel
==========================================================================
*/
VOID ScanNextChannel(
IN PRTMP_ADAPTER pAd)
{
HEADER_802_11 Hdr80211;
PUCHAR pOutBuffer = NULL;
ULONG FrameLen = 0;
UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType;
USHORT Status;
PHEADER_802_11 pHdr80211;
USHORT NStatus;
PUCHAR pSupRate = NULL;
UCHAR SupRateLen;
PUCHAR pExtRate = NULL;
UCHAR ExtRateLen;
//For A band
UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
DBGPRINT(RT_DEBUG_INFO, "ScanNextChannel(ch=%d)\n",pAd->MlmeAux.Channel);
if (pAd->MlmeAux.Channel == 0)
{
DBGPRINT(RT_DEBUG_TRACE, "SYNC - End of SCAN, restore to channel %d\n",pAd->PortCfg.Channel);
AsicSwitchChannel(pAd, pAd->PortCfg.Channel);
AsicLockChannel(pAd, pAd->PortCfg.Channel);
// G band - set BBP_R62 to 0x02 when site survey or rssi<-82
// A band - always set BBP_R62 to 0x04
if (pAd->PortCfg.Channel <= 14)
{
RTUSBWriteBBPRegister(pAd, BBP_R62, 0x02);
}
else
{
RTUSBWriteBBPRegister(pAd, BBP_R62, 0x04);
}
//
// 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); //Get an unused nonpaged memory
if (NStatus == NDIS_STATUS_SUCCESS)
{
pHdr80211 = (PHEADER_802_11) pOutBuffer;
MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->PortCfg.Bssid, pAd->PortCfg.Bssid);
pHdr80211->Duration = 0;
pHdr80211->FC.Type = BTYPE_DATA;
pHdr80211->FC.PwrMgmt = PWR_ACTIVE;
// Send using priority queue
MiniportMMRequest(pAd, pOutBuffer, sizeof(HEADER_802_11));
DBGPRINT(RT_DEBUG_TRACE, "MlmeScanReqAction -- Send PSM Data frame\n");
RTMPusecDelay(5000);
}
}
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_SUCCESS;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
Status = MLME_FAIL_NO_RESOURCE;
MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
}
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -