static INT scan_active(RTMP_ADAPTER *pAd, UCHAR OpMode, UCHAR ScanType) { UCHAR *frm_buf = NULL; HEADER_802_11 Hdr80211; ULONG FrameLen = 0; UCHAR SsidLen = 0; #ifdef CONFIG_STA_SUPPORT USHORT Status; #endif /* CONFIG_STA_SUPPORT */ if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n")); #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) { pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status, 0); } #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; #endif /* CONFIG_AP_SUPPORT */ return FALSE; } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if (ScanType == SCAN_2040_BSS_COEXIST) { DBGPRINT(RT_DEBUG_INFO, ("SYNC - SCAN_2040_BSS_COEXIST !! Prepare to send Probe Request\n")); } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* There is no need to send broadcast probe request if active scan is in effect.*/ SsidLen = 0; if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) #ifdef WSC_STA_SUPPORT || ((ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_STA)) #endif /* WSC_STA_SUPPORT */ ) SsidLen = pAd->MlmeAux.SsidLen; #ifdef P2P_SUPPORT if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH) #ifdef P2P_APCLI_SUPPORT || ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd))) #endif /* P2P_APCLI_SUPPORT */ ) { PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen = 0; SsidLen = WILDP2PSSIDLEN; /* Use Wildword SSID */ SupRate[0] = 0x8C; /* 6 mbps, in units of 0.5 Mbps, basic rate */ SupRate[1] = 0x12; /* 9 mbps, in units of 0.5 Mbps */ SupRate[2] = 0x98; /* 12 mbps, in units of 0.5 Mbps, basic rate */ SupRate[3] = 0x24; /* 18 mbps, in units of 0.5 Mbps */ SupRate[4] = 0xb0; /* 24 mbps, in units of 0.5 Mbps, basic rate */ SupRate[5] = 0x48; /* 36 mbps, in units of 0.5 Mbps */ SupRate[6] = 0x60; /* 48 mbps, in units of 0.5 Mbps */ SupRate[7] = 0x6c; /* 54 mbps, in units of 0.5 Mbps */ SupRateLen = 8; /* P2P scan must use P2P mac address. */ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, pP2PCtrl->CurrentAddress, BROADCAST_ADDR); MakeOutgoingFrame(frm_buf, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &SsidLen, SsidLen, &WILDP2PSSID[0], 1, &SupRateIe, 1, &SupRateLen, SupRateLen, SupRate, END_OF_ARGS); } else #endif /* P2P_SUPPORT */ { #ifdef CONFIG_AP_SUPPORT /*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */ if (OpMode == OPMODE_AP) { MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, #ifdef P2P_SUPPORT pAd->ApCfg.MBSSID[0].Bssid, #endif /* P2P_SUPPORT */ pAd->ApCfg.MBSSID[0].Bssid); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT /*IF_DEV_CONFIG_OPMODE_ON_STA(pAd) */ if (OpMode == OPMODE_STA) { MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, #ifdef P2P_SUPPORT pAd->CurrentAddress, #endif /* P2P_SUPPORT */ BROADCAST_ADDR); } #endif /* CONFIG_STA_SUPPORT */ MakeOutgoingFrame(frm_buf, &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(frm_buf + FrameLen, &Tmp, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += Tmp; } } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG Tmp; UCHAR HtLen; UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33}; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; #endif if (pAd->bBroadComHT == TRUE) { HtLen = pAd->MlmeAux.HtCapabilityLen + 4; #ifdef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &WpaIe, 1, &HtLen, 4, &BROADCOM[0], pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); #else MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &WpaIe, 1, &HtLen, 4, &BROADCOM[0], pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability, END_OF_ARGS); #endif /* RT_BIG_ENDIAN */ } else { HtLen = sizeof(HT_CAPABILITY_IE); #ifdef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS); #else MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #endif /* RT_BIG_ENDIAN */ } FrameLen += Tmp; #ifdef DOT11N_DRAFT3 if ((pAd->MlmeAux.Channel <= 14) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { ULONG Tmp; HtLen = 1; MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &ExtHtCapIe, 1, &HtLen, 1, &pAd->CommonCfg.BSSCoexist2040.word, END_OF_ARGS); FrameLen += Tmp; } #endif /* DOT11N_DRAFT3 */ } #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->MlmeAux.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(frm_buf + FrameLen), SUBTYPE_PROBE_REQ); } #endif /* DOT11_VHT_AC */ #ifdef WSC_STA_SUPPORT if (OpMode == OPMODE_STA) { BOOLEAN bHasWscIe = FALSE; /* Append WSC information in probe request if WSC state is running */ if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) && (pAd->StaCfg.WscControl.bWscTrigger == TRUE)) bHasWscIe = TRUE; #ifdef WSC_V2_SUPPORT else if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2)) bHasWscIe = TRUE; #endif /* WSC_V2_SUPPORT */ #ifdef P2P_SUPPORT /* P2pMakeProbeReqIE will build WSC IE for P2P, it is not good to append normal WSC IE into P2P probe request frame here. */ if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH) || ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd)))) bHasWscIe = FALSE; #endif /* P2P_SUPPORT */ if (bHasWscIe) { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; os_alloc_mem(NULL, (UCHAR **)&pWscBuf, 512); if (pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); WscBuildProbeReqIE(pAd, STA_MODE, pWscBuf, &WscIeLen); MakeOutgoingFrame(frm_buf + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } } #endif /* WSC_STA_SUPPORT */ #ifdef WPA_SUPPLICANT_SUPPORT if ((OpMode == OPMODE_STA) && (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->StaCfg.WpsProbeReqIeLen != 0)) { ULONG WpsTmpLen = 0; MakeOutgoingFrame(frm_buf + FrameLen, &WpsTmpLen, pAd->StaCfg.WpsProbeReqIeLen, pAd->StaCfg.pWpsProbeReqIe, END_OF_ARGS); FrameLen += WpsTmpLen; } #endif /* WPA_SUPPLICANT_SUPPORT */ #ifdef P2P_SUPPORT if ((pAd->MlmeAux.ScanType == SCAN_P2P) || (pAd->MlmeAux.ScanType == SCAN_P2P_SEARCH) #ifdef P2P_APCLI_SUPPORT || ((pAd->MlmeAux.ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_AP) && (P2P_CLI_ON(pAd))) #endif /* P2P_APCLI_SUPPORT */ ) { ULONG P2PIeLen; UCHAR tmp_len; PUCHAR ptr; ptr = frm_buf + FrameLen; P2pMakeProbeReqIE(pAd, ptr, &tmp_len); FrameLen += tmp_len; /* Put P2P IE to the last. */ ptr = frm_buf + FrameLen; P2pMakeP2pIE(pAd, SUBTYPE_PROBE_REQ, ptr, &P2PIeLen); FrameLen += P2PIeLen; } #endif /* P2P_SUPPORT */ MiniportMMRequest(pAd, 0, frm_buf, FrameLen); #ifdef CONFIG_STA_SUPPORT if (OpMode == OPMODE_STA) { /* To prevent data lost. Send an NULL data with turned PSM bit on to current associated AP when SCAN in the channel where associated AP located. */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)) && (pAd->CommonCfg.Channel == pAd->MlmeAux.Channel)) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE), PWR_SAVE); DBGPRINT(RT_DEBUG_TRACE, ("ScanNextChannel():Send PWA NullData frame to notify the associated AP!\n")); } } #if 0//def RT_CFG80211_SUPPORT if (pAd->ApCfg.ApCliTab[MAIN_MBSSID].Valid && RTMP_CFG80211_VIF_P2P_CLI_ON(pAd) && (pAd->CommonCfg.Channel == pAd->MlmeAux.Channel)) { DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: PWR_SAVE SCANNING\n")); RT_CFG80211_P2P_CLI_SEND_NULL_FRAME(pAd, PWR_SAVE); } #endif /* RT_CFG80211_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ MlmeFreeMemory(pAd, frm_buf); return TRUE; }
static INT scan_active(RTMP_ADAPTER *pAd, UCHAR OpMode, UCHAR ScanType) { UCHAR *frm_buf = NULL; HEADER_802_11 Hdr80211; ULONG FrameLen = 0; UCHAR SsidLen = 0; if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("%s():allocate memory fail\n", __FUNCTION__)); #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; #endif /* CONFIG_AP_SUPPORT */ return FALSE; } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if (ScanType == SCAN_2040_BSS_COEXIST) { DBGPRINT(RT_DEBUG_INFO, ("SYNC - SCAN_2040_BSS_COEXIST !! Prepare to send Probe Request\n")); } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* There is no need to send broadcast probe request if active scan is in effect.*/ SsidLen = 0; if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) #ifdef WSC_STA_SUPPORT || ((ScanType == SCAN_WSC_ACTIVE) && (OpMode == OPMODE_STA)) #endif /* WSC_STA_SUPPORT */ ) SsidLen = pAd->ScanCtrl.SsidLen; //CFG_TODO { #ifdef CONFIG_AP_SUPPORT /*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */ if (OpMode == OPMODE_AP) { MgtMacHeaderInitExt(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, pAd->ApCfg.MBSSID[0].wdev.bssid, BROADCAST_ADDR); } #endif /* CONFIG_AP_SUPPORT */ MakeOutgoingFrame(frm_buf, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &SsidLen, SsidLen, pAd->ScanCtrl.Ssid, 1, &SupRateIe, 1, &pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); if (pAd->CommonCfg.ExtRateLen) { ULONG Tmp; MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += Tmp; } } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG Tmp; UCHAR HtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; #endif { HtLen = sizeof(HT_CAPABILITY_IE); #ifdef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS); #else MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #endif /* RT_BIG_ENDIAN */ } FrameLen += Tmp; #ifdef DOT11N_DRAFT3 if ((pAd->ScanCtrl.Channel <= 14) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { ULONG Tmp; HtLen = 1; MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &ExtHtCapIe, 1, &HtLen, 1, &pAd->CommonCfg.BSSCoexist2040.word, END_OF_ARGS); FrameLen += Tmp; } #endif /* DOT11N_DRAFT3 */ } #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->ScanCtrl.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(frm_buf + FrameLen), SUBTYPE_PROBE_REQ); } #endif /* DOT11_VHT_AC */ #ifdef WSC_STA_SUPPORT if (OpMode == OPMODE_STA) { BOOLEAN bHasWscIe = FALSE; /* Append WSC information in probe request if WSC state is running */ if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) && (pAd->StaCfg.WscControl.bWscTrigger == TRUE)) bHasWscIe = TRUE; #ifdef WSC_V2_SUPPORT else if ((pAd->StaCfg.WscControl.WscEnProbeReqIE) && (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2)) bHasWscIe = TRUE; #endif /* WSC_V2_SUPPORT */ if (bHasWscIe) { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; os_alloc_mem(NULL, (UCHAR **)&pWscBuf, 512); if (pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); WscBuildProbeReqIE(pAd, STA_MODE, pWscBuf, &WscIeLen); MakeOutgoingFrame(frm_buf + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } } #endif /* WSC_STA_SUPPORT */ #ifdef RT_CFG80211_SUPPORT if ((OpMode == OPMODE_STA) && (pAd->StaCfg.wpa_supplicant_info.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && CFG80211DRV_OpsScanRunning(pAd)) { ULONG ExtraIeTmpLen = 0; MakeOutgoingFrame(frm_buf + FrameLen, &ExtraIeTmpLen, pAd->cfg80211_ctrl.ExtraIeLen, pAd->cfg80211_ctrl.pExtraIe, END_OF_ARGS); FrameLen += ExtraIeTmpLen; } #endif /* RT_CFG80211_SUPPORT */ MiniportMMRequest(pAd, 0, frm_buf, FrameLen); MlmeFreeMemory(pAd, frm_buf); return TRUE; }
/* ========================================================================== Description: Pre-build a BEACON frame in the shared memory ========================================================================== */ VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx) { UCHAR DsLen = 1, SsidLen; HEADER_802_11 BcnHdr; LARGE_INTEGER FakeTimestamp; ULONG FrameLen = 0; PUCHAR pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf; UCHAR *ptr; UINT i; UINT32 longValue, reg_base; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ UCHAR PhyMode, SupRateLen; UINT8 TXWISize = pAd->chipCap.TXWISize; if(!BeaconTransmitRequired(pAd, apidx, &pAd->ApCfg.MBSSID[apidx])) return; PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode; if (pAd->ApCfg.MBSSID[apidx].bHideSsid) SsidLen = 0; else SsidLen = pAd->ApCfg.MBSSID[apidx].SsidLen; MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->ApCfg.MBSSID[apidx].Bssid); /* for update framelen to TxWI later. */ SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pBeaconFrame, &FrameLen, sizeof(HEADER_802_11), &BcnHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo, 1, &SsidIe, 1, &SsidLen, SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; UCHAR CountryIe = IE_COUNTRY; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT /* AP Channel Report */ { UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT; ULONG TmpLen; /* 802.11n D2.0 Annex J, USA regulatory class 32, channel set 1~7 class 33, channel set 5-11 */ UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7}; UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11}; UCHAR rclasslen = 8; /*sizeof(rclass32); */ if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN)) { MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass32, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass33, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID, FrameLen, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTransmit); /* step 6. move BEACON TXD and frame content to on-chip memory */ ptr = (PUCHAR)&pAd->BeaconTxWI; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, ptr, TYPE_TXWI); #endif reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx]; for (i=0; i < TXWISize; i+=4) { longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4); ptr += 4; } /* update BEACON frame content. start right after the TXWI field. */ ptr = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf; #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE); #endif reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx] + TXWISize; for (i= 0; i< FrameLen; i+=4) { longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4); ptr += 4; } pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon = (UCHAR)FrameLen; pAd->ApCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2; } /* ========================================================================== Description: Update the BEACON frame in the shared memory. Because TIM IE is variable length. other IEs after TIM has to shift and total frame length may change for each BEACON period. Output: pAd->ApCfg.MBSSID[apidx].CapabilityInfo pAd->ApCfg.ErpIeContent ========================================================================== */ VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx) { UCHAR *pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf; UCHAR *ptr; ULONG FrameLen = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon; ULONG UpdatePos = pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; UCHAR ID_1B, TimFirst, TimLast, *pTim; MULTISSID_STRUCT *pMbss; COMMON_CONFIG *pComCfg; UCHAR PhyMode; BOOLEAN bHasWpsIE = FALSE; UINT i; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ pMbss = &pAd->ApCfg.MBSSID[apidx]; pComCfg = &pAd->CommonCfg; PhyMode = pMbss->PhyMode; if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; /* step 1 - update BEACON's Capability */ ptr = pBeaconFrame + pMbss->CapabilityInfoLocationInBeacon; *ptr = (UCHAR)(pMbss->CapabilityInfo & 0x00ff); *(ptr+1) = (UCHAR)((pMbss->CapabilityInfo & 0xff00) >> 8); /* step 2 - update TIM IE TODO: enlarge TIM bitmap to support up to 64 STAs TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time */ ptr = pBeaconFrame + pMbss->TimIELocationInBeacon; *ptr = IE_TIM; *(ptr + 2) = pAd->ApCfg.DtimCount; *(ptr + 3) = pAd->ApCfg.DtimPeriod; /* find the smallest AID (PS mode) */ TimFirst = 0; /* record first TIM byte != 0x00 */ TimLast = 0; /* record last TIM byte != 0x00 */ pTim = pMbss->TimBitmaps; for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++) { /* get the TIM indicating PS packets for 8 stations */ UCHAR tim_1B = pTim[ID_1B]; if (ID_1B == 0) tim_1B &= 0xfe; /* skip bit0 bc/mc */ if (tim_1B == 0) continue; /* find next 1B */ if (TimFirst == 0) TimFirst = ID_1B; TimLast = ID_1B; } /* fill TIM content to beacon buffer */ if (TimFirst & 0x01) TimFirst --; /* find the even offset byte */ *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */ *(ptr + 4) = TimFirst; for(i=TimFirst; i<=TimLast; i++) *(ptr + 5 + i - TimFirst) = pTim[i]; /* bit0 means backlogged mcast/bcast */ if (pAd->ApCfg.DtimCount == 0) *(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01); /* adjust BEACON length according to the new TIM */ FrameLen += (2 + *(ptr+1)); #ifdef HOSTAPD_SUPPORT if ( pAd->ApCfg.MBSSID[apidx].HostapdWPS && (pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen)) bHasWpsIE = TRUE; #endif #ifdef WSC_AP_SUPPORT /* add Simple Config Information Element */ if (((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode >= 1) && (pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen))) { bHasWpsIE = TRUE; } #endif /* WSC_AP_SUPPORT */ if (bHasWpsIE) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen, pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #ifdef WSC_AP_SUPPORT if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && #endif /* DOT1X_SUPPORT */ (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http:msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TempLen, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen; } #endif /* WSC_AP_SUPPORT */ /* Update ERP */ if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B)) { /* fill ERP IE */ ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */ *ptr = IE_ERP; *(ptr + 1) = 1; *(ptr + 2) = pAd->ApCfg.ErpIeContent; FrameLen += 3; } #ifdef A_BAND_SUPPORT /* fill up Channel Switch Announcement Element */ if ((pComCfg->Channel > 14) && (pComCfg->bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { ptr = pBeaconFrame + FrameLen; *ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT; *(ptr + 1) = 3; *(ptr + 2) = 1; *(ptr + 3) = pComCfg->Channel; *(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1); ptr += 5; FrameLen += 5; #ifdef DOT11_N_SUPPORT /* Extended Channel Switch Announcement Element */ if (pComCfg->bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE)); ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); } #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT /* step 5. Update HT. Since some fields might change in the same BSS. */ if (WMODE_CAP_N(PhyMode) && (pMbss->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; /*UCHAR i; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; /* USHORT b2lTmp, b2lTmp2; // no use */ #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &pComCfg->HtCapability, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if ((pComCfg->Channel <= 14) && (pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11N_DRAFT3 */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14)) { int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON); FrameLen += _len; } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #if defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT) /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen, infoPos; PUCHAR pInfo; UCHAR extInfoLen; BOOLEAN bNeedAppendExtIE = FALSE; EXT_CAP_INFO_ELEMENT extCapInfo; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) && (pMbss->DesiredHtPhyInfo.bHtEnable) && (pComCfg->bBssCoexEnable == TRUE) ) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ pInfo = (PUCHAR)(&extCapInfo); for (infoPos = 0; infoPos < extInfoLen; infoPos++) { if (pInfo[infoPos] != 0) { bNeedAppendExtIE = TRUE; break; } } if (bNeedAppendExtIE == TRUE) { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* defined(DOT11N_DRAFT3) || defined(DOT11V_WNM_SUPPORT) */ if ((pMbss->AuthMode == Ndis802_11AuthModeWPA) || (pMbss->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((pMbss->AuthMode == Ndis802_11AuthModeWPA2) || (pMbss->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((pMbss->AuthMode == Ndis802_11AuthModeWAICERT) || (pMbss->AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif /* WAPI_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if ((pMbss->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pMbss->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], 1, &RSNIe2, 1, &pMbss->RSNIE_Len[1], pMbss->RSNIE_Len[1], pMbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else if (pMbss->AuthMode >= Ndis802_11AuthModeWPA) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (pMbss->bWmmCapable) { ULONG TmpLen; UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; UINT8 AIFSN[4]; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->UapsdInfo); #endif /* UAPSD_SUPPORT */ NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN)); for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (AIFSN[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE) ) { ULONG TmpLen; UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT; UINT8 PwrConstraintLen = 1; UINT8 PwrConstraint = pComCfg->PwrConstraint; /* prepare power constraint IE */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &PwrConstraintIE, 1, &PwrConstraintLen, 1, &PwrConstraint, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (pMbss->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; /*UCHAR i; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; /* USHORT b2lTmp, b2lTmp2;*/ /* no use */ #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pComCfg->HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = HtLen1 + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pComCfg->bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pComCfg->bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pComCfg->bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* step 6. Since FrameLen may change, update TXWI. */ #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.Channel > 14) { BeaconTransmit.field.MODE = MODE_OFDM; BeaconTransmit.field.MCS = MCS_RATE_6; } #endif /* A_BAND_SUPPORT */ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen, PID_MGMT, QID_MGMT, 0, IFS_HTTXOP, FALSE, &BeaconTransmit); /* step 7. move BEACON TXWI and frame content to on-chip memory */ RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos); }
/* ========================================================================== Description: mlme assoc req handling procedure Parameters: Adapter - Adapter pointer Elem - MLME Queue Element Pre: the station has been authenticated and the following information is stored in the config -# SSID -# supported rates and their length Post : -# An association request frame is generated and sent to the air -# Association timer starts -# Association state -> ASSOC_WAIT_RSP ========================================================================== */ static VOID ApCliMlmeAssocReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { NDIS_STATUS NStatus; BOOLEAN Cancelled; UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT ListenIntv; ULONG Timeout; USHORT CapabilityInfo; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG tmp; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ExtRateIe = IE_EXT_SUPP_RATES; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = NULL; UCHAR RSNIe = IE_WPA; APCLI_STRUCT *apcli_entry; struct wifi_dev *wdev; #ifdef MAC_REPEATER_SUPPORT UCHAR CliIdx = 0xFF; #endif /* MAC_REPEATER_SUPPORT */ if ((ifIndex >= MAX_APCLI_NUM) #ifdef MAC_REPEATER_SUPPORT && (ifIndex < 64) #endif /* MAC_REPEATER_SUPPORT */ ) return; #ifdef MAC_REPEATER_SUPPORT if (ifIndex >= 64) { CliIdx = ((ifIndex - 64) % 16); ifIndex = ((ifIndex - 64) / 16); pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].RepeaterCli[CliIdx].AssocCurrState; } else #endif /* MAC_REPEATER_SUPPORT */ pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].AssocCurrState; apcli_entry = &pAd->ApCfg.ApCliTab[ifIndex]; wdev = &apcli_entry->wdev; /* Block all authentication request durning WPA block period */ if (apcli_entry->bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Block Auth request durning WPA block period!\n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv)) { //RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPCancelTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, &Cancelled); else #endif /* MAC_REPEATER_SUPPORT */ RTMPCancelTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, &Cancelled); /* allocate and send out AssocRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() allocate memory failed \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); return; } DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - Send ASSOC request...\n")); ApCliMgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr, ifIndex); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) COPY_MAC_ADDR(AssocHdr.Addr2, apcli_entry->RepeaterCli[CliIdx].CurrentAddress); #endif /* MAC_REPEATER_SUPPORT */ /* Build basic frame first */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocHdr, 2, &CapabilityInfo, 2, &ListenIntv, 1, &SsidIe, 1, &apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.SsidLen, apcli_entry->MlmeAux.Ssid, 1, &SupRateIe, 1, &apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRateLen, apcli_entry->MlmeAux.SupRate, END_OF_ARGS); if(apcli_entry->MlmeAux.ExtRateLen != 0) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRateLen, apcli_entry->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_N_SUPPORT /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(wdev->WepStatus)) { /* Force to None-HT mode due to WiFi 11n policy */ apcli_entry->MlmeAux.HtCapabilityLen = 0; #ifdef DOT11_VHT_AC apcli_entry->MlmeAux.vht_cap_len = 0; #endif /* DOT11_VHT_AC */ DBGPRINT(RT_DEBUG_TRACE, ("%s : Force AP-client as Non-HT mode\n", __FUNCTION__)); } /* HT */ if ((apcli_entry->MlmeAux.HtCapabilityLen > 0) && WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG TmpLen; HT_CAPABILITY_IE HtCapabilityTmp; NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &apcli_entry->MlmeAux.HtCapability, apcli_entry->MlmeAux.HtCapabilityLen); #ifdef DOT11N_SS3_SUPPORT HtCapabilityTmp.MCSSet[2] = (apcli_entry->MlmeAux.HtCapability.MCSSet[2] & apcli_entry->RxMcsSet[2]); #endif /* DOT11N_SS3_SUPPORT */ #ifdef RT_BIG_ENDIAN *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* RT_BIG_ENDINA */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &apcli_entry->MlmeAux.HtCapabilityLen, apcli_entry->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->CommonCfg.Channel > 14) && (apcli_entry->MlmeAux.vht_cap_len)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer + FrameLen), SUBTYPE_ASSOC_REQ); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #ifdef AGGREGATION_SUPPORT /* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION Case I: (Aggregation + Piggy-Back) 1. user enable aggregation, AND 2. Mac support piggy-back 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON Case II: (Aggregation) 1. user enable aggregation, AND 2. AP annouces it's AGGREGATION-capable in BEACON */ if (pAd->CommonCfg.bAggregationCapable) { #ifdef PIGGYBACK_SUPPORT if ((pAd->CommonCfg.bPiggyBackCapable) && ((apcli_entry->MlmeAux.APRalinkIe & 0x00000003) == 3)) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } else #endif /* PIGGYBACK_SUPPORT */ if (apcli_entry->MlmeAux.APRalinkIe & 0x00000001) { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } } else { ULONG TmpLen; UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* AGGREGATION_SUPPORT */ if (apcli_entry->MlmeAux.APEdcaParm.bValid) { if (apcli_entry->wdev.UapsdInfo.bAPSDCapable && apcli_entry->MlmeAux.APEdcaParm.bAPSDCapable) { QBSS_STA_INFO_PARM QosInfo; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength; WmeIe[8] |= *(PUCHAR)&QosInfo; } else { /* The Parameter Set Count is set to бз0би in the association request frames */ /* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */ } MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 9, &WmeIe[0], END_OF_ARGS); FrameLen += tmp; } #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA) apcli_entry->ReqVarIELen = 0; NdisZeroMemory(apcli_entry->ReqVarIEs, MAX_VIE_LEN); if ((apcli_entry->wpa_supplicant_info.WpaSupplicantUP & 0x7F ) == WPA_SUPPLICANT_ENABLE) { DBGPRINT(RT_DEBUG_TRACE,("%s:: APCLI WPA_ASSOC_IE FROM SUPPLICANT\n", __FUNCTION__)); ULONG TmpWpaAssocIeLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpWpaAssocIeLen, apcli_entry->wpa_supplicant_info.WpaAssocIeLen, apcli_entry->wpa_supplicant_info.pWpaAssocIe, END_OF_ARGS); FrameLen += TmpWpaAssocIeLen; VarIesOffset = 0; NdisMoveMemory(apcli_entry->ReqVarIEs + VarIesOffset, apcli_entry->wpa_supplicant_info.pWpaAssocIe, apcli_entry->wpa_supplicant_info.WpaAssocIeLen); VarIesOffset += apcli_entry->wpa_supplicant_info.WpaAssocIeLen; // Set Variable IEs Length apcli_entry->ReqVarIELen = VarIesOffset; } else #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */ /* Append RSN_IE when WPAPSK OR WPA2PSK, */ if (((wdev->AuthMode == Ndis802_11AuthModeWPAPSK) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) #ifdef WSC_AP_SUPPORT && ((apcli_entry->WscControl.WscConfMode == WSC_DISABLE) || ((apcli_entry->WscControl.WscConfMode != WSC_DISABLE) && !(apcli_entry->WscControl.bWscTrigger))) #endif /* WSC_AP_SUPPORT */ ) { RSNIe = IE_WPA; if ((wdev->AuthMode == Ndis802_11AuthModeWPA2PSK) ) RSNIe = IE_WPA2; MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &RSNIe, 1, &apcli_entry->RSNIE_Len, apcli_entry->RSNIE_Len, apcli_entry->RSN_IE, END_OF_ARGS); FrameLen += tmp; } #ifdef WSC_AP_SUPPORT /* Add WSC IE if we are connecting to WSC AP */ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger)) { UCHAR *pWscBuf = NULL, WscIeLen = 0; ULONG WscTmpLen = 0; os_alloc_mem(pAd, (UCHAR **) &pWscBuf, 512); /* if( (pWscBuf = kmalloc(512, GFP_ATOMIC)) != NULL) */ if (pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); WscBuildAssocReqIE(&pAd->ApCfg.ApCliTab[ifIndex].WscControl, pWscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; /* kfree(pWscBuf); */ os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); } #endif /* WSC_AP_SUPPORT */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); #ifdef MAC_REPEATER_SUPPORT if (CliIdx != 0xFF) RTMPSetTimer(&apcli_entry->RepeaterCli[CliIdx].ApCliAssocTimer, Timeout); else #endif /* MAC_REPEATER_SUPPORT */ RTMPSetTimer(&apcli_entry->MlmeAux.ApCliAssocTimer, Timeout); *pCurrState = APCLI_ASSOC_WAIT_RSP; } else { DBGPRINT(RT_DEBUG_TRACE, ("APCLI_ASSOC - ApCliMlmeAssocReqAction() sanity check failed. BUG!!!!!! \n")); *pCurrState = APCLI_ASSOC_IDLE; ApCliCtrlMsg.Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_ASSOC_RSP, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex); } return; }
/* ========================================================================== Description: ========================================================================== */ static VOID ApCliEnqueueProbeRequest( IN PRTMP_ADAPTER pAd, IN UCHAR SsidLen, OUT PCHAR Ssid, IN USHORT ifIndex) { NDIS_STATUS NState; PUCHAR pOutBuffer; ULONG FrameLen = 0; HEADER_802_11 Hdr80211; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ssidLen; CHAR ssid[MAX_LEN_OF_SSID]; APCLI_STRUCT *pApCliEntry = NULL; BOOLEAN bHasWscIe = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n")); if (ifIndex >= MAX_APCLI_NUM) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; NState = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if(NState != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("EnqueueProbeRequest() allocate memory fail\n")); return; } else { if(MAC_ADDR_EQUAL(pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ZERO_MAC_ADDR)) ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR, ifIndex); else ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, pAd->ApCfg.ApCliTab[ifIndex].CfgApCliBssid, ifIndex); ssidLen = SsidLen; NdisZeroMemory(ssid, MAX_LEN_OF_SSID); NdisMoveMemory(ssid, Ssid, ssidLen); /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &ssidLen, ssidLen, ssid, 1, &SupRateIe, 1, &pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.SupRate, END_OF_ARGS); /* Add the extended rate IE */ if (pApCliEntry->MlmeAux.ExtRateLen != 0) { ULONG tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pApCliEntry->MlmeAux.ExtRateLen, pApCliEntry->MlmeAux.ExtRateLen, pApCliEntry->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->CommonCfg.Channel > 14)) { build_vht_cap_ie(pAd, (UCHAR *)&pApCliEntry->MlmeAux.vht_cap); pApCliEntry->MlmeAux.vht_cap_len = sizeof(VHT_CAP_IE); FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer + FrameLen), SUBTYPE_PROBE_REQ); } #endif /* DOT11_VHT_AC */ #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE if ((pAd->StaCfg.wpa_supplicant_info.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->cfg80211_ctrl.ExtraIeLen != 0)) { ULONG ExtraIeTmpLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &ExtraIeTmpLen, pAd->cfg80211_ctrl.ExtraIeLen, pAd->cfg80211_ctrl.pExtraIe, END_OF_ARGS); FrameLen += ExtraIeTmpLen; } #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE*/ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } return; }
/* ========================================================================== Description: Pre-build a BEACON frame in the shared memory ========================================================================== */ VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx) { UCHAR DsLen = 1, SsidLen; HEADER_802_11 BcnHdr; LARGE_INTEGER FakeTimestamp; ULONG FrameLen = 0; PUCHAR pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf; UCHAR *ptr; UINT i; UINT32 longValue, reg_base; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ UCHAR PhyMode, SupRateLen; UINT8 TXWISize = pAd->chipCap.TXWISize; MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; #ifdef SPECIFIC_TX_POWER_SUPPORT UCHAR TxPwrAdj = 0; #endif /* SPECIFIC_TX_POWER_SUPPORT */ if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; PhyMode = pMbss->wdev.PhyMode; if (pMbss->bHideSsid) SsidLen = 0; else SsidLen = pMbss->SsidLen; MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pMbss->wdev.if_addr, pMbss->wdev.bssid); /* for update framelen to TxWI later. */ SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pBeaconFrame, &FrameLen, sizeof(HEADER_802_11), &BcnHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pMbss->CapabilityInfo, 1, &SsidIe, 1, &SsidLen, SsidLen, pMbss->Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; UCHAR CountryIe = IE_COUNTRY; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT /* AP Channel Report */ { UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT; ULONG TmpLen; /* 802.11n D2.0 Annex J, USA regulatory class 32, channel set 1~7 class 33, channel set 5-11 */ UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7}; UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11}; UCHAR rclasslen = 8; /*sizeof(rclass32); */ if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN)) { MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass32, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass33, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ BeaconTransmit.word = 0; #ifdef SPECIFIC_TX_POWER_SUPPORT /* Specific Power for Long-Range Beacon */ if ((pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) /* && (BeaconTransmit.field.MODE == MODE_CCK)*/) { TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; } #endif /* SPECIFIC_TX_POWER_SUPPORT */ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID, FrameLen, PID_MGMT, 0, 0,IFS_HTTXOP, &BeaconTransmit); #ifdef SPECIFIC_TX_POWER_SUPPORT #ifdef RTMP_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RTMP)) pAd->BeaconTxWI.TXWI_O.TxPwrAdj = TxPwrAdj; #endif /* RTMP_MAC */ #ifdef RLT_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RLT)) pAd->BeaconTxWI.TXWI_N.TxPwrAdj = TxPwrAdj; #endif /* RLT_MAC */ #endif /* SPECIFIC_TX_POWER_SUPPORT */ /* step 6. move BEACON TXD and frame content to on-chip memory */ ptr = (PUCHAR)&pAd->BeaconTxWI; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, ptr, TYPE_TXWI); #endif reg_base = pAd->BeaconOffset[pMbss->BcnBufIdx]; for (i=0; i < TXWISize; i+=4) { longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4); ptr += 4; } /* update BEACON frame content. start right after the TXWI field. */ ptr = (PUCHAR)pMbss->BeaconBuf; #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE); #endif reg_base = pAd->BeaconOffset[pMbss->BcnBufIdx] + TXWISize; for (i= 0; i< FrameLen; i+=4) { longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4); ptr += 4; } pMbss->TimIELocationInBeacon = (UCHAR)FrameLen; pMbss->CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2; } /* ========================================================================== Description: Update the BEACON frame in the shared memory. Because TIM IE is variable length. other IEs after TIM has to shift and total frame length may change for each BEACON period. Output: pAd->ApCfg.MBSSID[apidx].CapabilityInfo pAd->ApCfg.ErpIeContent ========================================================================== */ VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx) { UCHAR *pBeaconFrame; UCHAR *ptr; ULONG FrameLen; ULONG UpdatePos; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; UCHAR ID_1B, TimFirst, TimLast, *pTim; MULTISSID_STRUCT *pMbss; COMMON_CONFIG *pComCfg; UCHAR PhyMode; BOOLEAN bHasWpsIE = FALSE; UINT i; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ struct wifi_dev *wdev; #ifdef SPECIFIC_TX_POWER_SUPPORT UCHAR TxPwrAdj = 0; #endif /* SPECIFIC_TX_POWER_SUPPORT */ pComCfg = &pAd->CommonCfg; pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; pBeaconFrame = (UCHAR *)&pMbss->BeaconBuf[0]; FrameLen = UpdatePos = pMbss->TimIELocationInBeacon; PhyMode = wdev->PhyMode; if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; /* step 1 - update BEACON's Capability */ ptr = pBeaconFrame + pMbss->CapabilityInfoLocationInBeacon; *ptr = (UCHAR)(pMbss->CapabilityInfo & 0x00ff); *(ptr+1) = (UCHAR)((pMbss->CapabilityInfo & 0xff00) >> 8); /* step 2 - update TIM IE TODO: enlarge TIM bitmap to support up to 64 STAs TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time */ ptr = pBeaconFrame + pMbss->TimIELocationInBeacon; *ptr = IE_TIM; *(ptr + 2) = pAd->ApCfg.DtimCount; *(ptr + 3) = pAd->ApCfg.DtimPeriod; /* find the smallest AID (PS mode) */ TimFirst = 0; /* record first TIM byte != 0x00 */ TimLast = 0; /* record last TIM byte != 0x00 */ pTim = pMbss->TimBitmaps; for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++) { /* get the TIM indicating PS packets for 8 stations */ UCHAR tim_1B = pTim[ID_1B]; if (ID_1B == 0) tim_1B &= 0xfe; /* skip bit0 bc/mc */ if (tim_1B == 0) continue; /* find next 1B */ if (TimFirst == 0) TimFirst = ID_1B; TimLast = ID_1B; } /* fill TIM content to beacon buffer */ if (TimFirst & 0x01) TimFirst --; /* find the even offset byte */ *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */ *(ptr + 4) = TimFirst; for(i=TimFirst; i<=TimLast; i++) *(ptr + 5 + i - TimFirst) = pTim[i]; /* bit0 means backlogged mcast/bcast */ if (pAd->ApCfg.DtimCount == 0) *(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01); /* adjust BEACON length according to the new TIM */ FrameLen += (2 + *(ptr+1)); /* move RSN IE from below to here for Ralink Win7 v3.0.0.61 version parse beacon issue. */ /* sync the order with BRCM's AP. */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA) || (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; /* Append RSN_IE when WPA OR WPAPSK, */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], 1, &RSNIe2, 1, &pMbss->RSNIE_Len[1], pMbss->RSNIE_Len[1], pMbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else if (wdev->AuthMode >= Ndis802_11AuthModeWPA) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } #ifdef HOSTAPD_SUPPORT if (pMbss->HostapdWPS && (pMbss->WscIEBeacon.ValueLen)) bHasWpsIE = TRUE; #endif if (bHasWpsIE) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen, pMbss->WscIEBeacon.ValueLen, pMbss->WscIEBeacon.Value, END_OF_ARGS); FrameLen += WscTmpLen; } /* Update ERP */ if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B)) { /* fill ERP IE */ ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */ *ptr = IE_ERP; *(ptr + 1) = 1; *(ptr + 2) = pAd->ApCfg.ErpIeContent; FrameLen += 3; } #ifdef A_BAND_SUPPORT /* fill up Channel Switch Announcement Element */ if ((pComCfg->Channel > 14) && (pComCfg->bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { ptr = pBeaconFrame + FrameLen; *ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT; *(ptr + 1) = 3; *(ptr + 2) = 1; *(ptr + 3) = pComCfg->Channel; *(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1); ptr += 5; FrameLen += 5; #ifdef DOT11_N_SUPPORT /* Extended Channel Switch Announcement Element */ if (pComCfg->bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE)); ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { INT tp_len, wb_len = 0; UCHAR *ch_sw_wrapper; VHT_TXPWR_ENV_IE txpwr_env; *ptr = IE_CH_SWITCH_WRAPPER; ch_sw_wrapper = (UCHAR *)(ptr + 1); // reserve for length ptr += 2; // skip len if (pComCfg->RegTransmitSetting.field.BW == BW_40) { WIDE_BW_CH_SWITCH_ELEMENT wb_info; *ptr = IE_WIDE_BW_CH_SWITCH; *(ptr + 1) = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); ptr += 2; NdisZeroMemory(&wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); if (pComCfg->vht_bw == VHT_BW_2040) wb_info.new_ch_width = 0; else wb_info.new_ch_width = 1; if (pComCfg->vht_bw == VHT_BW_80) { wb_info.center_freq_1 = vht_cent_ch_freq(pAd, pComCfg->Channel); wb_info.center_freq_2 = 0; } NdisMoveMemory(ptr, &wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); wb_len = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); ptr += wb_len; wb_len += 2; } *ptr = IE_VHT_TXPWR_ENV; NdisZeroMemory(&txpwr_env, sizeof(VHT_TXPWR_ENV_IE)); tp_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); *(ptr + 1) = tp_len; ptr += 2; NdisMoveMemory(ptr, &txpwr_env, tp_len); ptr += tp_len; tp_len += 2; *ch_sw_wrapper = wb_len + tp_len; FrameLen += (2 + wb_len + tp_len); } #endif /* DOT11_VHT_AC */ #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT /* step 5. Update HT. Since some fields might change in the same BSS. */ if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; /*UCHAR i; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; /* USHORT b2lTmp, b2lTmp2; // no use */ #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &pComCfg->HtCapability, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if ((pComCfg->Channel <= 14) && (pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11N_DRAFT3 */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14)) { int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON); FrameLen += _len; } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen, infoPos; PUCHAR pInfo; UCHAR extInfoLen; BOOLEAN bNeedAppendExtIE = FALSE; EXT_CAP_INFO_ELEMENT extCapInfo; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) && (pMbss->wdev.DesiredHtPhyInfo.bHtEnable) && (pComCfg->bBssCoexEnable == TRUE) ) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) extCapInfo.operating_mode_notification = 1; #endif /* DOT11_VHT_AC */ pInfo = (PUCHAR)(&extCapInfo); for (infoPos = 0; infoPos < extInfoLen; infoPos++) { if (pInfo[infoPos] != 0) { bNeedAppendExtIE = TRUE; break; } } if (bNeedAppendExtIE == TRUE) { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #ifdef WFA_VHT_PF if (pAd->force_vht_op_mode == TRUE) { ULONG TmpLen; UCHAR operating_ie = IE_OPERATING_MODE_NOTIFY, operating_len = 1; OPERATING_MODE operating_mode; operating_mode.rx_nss_type = 0; operating_mode.rx_nss = (pAd->vht_pf_op_ss - 1); operating_mode.ch_width = pAd->vht_pf_op_bw; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &operating_ie, 1, &operating_len, 1, &operating_mode, END_OF_ARGS); FrameLen += TmpLen; } #endif /* WFA_VHT_PF */ /* add WMM IE here */ if (pMbss->wdev.bWmmCapable) { ULONG TmpLen; UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; UINT8 AIFSN[4]; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->UapsdInfo); #endif /* UAPSD_SUPPORT */ NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN)); for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (AIFSN[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->phy_ctrl.FlgQloadEnable != 0) FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen); #endif /* AP_QLOAD_SUPPORT */ #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE) ) { ULONG TmpLen; UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT; UINT8 PwrConstraintLen = 1; UINT8 PwrConstraint = pComCfg->PwrConstraint; /* prepare power constraint IE */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &PwrConstraintIE, 1, &PwrConstraintLen, 1, &PwrConstraint, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pComCfg->HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = HtLen1 + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pComCfg->bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pComCfg->bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pComCfg->bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (pComCfg->b256QAM_2G && WMODE_2G_ONLY(pComCfg->PhyMode)) RalinkSpecificIe[5] |= 0x8; #endif /* DOT11_VHT_AC */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* step 6. Since FrameLen may change, update TXWI. */ #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.Channel > 14) { BeaconTransmit.field.MODE = MODE_OFDM; BeaconTransmit.field.MCS = MCS_RATE_6; } #endif /* A_BAND_SUPPORT */ #ifdef SPECIFIC_TX_POWER_SUPPORT /* Specific Power for Long-Range Beacon */ if ((pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) /* && (BeaconTransmit.field.MODE == MODE_CCK)*/) { TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; } #endif /* SPECIFIC_TX_POWER_SUPPORT */ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, RESERVED_WCID, FrameLen, PID_MGMT, 0 /*QID_MGMT*/, 0, IFS_HTTXOP, &BeaconTransmit); #ifdef SPECIFIC_TX_POWER_SUPPORT #ifdef RTMP_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RTMP)) pAd->BeaconTxWI.TXWI_O.TxPwrAdj = TxPwrAdj; #endif /* RTMP_MAC */ #ifdef RLT_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RLT)) pAd->BeaconTxWI.TXWI_N.TxPwrAdj = TxPwrAdj; #endif /* RLT_MAC */ #endif /* SPECIFIC_TX_POWER_SUPPORT */ /* step 7. move BEACON TXWI and frame content to on-chip memory */ RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos); }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( 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; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1; UCHAR ErpIeLen = 1; UCHAR apidx = 0, PhyMode, SupRateLen; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; BOOLEAN bRequestRssi=FALSE; #ifdef WSC_AP_SUPPORT UCHAR Addr3[MAC_ADDR_LEN]; PFRAME_802_11 pFrame = (PFRAME_802_11)Elem->Msg; COPY_MAC_ADDR(Addr3, pFrame->Hdr.Addr3); #endif /* WSC_AP_SUPPORT */ #ifdef WDS_SUPPORT /* if in bridge mode, no need to reply probe req. */ if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE) return; #endif /* WDS_SUPPORT */ if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { RSNIe = IE_WPA; if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev))) { /* the interface is down, so we can not send probe response */ continue; } PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode; if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) || #ifdef WSC_AP_SUPPORT /* buffalo WPS testbed STA send ProbrRequest ssid length = 32 and ssid are not AP , but DA are AP. for WPS test send ProbeResponse */ ((SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, pAd->ApCfg.MBSSID[apidx].Bssid) && (pAd->ApCfg.MBSSID[apidx].bHideSsid == 0)) || #endif /* WSC_AP_SUPPORT */ ((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen))) ; else continue; /* check next BSS */ #ifdef RT_CFG80211_SUPPORT if (pAd->Cfg80211RegisterProbeReqFrame) { UINT32 freq; MAP_CHANNEL_ID_TO_KHZ(Elem->Channel, freq); freq /= 1000; CFG80211OS_RxMgmt(pAd->ApCfg.MBSSID[apidx].MSSIDDev, freq, (PUCHAR)Elem->Msg, Elem->MsgLen); } #endif /* RT_CFG80211_SUPPORT */ #ifdef BAND_STEERING BND_STRG_CHECK_CONNECTION_REQ( pAd, NULL, Addr2, Elem->MsgType, Elem->Rssi0, Elem->Rssi1, Elem->Rssi2, NULL); #endif /* BAND_STEERING */ /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid); if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAICERT) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif /* WAPI_SUPPORT */ { SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo, 1, &SsidIe, 1, &pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); } if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14)) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA) ; /* enough information */ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], 1, &RSNIe2, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (pAd->ApCfg.MBSSID[apidx].bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pAd->ApCfg.MBSSID[apidx].UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR *TmpFrame = NULL; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { ULONG TmpLen = 0; UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef RSSI_FEEDBACK if (bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", PRINT_MAC(Addr2))); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif /* RSSI_FEEDBACK */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { /* prepare power constraint IE */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); /* prepare channel information */ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }/* Country IE - */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;/*, NewExtLen; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer+FrameLen), SUBTYPE_PROBE_RSP, pAd->CommonCfg.vht_max_mcs_cap); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ #ifdef WSC_AP_SUPPORT /* for windows 7 logo test */ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && #endif /* DOT1X_SUPPORT */ (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen1 = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TempLen1, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen1; } /* add Simple Config Information Element */ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode > WSC_DISABLE) && (pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen)) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pOutBuffer+FrameLen, &WscTmpLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #endif /* WSC_AP_SUPPORT */ #ifdef RT_CFG80211_SUPPORT if (pAd->ApCfg.MBSSID[apidx].ProbRespExtraIeLen != 0) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, pAd->ApCfg.MBSSID[apidx].ProbRespExtraIeLen, &pAd->ApCfg.MBSSID[apidx].ProbRespExtraIe[0], END_OF_ARGS); FrameLen += TmpLen; } #endif /* RT_CFG80211_SUPPORT */ /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ========================================================================== Description: Pre-build a BEACON frame in the shared memory ========================================================================== */ VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx) { BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; UCHAR DsLen = 1, SsidLen; HEADER_802_11 BcnHdr; LARGE_INTEGER FakeTimestamp; ULONG FrameLen = 0; UCHAR *pBeaconFrame, *tmac_info; #if defined(DOT11_N_SUPPORT) && defined(DOT11K_RRM_SUPPORT) UINT i; #endif HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at HT rate. */ UCHAR PhyMode, SupRateLen; UINT8 TXWISize = pAd->chipCap.TXWISize; UINT8 tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len; if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; if (pMbss->bcn_buf.BeaconPkt == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s():Invalid BeaconPkt for MBSS[%d]\n", __FUNCTION__, apidx)); return; } #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) { return; //Carter, 20140306 for MT7603, merge MakeAllBeacon into UpdateAllBeacon } #endif tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->bcn_buf.BeaconPkt); if (pAd->chipCap.hif_type == HIF_MT) { pBeaconFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len); } else { pBeaconFrame = (UCHAR *)(tmac_info + TXWISize); } PhyMode = pMbss->wdev.PhyMode; SsidLen = (pMbss->bHideSsid) ? 0 : pMbss->SsidLen; MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pMbss->wdev.if_addr, pMbss->wdev.bssid); /* for update framelen to TxWI later. */ SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pBeaconFrame, &FrameLen, sizeof(HEADER_802_11), &BcnHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pMbss->CapabilityInfo, 1, &SsidIe, 1, &SsidLen, SsidLen, pMbss->Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; UCHAR CountryIe = IE_COUNTRY; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT /* AP Channel Report */ { UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT; ULONG TmpLen; /* 802.11n D2.0 Annex J, USA regulatory class 32, channel set 1~7 class 33, channel set 5-11 */ UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7}; UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11}; UCHAR rclasslen = 8; /*sizeof(rclass32); */ if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN)) { MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass32, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass33, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ BeaconTransmit.word = 0; write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen); /* step 6. move BEACON TXD and frame content to on-chip memory */ asic_write_bcn_buf(pAd, tmac_info, TXWISize, pBeaconFrame, FrameLen, pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]); pMbss->TimIELocationInBeacon = (UCHAR)FrameLen; pMbss->bcn_buf.cap_ie_pos = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2; //pMbss->bcn_buf.bcn_state = BCN_TX_IDLE; //+++Add by shiang for debug //---Add by shiang for debug } /* ========================================================================== Description: Update the BEACON frame in the shared memory. Because TIM IE is variable length. other IEs after TIM has to shift and total frame length may change for each BEACON period. Output: pAd->ApCfg.MBSSID[apidx].CapabilityInfo pAd->ApCfg.ErpIeContent ========================================================================== */ VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx) { UCHAR *pBeaconFrame, *tmac_info; UCHAR *ptr; ULONG FrameLen; ULONG UpdatePos = 0; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; UCHAR ID_1B, TimFirst, TimLast, *pTim; BSS_STRUCT *pMbss; COMMON_CONFIG *pComCfg; BOOLEAN bHasWpsIE = FALSE; UINT i; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ struct wifi_dev *wdev; UCHAR tx_hw_hdr_len = pAd->chipCap.tx_hw_hdr_len; UINT8 TXWISize = pAd->chipCap.TXWISize; UCHAR DsLen = 1, SsidLen; HEADER_802_11 BcnHdr; LARGE_INTEGER FakeTimestamp; UCHAR PhyMode = 0, SupRateLen; pComCfg = &pAd->CommonCfg; pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; if (!pMbss || !pMbss->bcn_buf.BeaconPkt) return; tmac_info = (UCHAR *)GET_OS_PKT_DATAPTR(pMbss->bcn_buf.BeaconPkt); if (pAd->chipCap.hif_type == HIF_MT) { pBeaconFrame = (UCHAR *)(tmac_info + tx_hw_hdr_len); } else { pBeaconFrame = (UCHAR *)(tmac_info + TXWISize); } if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; #ifdef CONFIG_FPGA_MODE if (pAd->fpga_ctl.fpga_on & 0x1) { if (pAd->fpga_ctl.tx_kick_cnt == 0) return; } #ifdef MT_MAC if (pAd->fpga_ctl.no_bcn) { DBGPRINT(RT_DEBUG_OFF, ("%s():Bcn Tx is blocked!\n", __FUNCTION__)); return; } #endif /* MT_MAC */ #endif /* CONFIG_FPGA_MODE */ #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) { BOOLEAN is_pretbtt_int = FALSE; #ifdef RTMP_PCI_SUPPORT USHORT FreeNum = GET_BCNRING_FREENO(pAd); if (FreeNum <= 0) { DBGPRINT(RT_DEBUG_ERROR, ("%s()=>BSS%d:BcnRing FreeNum is not enough!\n", __FUNCTION__, apidx)); return; } #endif /* RTMP_PCI_SUPPORT */ if (pMbss->bcn_buf.bcn_state != BCN_TX_IDLE) { #ifdef RTMP_PCI_SUPPORT APCheckBcnQHandler(pAd, apidx, &is_pretbtt_int); #endif /* RTMP_PCI_SUPPORT */ if (is_pretbtt_int == FALSE) return; } PhyMode = pMbss->wdev.PhyMode; SsidLen = (pMbss->bHideSsid) ? 0 : pMbss->SsidLen; MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pMbss->wdev.if_addr, pMbss->wdev.bssid); /* for update framelen to TxWI later. */ SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pBeaconFrame, &FrameLen, sizeof(HEADER_802_11), &BcnHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pMbss->CapabilityInfo, 1, &SsidIe, 1, &SsidLen, SsidLen, pMbss->Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; UCHAR CountryIe = IE_COUNTRY; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT /* AP Channel Report */ { UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT; ULONG TmpLen; /* 802.11n D2.0 Annex J, USA regulatory class 32, channel set 1~7 class 33, channel set 5-11 */ UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7}; UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11}; UCHAR rclasslen = 8; /*sizeof(rclass32); */ if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN)) { MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass32, 1, &APChannelReportIe, 1, &rclasslen, rclasslen, rclass33, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ BeaconTransmit.word = 0; //write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen); pMbss->TimIELocationInBeacon = (UCHAR)FrameLen; pMbss->bcn_buf.cap_ie_pos = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2; FrameLen = UpdatePos = pMbss->TimIELocationInBeacon; PhyMode = wdev->PhyMode; } #endif /* MT_MAC */ /* step 1 - update BEACON's Capability */ ptr = pBeaconFrame + pMbss->bcn_buf.cap_ie_pos; //prevent little/big endian issue. and let asic_write_bcn_buf() handle it. *(UINT16 *)ptr = pMbss->CapabilityInfo; /* step 2 - update TIM IE TODO: enlarge TIM bitmap to support up to 64 STAs TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time */ ptr = pBeaconFrame + pMbss->TimIELocationInBeacon; *ptr = IE_TIM; *(ptr + 2) = pAd->ApCfg.DtimCount; *(ptr + 3) = pAd->ApCfg.DtimPeriod; /* find the smallest AID (PS mode) */ TimFirst = 0; /* record first TIM byte != 0x00 */ TimLast = 0; /* record last TIM byte != 0x00 */ pTim = pMbss->TimBitmaps; for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++) { /* get the TIM indicating PS packets for 8 stations */ UCHAR tim_1B = pTim[ID_1B]; if (ID_1B == 0) tim_1B &= 0xfe; /* skip bit0 bc/mc */ if (tim_1B == 0) continue; /* find next 1B */ if (TimFirst == 0) TimFirst = ID_1B; TimLast = ID_1B; } /* fill TIM content to beacon buffer */ if (TimFirst & 0x01) TimFirst --; /* find the even offset byte */ *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */ *(ptr + 4) = TimFirst; for(i=TimFirst; i<=TimLast; i++) *(ptr + 5 + i - TimFirst) = pTim[i]; /* bit0 means backlogged mcast/bcast */ if (pAd->ApCfg.DtimCount == 0) *(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01); /* adjust BEACON length according to the new TIM */ FrameLen += (2 + *(ptr+1)); /* move RSN IE from below to here for Ralink Win7 v3.0.0.61 version parse beacon issue. */ /* sync the order with BRCM's AP. */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA) || (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((wdev->AuthMode == Ndis802_11AuthModeWAICERT) || (wdev->AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif /* WAPI_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], 1, &RSNIe2, 1, &pMbss->RSNIE_Len[1], pMbss->RSNIE_Len[1], pMbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else if (wdev->AuthMode >= Ndis802_11AuthModeWPA) { ULONG TmpLen; { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } } #ifdef HOSTAPD_SUPPORT if (pMbss->HostapdWPS && (pMbss->WscIEBeacon.ValueLen)) bHasWpsIE = TRUE; #endif #ifdef WSC_AP_SUPPORT /* add Simple Config Information Element */ if (((pMbss->WscControl.WscConfMode >= 1) && (pMbss->WscIEBeacon.ValueLen))) bHasWpsIE = TRUE; #endif /* WSC_AP_SUPPORT */ if (bHasWpsIE) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen, pMbss->WscIEBeacon.ValueLen, pMbss->WscIEBeacon.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #ifdef WSC_AP_SUPPORT if ((pMbss->WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pMbss->wdev.IEEE8021X == FALSE) && #endif /* DOT1X_SUPPORT */ (pMbss->wdev.WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http:msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TempLen, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen; } #endif /* WSC_AP_SUPPORT */ /* Update ERP */ if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B)) { /* fill ERP IE */ ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */ *ptr = IE_ERP; *(ptr + 1) = 1; *(ptr + 2) = pAd->ApCfg.ErpIeContent; FrameLen += 3; } #ifdef A_BAND_SUPPORT /* fill up Channel Switch Announcement Element */ if ((pComCfg->Channel > 14) && (pComCfg->bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { ptr = pBeaconFrame + FrameLen; *ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT; *(ptr + 1) = 3; *(ptr + 2) = 1; *(ptr + 3) = pComCfg->Channel; *(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1); ptr += 5; FrameLen += 5; #ifdef DOT11_N_SUPPORT /* Extended Channel Switch Announcement Element */ if (pComCfg->bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE)); ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { INT tp_len, wb_len = 0; UCHAR *ch_sw_wrapper; VHT_TXPWR_ENV_IE txpwr_env; *ptr = IE_CH_SWITCH_WRAPPER; ch_sw_wrapper = (UCHAR *)(ptr + 1); // reserve for length ptr += 2; // skip len if (pComCfg->RegTransmitSetting.field.BW == BW_40) { WIDE_BW_CH_SWITCH_ELEMENT wb_info; *ptr = IE_WIDE_BW_CH_SWITCH; *(ptr + 1) = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); ptr += 2; NdisZeroMemory(&wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); if (pComCfg->vht_bw == VHT_BW_2040) wb_info.new_ch_width = 0; else wb_info.new_ch_width = 1; if (pComCfg->vht_bw == VHT_BW_80) { wb_info.center_freq_1 = vht_cent_ch_freq(pAd, pComCfg->Channel); wb_info.center_freq_2 = 0; } NdisMoveMemory(ptr, &wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); wb_len = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); ptr += wb_len; wb_len += 2; } *ptr = IE_VHT_TXPWR_ENV; NdisZeroMemory(&txpwr_env, sizeof(VHT_TXPWR_ENV_IE)); tp_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); *(ptr + 1) = tp_len; ptr += 2; NdisMoveMemory(ptr, &txpwr_env, tp_len); ptr += tp_len; tp_len += 2; *ch_sw_wrapper = wb_len + tp_len; FrameLen += (2 + wb_len + tp_len); } #endif /* DOT11_VHT_AC */ #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT /* step 5. Update HT. Since some fields might change in the same BSS. */ if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; /*UCHAR i; */ HT_CAPABILITY_IE HtCapabilityTmp; #ifdef RT_BIG_ENDIAN ADD_HT_INFO_IE addHTInfoTmp; /* USHORT b2lTmp, b2lTmp2; // no use */ #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); #ifndef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); HtCapabilityTmp.HtCapInfo.ChannelWidth = pComCfg->AddHTInfo.AddHtInfo.RecomWidth; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); HtCapabilityTmp.HtCapInfo.ChannelWidth = pComCfg->AddHTInfo.AddHtInfo.RecomWidth; *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if ((pComCfg->Channel <= 14) && (pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11N_DRAFT3 */ #ifdef CONFIG_HOTSPOT if (pMbss->HotSpotCtrl.HotSpotEnable) { ULONG TmpLen; /* Indication element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.HSIndicationIELen, pMbss->HotSpotCtrl.HSIndicationIE, END_OF_ARGS); FrameLen += TmpLen; /* Interworking element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.InterWorkingIELen, pMbss->HotSpotCtrl.InterWorkingIE, END_OF_ARGS); FrameLen += TmpLen; /* Advertisement Protocol element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.AdvertisementProtoIELen, pMbss->HotSpotCtrl.AdvertisementProtoIE, END_OF_ARGS); FrameLen += TmpLen; /* Roaming Consortium element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.RoamingConsortiumIELen, pMbss->HotSpotCtrl.RoamingConsortiumIE, END_OF_ARGS); FrameLen += TmpLen; /* P2P element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.P2PIELen, pMbss->HotSpotCtrl.P2PIE, END_OF_ARGS); FrameLen += TmpLen; } #endif #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14)) { int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON); FrameLen += _len; } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen, infoPos; PUCHAR pInfo; UCHAR extInfoLen; BOOLEAN bNeedAppendExtIE = FALSE; EXT_CAP_INFO_ELEMENT extCapInfo; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) && (pMbss->wdev.DesiredHtPhyInfo.bHtEnable) && (pComCfg->bBssCoexEnable == TRUE) ) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ #ifdef CONFIG_DOT11V_WNM if (pMbss->WNMCtrl.ProxyARPEnable) extCapInfo.proxy_arp = 1; #endif /* CONFIG_DOT11V_WNM */ #ifdef CONFIG_HOTSPOT if (pMbss->HotSpotCtrl.HotSpotEnable) extCapInfo.interworking = 1; #endif /* CONFIG_HOTSPOT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) extCapInfo.operating_mode_notification = 1; #endif /* DOT11_VHT_AC */ pInfo = (PUCHAR)(&extCapInfo); for (infoPos = 0; infoPos < extInfoLen; infoPos++) { if (pInfo[infoPos] != 0) { bNeedAppendExtIE = TRUE; break; } } if (bNeedAppendExtIE == TRUE) { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #ifdef WFA_VHT_PF if (pAd->force_vht_op_mode == TRUE) { ULONG TmpLen; UCHAR operating_ie = IE_OPERATING_MODE_NOTIFY, operating_len = 1; OPERATING_MODE operating_mode; operating_mode.rx_nss_type = 0; operating_mode.rx_nss = (pAd->vht_pf_op_ss - 1); operating_mode.ch_width = pAd->vht_pf_op_bw; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &operating_ie, 1, &operating_len, 1, &operating_mode, END_OF_ARGS); FrameLen += TmpLen; } #endif /* WFA_VHT_PF */ /* add WMM IE here */ if (pMbss->wdev.bWmmCapable) { ULONG TmpLen; UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; UINT8 AIFSN[4]; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->wdev.UapsdInfo); #endif /* UAPSD_SUPPORT */ NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN)); for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (AIFSN[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->phy_ctrl.FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE) ) { ULONG TmpLen; UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT; UINT8 PwrConstraintLen = 1; UINT8 PwrConstraint = pComCfg->PwrConstraint; /* prepare power constraint IE */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &PwrConstraintIE, 1, &PwrConstraintLen, 1, &PwrConstraint, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pComCfg->HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = HtLen1 + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pComCfg->bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pComCfg->bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pComCfg->bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* step 6. Since FrameLen may change, update TXWI. */ #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.Channel > 14) { BeaconTransmit.field.MODE = MODE_OFDM; BeaconTransmit.field.MCS = MCS_RATE_6; } #endif /* A_BAND_SUPPORT */ write_tmac_info_beacon(pAd, apidx, tmac_info, &BeaconTransmit, FrameLen); /* step 6. move BEACON TXD and frame content to on-chip memory */ asic_write_bcn_buf(pAd, tmac_info, TXWISize, pBeaconFrame, FrameLen, pAd->BeaconOffset[pMbss->bcn_buf.BcnBufIdx]); #if defined(MT7603_FPGA) || defined(MT7628_FPGA) // TODO: shiang-7603, we use different way to update beacon packet! if (0)//IS_MT7603(pAd)) { hex_dump("Beacon_TMAC_INFO", (UCHAR *)tmac_info, tx_hw_hdr_len); dump_tmac_info(pAd, tmac_info); hex_dump("BeaconFrame", pBeaconFrame, FrameLen); } #endif /* MT7603_FPGA */ /* step 7. move BEACON TXWI and frame content to on-chip memory */ RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos); { UINT32 Lowpart, Highpart; AsicGetTsfTime(pAd, &Highpart, &Lowpart); pMbss->WriteBcnDoneTime[pMbss->timer_loop] = Lowpart; } }
/* ========================================================================== Description: ========================================================================== */ static VOID ApCliEnqueueProbeRequest( IN PRTMP_ADAPTER pAd, IN UCHAR SsidLen, IN PCHAR Ssid, IN PCHAR Bssid, IN USHORT ifIndex) { NDIS_STATUS NState; PUCHAR pOutBuffer; ULONG FrameLen = 0; HEADER_802_11 Hdr80211; UCHAR SsidIe = IE_SSID; UCHAR SupRateIe = IE_SUPP_RATES; UCHAR ssidLen; CHAR ssid[MAX_LEN_OF_SSID]; APCLI_STRUCT *pApCliEntry = NULL; BOOLEAN bHasWscIe = FALSE; UCHAR PhyMode = pAd->CommonCfg.PhyMode; DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n")); if (ifIndex >= MAX_APCLI_NUM) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; #ifdef APCLI_AUTO_BW_SUPPORT PhyMode = pApCliEntry->wdev.PhyMode; #endif /* APCLI_AUTO_BW_SUPPORT */ NState = MlmeAllocateMemory(pAd, &pOutBuffer); /* Get an unused nonpaged memory */ if(NState != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("EnqueueProbeRequest() allocate memory fail\n")); return; } else { if(MAC_ADDR_EQUAL(Bssid, ZERO_MAC_ADDR)) ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR, ifIndex); else ApCliMgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, Bssid, Bssid, ifIndex); ssidLen = SsidLen; NdisZeroMemory(ssid, MAX_LEN_OF_SSID); NdisMoveMemory(ssid, Ssid, ssidLen); /* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &Hdr80211, 1, &SsidIe, 1, &ssidLen, ssidLen, ssid, 1, &SupRateIe, 1, &pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.SupRateLen, pApCliEntry->MlmeAux.SupRate, END_OF_ARGS); /* Add the extended rate IE */ if (pApCliEntry->MlmeAux.ExtRateLen != 0) { ULONG tmp; MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, 1, &ExtRateIe, 1, &pApCliEntry->MlmeAux.ExtRateLen, pApCliEntry->MlmeAux.ExtRateLen, pApCliEntry->MlmeAux.ExtRate, END_OF_ARGS); FrameLen += tmp; } #ifdef SMART_MESH SMART_MESH_INSERT_IE(pApCliEntry->SmartMeshCfg, pOutBuffer, FrameLen, SM_IE_PROBE_REQ); #endif /* SMART_MESH */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) { build_vht_cap_ie(pAd, (UCHAR *)&pApCliEntry->MlmeAux.vht_cap); pApCliEntry->MlmeAux.vht_cap_len = sizeof(VHT_CAP_IE); FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer + FrameLen), SUBTYPE_PROBE_REQ); } #endif /* DOT11_VHT_AC */ #ifdef WSC_AP_SUPPORT /* Append WSC information in probe request if WSC state is running */ if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) && (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger)) { bHasWscIe = TRUE; } #ifdef WSC_V2_SUPPORT else if (pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscV2Info.bEnableWpsV2) { bHasWscIe = TRUE; } #endif /* WSC_V2_SUPPORT */ #ifdef WSC_AP_SUPPORT #ifdef SMART_MESH_HIDDEN_WPS if(pAd->ApCfg.ApCliTab[ifIndex].SmartMeshCfg.bSupportHiddenWPS) bHasWscIe = FALSE; #endif /* SMART_MESH_HIDDEN_WPS */ #endif /* WSC_AP_SUPPORT */ if (bHasWscIe) { UCHAR /* WscBuf[256], */ WscIeLen = 0; UCHAR *WscBuf = NULL; ULONG WscTmpLen = 0; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&WscBuf, 512); if (WscBuf != NULL) { NdisZeroMemory(WscBuf, 512); WscBuildProbeReqIE(pAd, STA_MODE, WscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, WscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, WscBuf); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #endif /*WSC_AP_SUPPORT*/ #ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE if ((pAd->StaCfg.wpa_supplicant_info.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->cfg80211_ctrl.ExtraIeLen != 0)) { ULONG ExtraIeTmpLen = 0; MakeOutgoingFrame(pOutBuffer + FrameLen, &ExtraIeTmpLen, pAd->cfg80211_ctrl.ExtraIeLen, pAd->cfg80211_ctrl.pExtraIe, END_OF_ARGS); FrameLen += ExtraIeTmpLen; } #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE*/ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } return; }
/* ========================================================================== Description: Update the BEACON frame in the shared memory. Because TIM IE is variable length. other IEs after TIM has to shift and total frame length may change for each BEACON period. Output: pAd->ApCfg.MBSSID[apidx].CapabilityInfo pAd->ApCfg.ErpIeContent ========================================================================== */ VOID APUpdateBeaconFrame(RTMP_ADAPTER *pAd, INT apidx) { UCHAR *pBeaconFrame; UCHAR *ptr; ULONG FrameLen; ULONG UpdatePos; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; UCHAR ID_1B, TimFirst, TimLast, *pTim; MULTISSID_STRUCT *pMbss; COMMON_CONFIG *pComCfg; UCHAR PhyMode; BOOLEAN bHasWpsIE = FALSE; UINT i; HTTRANSMIT_SETTING BeaconTransmit = {.word = 0}; /* MGMT frame PHY rate setting when operatin at Ht rate. */ struct wifi_dev *wdev; #ifdef SPECIFIC_TX_POWER_SUPPORT UCHAR TxPwrAdj = 0; #endif /* SPECIFIC_TX_POWER_SUPPORT */ pComCfg = &pAd->CommonCfg; pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; pBeaconFrame = (UCHAR *)&pMbss->BeaconBuf[0]; FrameLen = UpdatePos = pMbss->TimIELocationInBeacon; PhyMode = wdev->PhyMode; if(!BeaconTransmitRequired(pAd, apidx, pMbss)) return; /* step 1 - update BEACON's Capability */ ptr = pBeaconFrame + pMbss->CapabilityInfoLocationInBeacon; *ptr = (UCHAR)(pMbss->CapabilityInfo & 0x00ff); *(ptr+1) = (UCHAR)((pMbss->CapabilityInfo & 0xff00) >> 8); /* step 2 - update TIM IE TODO: enlarge TIM bitmap to support up to 64 STAs TODO: re-measure if RT2600 TBTT interrupt happens faster than BEACON sent out time */ ptr = pBeaconFrame + pMbss->TimIELocationInBeacon; *ptr = IE_TIM; *(ptr + 2) = pAd->ApCfg.DtimCount; *(ptr + 3) = pAd->ApCfg.DtimPeriod; /* find the smallest AID (PS mode) */ TimFirst = 0; /* record first TIM byte != 0x00 */ TimLast = 0; /* record last TIM byte != 0x00 */ pTim = pMbss->TimBitmaps; for(ID_1B=0; ID_1B<WLAN_MAX_NUM_OF_TIM; ID_1B++) { /* get the TIM indicating PS packets for 8 stations */ UCHAR tim_1B = pTim[ID_1B]; if (ID_1B == 0) tim_1B &= 0xfe; /* skip bit0 bc/mc */ if (tim_1B == 0) continue; /* find next 1B */ if (TimFirst == 0) TimFirst = ID_1B; TimLast = ID_1B; } /* fill TIM content to beacon buffer */ if (TimFirst & 0x01) TimFirst --; /* find the even offset byte */ *(ptr + 1) = 3+(TimLast-TimFirst+1); /* TIM IE length */ *(ptr + 4) = TimFirst; for(i=TimFirst; i<=TimLast; i++) *(ptr + 5 + i - TimFirst) = pTim[i]; /* bit0 means backlogged mcast/bcast */ if (pAd->ApCfg.DtimCount == 0) *(ptr + 4) |= (pMbss->TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] & 0x01); /* adjust BEACON length according to the new TIM */ FrameLen += (2 + *(ptr+1)); /* move RSN IE from below to here for Ralink Win7 v3.0.0.61 version parse beacon issue. */ /* sync the order with BRCM's AP. */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA) || (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((wdev->AuthMode == Ndis802_11AuthModeWAICERT) || (wdev->AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif /* WAPI_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { ULONG TmpLen; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], 1, &RSNIe2, 1, &pMbss->RSNIE_Len[1], pMbss->RSNIE_Len[1], pMbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else if (wdev->AuthMode >= Ndis802_11AuthModeWPA) { ULONG TmpLen; #ifdef CONFIG_HOTSPOT_R2 extern UCHAR OSEN_IE[]; extern UCHAR OSEN_IELEN; if ((pMbss->HotSpotCtrl.HotSpotEnable == 0) && (pMbss->HotSpotCtrl.bASANEnable == 1) && (pMbss->wdev.AuthMode == Ndis802_11AuthModeWPA2)) { RSNIe = IE_WPA; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &OSEN_IELEN, OSEN_IELEN, OSEN_IE, END_OF_ARGS); FrameLen += TmpLen; } else #endif /* CONFIG_HOTSPOT_R2 */ { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &RSNIe, 1, &pMbss->RSNIE_Len[0], pMbss->RSNIE_Len[0], pMbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } } #ifdef HOSTAPD_SUPPORT if (pMbss->HostapdWPS && (pMbss->WscIEBeacon.ValueLen)) bHasWpsIE = TRUE; #endif #ifdef WSC_AP_SUPPORT /* add Simple Config Information Element */ if (((pMbss->WscControl.WscConfMode >= 1) && (pMbss->WscIEBeacon.ValueLen))) bHasWpsIE = TRUE; #endif /* WSC_AP_SUPPORT */ if (bHasWpsIE) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pBeaconFrame+FrameLen, &WscTmpLen, pMbss->WscIEBeacon.ValueLen, pMbss->WscIEBeacon.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #ifdef WSC_AP_SUPPORT if ((pMbss->WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pMbss->wdev.IEEE8021X == FALSE) && #endif /* DOT1X_SUPPORT */ (pMbss->wdev.WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http:msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TempLen, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen; } #endif /* WSC_AP_SUPPORT */ /* Update ERP */ if ((pComCfg->ExtRateLen) && (PhyMode != WMODE_B)) { /* fill ERP IE */ ptr = (UCHAR *)pBeaconFrame + FrameLen; /* pTxD->DataByteCnt; */ *ptr = IE_ERP; *(ptr + 1) = 1; *(ptr + 2) = pAd->ApCfg.ErpIeContent; FrameLen += 3; } #ifdef A_BAND_SUPPORT /* fill up Channel Switch Announcement Element */ if (((pComCfg->Channel > 14) && (pComCfg->bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) #ifdef CUSTOMER_DCC_FEATURE || (pComCfg->channelSwitch.CHSWMode == CHANNEL_SWITCHING_MODE) #endif ) { ptr = pBeaconFrame + FrameLen; *ptr = IE_CHANNEL_SWITCH_ANNOUNCEMENT; *(ptr + 1) = 3; *(ptr + 2) = 1; *(ptr + 3) = pComCfg->Channel; #ifdef CUSTOMER_DCC_FEATURE if(pComCfg->channelSwitch.CHSWMode == CHANNEL_SWITCHING_MODE) *(ptr + 4) = (pComCfg->channelSwitch.CHSWPeriod - pComCfg->channelSwitch.CHSWCount); else #endif *(ptr + 4) = (pAd->Dot11_H.CSPeriod - pAd->Dot11_H.CSCount - 1); ptr += 5; FrameLen += 5; #ifdef DOT11_N_SUPPORT /* Extended Channel Switch Announcement Element */ if (pComCfg->bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); NdisMoveMemory(ptr, &HtExtChannelSwitchIe, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE)); ptr += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); FrameLen += sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE); } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { INT tp_len, wb_len = 0; UCHAR *ch_sw_wrapper; VHT_TXPWR_ENV_IE txpwr_env; *ptr = IE_CH_SWITCH_WRAPPER; ch_sw_wrapper = (UCHAR *)(ptr + 1); // reserve for length ptr += 2; // skip len if (pComCfg->RegTransmitSetting.field.BW == BW_40) { WIDE_BW_CH_SWITCH_ELEMENT wb_info; *ptr = IE_WIDE_BW_CH_SWITCH; //*(ptr + 1) = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); *(ptr + 1) = 3; ptr += 2; NdisZeroMemory(&wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); if (pComCfg->vht_bw == VHT_BW_2040) wb_info.new_ch_width = 0; else wb_info.new_ch_width = 1; if (pComCfg->vht_bw == VHT_BW_80) { wb_info.center_freq_1 = vht_cent_ch_freq(pAd, pComCfg->Channel); wb_info.center_freq_2 = 0; } NdisMoveMemory(ptr, &wb_info, sizeof(WIDE_BW_CH_SWITCH_ELEMENT)); //wb_len = sizeof(WIDE_BW_CH_SWITCH_ELEMENT); wb_len = 3; ptr += wb_len; wb_len += 2; } *ptr = IE_VHT_TXPWR_ENV; NdisZeroMemory(&txpwr_env, sizeof(VHT_TXPWR_ENV_IE)); tp_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); *(ptr + 1) = tp_len; ptr += 2; NdisMoveMemory(ptr, &txpwr_env, tp_len); ptr += tp_len; tp_len += 2; *ch_sw_wrapper = wb_len + tp_len; FrameLen += (2 + wb_len + tp_len); } #endif /* DOT11_VHT_AC */ #endif /* DOT11_N_SUPPORT */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT /* step 5. Update HT. Since some fields might change in the same BSS. */ if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; /*UCHAR i; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; /* USHORT b2lTmp, b2lTmp2; // no use */ #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &pComCfg->HtCapability, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &HtLen1, HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if ((pComCfg->Channel <= 14) && (pComCfg->HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pComCfg->Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pComCfg->Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pComCfg->Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pComCfg->Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pComCfg->Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pComCfg->Dot11OBssScanActivityThre); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11N_DRAFT3 */ #ifdef CONFIG_HOTSPOT if (pMbss->HotSpotCtrl.HotSpotEnable) { ULONG TmpLen; /* Indication element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.HSIndicationIELen, pMbss->HotSpotCtrl.HSIndicationIE, END_OF_ARGS); FrameLen += TmpLen; /* Interworking element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.InterWorkingIELen, pMbss->HotSpotCtrl.InterWorkingIE, END_OF_ARGS); FrameLen += TmpLen; /* Advertisement Protocol element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.AdvertisementProtoIELen, pMbss->HotSpotCtrl.AdvertisementProtoIE, END_OF_ARGS); FrameLen += TmpLen; /* Roaming Consortium element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.RoamingConsortiumIELen, pMbss->HotSpotCtrl.RoamingConsortiumIE, END_OF_ARGS); FrameLen += TmpLen; /* P2P element */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, pMbss->HotSpotCtrl.P2PIELen, pMbss->HotSpotCtrl.P2PIE, END_OF_ARGS); FrameLen += TmpLen; } #endif #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pComCfg->Channel > 14)) { int _len = build_vht_ies(pAd, (UCHAR *)(pBeaconFrame+FrameLen), SUBTYPE_BEACON); FrameLen += _len; } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen, infoPos; PUCHAR pInfo; UCHAR extInfoLen; BOOLEAN bNeedAppendExtIE = FALSE; EXT_CAP_INFO_ELEMENT extCapInfo; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pComCfg->Channel <= 14) && (pMbss->wdev.DesiredHtPhyInfo.bHtEnable) && (pComCfg->bBssCoexEnable == TRUE) ) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ #ifdef CONFIG_DOT11V_WNM if (pMbss->WNMCtrl.ProxyARPEnable) extCapInfo.proxy_arp = 1; #ifdef CONFIG_HOTSPOT_R2 if (pMbss->WNMCtrl.WNMNotifyEnable) extCapInfo.wnm_notification = 1; if (pMbss->HotSpotCtrl.QosMapEnable) extCapInfo.qosmap= 1; #endif /* CONFIG_HOTSPOT_R2 */ #endif /* CONFIG_DOT11V_WNM */ #ifdef CONFIG_HOTSPOT if (pMbss->HotSpotCtrl.HotSpotEnable) extCapInfo.interworking = 1; #endif /* CONFIG_HOTSPOT */ #ifdef DOT11V_WNM_SUPPORT if (IS_BSS_TRANSIT_MANMT_SUPPORT(pAd, apidx)) { extCapInfo.BssTransitionManmt = 1; } if (IS_WNMDMS_SUPPORT(pAd, apidx)) { extCapInfo.DMSSupport = 1; } #endif /* DOT11V_WNM_SUPPORT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) extCapInfo.operating_mode_notification = 1; #endif /* DOT11_VHT_AC */ pInfo = (PUCHAR)(&extCapInfo); for (infoPos = 0; infoPos < extInfoLen; infoPos++) { if (pInfo[infoPos] != 0) { bNeedAppendExtIE = TRUE; break; } } if (bNeedAppendExtIE == TRUE) { MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #ifdef WFA_VHT_PF if (pAd->force_vht_op_mode == TRUE) { ULONG TmpLen; UCHAR operating_ie = IE_OPERATING_MODE_NOTIFY, operating_len = 1; OPERATING_MODE operating_mode; operating_mode.rx_nss_type = 0; operating_mode.rx_nss = (pAd->vht_pf_op_ss - 1); operating_mode.ch_width = pAd->vht_pf_op_bw; MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &operating_ie, 1, &operating_len, 1, &operating_mode, END_OF_ARGS); FrameLen += TmpLen; } #endif /* WFA_VHT_PF */ /* add WMM IE here */ if (pMbss->wdev.bWmmCapable) { ULONG TmpLen; UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; UINT8 AIFSN[4]; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pMbss->UapsdInfo); #endif /* UAPSD_SUPPORT */ NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN)); for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (AIFSN[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->phy_ctrl.FlgQloadEnable != 0) { #ifdef CONFIG_HOTSPOT_R2 if (pMbss->HotSpotCtrl.QLoadTestEnable == 1) FrameLen += QBSS_LoadElementAppend_HSTEST(pAd, pBeaconFrame+FrameLen, apidx); else if (pMbss->HotSpotCtrl.QLoadTestEnable == 0) #endif FrameLen += QBSS_LoadElementAppend(pAd, pBeaconFrame+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (((pComCfg->Channel > 14) && pComCfg->bIEEE80211H == TRUE) #ifdef DOT11K_RRM_SUPPORT || IS_RRM_ENABLE(pAd, apidx) #endif /* DOT11K_RRM_SUPPORT */ ) { ULONG TmpLen; UINT8 PwrConstraintIE = IE_POWER_CONSTRAINT; UINT8 PwrConstraintLen = 1; UINT8 PwrConstraint = pComCfg->PwrConstraint; /* prepare power constraint IE */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &PwrConstraintIE, 1, &PwrConstraintLen, 1, &PwrConstraint, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ #ifdef DOT11K_RRM_SUPPORT if (IS_RRM_ENABLE(pAd, apidx)) { PRRM_QUIET_CB pQuietCB = &pMbss->RrmCfg.QuietCB; RRM_InsertQuietIE(pAd, pBeaconFrame+FrameLen, &FrameLen, pQuietCB->QuietCnt ,pQuietCB->QuietPeriod, pQuietCB->QuietDuration, pQuietCB->QuietOffset); #ifndef APPLE_11K_IOT /* Insert BSS AC Access Delay IE. */ RRM_InsertBssACDelayIE(pAd, pBeaconFrame+FrameLen, &FrameLen); /* Insert BSS Available Access Capacity IE. */ RRM_InsertBssAvailableACIE(pAd, pBeaconFrame+FrameLen, &FrameLen); #endif /* !APPLE_11K_IOT */ } #endif /* DOT11K_RRM_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, HtLen1; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif /* add HT Capability IE */ HtLen = sizeof(pComCfg->HtCapability); HtLen1 = sizeof(pComCfg->AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pComCfg->HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pComCfg->HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = HtLen1 + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &pComCfg->AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pComCfg->AddHTInfo, HtLen1); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], HtLen1, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pComCfg->bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pComCfg->bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pComCfg->bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (pComCfg->b256QAM_2G && WMODE_2G_ONLY(pComCfg->PhyMode)) RalinkSpecificIe[5] |= 0x8; #endif /* DOT11_VHT_AC */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* add Mediatek-specific IE here */ { ULONG TmpLen = 0; UCHAR MediatekSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0xe7, 0x00, 0x00, 0x00, 0x00}; #ifdef DOT11_VHT_AC if (pComCfg->b256QAM_2G && WMODE_2G_ONLY(pComCfg->PhyMode)) MediatekSpecificIe[5] |= 0x8; #endif /* DOT11_VHT_AC */ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen, 9, MediatekSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* step 6. Since FrameLen may change, update TXWI. */ #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.Channel > 14) { BeaconTransmit.field.MODE = MODE_OFDM; BeaconTransmit.field.MCS = MCS_RATE_6; } #endif /* A_BAND_SUPPORT */ #ifdef SPECIFIC_TX_POWER_SUPPORT /* Specific Power for Long-Range Beacon */ if ((pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) /* && (BeaconTransmit.field.MODE == MODE_CCK)*/) { TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; } #endif /* SPECIFIC_TX_POWER_SUPPORT */ RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, RESERVED_WCID, FrameLen, PID_MGMT, 0 /*QID_MGMT*/, 0, IFS_HTTXOP, &BeaconTransmit); #ifdef SPECIFIC_TX_POWER_SUPPORT #ifdef RTMP_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RTMP)) pAd->BeaconTxWI.TXWI_O.TxPwrAdj = TxPwrAdj; #endif /* RTMP_MAC */ #ifdef RLT_MAC if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RLT)) pAd->BeaconTxWI.TXWI_N.TxPwrAdj = TxPwrAdj; #endif /* RLT_MAC */ #endif /* SPECIFIC_TX_POWER_SUPPORT */ /* step 7. move BEACON TXWI and frame content to on-chip memory */ RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos); #ifdef CUSTOMER_DCC_FEATURE { HTTRANSMIT_SETTING HTSetting; UINT32 Index; MULTISSID_STRUCT *pMbss = NULL; NdisZeroMemory(&HTSetting, sizeof(HTTRANSMIT_SETTING)); HTSetting.field.MODE = BeaconTransmit.field.MODE; HTSetting.field.BW = BeaconTransmit.field.BW; HTSetting.field.ShortGI = BeaconTransmit.field.ShortGI; HTSetting.field.MCS = BeaconTransmit.field.MCS; if ((pAd->ApCfg.MBSSID[apidx].wdev.if_dev != NULL) && (RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].wdev.if_dev))) { pMbss = &pAd->ApCfg.MBSSID[apidx]; GetMultShiftFactorIndex(HTSetting, &Index); RTMPCalculateAPTxRxActivityTime(pAd, Index, FrameLen, pMbss, NULL); } } #endif }
static int scan_active(RTMP_ADAPTER *pAd, UCHAR OpMode, UCHAR ScanType) { UCHAR *frm_buf = NULL; HEADER_802_11 Hdr80211; ULONG FrameLen = 0; UCHAR SsidLen = 0; if (MlmeAllocateMemory(pAd, &frm_buf) != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n")); #ifdef CONFIG_AP_SUPPORT if (OpMode == OPMODE_AP) pAd->Mlme.ApSyncMachine.CurrState = AP_SYNC_IDLE; #endif /* CONFIG_AP_SUPPORT */ return FALSE; } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if (ScanType == SCAN_2040_BSS_COEXIST) { DBGPRINT(RT_DEBUG_INFO, ("SYNC - SCAN_2040_BSS_COEXIST !! Prepare to send Probe Request\n")); } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* There is no need to send broadcast probe request if active scan is in effect.*/ SsidLen = 0; if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ) SsidLen = pAd->MlmeAux.SsidLen; { #ifdef CONFIG_AP_SUPPORT /*IF_DEV_CONFIG_OPMODE_ON_AP(pAd) */ if (OpMode == OPMODE_AP) { MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, pAd->ApCfg.MBSSID[0].Bssid); } #endif /* CONFIG_AP_SUPPORT */ MakeOutgoingFrame(frm_buf, &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(frm_buf + FrameLen, &Tmp, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += Tmp; } } #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { ULONG Tmp; UCHAR HtLen; UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33}; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; #endif if (pAd->bBroadComHT == TRUE) { HtLen = pAd->MlmeAux.HtCapabilityLen + 4; #ifdef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &WpaIe, 1, &HtLen, 4, &BROADCOM[0], pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp, END_OF_ARGS); #else MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &WpaIe, 1, &HtLen, 4, &BROADCOM[0], pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability, END_OF_ARGS); #endif /* RT_BIG_ENDIAN */ } else { HtLen = sizeof(HT_CAPABILITY_IE); #ifdef RT_BIG_ENDIAN NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS); #else MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &HtCapIe, 1, &HtLen, HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #endif /* RT_BIG_ENDIAN */ } FrameLen += Tmp; #ifdef DOT11N_DRAFT3 if ((pAd->MlmeAux.Channel <= 14) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { ULONG Tmp; HtLen = 1; MakeOutgoingFrame(frm_buf + FrameLen, &Tmp, 1, &ExtHtCapIe, 1, &HtLen, 1, &pAd->CommonCfg.BSSCoexist2040.word, END_OF_ARGS); FrameLen += Tmp; } #endif /* DOT11N_DRAFT3 */ } #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (pAd->MlmeAux.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(frm_buf + FrameLen), SUBTYPE_PROBE_REQ); } #endif /* DOT11_VHT_AC */ MiniportMMRequest(pAd, 0, frm_buf, FrameLen); MlmeFreeMemory(pAd, frm_buf); return TRUE; }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PEER_PROBE_REQ_PARAM ProbeReqParam; HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1; UCHAR ErpIeLen = 1; UCHAR apidx = 0, PhyMode, SupRateLen; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2; MULTISSID_STRUCT *mbss; struct wifi_dev *wdev; CHAR rssi = 0, idx = 0; if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, &ProbeReqParam)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { mbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &mbss->wdev; RSNIe = IE_WPA; if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { /* the interface is down, so we can not send probe response */ continue; } PhyMode = wdev->PhyMode; if ( ((((ProbeReqParam.SsidLen == 0) && (!mbss->bHideSsid)) || ((ProbeReqParam.SsidLen == mbss->SsidLen) && NdisEqualMemory(ProbeReqParam.Ssid, mbss->Ssid, (ULONG) ProbeReqParam.SsidLen))) ) ) ; else continue; /* check next BSS */ rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, (CHAR)Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, (CHAR)Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, (CHAR)Elem->Rssi2, RSSI_2)); if ((mbss->ProbeRspRssiThreshold != 0) && (rssi < mbss->ProbeRspRssiThreshold)) { DBGPRINT(RT_DEBUG_INFO, ("%s: PROBE_RSP Threshold = %d , PROBE RSSI = %d\n", wdev->if_dev->name, mbss->ProbeRspRssiThreshold, rssi)); continue; } /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, ProbeReqParam.Addr2, wdev->if_addr, wdev->bssid); if ((wdev->AuthMode == Ndis802_11AuthModeWPA) || (wdev->AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((wdev->AuthMode == Ndis802_11AuthModeWPA2) ||(wdev->AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; { SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == WMODE_B) SupRateLen = 4; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &mbss->CapabilityInfo, 1, &SsidIe, 1, &mbss->SsidLen, mbss->SsidLen, mbss->Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); } if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif /* YF@20120419: Fix IOT Issue with Atheros STA on Windows 7 When IEEE80211H flag turn on. */ HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if (wdev->AuthMode < Ndis802_11AuthModeWPA) ; /* enough information */ else if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &mbss->RSNIE_Len[0], mbss->RSNIE_Len[0], mbss->RSN_IE[0], 1, &RSNIe2, 1, &mbss->RSNIE_Len[1], mbss->RSNIE_Len[1], mbss->RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &mbss->RSNIE_Len[0], mbss->RSNIE_Len[0], mbss->RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D1.10, HT Information Exchange Support */ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].wdev.DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->phy_ctrl.FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ /* add WMM IE here */ if (mbss->wdev.bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &mbss->UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR *TmpFrame = NULL; os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256); if (TmpFrame != NULL) { NdisZeroMemory(TmpFrame, 256); /* prepare channel information */ #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif /* EXT_BUILD_CHANNEL_LIST */ os_free_mem(NULL, TmpFrame); } else DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (wdev->DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); /* P802.11n_D1.10, HT Information Exchange Support */ if (WMODE_CAP_N(PhyMode) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].wdev.DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { /* prepare power constraint IE */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode)) { ULONG TmpLen; UINT8 vht_txpwr_env_ie = IE_VHT_TXPWR_ENV; UINT8 ie_len; VHT_TXPWR_ENV_IE txpwr_env; ie_len = build_vht_txpwr_envelope(pAd, (UCHAR *)&txpwr_env); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &vht_txpwr_env_ie, 1, &ie_len, ie_len, &txpwr_env, END_OF_ARGS); FrameLen += TmpLen; } #endif /* DOT11_VHT_AC */ } #endif /* A_BAND_SUPPORT */ NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); /* prepare channel information */ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }/* Country IE - */ #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); } #endif /* DOT11_N_SUPPORT */ FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if (WMODE_CAP_N(PhyMode) && (wdev->DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;/*, NewExtLen; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(PhyMode) && (pAd->CommonCfg.Channel > 14)) { FrameLen += build_vht_ies(pAd, (UCHAR *)(pOutBuffer+FrameLen), SUBTYPE_PROBE_RSP); } #endif /* DOT11_VHT_AC */ } #endif /* DOT11_N_SUPPORT */ /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef DOT11_VHT_AC if (pAd->CommonCfg.b256QAM_2G && WMODE_2G_ONLY(pAd->CommonCfg.PhyMode)) RalinkSpecificIe[5] |= 0x8; #endif /* DOT11_VHT_AC */ #ifdef RSSI_FEEDBACK if (ProbeReqParam.bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", PRINT_MAC(Addr2))); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif /* RSSI_FEEDBACK */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */ for (idx = 0; idx < mbss->ProbeRspTimes; idx++) MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }