mirror of
https://github.com/YikeStone/MT7601u.git
synced 2025-08-03 03:14:08 +05:30
1146 lines
36 KiB
C
1146 lines
36 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(
|
|
IN RTMP_ADAPTER *pAd,
|
|
IN INT apidx,
|
|
IN MULTISSID_STRUCT *pMbss)
|
|
{
|
|
BOOLEAN result = FALSE;
|
|
|
|
do
|
|
{
|
|
|
|
#ifdef CARRIER_DETECTION_SUPPORT
|
|
if (isCarrierDetectExist(pAd) == TRUE)
|
|
break;
|
|
#endif /* CARRIER_DETECTION_SUPPORT */
|
|
|
|
|
|
if (apidx == MAIN_MBSSID)
|
|
{
|
|
if (pMbss->bBcnSntReq == TRUE)
|
|
{
|
|
result = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pMbss->bBcnSntReq == TRUE)
|
|
result = TRUE;
|
|
}
|
|
}
|
|
while (FALSE);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
==========================================================================
|
|
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,
|
|
#ifdef P2P_SUPPORT
|
|
pAd->ApCfg.MBSSID[apidx].Bssid,
|
|
#endif /* P2P_SUPPORT */
|
|
pAd->ApCfg.MBSSID[apidx].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, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo,
|
|
1, &SsidIe,
|
|
1, &SsidLen,
|
|
SsidLen, pAd->ApCfg.MBSSID[apidx].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, &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;
|
|
|
|
}
|
|
|
|
#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
|
|
/* Call InsertWfdSubelmtTlv directly for beacon update (timing issue) */
|
|
if (pAd->StaCfg.WfdCfg.bWfdEnable)
|
|
{
|
|
PUCHAR pData;
|
|
ULONG TmpLen = 0, Len = 0;
|
|
UCHAR WfdIEFixed[6] = {0xdd, 0x0c, 0x50, 0x6f, 0x9a, 0x0a}; /* Length will be modified later */
|
|
|
|
pData = pBeaconFrame + FrameLen;
|
|
RTMPMoveMemory(pData, &WfdIEFixed[0], 6);
|
|
Len += 6;
|
|
pData += 6;
|
|
|
|
TmpLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_DEVICE_INFO, NULL, pData, ACTION_WIFI_DIRECT);
|
|
Len += TmpLen;
|
|
pData += TmpLen;
|
|
|
|
TmpLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_ASSOCIATED_BSSID, NULL, pData, ACTION_WIFI_DIRECT);
|
|
Len += TmpLen;
|
|
pData += TmpLen;
|
|
|
|
TmpLen = InsertWfdSubelmtTlv(pAd, SUBID_WFD_COUPLED_SINK_INFO, NULL, pData, ACTION_WIFI_DIRECT);
|
|
Len += TmpLen;
|
|
pData += TmpLen;
|
|
|
|
*(pBeaconFrame + FrameLen + 1) = (Len-2);
|
|
FrameLen += Len;
|
|
}
|
|
#endif /* 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 */
|
|
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:
|
|
Pre-build All BEACON frame in the shared memory
|
|
==========================================================================
|
|
*/
|
|
static UCHAR GetBcnNum(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
int i;
|
|
int NumBcn;
|
|
|
|
NumBcn = 0;
|
|
for (i=0; i<pAd->ApCfg.BssidNum; i++)
|
|
{
|
|
if (pAd->ApCfg.MBSSID[i].bBcnSntReq)
|
|
{
|
|
pAd->ApCfg.MBSSID[i].BcnBufIdx = NumBcn;
|
|
NumBcn ++;
|
|
}
|
|
}
|
|
|
|
|
|
return NumBcn;
|
|
}
|
|
|
|
VOID APMakeAllBssBeacon(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
INT i, j;
|
|
UINT32 regValue;
|
|
UCHAR NumOfMacs;
|
|
UCHAR NumOfBcns;
|
|
UINT8 TXWISize = pAd->chipCap.TXWISize;
|
|
|
|
/* 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 SRAM of chip */
|
|
/* use pAd->ApCfg.BssidNum to avoid the case is best */
|
|
|
|
/* choose the Beacon number */
|
|
NumOfBcns = GetBcnNum(pAd);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
#ifdef RTMP_MAC_USB
|
|
RTUSBBssBeaconStop(pAd);
|
|
#endif /* RTMP_MAC_USB */
|
|
|
|
for(i=0; i<pAd->ApCfg.BssidNum; i++)
|
|
{
|
|
APMakeBssBeacon(pAd, i);
|
|
}
|
|
|
|
RTMP_IO_READ32(pAd, MAC_BSSID_DW1, ®Value);
|
|
regValue &= 0x0000FFFF;
|
|
|
|
|
|
/*
|
|
Note:
|
|
1.The MAC address of Mesh and AP-Client link are different from Main BSSID.
|
|
2.If the Mesh link is included, its MAC address shall follow the last MBSSID's MAC by increasing 1.
|
|
3.If the AP-Client link is included, its MAC address shall follow the Mesh interface MAC by increasing 1.
|
|
*/
|
|
NumOfMacs = pAd->ApCfg.BssidNum + MAX_MESH_NUM + MAX_APCLI_NUM;
|
|
|
|
#ifdef P2P_SUPPORT
|
|
#ifdef P2P_ODD_MAC_ADJUST
|
|
if (NumOfMacs != 2)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR,
|
|
("The P2P mode is enabled, the NumOfMacs MUST be 2, NumOfMacs=%d\n",
|
|
NumOfMacs));
|
|
}
|
|
#endif /* P2P_ODD_MAC_ADJUST */
|
|
#endif /* P2P_SUPPORT */
|
|
|
|
/* set Multiple BSSID mode */
|
|
if (NumOfMacs <= 1)
|
|
{
|
|
pAd->ApCfg.MacMask = ~(1-1);
|
|
/*regValue |= 0x0; */
|
|
}
|
|
else if (NumOfMacs <= 2)
|
|
{
|
|
if ((pAd->CurrentAddress[5] % 2 != 0)
|
|
#ifdef P2P_SUPPORT
|
|
#ifdef P2P_ODD_MAC_ADJUST
|
|
&& FALSE
|
|
#endif /* P2P_ODD_MAC_ADJUST */
|
|
#endif /* P2P_SUPPORT */
|
|
)
|
|
DBGPRINT(RT_DEBUG_ERROR, ("The 2-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 2\n"));
|
|
|
|
regValue |= (1<<16);
|
|
pAd->ApCfg.MacMask = ~(2-1);
|
|
}
|
|
else if (NumOfMacs <= 4)
|
|
{
|
|
if (pAd->CurrentAddress[5] % 4 != 0)
|
|
DBGPRINT(RT_DEBUG_ERROR, ("The 4-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 4\n"));
|
|
|
|
regValue |= (2<<16);
|
|
pAd->ApCfg.MacMask = ~(4-1);
|
|
}
|
|
else if (NumOfMacs <= 8)
|
|
{
|
|
if (pAd->CurrentAddress[5] % 8 != 0)
|
|
DBGPRINT(RT_DEBUG_ERROR, ("The 8-BSSID mode is enabled, the BSSID byte5 MUST be the multiple of 8\n"));
|
|
|
|
regValue |= (3<<16);
|
|
pAd->ApCfg.MacMask = ~(8-1);
|
|
}
|
|
|
|
/* set Multiple BSSID Beacon number */
|
|
if (NumOfBcns > 1)
|
|
{
|
|
regValue |= (((NumOfBcns - 1) & 0x7) << 18);
|
|
}
|
|
|
|
/* set as 0/1 bit-21 of MAC_BSSID_DW1(offset: 0x1014)
|
|
to disable/enable the new MAC address assignment. */
|
|
if (pAd->chipCap.MBSSIDMode == MBSSID_MODE1)
|
|
regValue |= (1 << 21);
|
|
|
|
RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, regValue);
|
|
|
|
#ifdef HDR_TRANS_SUPPORT
|
|
/*
|
|
point WCID MAC table to 0x1800
|
|
This is for debug.
|
|
But HDR_TRANS doesn't work if you remove it.
|
|
Check after IC formal release.
|
|
*/
|
|
regValue |= 0x18000000;
|
|
RTMP_IO_WRITE32(pAd, HT_MAC_BSSID_DW1, regValue);
|
|
#endif /* HDR_TRANS_SUPPORT */
|
|
|
|
#ifdef RTMP_MAC_USB
|
|
RTUSBBssBeaconStart(pAd);
|
|
#endif /* RTMP_MAC_USB */
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
==========================================================================
|
|
Description:
|
|
Pre-build All BEACON frame in the shared memory
|
|
==========================================================================
|
|
*/
|
|
VOID APUpdateAllBeaconFrame(
|
|
IN PRTMP_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;
|
|
}
|
|
#endif /* DOT11N_DRAFT3 */
|
|
#endif /* DOT11_N_SUPPORT */
|
|
|
|
for(i=0; i<pAd->ApCfg.BssidNum; i++)
|
|
{
|
|
APUpdateBeaconFrame(pAd, i);
|
|
}
|
|
}
|
|
|
|
|