extractedLnx/linux-2.6.32/drivers/staging/rt2860/sta/sync.c_PeerBeacon.c
VOID PeerBeacon(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
CHAR Ssid[MAX_LEN_OF_SSID];
CF_PARM CfParm;
UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
USHORT CapabilityInfo, AtimWin, BeaconPeriod;
LARGE_INTEGER TimeStamp;
USHORT TbttNumToNextWakeUp;
UCHAR Erp;
UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
UCHAR SupRateLen, ExtRateLen;
UCHAR CkipFlag;
USHORT LenVIE;
UCHAR AironetCellPowerLimit;
EDCA_PARM EdcaParm;
QBSS_LOAD_PARM QbssLoad;
QOS_CAPABILITY_PARM QosCapability;
ULONG RalinkIe;
// New for WPA security suites
UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
HT_CAPABILITY_IE HtCapability;
ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
UCHAR HtCapabilityLen, PreNHtCapabilityLen;
UCHAR AddHtInfoLen;
UCHAR NewExtChannelOffset = 0xff;
if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
))
return;
// Init Variable IE structure
pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
pVIE->Length = 0;
RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
if (PeerBeaconAndProbeRspSanity(pAd,
Elem->Msg,
Elem->MsgLen,
Elem->Channel,
Addr2,
Bssid,
Ssid,
&SsidLen,
&BssType,
&BeaconPeriod,
&Channel,
&NewChannel,
&TimeStamp,
&CfParm,
&AtimWin,
&CapabilityInfo,
&Erp,
&DtimCount,
&DtimPeriod,
&BcastFlag,
&MessageToMe,
SupRate,
&SupRateLen,
ExtRate,
&ExtRateLen,
&CkipFlag,
&AironetCellPowerLimit,
&EdcaParm,
&QbssLoad,
&QosCapability,
&RalinkIe,
&HtCapabilityLen,
&PreNHtCapabilityLen,
&HtCapability,
&AddHtInfoLen,
&AddHtInfo,
&NewExtChannelOffset,
&LenVIE,
pVIE))
{
BOOLEAN is_my_bssid, is_my_ssid;
ULONG Bssidx, Now;
BSS_ENTRY *pBss;
CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
// ignore BEACON not for my SSID
if ((! is_my_ssid) && (! is_my_bssid))
return;
// It means STA waits disassoc completely from this AP, ignores this beacon.
if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
return;
// Copy Control channel for this BSSID.
if (AddHtInfoLen != 0)
Channel = AddHtInfo.ControlChan;
if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
HtCapabilityLen = SIZE_HT_CAP_IE;
//
// Housekeeping "SsidBssTab" table for later-on ROAMing usage.
//
Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
if (Bssidx == BSS_NOT_FOUND)
{
// discover new AP of this network, create BSS entry
Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
&HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
&QbssLoad, LenVIE, pVIE);
if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
return;
NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
}
if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
{
// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
AsicSwitchChannel(pAd, 1, FALSE);
AsicLockChannel(pAd, 1);
LinkDown(pAd, FALSE);
MlmeQueueInit(&pAd->Mlme.Queue);
BssTableInit(&pAd->ScanTab);
RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
// channel sanity check
for (index = 0 ; index < pAd->ChannelListNum; index++)
{
if (pAd->ChannelList[index].Channel == NewChannel)
{
pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
pAd->CommonCfg.Channel = NewChannel;
AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.Channel);
DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
break;
}
}
if (index >= pAd->ChannelListNum)
{
DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
}
}
// if the ssid matched & bssid unmatched, we should select the bssid with large value.
// This might happened when two STA start at the same time
if ((! is_my_bssid) && ADHOC_ON(pAd))
{
INT i;
// Add the safeguard against the mismatch of adhoc wep status
if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
return;
}
// collapse into the ADHOC network which has bigger BSSID value.
for (i = 0; i < 6; i++)
{
if (Bssid[i] > pAd->CommonCfg.Bssid[i])
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
AsicDisableSync(pAd);
COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
MakeIbssBeacon(pAd); // re-build BEACON frame
AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
is_my_bssid = TRUE;
break;
}
else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
break;
}
}
NdisGetSystemUpTime(&Now);
pBss = &pAd->ScanTab.BssEntry[Bssidx];
pBss->Rssi = RealRssi; // lastest RSSI
pBss->LastBeaconRxTime = Now; // last RX timestamp
//
// BEACON from my BSSID - either IBSS or INFRA network
//
if (is_my_bssid)
{
RXWI_STRUC RxWI;
pAd->StaCfg.DtimCount = DtimCount;
pAd->StaCfg.DtimPeriod = DtimPeriod;
pAd->StaCfg.LastBeaconRxTime = Now;
RxWI.RSSI0 = Elem->Rssi0;
RxWI.RSSI1 = Elem->Rssi1;
RxWI.RSSI2 = Elem->Rssi2;
Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
if (AironetCellPowerLimit != 0xFF)
{
//
// We get the Cisco (ccx) "TxPower Limit" required
// Changed to appropriate TxPower Limit for Ciso Compatible Extensions
//
ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
}
else
{
//
// AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
// Used the default TX Power Percentage, that set from UI.
//
pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
}
#ifdef RT2860
// at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
// after last 11b peer left for several seconds, we'll auto switch back to 11G rate
// in MlmePeriodicExec()
#endif
if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
{
#ifdef RT2860
BOOLEAN bRestart;
BOOLEAN bnRestart;
bRestart = FALSE;
bnRestart = FALSE;
do
{
if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11))
{
if (pAd->StaCfg.AdhocBOnlyJoined == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
bRestart = TRUE;
NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
pAd->StaActive.SupRateLen = SupRateLen;
NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
pAd->StaActive.ExtRateLen = ExtRateLen;
pAd->StaCfg.AdhocBOnlyJoined = TRUE;
pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
AsicSetEdcaParm(pAd, NULL);
}
// this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
pAd->StaCfg.Last11bBeaconRxTime = Now;
break;
}
// Update Ht Phy.
if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
{
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
!pAd->StaCfg.AdhocBGJoined &&
!pAd->StaCfg.AdhocBOnlyJoined)
AdhocTurnOnQos(pAd);
// Handle rate switch issue when Adhoc mode
if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0))
{
if (pAd->StaCfg.AdhocBGJoined == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
bRestart = TRUE;
NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
pAd->StaActive.SupRateLen = SupRateLen;
NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
pAd->StaActive.ExtRateLen = ExtRateLen;
pAd->StaCfg.AdhocBGJoined = TRUE;
pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
AsicSetEdcaParm(pAd, NULL);
}
// this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
pAd->StaCfg.Last11gBeaconRxTime = Now;
break;
}
else if (!pAd->StaCfg.AdhocBGJoined &&
!pAd->StaCfg.AdhocBOnlyJoined &&
(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
(HtCapability.HtCapInfo.ChannelWidth == BW_20))
{
if (pAd->StaCfg.Adhoc20NJoined == FALSE)
{
pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
pAd->StaCfg.Adhoc20NJoined = TRUE;
NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE);
if (AddHtInfoLen != 0)
NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen);
NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
bRestart = TRUE;
bnRestart = TRUE;
}
// this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
pAd->StaCfg.Last20NBeaconRxTime = Now;
}
}
else
{
RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
}
}while (FALSE);
// If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
if ((bRestart == TRUE) && (bnRestart == FALSE))
{
MlmeUpdateTxRates(pAd, FALSE, 0);
MakeIbssBeacon(pAd); // re-build BEACON frame
AsicEnableIbssSync(pAd); // copy to on-chip memory
}
else if ((bRestart == TRUE) && (bnRestart == TRUE))
{
MlmeUpdateTxRates(pAd, FALSE, BSS0);
MlmeUpdateHtTxRates(pAd, BSS0);
MakeIbssBeacon(pAd); // re-build BEACON frame
AsicEnableIbssSync(pAd); // copy to on-chip memory
}
// At least another peer in this IBSS, declare MediaState as CONNECTED
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
pAd->IndicateMediaState = NdisMediaStateConnected;
RTMP_IndicateMediaState(pAd);
pAd->ExtraInfo = GENERAL_LINK_UP;
AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
// 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, &HtCapability,
&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
}
DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
}
// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID))
{
UCHAR idx;
MAC_TABLE_ENTRY *pEntry;
// look up the existing table
pEntry = MacTableLookup(pAd, Addr2);
if (pEntry == NULL)
{
// Another adhoc joining, add to our MAC table.
pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
if (pEntry)
{
pEntry->Sst = SST_ASSOC;
idx = pAd->StaCfg.DefaultKeyId;
// After InsertEntry, Write to ASIC on-chip table.
RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
DBGPRINT(RT_DEBUG_TRACE, ("ADHOC %x:%x:%x:%x:%x:%x join in.Entry=%d\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5], pEntry->Aid));
pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
if (HtCapabilityLen <= 0)
{
pEntry->HTPhyMode.field.STBC = 0;
pEntry->HTPhyMode.field.BW = 0;
pEntry->HTPhyMode.field.ShortGI = 0;
if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14))
{
pEntry->HTPhyMode.field.MODE = MODE_CCK;
}
else
{
pEntry->HTPhyMode.field.MODE = MODE_OFDM;
}
MlmeUpdateTxRates(pAd, FALSE, 0);
}
else
{
MlmeUpdateTxRates(pAd, FALSE, 0);
MlmeUpdateHtTxRates(pAd, BSS0);
}
{
union iwreq_data wrqu;
wext_notify_event_assoc(pAd);
memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
}
}
}
}
#endif /* RT2860 */
#ifdef RT2870
UCHAR MaxSupportedRateIn500Kbps = 0;
UCHAR idx;
MAC_TABLE_ENTRY *pEntry;
// supported rates array may not be sorted. sort it and find the maximum rate
for (idx=0; idx<SupRateLen; idx++)
{
if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
}
for (idx=0; idx<ExtRateLen; idx++)
{
if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
}
// look up the existing table
pEntry = MacTableLookup(pAd, Addr2);
// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
(pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
{
if (pEntry == NULL)
// Another adhoc joining, add to our MAC table.
pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
return;
}
if (pEntry &&
(Elem->Wcid == RESERVED_WCID))
{
idx = pAd->StaCfg.DefaultKeyId;
RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
}
}
if (pEntry && pEntry->ValidAsCLI)
pEntry->LastBeaconRxTime = Now;
// At least another peer in this IBSS, declare MediaState as CONNECTED
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
pAd->IndicateMediaState = NdisMediaStateConnected;
RTMP_IndicateMediaState(pAd);
pAd->ExtraInfo = GENERAL_LINK_UP;
AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
// 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, &HtCapability,
&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
}
DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
}
#endif /* RT2870 */
}
if (INFRA_ON(pAd))
{
BOOLEAN bUseShortSlot, bUseBGProtection;
// decide to use/change to -
// 1. long slot (20 us) or short slot (9 us) time
// 2. turn on/off RTS/CTS and/or CTS-to-self protection
// 3. short preamble
//bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
AsicSetSlotTime(pAd, bUseShortSlot);
bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
bUseBGProtection = FALSE;
if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
{
if (bUseBGProtection)
{
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
}
else
{
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
}
DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
}
// check Ht protection mode. and adhere to the Non-GF device indication by AP.
if ((AddHtInfoLen != 0) &&
((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
(AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
{
pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
{
AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
}
else
AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
}
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
ERP_IS_USE_BARKER_PREAMBLE(Erp))
{
MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
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->CommonCfg.APEdcaParm.EdcaUpdateCount))
{
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
EdcaParm.EdcaUpdateCount));
AsicSetEdcaParm(pAd, &EdcaParm);
}
// copy QOS related information
NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
}
// only INFRASTRUCTURE mode support power-saving feature
if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
{
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)
{
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
#endif
if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
{
pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
}
else
RT28XX_PS_POLL_ENQUEUE(pAd);
}
else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
{
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
#endif
}
else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
(pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
(pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
(pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
(RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
(RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
(RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
(RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
(RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &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?
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
#endif
}
else
{
USHORT NextDtim = DtimCount;
if (NextDtim == 0)
NextDtim = DtimPeriod;
TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
TbttNumToNextWakeUp = NextDtim;
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
#ifdef RT2860
// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
#endif
#ifdef RT2870
AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
#endif
}
}
}
}
// not my BSSID, ignore it
}
// sanity check fail, ignore this frame
}
Generated by GNU enscript 1.6.4.