Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/ap/ap_connect.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

1887 lines
59 KiB
C

/****************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
* (c) Copyright 2002, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attemp
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
****************************************************************************
Module Name:
connect.c
Abstract:
Routines to deal Link UP/DOWN and build/update BEACON frame contents
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Chang 08-04-2003 created for 11g soft-AP
*/
#include "rt_config.h"
UCHAR PowerConstraintIE[3] = {IE_POWER_CONSTRAINT, 1, 3};
/*
==========================================================================
Description:
Used to check the necessary to send Beancon.
return value
0: mean no necessary.
0: mean need to send Beacon for the service.
==========================================================================
*/
BOOLEAN BeaconTransmitRequired(RTMP_ADAPTER *pAd, INT apidx, BSS_STRUCT *pMbss)
{
#ifdef WDS_SUPPORT
UCHAR idx;
#endif /* WDS_SUPPORT */
BOOLEAN result = FALSE;
BCN_BUF_STRUC *bcn_info;
do
{
#ifdef WDS_SUPPORT
if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
break;
#endif /* WDS_SUPPORT */
#ifdef CARRIER_DETECTION_SUPPORT
if (isCarrierDetectExist(pAd) == TRUE)
break;
#endif /* CARRIER_DETECTION_SUPPORT */
#ifdef DOT11K_RRM_SUPPORT
#ifdef QUIET_SUPPORT
if ((apidx < pAd->ApCfg.BssidNum) && IS_RRM_QUIET(pAd, apidx))
break;
#endif /* QUIET_SUPPORT */
#endif /* DOT11K_RRM_SUPPORT */
bcn_info = &pMbss->bcn_buf;
if (bcn_info->BcnBufIdx >= HW_BEACON_MAX_NUM)
break;
if (apidx == MAIN_MBSSID)
{
if (bcn_info->bBcnSntReq == TRUE)
{
result = TRUE;
break;
}
#ifdef WDS_SUPPORT
for (idx = 0; idx < MAX_WDS_ENTRY; idx++)
{
if ((pAd->WdsTab.WdsEntry[idx].wdev.if_dev != NULL)
&& (RTMP_OS_NETDEV_STATE_RUNNING(pAd->WdsTab.WdsEntry[idx].wdev.if_dev)))
{
result = TRUE;
break;
}
}
#endif /* WDS_SUPPORT */
}
else
{
if (bcn_info->bBcnSntReq == TRUE)
result = TRUE;
}
}
while (FALSE);
return result;
}
#ifdef MT_MAC
VOID write_tmac_info_beacon(RTMP_ADAPTER *pAd, INT apidx, UCHAR *tmac_buf, HTTRANSMIT_SETTING *BeaconTransmit, ULONG frmLen)
{
MAC_TX_INFO mac_info;
NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info));
mac_info.FRAG = FALSE;
mac_info.CFACK = FALSE;
mac_info.InsTimestamp = TRUE;
mac_info.AMPDU = FALSE;
mac_info.BM = 1;
mac_info.Ack = FALSE;
mac_info.NSeq = TRUE;
mac_info.BASize = 0;
mac_info.WCID = 0;
mac_info.Length = frmLen;
mac_info.TID = 0;
mac_info.TxRate = 0;
mac_info.Txopmode = IFS_HTTXOP;
#ifdef MT_MAC
mac_info.q_idx = Q_IDX_BCN;
mac_info.TxSPriv = apidx;
#endif /* MT_MAC */
mac_info.hdr_len = 24;
mac_info.bss_idx = (UCHAR)apidx;
mac_info.SpeEn = 1;
mac_info.Preamble = LONG_PREAMBLE;
NdisZeroMemory(tmac_buf, sizeof(TMAC_TXD_L));
write_tmac_info(pAd, tmac_buf, &mac_info, BeaconTransmit);
}
VOID asic_write_bcn_buf(RTMP_ADAPTER *pAd, UCHAR *tmac_info, INT info_len, UCHAR *bcn_buf, INT buf_len, UINT32 hw_addr)
{
#ifdef RT_BIG_ENDIAN
UCHAR *ptr;
#if 0//def MT_MAC
if (pAd->chipCap.hif_type == HIF_MT)
{
MTMacInfoEndianChange(pAd, tmac_info, TYPE_TXWI, sizeof(TMAC_TXD_L));
}
#endif
#if defined(RTMP_MAC) || defined(RLT_MAC)
if (pAd->chipCap.hif_type == HIF_RTMP || pAd->chipCap.hif_type == HIF_RLT)
{
RTMPWIEndianChange(pAd, tmac_info, TYPE_TXWI);
}
#endif
#endif
/* update BEACON frame content. start right after the TXWI field. */
#ifdef RT_BIG_ENDIAN
ptr = bcn_buf;
RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif
// TODO: shiang-MT7603, Send to ASIC!
}
#endif /* MT_MAC */
#if defined(RTMP_MAC) || defined(RLT_MAC)
VOID write_tmac_info_beacon(RTMP_ADAPTER *pAd, INT apidx, UCHAR *tmac_buf, HTTRANSMIT_SETTING *BeaconTransmit, ULONG frmLen)
{
MAC_TX_INFO mac_info;
NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info));
mac_info.FRAG = FALSE;
mac_info.CFACK = FALSE;
mac_info.InsTimestamp = TRUE;
mac_info.AMPDU = FALSE;
mac_info.BM = 1;
mac_info.Ack = FALSE;
mac_info.NSeq = TRUE;
mac_info.BASize = 0;
mac_info.WCID = RESERVED_WCID;
mac_info.Length = frmLen;
mac_info.PID = PID_MGMT;
mac_info.TID = 0;
mac_info.TxRate = 0;
mac_info.Txopmode = IFS_HTTXOP;
mac_info.Preamble = LONG_PREAMBLE;
write_tmac_info(pAd, tmac_buf, &mac_info, BeaconTransmit);
#ifdef SPECIFIC_TX_POWER_SUPPORT
/* Specific Power for Long-Range Beacon */
if ((pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) &&
(BeaconTransmit->field.MODE == MODE_CCK))
{
UCHAR TxPwrAdj = 0;
TXWI_STRUC *pTxWI = (TXWI_STRUC *)tmac_buf;
TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj;
#ifdef RTMP_MAC
if (pAd->chipCap.hif_type == HIF_RTMP)
pTxWI->TXWI_O.TxPwrAdj = TxPwrAdj;
#endif /* RTMP_MAC */
#ifdef RLT_MAC
if (pAd->chipCap.hif_type == HIF_RLT)
pTxWI->TXWI_N.TxPwrAdj = TxPwrAdj;
#endif /* RLT_MAC */
}
#endif /* SPECIFIC_TX_POWER_SUPPORT */
}
VOID asic_write_bcn_buf(RTMP_ADAPTER *pAd, UCHAR *tmac_info, INT info_len, UCHAR *bcn_buf, INT buf_len, UINT32 hw_addr)
{
INT i;
UCHAR *ptr = tmac_info;
UINT32 longValue, reg_base = hw_addr;
#ifdef RT_BIG_ENDIAN
RTMPWIEndianChange(pAd, tmac_info, TYPE_TXWI);
#endif
for (i = 0; i < info_len; 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 = bcn_buf;
#ifdef RT_BIG_ENDIAN
RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif
reg_base = hw_addr + info_len;
for (i= 0; i< buf_len; 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;
}
}
#endif /* defined(RTMP_MAC) || defined(RLT_MAC) */
/*
==========================================================================
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 /* defined(DOT11_N_SUPPORT) && defined(DOT11K_RRM_SUPPORT) */
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
#if 0
if (pMbss->bcn_buf.bcn_state != BCN_TX_UNINIT) {
DBGPRINT(RT_DEBUG_TRACE, ("%s()=>BSS%d:BcnPkt not init(%d)!\n",
__FUNCTION__, apidx, pMbss->bcn_buf.bcn_state));
//APCleanBcnQ(pAd, apidx);
return;
}
#endif
}
#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;
#ifdef P2P_SUPPORT
if (P2P_GO_ON(pAd))
{
UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
UCHAR SupRateIe = IE_SUPP_RATES;
UCHAR SupRateLen = 0;
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;
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, &SupRate,
1, &DsIe,
1, &DsLen,
1, &pAd->CommonCfg.Channel,
END_OF_ARGS);
}
else
#endif /* P2P_SUPPORT */
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 */
#ifdef DOT11K_RRM_SUPPORT
if (IS_RRM_ENABLE(pAd, apidx)
&& (pAd->CommonCfg.RegulatoryClass[0] != 0))
{
TmpLen2 = 0;
NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2);
}
#endif /* DOT11K_RRM_SUPPORT */
/* 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 DOT11K_RRM_SUPPORT
if (IS_RRM_ENABLE(pAd, apidx))
{
InsertTpcReportIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0);
RRM_InsertRRMEnCapIE(pAd, pBeaconFrame+FrameLen, &FrameLen, apidx);
}
#endif /* DOT11K_RRM_SUPPORT */
#ifdef DOT11_N_SUPPORT
/* AP Channel Report */
#ifdef DOT11K_RRM_SUPPORT
for (i=0; i<MAX_NUM_OF_REGULATORY_CLASS; i++)
{
if (pAd->CommonCfg.RegulatoryClass[i] == 0)
break;
InsertChannelRepIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
(RTMP_STRING *)pAd->CommonCfg.CountryCode,
pAd->CommonCfg.RegulatoryClass[i]);
}
#else
{
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
#endif /* DOT11_N_SUPPORT */
#ifdef DOT11R_FT_SUPPORT
/*
The Mobility Domain information element (MDIE) is present in Beacon
frame when dot11FastBssTransitionEnable is set to true.
*/
if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable)
{
PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg;
FT_CAP_AND_POLICY FtCap;
NdisZeroMemory(&FtCap, sizeof(FT_CAP_AND_POLICY));
FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs;
FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap;
FT_InsertMdIE(pAd, pBeaconFrame + FrameLen, &FrameLen,
pFtCfg->FtMdId, FtCap);
}
#endif /* DOT11R_FT_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
#if 0
DBGPRINT(RT_DEBUG_OFF, ("%s(): Dump the Beacon Packet of BSS%d!\n", __FUNCTION__, apidx));
hex_dump("Initial BeaconBuf", tmac_info, FrameLen + tx_hw_hdr_len);
#endif
//---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 = 0;
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;
UINT32 mac_val = 0, bmc_cnt = 0;
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)) {
#ifdef BCN_OFFLOAD_SUPPORT
RT28xx_UpdateBeaconToMcu(pAd, apidx, FALSE, 0, 0, 0);
pMbss->updateEventIsTriggered = FALSE;
#endif /* BCN_OFFLOAD_SUPPORT */
return;
}
#if 0
if (RTMP_TEST_FLAG(pAd, TX_FLAG_STOP_DEQUEUE))
return;
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DISABLE_DEQUEUEPACKET))
return;
if (pMbss->TimIELocationInBeacon == 0)
{
return;
}
#endif
#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) {
#ifdef RTMP_PCI_SUPPORT
BOOLEAN is_pretbtt_int = FALSE;
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) {
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) {
DBGPRINT(RT_DEBUG_WARN, ("%s()=>BSS%d:BcnPkt not idle(%d)!\n",
__FUNCTION__, apidx, pMbss->bcn_buf.bcn_state));
}
#ifdef RTMP_PCI_SUPPORT
APCheckBcnQHandler(pAd, apidx, &is_pretbtt_int);
if (is_pretbtt_int == FALSE)
#endif /* RTMP_PCI_SUPPORT */
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;
#ifdef P2P_SUPPORT
if (P2P_GO_ON(pAd))
{
UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
UCHAR SupRateIe = IE_SUPP_RATES;
UCHAR SupRateLen = 0;
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;
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, &SupRate,
1, &DsIe,
1, &DsLen,
1, &pAd->CommonCfg.Channel,
END_OF_ARGS);
}
else
#endif /* P2P_SUPPORT */
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 */
#ifdef DOT11K_RRM_SUPPORT
if (IS_RRM_ENABLE(pAd, apidx)
&& (pAd->CommonCfg.RegulatoryClass[0] != 0))
{
TmpLen2 = 0;
NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2);
}
#endif /* DOT11K_RRM_SUPPORT */
/* 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 DOT11K_RRM_SUPPORT
if (IS_RRM_ENABLE(pAd, apidx))
{
InsertTpcReportIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0);
RRM_InsertRRMEnCapIE(pAd, pBeaconFrame+FrameLen, &FrameLen, apidx);
}
#endif /* DOT11K_RRM_SUPPORT */
#ifdef DOT11_N_SUPPORT
/* AP Channel Report */
#ifdef DOT11K_RRM_SUPPORT
for (i=0; i<MAX_NUM_OF_REGULATORY_CLASS; i++)
{
if (pAd->CommonCfg.RegulatoryClass[i] == 0)
break;
InsertChannelRepIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
(RTMP_STRING *)pAd->CommonCfg.CountryCode,
pAd->CommonCfg.RegulatoryClass[i]);
}
#else
{
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
#endif /* DOT11_N_SUPPORT */
#ifdef DOT11R_FT_SUPPORT
/*
The Mobility Domain information element (MDIE) is present in Beacon
frame when dot11FastBssTransitionEnable is set to true.
*/
if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable)
{
PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg;
FT_CAP_AND_POLICY FtCap;
NdisZeroMemory(&FtCap, sizeof(FT_CAP_AND_POLICY));
FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs;
FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap;
FT_InsertMdIE(pAd, pBeaconFrame + FrameLen, &FrameLen,
pFtCfg->FtMdId, FtCap);
}
#endif /* DOT11R_FT_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;
*ptr = (UCHAR)(pMbss->CapabilityInfo & 0x00ff);
*(ptr+1) = (UCHAR)((pMbss->CapabilityInfo & 0xff00) >> 8);
AsicSetBmcQCR(pAd, BMC_CNT_UPDATE, CR_READ, apidx, &mac_val);
if ((apidx >= 0) && (apidx <= 4))
{
if (apidx == 0)
bmc_cnt = mac_val & 0xf;
else
bmc_cnt = (mac_val >> (12+ (4*apidx))) & 0xf;
}
else if ((apidx >= 5) && (apidx <= 12))
{
bmc_cnt = (mac_val >> (4*(apidx-5))) & 0xf;
}
else if ((apidx >=13) && (apidx <= 15))
{
bmc_cnt = (mac_val >> (4*(apidx-13))) & 0xf;
}
if (bmc_cnt > 0)
{
WLAN_MR_TIM_BCMC_SET(apidx);
}
//else
//{
//WLAN_MR_TIM_BCMC_CLEAR(apidx);
//}
/*
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)
#ifdef WPA3_SUPPORT
|| (wdev->AuthMode == Ndis802_11AuthModeWPA3SAE)
#endif
)
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);
}
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 */
#ifdef WAC_SUPPORT
WAC_AddDevAdvAttrIE(pAd, apidx, pBeaconFrame, &FrameLen);
if (pMbss->EasyConfigInfo.pVendorInfoForBeacon)
{
ULONG tmpWACLen = 0;
MakeOutgoingFrame(pBeaconFrame+FrameLen,
&tmpWACLen,
pMbss->EasyConfigInfo.VendorInfoForBeaconLen,
pMbss->EasyConfigInfo.pVendorInfoForBeacon,
END_OF_ARGS);
FrameLen += tmpWACLen;
}
#endif /* WAC_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;
#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->wdev.UapsdInfo);
#endif /* UAPSD_SUPPORT */
NdisMoveMemory(AIFSN, pAd->ApCfg.BssEdcaParm.Aifsn, sizeof(AIFSN));
#ifdef WMM_ACM_SUPPORT
ACM_TG_CMT_WMMAC_SUPPORT_SIGNALLING;
ACMP_NullTspecSupportSignal(pAd, WmeParmIe);
ACMP_NonAcmAdjustParamUpdate(pAd, AIFSN);
#endif /* WMM_ACM_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 */
(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);
/* 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 /* 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 */
MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
9, RalinkSpecificIe,
END_OF_ARGS);
FrameLen += TmpLen;
#ifdef RT3883
if (IS_RT3883(pAd))
FrameLen += RT3883_ext_pkt_len(pBeaconFrame, FrameLen, RalinkSpecificIe, 9);
#endif /* RT3883 */
}
#ifdef P2P_SUPPORT
if (P2P_GO_ON(pAd))
{
PUCHAR pP2pNoAIE = NULL;
ULONG P2pTmpLen;
UCHAR P2pCapId = SUBID_P2P_CAP, P2pDevId = SUBID_P2P_DEVICE_ID;
USHORT P2pCapIdLen = 2, P2pDevIdLen = 6;
UCHAR P2pIEFixed[6] = {0xdd, 0x12, 0x50, 0x6f, 0x9a, 0x9};
MakeOutgoingFrame(pBeaconFrame+FrameLen, &P2pTmpLen,
6, &P2pIEFixed[0],
1, &P2pCapId,
2, &P2pCapIdLen,
2, &pAd->P2pCfg.P2pCapability,
END_OF_ARGS);
FrameLen += P2pTmpLen;
MakeOutgoingFrame(pBeaconFrame+FrameLen, &P2pTmpLen,
1, &P2pDevId,
2, &P2pDevIdLen,
6, &pAd->P2pCfg.CurrentAddress,
END_OF_ARGS);
FrameLen += P2pTmpLen;
/* NoA */
pP2pNoAIE = pBeaconFrame + FrameLen;
P2pTmpLen = P2pUpdateNoABeacon(pAd, apidx, pP2pNoAIE);
FrameLen += P2pTmpLen;
BeaconTransmit.field.MODE = MODE_OFDM;
BeaconTransmit.field.MCS = MCS_RATE_6;
}
#ifdef WFD_SUPPORT
{
ULONG TmpLen;
ptr = pBeaconFrame + FrameLen;
WfdMakeWfdIE(pAd, SUBTYPE_BEACON, ptr, &TmpLen);
FrameLen += TmpLen;
}
#endif /* WFD_SUPPORT */
#ifdef WFA_WFD_SUPPORT
if (pAd->P2pCfg.bWIDI)
{
if (pAd->pWfdIeInBeacon && (pAd->WfdIeInBeaconLen != 0))
{
ULONG WfdIeTmpLen = 0;
MakeOutgoingFrame(pBeaconFrame+FrameLen, &WfdIeTmpLen,
pAd->WfdIeInBeaconLen, pAd->pWfdIeInBeacon,
END_OF_ARGS);
FrameLen += WfdIeTmpLen;
}
}
#endif /* WFA_WFD_SUPPORT */
#endif /* P2P_SUPPORT */
/* 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 */
#ifdef BCN_OFFLOAD_SUPPORT
if (pMbss->updateEventIsTriggered == FALSE) {
RT28xx_UpdateBeaconToMcu(pAd, apidx, 0, TRUE, FrameLen, UpdatePos);
pMbss->updateEventIsTriggered = TRUE;
}
#endif
RT28xx_UpdateBeaconToAsic(pAd, apidx, FrameLen, UpdatePos);
#ifdef DBG
{
UINT32 Lowpart, Highpart;
AsicGetTsfTime(pAd, &Highpart, &Lowpart);
pMbss->WriteBcnDoneTime[pMbss->timer_loop] = Lowpart;
}
#endif /* DBG */
}
/*
==========================================================================
Description:
Pre-build All BEACON frame in the shared memory
==========================================================================
*/
static UCHAR GetBcnNum(RTMP_ADAPTER *pAd)
{
int i;
UCHAR NumBcn;
BCN_BUF_STRUC *bcn_info;
NumBcn = 0;
for (i=0; i<pAd->ApCfg.BssidNum; i++)
{
bcn_info = &pAd->ApCfg.MBSSID[i].bcn_buf;
if (bcn_info->bBcnSntReq)
{
bcn_info->BcnBufIdx = NumBcn;
NumBcn ++;
}
}
#ifdef MESH_SUPPORT
bcn_info = &pAd->MeshTab.bcn_buf;
if (bcn_info->bBcnSntReq)
{
bcn_info->BcnBufIdx = NumBcn;
NumBcn++;
}
#endif /* MESH_SUPPORT */
return NumBcn;
}
VOID APMakeAllBssBeacon(RTMP_ADAPTER *pAd)
{
INT i;
UCHAR NumOfBcns;
/* choose the Beacon number */
NumOfBcns = GetBcnNum(pAd);
#if defined(RTMP_MAC) || defined(RLT_MAC)
if ((pAd->chipCap.hif_type == HIF_RTMP) || (pAd->chipCap.hif_type == HIF_RLT)) {
INT j;
/*
before MakeBssBeacon, clear all beacon TxD's valid bit
Note: can not use MAX_MBSSID_NUM here, or
1. when MBSS_SUPPORT is enabled;
2. MAX_MBSSID_NUM will be 8;
3. if HW_BEACON_OFFSET is 0x0200,
we will overwrite other shared memory of chip.
use pAd->ApCfg.BssidNum to avoid the case is best
*/
UINT8 TXWISize = pAd->chipCap.TXWISize;
for (i=0; i<HW_BEACON_MAX_COUNT(pAd); i++)
{
for (j=0; j < TXWISize; j+=4)
{
RTMP_CHIP_UPDATE_BEACON(pAd, pAd->BeaconOffset[i] + j, 0, 4);
}
}
}
#endif /* defined(RTMP_MAC) || defined(RLT_MAC) */
#ifdef RTMP_MAC_USB
RTUSBBssBeaconStop(pAd);
#endif /* RTMP_MAC_USB */
for(i=0; i<pAd->ApCfg.BssidNum; i++)
APMakeBssBeacon(pAd, i);
AsicSetMbssMode(pAd, NumOfBcns);
#ifdef RTMP_MAC_USB
#ifndef RT_CFG80211_SUPPORT
RTUSBBssBeaconStart(pAd);
#endif
#endif /* RTMP_MAC_USB */
}
/*
==========================================================================
Description:
Pre-build All BEACON frame in the shared memory
==========================================================================
*/
VOID APUpdateAllBeaconFrame(RTMP_ADAPTER *pAd)
{
INT i;
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
BOOLEAN FlgQloadIsAlarmIssued = FALSE;
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
if (pAd->ApCfg.DtimCount == 0)
pAd->ApCfg.DtimCount = pAd->ApCfg.DtimPeriod - 1;
else
pAd->ApCfg.DtimCount -= 1;
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
/* QLOAD ALARM */
#ifdef AP_QLOAD_SUPPORT
FlgQloadIsAlarmIssued = QBSS_LoadIsAlarmIssued(pAd);
#endif /* AP_QLOAD_SUPPORT */
if ((pAd->ApCfg.DtimCount == 0) &&
(((pAd->CommonCfg.Bss2040CoexistFlag & BSS_2040_COEXIST_INFO_SYNC) &&
(pAd->CommonCfg.bForty_Mhz_Intolerant == FALSE)) ||
(FlgQloadIsAlarmIssued == TRUE)))
{
UCHAR prevBW, prevExtChOffset;
DBGPRINT(RT_DEBUG_TRACE, ("DTIM Period reached, BSS20WidthReq=%d, Intolerant40=%d!\n",
pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq, pAd->CommonCfg.LastBSSCoexist2040.field.Intolerant40));
pAd->CommonCfg.Bss2040CoexistFlag &= (~BSS_2040_COEXIST_INFO_SYNC);
prevBW = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
prevExtChOffset = pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset;
if (pAd->CommonCfg.LastBSSCoexist2040.field.BSS20WidthReq ||
pAd->CommonCfg.LastBSSCoexist2040.field.Intolerant40 ||
(pAd->MacTab.fAnyStaFortyIntolerant == TRUE) ||
(FlgQloadIsAlarmIssued == TRUE))
{
pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = 0;
}
else
{
pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = pAd->CommonCfg.RegTransmitSetting.field.BW;
pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
}
DBGPRINT(RT_DEBUG_TRACE,("\tNow RecomWidth=%d, ExtChanOffset=%d, prevBW=%d, prevExtOffset=%d\n",
pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth,
pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset,
prevBW, prevExtChOffset));
pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_INFO_NOTIFY;
pAd->CommonCfg.Bss2040CoexistFlag |= BSS_2040_COEXIST_BW_SYNC;
}
#endif /* DOT11N_DRAFT3 */
#endif /* DOT11_N_SUPPORT */
for(i=0; i<pAd->ApCfg.BssidNum; i++)
{
APUpdateBeaconFrame(pAd, i);
}
}