diff options
Diffstat (limited to 'network/wlan/WDI/COMMON/HTGen.c')
| -rw-r--r-- | network/wlan/WDI/COMMON/HTGen.c | 1730 |
1 files changed, 1730 insertions, 0 deletions
diff --git a/network/wlan/WDI/COMMON/HTGen.c b/network/wlan/WDI/COMMON/HTGen.c new file mode 100644 index 00000000..84af5275 --- /dev/null +++ b/network/wlan/WDI/COMMON/HTGen.c @@ -0,0 +1,1730 @@ + +#include "Mp_Precomp.h" + +#if WPP_SOFTWARE_TRACE +#include "HTGen.tmh" +#endif + +u1Byte MCS_FILTER_ALL[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +u1Byte MCS_FILTER_1SS[16] = { 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +const u2Byte MCS_DATA_RATE[2][2][33] = + { { { 13, 26, 39, 52, 78, 104, 117, 130, + 26, 52, 78 ,104, 156, 208, 234, 260, + 39, 78, 117, 156, 234, 312, 351, 390, + 52, 104, 156, 208, 312, 416, 468, 520, 0}, // Long GI, 20MHz + { 14, 29, 43, 58, 87, 116, 130, 144, + 29, 58, 87, 116, 173, 231, 260, 289, + 43, 87, 130, 173, 260, 347, 390, 433, + 58, 116, 173, 231, 347, 462, 520, 578, 0} }, // Short GI, 20MHz + { { 27, 54, 81, 108, 162, 216, 243, 270, + 54, 108, 162, 216, 324, 432, 486, 540, + 81, 162, 243, 324, 486, 648, 729, 810, + 108, 216, 324, 432, 648, 864, 972, 1080, 12}, // Long GI, 40MHz + { 30, 60, 90, 120, 180, 240, 270, 300, + 60, 120, 180, 240, 360, 480, 540, 600, + 90, 180, 270, 360, 540, 720, 810, 900, + 120, 240, 360, 480, 720, 960, 1080, 1200, 13} } // Short GI, 40MHz + }; + + + +//static u1Byte UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; +//static u1Byte LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; +//static u1Byte LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; +//static u1Byte NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; +//static u1Byte BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; //cosa 03202008 +//static u1Byte BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; +//static u1Byte PCI_RALINK[3] = {0x00, 0x90, 0xcc}; +//static u1Byte EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; +//static u1Byte AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; +//static u1Byte DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; +//static u1Byte DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; +//static u1Byte CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; +static u1Byte NETGEAR_BROADCOM[3] = {0x00, 0x1f, 0x33}; +//static u1Byte NETGEAR_CONEXANT[3] = {0x00, 0x1f, 0x33}; + +// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the +// code in other place?? +//static u1Byte WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; + +/** +* Function: HTDebugHTCapability +* +* Overview: Print out each field on HT capability IE in(Beacon/ProbeRsp/AssocReq/ +* AssocRsp) +* +* Input: +* u4Byte DebugLevel +* PADAPTER Adapter, +* POCTET_STRING pocCap, +* pu1Byte titleString +* +* Output: None +* Return: None +* Note: Driver should not print out this message by default +*/ +VOID +HTDebugHTCapability( + u4Byte DebugLevel, + PADAPTER Adapter, + POCTET_STRING pocCap, + pu1Byte TitleString + +) +{ + + static u1Byte EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + pu1Byte pCapELE; + pu1Byte pMCS; + + if(!PlatformCompareMemory(pocCap->Octet, EWC11NHTCap, sizeof(EWC11NHTCap))) + { + // Not EWC IE + pCapELE = (pu1Byte)&pocCap->Octet[4]; + }else + pCapELE = (pu1Byte)&pocCap->Octet[0]; + + pMCS= GET_HT_CAPABILITY_ELE_MCS(pCapELE); + + RT_TRACE(COMP_HT, DebugLevel, ("<Log HT Capability>. Called by %s\n", TitleString )); + + RT_TRACE(COMP_HT, DebugLevel, ("\tSupported Channel Width = %s\n", (GET_HT_CAPABILITY_ELE_CHL_WIDTH(pCapELE) )?"20MHz": "20/40MHz")); + RT_TRACE(COMP_HT, DebugLevel, ("\tSupport Short GI for 20M = %s\n", (GET_HT_CAPABILITY_ELE_SHORT_GI20M(pCapELE))?"YES": "NO")); + RT_TRACE(COMP_HT, DebugLevel, ("\tSupport Short GI for 40M = %s\n", (GET_HT_CAPABILITY_ELE_SHORT_GI40M(pCapELE))?"YES": "NO")); + RT_TRACE(COMP_HT, DebugLevel, ("\tSupport TX STBC = %s\n", (GET_HT_CAPABILITY_ELE_TX_STBC(pCapELE))?"YES": "NO")); + RT_TRACE(COMP_HT, DebugLevel, ("\tMax AMSDU Size = %s\n", (GET_HT_CAPABILITY_ELE_MAX_AMSDU_SIZE(pCapELE))?"3839": "7935")); + RT_TRACE(COMP_HT, DebugLevel, ("\tSupport CCK in 20/40 mode = %s\n", (GET_HT_CAPABILITY_ELE_DSS_CCK(pCapELE))?"YES": "NO")); + RT_TRACE(COMP_HT, DebugLevel, ("\tMax AMPDU Factor = %d\n", GET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pCapELE))); + RT_TRACE(COMP_HT, DebugLevel, ("\tMPDU Density = %d\n", GET_HT_CAPABILITY_ELE_MPDU_DENSITY(pCapELE))); + //RT_TRACE(COMP_HT, DebugLevel, ("\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pMCS[0],\ + // pMCS[1], pMCS[2], pMCS[3], pMCS[4])); + RT_TRACE(COMP_HT, DebugLevel, ("\n")); + +} + +/** +* Function: HTDebugHTInfo +* +* Overview: Print out each field on HT Information IE in(Beacon/PorbeRsp) +* +* Input: +* u4Byte DebugLevel, +* PADAPTER Adapter, +* POCTET_STRING pocCap, +* pu1Byte TitleString +* +* Output: None +* Return: None +* Note: Driver should not print out this message by default +*/ +VOID +HTDebugHTInfo( + u4Byte DebugLevel, + PADAPTER Adapter, + POCTET_STRING pocInfo, + pu1Byte TitleString +) +{ + + static u1Byte EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily + pu1Byte pHTInfoEle, pBasicMCS; + + if(!PlatformCompareMemory(pocInfo->Octet, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + pHTInfoEle = (pu1Byte)(&pocInfo->Octet[4]); // Not EWC IE + else + pHTInfoEle = (pu1Byte)(&pocInfo->Octet[0]); + + + pBasicMCS= GET_HT_INFO_ELE_BASIC_MCS(pHTInfoEle); + + RT_TRACE(COMP_HT, DebugLevel, ("<Log HT Information Element>. Called by %s\n", TitleString )); + + RT_TRACE(COMP_HT, DebugLevel, ("\tPrimary channel = %d\n", GET_HT_INFO_ELE_CONTROL_CHL(pHTInfoEle))); + RT_TRACE(COMP_HT, DebugLevel, ("\tSenondary channel =")); + switch(GET_HT_INFO_ELE_EXT_CHL_OFFSET(pHTInfoEle)) + { + case 0: + RT_TRACE(COMP_HT, DebugLevel, ("Not Present\n")); + break; + case 1: + RT_TRACE(COMP_HT, DebugLevel, ("Upper channel\n")); + break; + case 2: + RT_TRACE(COMP_HT, DebugLevel, ("Reserved. Eooro!!!\n")); + break; + case 3: + RT_TRACE(COMP_HT, DebugLevel, ("Lower Channel\n")); + break; + } + RT_TRACE(COMP_HT, DebugLevel, ("\tRecommended channel width = %s\n", (GET_HT_INFO_ELE_STA_CHL_WIDTH(pHTInfoEle))?"20Mhz": "40Mhz")); + + RT_TRACE(COMP_HT, DebugLevel, ("\tOperation mode for protection = ")); + switch(GET_HT_INFO_ELE_OPT_MODE(pHTInfoEle)) + { + case 0: + RT_TRACE(COMP_HT, DebugLevel, ("No Protection\n")); + break; + case 1: + RT_TRACE(COMP_HT, DebugLevel, ("HT non-member protection mode\n")); + break; + case 2: + RT_TRACE(COMP_HT, DebugLevel, ("Suggest to open protection\n")); + break; + case 3: + RT_TRACE(COMP_HT, DebugLevel, ("HT mixed mode\n")); + break; + } + + //RT_TRACE(COMP_HT, DebugLevel, ("\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pBasicMCS[0],\ + // pBasicMCS[1], pBasicMCS[2], pBasicMCS[3], pBasicMCS[4])); + + RT_TRACE(COMP_HT, DebugLevel, ("\n")); +} + + +u2Byte +HTMcsToDataRate( + PADAPTER Adapter, + u2Byte nMcsRate + ) +{ + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + u1Byte BandWidth; + + u1Byte isShortGI = CHNL_RUN_ABOVE_40MHZ(pMgntInfo)? + ((pHTInfo->bCurShortGI40MHz)?1:0): + ((pHTInfo->bCurShortGI20MHz)?1:0); + + nMcsRate -= MGN_MCS0; + + BandWidth = CHNL_RUN_ABOVE_40MHZ(pMgntInfo)?1:0; + + // Prefast warning ignore +#pragma warning( disable:6385 ) + RT_TRACE_F(COMP_HT, DBG_LOUD, ("MCS_DATA_RATE[%d][%d][(%d&0x3f)] = %d\n", + BandWidth, isShortGI, nMcsRate, MCS_DATA_RATE[BandWidth][isShortGI][(nMcsRate&0x3f)])); + + return MCS_DATA_RATE[BandWidth][isShortGI][nMcsRate]; +} + +u2Byte +HTPeerMcsToDataRate( + PADAPTER Adapter, + PRT_WLAN_STA pEntry, + u1Byte nMcsRate + ) +{ + u1Byte is40MHz; + u1Byte isShortGI; + + if(pEntry!=NULL) + { + nMcsRate -= MGN_MCS0; + is40MHz = (pEntry->BandWidth >= CHANNEL_WIDTH_40)? TRUE: FALSE; + isShortGI = (is40MHz)?pEntry->HTInfo.bShortGI40M:pEntry->HTInfo.bShortGI20M; + return MCS_DATA_RATE[is40MHz][isShortGI][nMcsRate]; + } + else + return HTMcsToDataRate(Adapter, nMcsRate); +} + + +VOID +HTSetCCKSupport( + PADAPTER Adapter, + BOOLEAN bStarter, + pu1Byte pPeerHTCap + ) +{ + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + + if(pMgntInfo->dot11CurrentChannelBandWidth == CHANNEL_WIDTH_80) + pHTInfo->bCurSuppCCK = FALSE; + else if(bStarter) // AP mode or IBSS starter + { + // Set in HTUseDefaultSettingFromReg/HTUseDefaultSettingFromDefault + } + else // Infrastuction client or IBSS joiner + { + if(pPeerHTCap != NULL) + pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK?GET_HT_CAPABILITY_ELE_DSS_CCK(pPeerHTCap):FALSE; + else + pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; + } +} + +VOID +IOTPeerDetermine( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PADAPTER DefAdapter = GetDefaultAdapter(Adapter); + + // [For Win7 Two Port] 2009.07.30, by Bohn + if(ACTING_AS_AP(Adapter)) + { + if(Adapter->MgntInfo.NdisVersion < RT_NDIS_VERSION_6_20) + pMgntInfo->IOTPeer = HT_IOT_PEER_SELF_SOFTAP; + else if(Adapter->MgntInfo.NdisVersion >= RT_NDIS_VERSION_6_20) + { + if(DefAdapter->MgntInfo.mAssoc==TRUE) + pMgntInfo->IOTPeer = DefAdapter->MgntInfo.IOTPeer; + else + pMgntInfo->IOTPeer = HT_IOT_PEER_SELF_SOFTAP; + } + } + else + { + pMgntInfo->IOTPeer = pBssDesc->Vender; + pMgntInfo->IOTPeerSubtype = pBssDesc->SubTypeOfVender; + + + // 2011/11/28 MH We need to disable TXOP for the AP to preven serious collision. + if (pBssDesc->SubTypeOfVender == HT_IOT_PEER_BROADCOM_NETGEAR_WNDAP4500) + { + pMgntInfo->IOTAction |=HT_IOT_ACT_DISABLE_AC_TXOP; + } + else + { + pMgntInfo->IOTAction &= ~HT_IOT_ACT_DISABLE_AC_TXOP; + } + + // + // Check MPDU maximum size 4/8/11K for VHT mode.~ VHT does not have the function now, + // + if (pBssDesc->BssVHT.bdVHTCapBuf) + { + pMgntInfo->IOTMaxMpduLen = GET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pBssDesc->BssVHT.bdVHTCapBuf); + pMgntInfo->IOTVhtAmsduSupport = TRUE; + //pMgntInfo->IOTMaxMpduLen = GET_VHT_CAPABILITY_ELE_MAX_MPDU_LENGTH(pBssDesc->BssVHT.bdVHTOperBuf); + //DbgPrint("pMgntInfo->IOTMaxMpduLen = %d\n", pMgntInfo->IOTMaxMpduLen); + } + else + { + pMgntInfo->IOTMaxMpduLen = 0; + pMgntInfo->IOTVhtAmsduSupport = FALSE; + } + + } +} + + + + +/** +* Function: HTIOTActIsDisableMCSTwoSpatialStream +* +* Overview: Check whether driver should declare capability of receving All 2 ss packets +* +* Input: +* PADAPTER Adapter, +* +* Output: None +* Return: TRUE if driver should disable all two spatial stream packet +* 2008.04.21 Emily +*/ +BOOLEAN +HTIOTActIsDisableMCSTwoSpatialStream( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + // Apply for 819u only + + if( (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_TKIP) ) + { + if( (pBssDesc->Vender != HT_IOT_PEER_ATHEROS) && + (pBssDesc->Vender != HT_IOT_PEER_UNKNOWN) && + (pBssDesc->Vender != HT_IOT_PEER_MARVELL) && + (pBssDesc->Vender != HT_IOT_PEER_REALTEK_92SE) && + (pBssDesc->Vender != HT_IOT_PEER_RALINK) ) + retValue = TRUE; + } + + return retValue; +} + + + + + +BOOLEAN +HTIOTActIsForcedCTS2Self( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + // Wifi Test 5.2.35 Basic Association in 802.11n Enviroment + if(Adapter->MgntInfo.bWiFiConfg) + retValue = FALSE; + else if(pBssDesc->Vender == HT_IOT_PEER_MARVELL || pBssDesc->Vender == HT_IOT_PEER_ATHEROS) + retValue = TRUE; + + return retValue; +} + + +/* + * EDCA parameters bias on downlink + */ +BOOLEAN +HTIOTActIsEDCABiasRx( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc + ) +{ + BOOLEAN retValue = FALSE; + + if(HAL_IsEdcaBiasRx(Adapter, pBssDesc)) + retValue = TRUE; + + return retValue; +} + + +BOOLEAN +HTIOTActDisableHighPower( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + if(pBssDesc->Vender==HT_IOT_PEER_RALINK || + pBssDesc->Vender==HT_IOT_PEER_REALTEK || + pBssDesc->Vender==HT_IOT_PEER_REALTEK_92SE) + { + retValue = TRUE; + } + + return retValue; +} + + +BOOLEAN +HTIOTActIsDisableTx40MHz( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + if( (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_TKIP) ) + { + if((pBssDesc->Vender==HT_IOT_PEER_REALTEK) && (pBssDesc->BssHT.bdSupportHT)) + retValue = TRUE; + } + + return retValue; +} + +BOOLEAN +HTIOTActIsTxNoAggregation( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + if( (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_TKIP) ) + { + if(pBssDesc->Vender==HT_IOT_PEER_REALTEK) + retValue = TRUE; + } + + return retValue; +} + +BOOLEAN +HTIOTActIsDisableTx2SS( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + + if( (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP104) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) || + (Adapter->MgntInfo.SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_TKIP) ) + { + if((pBssDesc->Vender==HT_IOT_PEER_REALTEK) && (pBssDesc->BssHT.bdSupportHT)) + retValue = TRUE; + } + + return retValue; +} + + + +BOOLEAN +HTIOCActIsDisableCckRate( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + BOOLEAN retValue = FALSE; + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if(pMgntInfo->bDisableCck) + { + retValue = TRUE; + } + + return retValue; + +} + +BOOLEAN +HTIOTActDisableRx40MHzShortGI( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + return FALSE; +} + +BOOLEAN +HTIOTActDisableRx20MHzShortGI( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + return FALSE; +} + + +VOID +ResetIOTSetting( + PMGNT_INFO pMgntInfo +) +{ + pMgntInfo->IOTAction = 0; + pMgntInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; +} + + +/* + The setting used in this functoin shall be our HT Rx capability that we want to inform the peer STA. + Both AP and STA Attach the Capailbity Element + AP/STA should include this element only if HTEnable is turned on. +*/ +VOID +HTConstructCapabilityElement( + PADAPTER Adapter, + POCTET_STRING posHTCap, + BOOLEAN bAssoc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + pu1Byte pCapELE = NULL, pCapMCS; + CHANNEL_WIDTH ChnlWidth; + u1Byte HtAggrSize = HT_AGG_SIZE_64K; + u1Byte HtDensity = HT_DENSITY_NO_RESTRICTION; + u1Byte HtSTBC = 0; + + PlatformZeroMemory(posHTCap->Octet, posHTCap->Length); + + if(bAssoc && pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) + { + u1Byte EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + PlatformMoveMemory(posHTCap->Octet, EWC11NHTCap, sizeof(EWC11NHTCap)); + pCapELE = (pu1Byte)&posHTCap->Octet[4]; + posHTCap->Length = 30; + } + else + { + pCapELE = (pu1Byte)posHTCap->Octet; + posHTCap->Length = 26; + } + + // B0 + SET_HT_CAPABILITY_ELE_LDPC_CAP(pCapELE, (pHTInfo->HtLdpcCap & LDPC_HT_ENABLE_RX) ? 1 : 0); + + ChnlWidth = (CHANNEL_WIDTH)AP_CheckBwWidth(Adapter); + + if(ACTING_AS_AP(Adapter) == FALSE && ACTING_AS_IBSS(Adapter) == FALSE) + { + // Determine peer capability for 40MHz bandwidth support when using STA mode. + // This prevents from some retarded AP from bandwidth configuration error. -- 20110530 Joseph + if(bAssoc && pHTInfo->bCurrentHTSupport) + { + if(GET_HT_CAPABILITY_ELE_CHL_WIDTH(pHTInfo->PeerHTCapBuf) == 0) + ChnlWidth = CHANNEL_WIDTH_20; + } + + ChnlWidth = CHNL_CheckChnlPlanWithBW(Adapter,pMgntInfo->dot11CurrentChannelNumber,ChnlWidth,pMgntInfo->ChannelOffset); + } + + + if(ChnlWidth == CHANNEL_WIDTH_40 || ChnlWidth == CHANNEL_WIDTH_80) + { + SET_HT_CAPABILITY_ELE_CHL_WIDTH(pCapELE, 1); + } + else + { + SET_HT_CAPABILITY_ELE_CHL_WIDTH(pCapELE, 0); + } + + // B2 B3 + SET_HT_CAPABILITY_ELE_MIMO_PWRSAVE(pCapELE, pHTInfo->SelfMimoPs); + // B4 + SET_HT_CAPABILITY_ELE_GREEN_FIELD(pCapELE, 0); // This feature is not supported now!! + // B5 + SET_HT_CAPABILITY_ELE_SHORT_GI20M(pCapELE, pHTInfo->bRegShortGI20MHz ? 1 : 0); // We can receive Short GI!! + // B6 + SET_HT_CAPABILITY_ELE_SHORT_GI40M(pCapELE, pHTInfo->bRegShortGI40MHz ? 1 : 0); // We can receive Short GI!! + + // BIT7 STBC + if(TEST_FLAG(pHTInfo->HtStbcCap, STBC_HT_ENABLE_TX)) + { + SET_HT_CAPABILITY_ELE_TX_STBC(pCapELE, 1); + } + else + { + SET_HT_CAPABILITY_ELE_TX_STBC(pCapELE, 0); + } + // B8 B9 + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_RX_STBC, (pu1Byte)&HtSTBC); + if(TEST_FLAG(pHTInfo->HtStbcCap, STBC_HT_ENABLE_RX)) + { + SET_HT_CAPABILITY_ELE_RX_STBC(pCapELE, HtSTBC); + } + else + { + SET_HT_CAPABILITY_ELE_RX_STBC(pCapELE, 0); + } + + // B10 + SET_HT_CAPABILITY_ELE_DELAY_BA(pCapELE, 0); // Do not support now!! + // B11 + { + SET_HT_CAPABILITY_ELE_MAX_AMSDU_SIZE(pCapELE, ( (Adapter->MAX_RECEIVE_BUFFER_SIZE >= HT_AMSDU_SIZE_8K) && \ + (!PLATFORM_LIMITED_RX_BUF_SIZE(Adapter)))?1:0); + } + + // B12 + if(IS_WIRELESS_MODE_5G(Adapter)) + { + SET_HT_CAPABILITY_ELE_DSS_CCK(pCapELE, 0); + } + else + { + SET_HT_CAPABILITY_ELE_DSS_CCK(pCapELE,(ChnlWidth?(pHTInfo->bRegSuppCCK?1:0):0) ); + } + + + SET_HT_CAPABILITY_ELE_PSMP(pCapELE, 0); // Do not support now!! + // B14 + if(IS_WIRELESS_MODE_5G(Adapter)) + { + SET_HT_CAPABILITY_ELE_FORTY_INTOLERANT(pCapELE, 0); + } + else + { + SET_HT_CAPABILITY_ELE_FORTY_INTOLERANT(pCapELE, pHTInfo->b40Intolerant); + } + // B15 + SET_HT_CAPABILITY_ELE_LSIG_TXOP_PROTECT(pCapELE, 0); // Do not support now!! + + //MAC HT parameters info + // Retrieve HAL AMPDU Factor and AMPDU density parameter for each ICs. Added by Roger, 2011.12.08. + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_RX_AMPDU_FACTOR, (pu1Byte)&HtAggrSize); + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_MPDU_DENSITY, (pu1Byte)&HtDensity); + + // RX AMPDU factor and MPDU density + SET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pCapELE, HtAggrSize); + SET_HT_CAPABILITY_ELE_MPDU_DENSITY(pCapELE, HtDensity); + + // Supported MCS set + pCapMCS = GET_HT_CAPABILITY_ELE_MCS(pCapELE); + PlatformMoveMemory(pCapMCS, pMgntInfo->Regdot11HTOperationalRateSet, 16); + + //Extended HT Capability Info + SET_HT_CAPABILITY_ELE_EXT_HTCAPINFO(pCapELE, 0); + + //TXBF Capabilities + SET_HT_CAPABILITY_ELE_TXBF_CAP(pCapELE, 0); + + // HT Beamformer + if(TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) + { + SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(pCapELE, 1); + SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pCapELE, 1); + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pCapELE, 1); + SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pCapELE, HAL_QueryBeamformerCap(Adapter)); + } + + // HT Beamformee + if(TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) + { + SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(pCapELE, 1); + SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pCapELE, 2); + SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pCapELE, HAL_QueryBeamformeeCap(Adapter)); + } + + //Antenna Selection Capabilities + SET_HT_CAPABILITY_ELE_AS_CAP(pCapELE, 0); + + if(bAssoc) + { + if(pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) + pCapMCS[1] &= 0x00; + + // disable Rx 40MHz Short GI + if(pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) + SET_HT_CAPABILITY_ELE_SHORT_GI40M(pCapELE, 0); + + if(pMgntInfo->IOTAction & HT_IOT_ACT_DISABLE_RX_20MHZ_SHORT_GI) + SET_HT_CAPABILITY_ELE_SHORT_GI20M(pCapELE, 0); + } + + + RT_PRINT_DATA( COMP_HT, DBG_TRACE, "Construct HTCap in Beacon/Assoc/ReAssoc", posHTCap->Octet, posHTCap->Length); + + //Print each field in detail. Driver should not print out this message by default + HTDebugHTCapability(DBG_TRACE, Adapter, posHTCap, (pu1Byte)"HTConstructCapability()"); +} + +/* + Only AP will attach the HT Information Element +*/ + +VOID +HTConstructInfoElement( + PADAPTER Adapter, + POCTET_STRING posHTInfo +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + pu1Byte pHTInfoEle = (pu1Byte)(posHTInfo->Octet); + PRT_CHANNEL_INFO pChnlInfo = GET_CHNL_INFO(pMgntInfo); + + PlatformZeroMemory(posHTInfo->Octet, posHTInfo->Length); + + if(ACTING_AS_AP(Adapter) || ACTING_AS_IBSS(Adapter)) + { + + if((GetDefaultAdapter(Adapter)->MgntInfo.bForceGoTxData20MBw == TRUE) && IsFirstGoAdapter(Adapter)){ + SET_HT_INFO_ELE_STA_CHL_WIDTH(pHTInfoEle, FALSE); + SET_HT_INFO_ELE_EXT_CHL_OFFSET(pHTInfoEle, EXTCHNL_OFFSET_NO_EXT); + } + else{ + SET_HT_INFO_ELE_STA_CHL_WIDTH(pHTInfoEle, CHNL_RUN_ABOVE_40MHZ(pMgntInfo)); + SET_HT_INFO_ELE_EXT_CHL_OFFSET(pHTInfoEle, pChnlInfo->Ext20MHzChnlOffsetOf40MHz); + } + + SET_HT_INFO_ELE_CONTROL_CHL(pHTInfoEle, pMgntInfo->dot11CurrentChannelNumber); + SET_HT_INFO_ELE_RIFS(pHTInfoEle, 0); + SET_HT_INFO_ELE_PSMP_ACCESS_ONLY(pHTInfoEle, 0); + SET_HT_INFO_ELE_SRV_INT_GRAN(pHTInfoEle, 0); + SET_HT_INFO_ELE_OPT_MODE(pHTInfoEle, pHTInfo->CurrentOpMode); + SET_HT_INFO_ELE_NON_GF_DEV(pHTInfoEle, 0); + SET_HT_INFO_ELE_DUAL_BEACON(pHTInfoEle, 0); + SET_HT_INFO_ELE_SECONDARY_BEACON(pHTInfoEle, 0); + SET_HT_INFO_ELE_LSIG_TXOP_PROTECT_FULL(pHTInfoEle, 0); + SET_HT_INFO_ELE_PCO_ACTIVE(pHTInfoEle, 0); + SET_HT_INFO_ELE_PCO_PHASE(pHTInfoEle, 0); + + PlatformZeroMemory(GET_HT_INFO_ELE_BASIC_MCS(pHTInfoEle), 16); + + posHTInfo->Length = 22; + } + else + { + //STA should not generate High Throughput Information Element + posHTInfo->Length = 0; + } + +} + + + +VOID +HT_PickMCSRate( + IN PADAPTER Adapter, + OUT pu1Byte pOperateMCS +) +{ + u1Byte i; + + if(IS_WIRELESS_MODE_N(Adapter)) + {//HT part + if(HAL_SkipMcsRates(Adapter)) + pOperateMCS[1] &=0xF8; //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily + + pOperateMCS[4] &= RATE_ADPT_MCS32_MASK; + } + else + {//no MCS rate + for(i = 0 ; i <= 15 ; i++) + pOperateMCS[i] = 0; + } +} + + + +/* +* Description: +* This function will get the highest speed rate in input MCS set. +* +* /param Adapter Pionter to Adapter entity +* pMCSRateSet Pointer to MCS rate bitmap +* pMCSFilter Pointer to MCS rate filter +* +* /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter. +* +*/ +u1Byte +HTGetHighestMCSRate( + IN PADAPTER Adapter, + IN pu1Byte pMCSRateSet, + IN pu1Byte pMCSFilter + ) +{ + u1Byte i, j, k; + u1Byte bitMap; + u1Byte mcsRate = 0; + u1Byte availableMcsRate[16]; + + for(i=0; i<16; i++) + availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; + + for(i = 0; i < 16; i++) + { + if(availableMcsRate[i] != 0) + break; + } + if(i == 16) + return 0; + + for(i = 0; i < 16; i++) + { + if(availableMcsRate[i] != 0) + { + bitMap = availableMcsRate[i]; + for(j = 0; j < 8; j++) + { + if((bitMap%2) != 0) + { + k = 8*i+j; + if(MCS_DATA_RATE[0][0][k] > MCS_DATA_RATE[0][0][mcsRate]) + mcsRate = k; + } + bitMap = bitMap>>1; + } + } + } + return (mcsRate + MGN_MCS0); +} + + + +/* +** +**1.Filter our operation rate set with AP's rate set +**2.shall reference channel bandwidth, STBC, Antenna number +**3.generate rate adative table for firmware +**David 20060906 +** +** \pHTSupportedCap: the connected STA's supported rate Capability element +*/ +BOOLEAN +HTFilterMCSRate( + IN PADAPTER Adapter, + IN pu1Byte pSupportMCS, + OUT pu1Byte pOperateMCS +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + UINT i=0; + + // filter out operational rate set not supported by AP, the lenth of it is 16 + for(i = 0;i <= 15; i++) + pOperateMCS[i] = pMgntInfo->Regdot11HTOperationalRateSet[i] & pSupportMCS[i]; + + // we also shall suggested the first start rate set according to our singal strength + HT_PickMCSRate(Adapter, pOperateMCS); + + return TRUE; +} + +VOID +HTOnAssocRsp( + IN PADAPTER Adapter, + IN OCTET_STRING asocpdu +) +{ + + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + pu1Byte pPeerHTCap, pPeerHTInfo; + OCTET_STRING osTmp; + pu1Byte pCapMCS, pMcsFilter; + static u1Byte EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily + static u1Byte EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily + u2Byte nMaxAMSDUSize; + + if( pHTInfo->bCurrentHTSupport == FALSE ) + { + RT_TRACE( COMP_QOS, DBG_LOUD, ("<=== HTOnAssocRsp(): HT_DISABLE\n") ); + return; + } + + PlatformZeroMemory(pHTInfo->PeerHTCapBuf, sizeof(pHTInfo->PeerHTCapBuf)); + PlatformZeroMemory(pHTInfo->PeerHTInfoBuf, sizeof(pHTInfo->PeerHTInfoBuf)); + + // Get HT CAP and copy into buffer + osTmp= PacketGetElement( asocpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length == 0) + osTmp = PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE); + + osTmp.Length = osTmp.Length > sizeof(pHTInfo->PeerHTCapBuf)?\ + sizeof(pHTInfo->PeerHTCapBuf):osTmp.Length; //prevent from overflow + + if(osTmp.Length > 0) + CopyMem(pHTInfo->PeerHTCapBuf, osTmp.Octet, osTmp.Length); + + // Get HT Info and copy into buffer + osTmp= PacketGetElement( asocpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length == 0) + osTmp = PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE); + + osTmp.Length = osTmp.Length>sizeof(pHTInfo->PeerHTCapBuf)?\ + sizeof(pHTInfo->PeerHTCapBuf):osTmp.Length; //prevent from overflow + + if(osTmp.Length > 0) + CopyMem(pHTInfo->PeerHTInfoBuf, osTmp.Octet, osTmp.Length); + + if(!PlatformCompareMemory(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap))) + pPeerHTCap = (pu1Byte)(&pHTInfo->PeerHTCapBuf[4]); + else + pPeerHTCap = (pu1Byte)(pHTInfo->PeerHTCapBuf); + + if(!PlatformCompareMemory(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + pPeerHTInfo = (pu1Byte)(&pHTInfo->PeerHTInfoBuf[4]); + else + pPeerHTInfo = (pu1Byte)(pHTInfo->PeerHTInfoBuf); + + // Get 20/40 BSS Coexistence Management Support from Extended Capabilities element + osTmp = PacketGetElement(asocpdu, EID_EXTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length != 0) + pHTInfo->bPeerBssCoexistence = GET_EXT_CAPABILITY_ELE_BSS_COEXIST(osTmp.Octet); + + // Get OBSS scan interval from Overlapping BSS Scan Parameters element + osTmp = PacketGetElement(asocpdu, EID_OBSS, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length != 0) + pHTInfo->CurOBSSScanInterval = GET_OBSS_PARAM_ELE_SCAN_INTERVAL(osTmp.Octet); + + // Get OBSS scan exemption grant from 20/40 BSS Coexistence element + osTmp = PacketGetElement(asocpdu, EID_BSSCoexistence, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(osTmp.Length != 0) + pHTInfo->bCurOBSSScanExemptionGrt = GET_BSS_COEXISTENCE_ELE_OBSS_EXEMPTION_GRT(osTmp.Octet); + + pHTInfo->bPeer40MHzCap = GET_HT_CAPABILITY_ELE_CHL_WIDTH(pPeerHTCap); + pHTInfo->PeerExtChnlOffset = (EXTCHNL_OFFSET)GET_HT_INFO_ELE_EXT_CHL_OFFSET(pPeerHTInfo); + pHTInfo->bPeer40MHzIntolerant = GET_HT_CAPABILITY_ELE_FORTY_INTOLERANT(pPeerHTCap); + + + // B0 Config LDPC Coding Capability + if(TEST_FLAG(pHTInfo->HtLdpcCap, LDPC_HT_ENABLE_TX)) + { + SET_FLAG(pHTInfo->HtCurLdpc, GET_HT_CAPABILITY_ELE_LDPC_CAP(pPeerHTCap) ? (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX) : 0); + RT_TRACE_F(COMP_HT, DBG_LOUD, ("Target BSS support HT LDPC, enable Tx LDPC!\n")); + } + + // B5 B6 Config Short GI/ Long GI setting + pHTInfo->bCurShortGI20MHz = GET_HT_CAPABILITY_ELE_SHORT_GI20M(pPeerHTCap); + pHTInfo->bCurShortGI40MHz = GET_HT_CAPABILITY_ELE_SHORT_GI40M(pPeerHTCap); + + // B7 B8 B9 Config STBC setting + if( TEST_FLAG(pHTInfo->HtStbcCap, STBC_HT_ENABLE_TX) && GET_HT_CAPABILITY_ELE_RX_STBC(pPeerHTCap)) + { + SET_FLAG(pHTInfo->HtCurStbc, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX) ); + } + + // B11 Maximum A-MSDU Length + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + nMaxAMSDUSize = (GET_HT_CAPABILITY_ELE_MAX_AMSDU_SIZE(pPeerHTCap)==0)?HT_AMSDU_SIZE_4K:HT_AMSDU_SIZE_8K; + if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize ) + pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; + else + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + RT_TRACE_F(COMP_AMSDU, DBG_LOUD, ("pHTInfo->bCurrent_AMSDU_Support = %d, CurrentSize = %d, ForcedSize = %d\n", pHTInfo->bCurrent_AMSDU_Support, pHTInfo->nCurrent_AMSDU_MaxSize, pHTInfo->ForcedAMSDUMaxSize)); + + // B12 Config DSSS/CCK mode in 40MHz mode + HTSetCCKSupport(Adapter, FALSE, pPeerHTCap); + + // A-MPDU setting + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + if( (pMgntInfo->SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP104) || + (pMgntInfo->SecurityInfo.GroupEncAlgorithm == RT_ENC_ALG_WEP40) || + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP104) || + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_WEP40) || + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == RT_ENC_ALG_TKIP)) + { + if( (pMgntInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || + (pMgntInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) ) + pHTInfo->bCurrentAMPDUEnable = FALSE; + } + + // B16 B17 Maximum A-MPDU Length Exponent + if(GET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pPeerHTCap) < pHTInfo->CurrentAMPDUFactor) + pHTInfo->CurrentAMPDUFactor = GET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pPeerHTCap); + + // BIT18 BIT19 BIT20 AMPDU Minimum MPDU Start Spacing + if(pHTInfo->MPDU_Density > GET_HT_CAPABILITY_ELE_MPDU_DENSITY(pPeerHTCap)) + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + else + pHTInfo->CurrentMPDUDensity = GET_HT_CAPABILITY_ELE_MPDU_DENSITY(pPeerHTCap); + + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_FACTOR, &pHTInfo->CurrentAMPDUFactor); + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, &pHTInfo->CurrentMPDUDensity); + + + if( pMgntInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE || + pMgntInfo->IOTAction & HT_IOT_ACT_AMSDU_AMPDU) + { + pHTInfo->bCurrent_AMSDU_Support = TRUE; + + if(pMgntInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) + pHTInfo->bCurrentAMPDUEnable = FALSE; + } + + // Rx Reorder Setting + pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; + + pCapMCS = GET_HT_CAPABILITY_ELE_MCS(pPeerHTCap); + + HTFilterMCSRate(Adapter, pCapMCS, pMgntInfo->dot11HTOperationalRateSet); + + // B2 B3 SM Power Save + pHTInfo->PeerMimoPs = GET_HT_CAPABILITY_ELE_MIMO_PWRSAVE(pPeerHTCap); + if(pHTInfo->PeerMimoPs <= MIMO_PS_DYNAMIC) + pMcsFilter = MCS_FILTER_1SS; + else + pMcsFilter = MCS_FILTER_ALL; + + pMgntInfo->HTHighestOperaRate = HTGetHighestMCSRate( + Adapter, + pMgntInfo->dot11HTOperationalRateSet, + pMcsFilter ); + + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MAX_TIME, &pMgntInfo->HTHighestOperaRate); + + // Config Tx beamforming setting + CLEAR_FLAGS(pHTInfo->HtCurBeamform); + if( TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pPeerHTCap)) + { + SET_FLAG(pHTInfo->HtCurBeamform, BEAMFORMING_HT_BEAMFORMER_ENABLE); + // Shit to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP + SET_FLAG(pHTInfo->HtCurBeamform, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pPeerHTCap)<<6); + } + + if( TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pPeerHTCap)) + { + SET_FLAG(pHTInfo->HtCurBeamform, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + // Shit to BEAMFORMING_HT_BEAMFORMER_STEER_NUM + SET_FLAG(pHTInfo->HtCurBeamform, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pPeerHTCap)<<4); + } + RT_DISP(FBEAM, FBEAM_FUN, ("Client HT Beaforming Cap = 0x%02X\n", pHTInfo->HtCurBeamform)); + + // Config current operation mode. + pHTInfo->CurrentOpMode = GET_HT_INFO_ELE_OPT_MODE(pPeerHTInfo); +} + + +/* +* This function is called when +* (1) MPInitialization Phase +* (2) Receiving of Deauthentication from AP +*/ + +// TODO: Should this funciton be called when receiving of Disassociation? +VOID +HTInitializeHTInfo(PADAPTER Adapter) +{ + PRT_HIGH_THROUGHPUT pHTInfo = Adapter->MgntInfo.pHTInfo; + + // These parameters will be reset when receiving deauthentication packet + pHTInfo->bCurrentHTSupport = FALSE; + + // LDPC support + CLEAR_FLAGS(pHTInfo->HtCurLdpc); + + // STBC support + CLEAR_FLAGS(pHTInfo->HtCurStbc); + + pHTInfo->bPeer40MHzCap = FALSE; + pHTInfo->bPeer40MHzIntolerant = FALSE; + + // Short GI support + pHTInfo->bCurShortGI20MHz = FALSE; + pHTInfo->bCurShortGI40MHz = FALSE; + + // CCK rate support + // This flag is set to TRUE to support CCK rate by default. + // It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to 11N BSS. + pHTInfo->bCurSuppCCK = TRUE; + + // AMSDU related + pHTInfo->bCurrent_AMSDU_Support = FALSE; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + // AMPUD related + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + // 20/40 Bss Coexistence related + pHTInfo->bPeerBssCoexistence = FALSE; + pHTInfo->bCurOBSSScanExemptionGrt = FALSE; + pHTInfo->CurOBSSScanInterval = 0; + pHTInfo->IdleOBSSScanCnt = 0; + pHTInfo->lastTimeSentObssRptUs = 0; + + // Initialize all of the parameters related to 11n + PlatformZeroMemory((PVOID)(&(pHTInfo->SelfHTCap)), sizeof(pHTInfo->SelfHTCap)); + PlatformZeroMemory((PVOID)(&(pHTInfo->SelfHTInfo)), sizeof(pHTInfo->SelfHTInfo)); + PlatformZeroMemory((PVOID)(&(pHTInfo->PeerHTCapBuf)), sizeof(pHTInfo->PeerHTCapBuf)); + PlatformZeroMemory((PVOID)(&(pHTInfo->PeerHTInfoBuf)), sizeof(pHTInfo->PeerHTInfoBuf)); + + // Set default IEEE spec for Draft N + pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; + + // Realtek proprietary aggregation mode + pHTInfo->RT2RT_HT_Mode = 0; + + // Beamforming support + CLEAR_FLAGS(pHTInfo->HtCurBeamform); +} + +VOID +HTInitializeBssDesc( + IN PBSS_HT pBssHT + ) +{ + + pBssHT->bdSupportHT = FALSE; + PlatformZeroMemory(pBssHT->bdHTCapBuf, sizeof(pBssHT->bdHTCapBuf)); + pBssHT->bdHTCapLen = 0; + PlatformZeroMemory(pBssHT->bdHTInfoBuf, sizeof(pBssHT->bdHTInfoBuf)); + pBssHT->bdHTInfoLen = 0; + + pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE; + + pBssHT->RT2RT_HT_Mode = 0; + + pBssHT->bd40Intolerant = FALSE; + pBssHT->bdOBSSExemption = FALSE; + pBssHT->OBSSScanInterval = 0; +} + + + +VOID +HTParsingHTCapElement( + IN PADAPTER Adapter, + IN OCTET_STRING HTCapIE, + OUT PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) ) + { + RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") ); + return; + } + + // TODO: Check the correctness of HT Cap + //Print each field in detail. Driver should not print out this message by default + if(!ACTING_AS_AP(Adapter) && !pMgntInfo->mAssoc) + HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu1Byte)"HTParsingHTCapElement()"); + + HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\ + sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length; //prevent from overflow + + CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length); + pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length; + +} + + +VOID +HTParsingHTInfoElement( + PADAPTER Adapter, + OCTET_STRING HTInfoIE, + PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + + if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)) + { + RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") ); + return; + } + + // TODO: Check the correctness of HT Info + //Print each field in detail. Driver should not print out this message by default + if(!ACTING_AS_AP(Adapter) && !pMgntInfo->mAssoc) + HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu1Byte)"HTParsingHTInfoElement()"); + + HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\ + sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length; //prevent from overflow + + CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length); + pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length; +} + +/* + * Get HT related information from beacon and save it in BssDesc + * + * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP + * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() + * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode). + * Input: + * PADAPTER Adapter + * + * Output: + * PRT_TCB BssDesc + * +*/ +VOID +HTGetValueFromBeaconOrProbeRsp( + PADAPTER Adapter, + POCTET_STRING pSRCmmpdu, + PRT_WLAN_BSS bssDesc +) +{ + OCTET_STRING HTCapIE, HTInfoIE, OBSSIE, BssCoexistenceIE, mmpdu; + + mmpdu.Octet = pSRCmmpdu->Octet; + mmpdu.Length = pSRCmmpdu->Length; + + //2Note: + // Mark for IOT testing using Linksys WRT350N, This AP does not contain WMM IE when + // it is configured at pure-N mode. + // if(bssDesc->BssQos.bdQoSMode & QOS_WMM) + // + + HTInitializeBssDesc (&bssDesc->BssHT); + + //2<1> Parse HTCap, and HTInfo + // Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE + HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + RT_DISP(FBEACON, BCN_SHOW, + ("EID_HTCapability HTCapIE.Length=%d\r\n", HTCapIE.Length)) + if(HTCapIE.Length == 0) + { + HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE); + if(HTCapIE.Length != 0) + bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC; + RT_DISP(FBEACON, BCN_SHOW, + ("EID_Vendor HTCapIE.Length=%d\r\n", HTCapIE.Length)) + } + if(HTCapIE.Length != 0) + HTParsingHTCapElement(Adapter, HTCapIE, bssDesc); + + // Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE + HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(HTInfoIE.Length == 0) + { + HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE); + if(HTInfoIE.Length != 0) + bssDesc->BssHT.bdHTSpecVer = HT_SPEC_VER_EWC; + } + if(HTInfoIE.Length != 0) + HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc); + + //2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() + if(HTCapIE.Length != 0) + { + bssDesc->BssHT.bdSupportHT = TRUE; + if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE) + QosSetLegacyWMMParamWithHT(Adapter, bssDesc); + } + else + { + bssDesc->BssHT.bdSupportHT = FALSE; + } + + //2<3>Parse OBSS Scan IE + OBSSIE = PacketGetElement(mmpdu, EID_OBSS, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); + if(OBSSIE.Length != 0) + BSS_ParsingOBSSInfoElement(Adapter, OBSSIE, bssDesc); + + //2<3>Parse 20 40 BSS Coexistence IE + // 23. 20/40 BSS Coexistence element + BssCoexistenceIE = PacketGetElement(mmpdu, EID_BSSCoexistence, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE ); + if(BssCoexistenceIE.Length != 0) + BSS_ParsingBSSCoexistElement(Adapter, BssCoexistenceIE, bssDesc); + + //2<4>Check peer configuration + if(HTCapIE.Length!=0 && HTCapIE.Octet != NULL) + { + bssDesc->bdBandWidth = (CHANNEL_WIDTH)(GET_HT_CAPABILITY_ELE_CHL_WIDTH(HTCapIE.Octet)); + bssDesc->BssHT.bd40Intolerant = GET_HT_CAPABILITY_ELE_FORTY_INTOLERANT(HTCapIE.Octet); + } + else + bssDesc->bdBandWidth = CHANNEL_WIDTH_20; +} + +/*----------------------------------------------------------------------------- + * Function: HTResetSelfAndSavePeerSetting() + * + * Overview: This function should ONLY be called before association. SetupJoinInfraInfo(). + * Driver reset it's state to it's capability and peer's capability + * + * Input: PADAPTER Adapter + * PRT_WLAN_BSS pBssDesc + * + * Output: NONE + * + * Return: NONE + + *---------------------------------------------------------------------------*/ +VOID +HTResetSelfAndSavePeerSetting( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc +) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + BOOLEAN bIOTAction; + + // + // Save Peer Setting before Association + // + if( pHTInfo->bEnableHT && pBssDesc->BssHT.bdSupportHT) + { + pHTInfo->bCurrentHTSupport = TRUE; + pHTInfo->ePeerHTSpecVer = pBssDesc->BssHT.bdHTSpecVer; + + // Save HTCap and HTInfo information Element + if(pBssDesc->BssHT.bdHTCapLen > 0 && pBssDesc->BssHT.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) + CopyMem(pHTInfo->PeerHTCapBuf, pBssDesc->BssHT.bdHTCapBuf, pBssDesc->BssHT.bdHTCapLen); + + if(pBssDesc->BssHT.bdHTInfoLen > 0 && pBssDesc->BssHT.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf)) + CopyMem(pHTInfo->PeerHTInfoBuf, pBssDesc->BssHT.bdHTInfoBuf, pBssDesc->BssHT.bdHTInfoLen); + + if(pBssDesc->BssHT.bdHTCapLen != 0) + pHTInfo->bPeer40MHzCap = GET_HT_CAPABILITY_ELE_CHL_WIDTH(pBssDesc->BssHT.bdHTCapBuf); + + if(pBssDesc->BssHT.bdHTInfoLen != 0) + pHTInfo->PeerExtChnlOffset = (EXTCHNL_OFFSET)GET_HT_INFO_ELE_EXT_CHL_OFFSET(pBssDesc->BssHT.bdHTInfoBuf); + + // Check whether RT to RT aggregation mode is enabled + pHTInfo->RT2RT_HT_Mode = pBssDesc->BssHT.RT2RT_HT_Mode; + + // Decide IOT Action + // Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided + pMgntInfo->IOTAction = 0; + bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; + + bIOTAction = HTIOTActIsForcedCTS2Self(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; + + bIOTAction = HTIOTActIsEDCABiasRx(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_EDCA_BIAS_ON_RX; + + bIOTAction = HTIOCActIsDisableCckRate(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_CCK_RATE; + + bIOTAction = HTIOTActDisableHighPower(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_HIGH_POWER; + + bIOTAction = HTIOTActIsTxNoAggregation(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_TX_NO_AGGREGATION; + + bIOTAction = HTIOTActIsDisableTx40MHz(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_40_MHZ; + + bIOTAction = HTIOTActIsDisableTx2SS(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_2SS; + + bIOTAction = HTIOTActDisableRx40MHzShortGI(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI; + + bIOTAction = HTIOTActDisableRx20MHzShortGI(Adapter, pBssDesc); + if(bIOTAction) + pMgntInfo->IOTAction |= HT_IOT_ACT_DISABLE_RX_20MHZ_SHORT_GI; + + if (pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_NETGEAR_WNDAP3200) + { + pMgntInfo->IOTAction |=HT_IOT_ACT_DISABLE_EXT_CHNL_COMBINE; + } + } + else + { + pHTInfo->bCurrentHTSupport = FALSE; + pHTInfo->bPeer40MHzCap = CHANNEL_WIDTH_20; + pHTInfo->PeerExtChnlOffset = EXTCHNL_OFFSET_NO_EXT; + pHTInfo->RT2RT_HT_Mode = 0; + pMgntInfo->IOTAction = 0; + } + +} + +VOID +HTUpdateSelfAndPeerSetting( + PADAPTER Adapter, + PRT_WLAN_BSS pBssDesc + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + pu1Byte pPeerHTInfo = (pu1Byte)pBssDesc->BssHT.bdHTInfoBuf; + + if(pHTInfo->bCurrentHTSupport) + { + // Config current operation mode. + if(pBssDesc->BssHT.bdHTInfoLen != 0) + { + pHTInfo->CurrentOpMode = GET_HT_INFO_ELE_OPT_MODE(pPeerHTInfo); + pHTInfo->PeerExtChnlOffset = (EXTCHNL_OFFSET)GET_HT_INFO_ELE_EXT_CHL_OFFSET(pPeerHTInfo); + } + + // <TODO: Config according to OBSS non-HT STA present!!> + pHTInfo->CurOBSSScanInterval = pBssDesc->BssHT.OBSSScanInterval; + pHTInfo->bCurOBSSScanExemptionGrt = pBssDesc->BssHT.bdOBSSExemption; + } +} + +VOID +HTUseDefaultSettingFromReg( + PADAPTER Adapter + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + PADAPTER DefAdapter = GetDefaultAdapter(Adapter); + BOOLEAN bRegBW40MHz = CHNL_GetRegBWSupport(Adapter)?TRUE:FALSE; + + pHTInfo->HtCurLdpc = pHTInfo->HtLdpcCap; + pHTInfo->HtCurStbc = pHTInfo->HtStbcCap; + pHTInfo->HtCurBeamform = pHTInfo->HtBeamformCap; + + pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; + pHTInfo->bCurShortGI20MHz= TRUE; + pHTInfo->bCurShortGI40MHz= bRegBW40MHz?TRUE:FALSE; + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + + // XP, Win7 DefAdapter AP mode mAssoc = FALSE. AP_SetupStartApInfo/SetupStartIBSSInfo (only default port) + // ExtAdapter AP mode mAssoc = FALSE. AP_SetupStartApInfo/SetupStartIBSSInfo (two port) + // DefAdapter AP mode mAssoc = TRUE. If STA connected (two port) + // Vista DefAdapter AP mode mAssoc = FALSE. AP_SetupStartApInfo/SetupStartIBSSInfo (only default port) + if(DefAdapter->MgntInfo.mAssoc == TRUE) + pMgntInfo->IOTPeer = DefAdapter->MgntInfo.IOTPeer; + else + pMgntInfo->IOTPeer = HT_IOT_PEER_SELF_SOFTAP; + + pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; + + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_FACTOR, &pHTInfo->CurrentAMPDUFactor); + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, &pHTInfo->CurrentMPDUDensity); + + HTFilterMCSRate(Adapter, pMgntInfo->Regdot11HTOperationalRateSet, pMgntInfo->dot11HTOperationalRateSet); + + pMgntInfo->HTHighestOperaRate = HTGetHighestMCSRate( + Adapter, + pMgntInfo->dot11HTOperationalRateSet, + MCS_FILTER_ALL ); + + if(bRegBW40MHz) + pMgntInfo->dot11CurrentChannelBandWidth = CHANNEL_WIDTH_40; + else + pMgntInfo->dot11CurrentChannelBandWidth = CHANNEL_WIDTH_20; +} + +VOID +HTUseDefaultSettingFromDefault( + PADAPTER Adapter + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + + PADAPTER DefAdapter = GetDefaultAdapter(Adapter); + PMGNT_INFO pDefMgntInfo = &DefAdapter->MgntInfo; + PRT_HIGH_THROUGHPUT pDefHTInfo = DefAdapter->MgntInfo.pHTInfo; + + //===== The ones that not follow ====== + pHTInfo->bCurShortGI20MHz = TRUE; + + pHTInfo->HtCurLdpc = pHTInfo->HtLdpcCap; + pHTInfo->HtCurStbc = pHTInfo->HtStbcCap; + pHTInfo->HtCurBeamform = pHTInfo->HtBeamformCap; + + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; + + HTFilterMCSRate(Adapter, pMgntInfo->Regdot11HTOperationalRateSet, pMgntInfo->dot11HTOperationalRateSet); + pMgntInfo->HTHighestOperaRate = HTGetHighestMCSRate( + Adapter, + pMgntInfo->dot11HTOperationalRateSet, + MCS_FILTER_ALL ); + + //============================== + pHTInfo->bCurSuppCCK = pDefHTInfo->bCurSuppCCK; + pHTInfo->bCurShortGI40MHz = pDefMgntInfo->dot11CurrentChannelBandWidth?FALSE:TRUE; + //AMPDU Factor and Density is register, can't be per pkt. AMPDU_Factor must use Default for register. by Bohn, 2009.12.18 + pHTInfo->CurrentAMPDUFactor = pDefHTInfo->CurrentAMPDUFactor; + pHTInfo->CurrentMPDUDensity = pDefHTInfo->CurrentMPDUDensity; + //[Win7] Adapter act as AP already, Defaualt Port Connected already, 2009.07.30, by Bohn + pMgntInfo->IOTPeer = pDefMgntInfo->IOTPeer; + + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_FACTOR, &pHTInfo->CurrentAMPDUFactor); + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, &pHTInfo->CurrentMPDUDensity); + + pMgntInfo->dot11CurrentChannelBandWidth = pDefMgntInfo->dot11CurrentChannelBandWidth; +} + + +VOID +HTUseDefaultSetting( + PADAPTER Adapter + ) +{ + PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + u1Byte TwoPortStatus =(u1Byte) TWO_PORT_STATUS__DEFAULT_ONLY; + + if(pHTInfo->bEnableHT) + { + pHTInfo->bCurrentHTSupport = TRUE; + + //[Win7] [Vista/XP] Cross Platform Capbility Enable!, 2009.07.31, by Bohn + GetTwoPortSharedResource(Adapter,TWO_PORT_SHARED_OBJECT__STATUS,NULL,&TwoPortStatus); + + //[win7 Two Port BW40Mhz issue] Extention Port Use Reg's Default Value. 2009.05.20, by bohn + if( TwoPortStatus==TWO_PORT_STATUS__DEFAULT_ONLY || + TwoPortStatus==TWO_PORT_STATUS__EXTENSION_ONLY || + TwoPortStatus==TWO_PORT_STATUS__WITHOUT_ANY_ASSOCIATE) + { + HTUseDefaultSettingFromReg(Adapter); + } + else if(TwoPortStatus==TWO_PORT_STATUS__EXTENSION_FOLLOW_DEFAULT) + { + //[win7 Two Port BW40Mhz issue] Extention Port obey the rule of Default Port. 2009.05.20, by bohn + HTUseDefaultSettingFromDefault(Adapter); + } + else if(TwoPortStatus==TWO_PORT_STATUS__DEFAULT_G_EXTENSION_N20 || + TwoPortStatus==TWO_PORT_STATUS__DEFAULT_A_EXTENSION_N20 || + TwoPortStatus==TWO_PORT_STATUS__ADHOC) + { + //[Win7] Now is the Default-G Extension-N20 case, we need to reset all HT value and forced to N20 + // 2009.07.09, by Bohn + HTUseDefaultSettingFromReg(Adapter); + + pMgntInfo->dot11CurrentChannelBandWidth = CHANNEL_WIDTH_20; + } + } + else + { + pHTInfo->bCurrentHTSupport = FALSE; + pMgntInfo->dot11CurrentChannelBandWidth = CHANNEL_WIDTH_20; + } +} + +BOOLEAN +HTCCheck( + PADAPTER Adapter, + PRT_RFD pRfd, + POCTET_STRING pFrame + ) +{ + if( IsQoSDataFrame(pFrame->Octet) && Frame_Order(*pFrame) == 1) + return TRUE; + else + return FALSE; +} + +VOID +HTCheckHTCap( + IN PADAPTER Adapter, + IN PRT_WLAN_STA pEntry, + IN pu1Byte pHTCap +) +{ + PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); + pu1Byte pMcsFilter; + u2Byte TmpValue; + PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); + u1Byte HtSTBC = 0; + + //1 Get HT properties of the STA + + // B0 Config LDPC Coding Capability + if(TEST_FLAG(pHTInfo->HtLdpcCap, LDPC_HT_ENABLE_TX)) + SET_FLAG(pEntry->HTInfo.LDPC, GET_HT_CAPABILITY_ELE_LDPC_CAP(pHTCap) ? (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX) : 0); + + // B2 B3 Config Mimo power save settings + pEntry->HTInfo.MimoPs = GET_HT_CAPABILITY_ELE_MIMO_PWRSAVE(pHTCap); + + // B5 B6 Config Short GI/ Long GI setting + if(pHTInfo->bCurShortGI20MHz) + pEntry->HTInfo.bShortGI20M = GET_HT_CAPABILITY_ELE_SHORT_GI20M(pHTCap)?TRUE:FALSE; + else + pEntry->HTInfo.bShortGI20M = FALSE; + + if(pHTInfo->bCurShortGI40MHz) + pEntry->HTInfo.bShortGI40M = GET_HT_CAPABILITY_ELE_SHORT_GI40M(pHTCap)?TRUE:FALSE; + else + pEntry->HTInfo.bShortGI40M = FALSE; + + // B7 B8 B9 Config STBC setting + Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_STBC, (pu1Byte)&HtSTBC); + if(!TEST_FLAG(pHTInfo->HtStbcCap, STBC_HT_ENABLE_TX)) + HtSTBC = 0; + + if(HtSTBC < GET_HT_CAPABILITY_ELE_RX_STBC(pHTCap)) + pEntry->HTInfo.STBC = HtSTBC; + else + pEntry->HTInfo.STBC = GET_HT_CAPABILITY_ELE_RX_STBC(pHTCap); + + // B11 Config A-MSDU setting + TmpValue = (GET_HT_CAPABILITY_ELE_MAX_AMSDU_SIZE(pHTCap)==0)?HT_AMSDU_SIZE_4K:HT_AMSDU_SIZE_8K; + if(pHTInfo->nAMSDU_MaxSize >= TmpValue) + pEntry->HTInfo.AMSDU_MaxSize = TmpValue; + else + pEntry->HTInfo.AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + // B12 Config DSSS/CCK mode in 40MHz mode + pEntry->HTInfo.bSupportCck = + ((pHTInfo->bCurSuppCCK)?(GET_HT_CAPABILITY_ELE_DSS_CCK(pHTCap)?TRUE:FALSE):FALSE); + + // Get operation bandwidth + if(CHNL_RUN_ABOVE_40MHZ(pMgntInfo)) + pEntry->BandWidth = GET_HT_CAPABILITY_ELE_CHL_WIDTH(pHTCap)?CHANNEL_WIDTH_40:CHANNEL_WIDTH_20; + else + pEntry->BandWidth = CHANNEL_WIDTH_20; + + // Get AMPDU Factor + if(GET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pHTCap) < pHTInfo->CurrentAMPDUFactor) + pEntry->HTInfo.AMPDU_Factor = GET_HT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(pHTCap); + else + pEntry->HTInfo.AMPDU_Factor = pHTInfo->CurrentAMPDUFactor; + + // Get AMPDU Density + if(pHTInfo->MPDU_Density >= GET_HT_CAPABILITY_ELE_MPDU_DENSITY(pHTCap)) + pEntry->HTInfo.MPDU_Density = pHTInfo->MPDU_Density; + else + pEntry->HTInfo.MPDU_Density = GET_HT_CAPABILITY_ELE_MPDU_DENSITY(pHTCap); + + // Filter MCS rate set that we support. + HTFilterMCSRate(Adapter, GET_HT_CAPABILITY_ELE_MCS(pHTCap), pEntry->HTInfo.McsRateSet); + + // This is for static mimo power save + if(pEntry->HTInfo.MimoPs <= MIMO_PS_DYNAMIC) + pMcsFilter = MCS_FILTER_1SS; + else + pMcsFilter = MCS_FILTER_ALL; + + pEntry->HTInfo.HTHighestOperaRate = HTGetHighestMCSRate(Adapter, pEntry->HTInfo.McsRateSet, pMcsFilter); + + CLEAR_FLAGS(pEntry->HTInfo.HtCurBeamform); + // B11 SU Beamformer Capable, we are Beamformee + if( TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(pHTCap)) + { + SET_FLAG(pEntry->HTInfo.HtCurBeamform, BEAMFORMING_HT_BEAMFORMER_ENABLE); + // Shit to BEAMFORMING_HT_BEAMFORMEE_CHNL_EST_CAP + SET_FLAG(pHTInfo->HtCurBeamform, GET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(pHTCap)<<6); + } + + // B12 SU Beamformee Capable, we are Beamformer + if( TEST_FLAG(pHTInfo->HtBeamformCap, BEAMFORMING_HT_BEAMFORMER_ENABLE) && + GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(pHTCap)) + { + SET_FLAG(pEntry->HTInfo.HtCurBeamform, BEAMFORMING_HT_BEAMFORMEE_ENABLE); + // Shit to BEAMFORMING_HT_BEAMFORMER_STEER_NUM + SET_FLAG(pHTInfo->HtCurBeamform, GET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(pHTCap)<<4); + } + RT_DISP(FBEAM, FBEAM_FUN, ("Entry HT Beaforming Cap = 0x%02X\n", pEntry->HTInfo.HtCurBeamform)); + + RT_PRINT_DATA( COMP_HT, DBG_TRACE, "Received HTCap in AsocReq", pHTCap, EID_HTCapability); +} + + + +// +// Description: Switch BW to 40HMz for a specific reason. It only needs to be operate if WoWLAN mode +// is enabled and we will call the function in PNP_SET_POWER OID handler. +// <Note> According to 802.11n spec chapter 11.14.12 "Switching between 40 MHz and 20 MHz", +// 2.4G AP will switch BW (40 <--> 20MHz) in some cases, and we will really switch BW +// to 20MHz if our BSS AP enable the capability in beacon. It will cause an issue that if we +// switch BW to 20MHz before the system enters WoWLAN mode, and the AP returns to 40MHz +// such that we cannot receive 40MHz data and will be deauth by AP in some cases, so we +// recover the BW to 40MHz in order to Rx 40MHz data and we should make sure that we will +// not Tx MCS rate during WoWLAN mode (now we set all the Tx packet rates to 1M, see +// FillFakeTxDescriptor_XXX().). +// +// 2012.12.20, by tynli. +// +VOID +HTRecoverBWTo40MHz( + IN PADAPTER Adapter +) +{ + CHANNEL_WIDTH RegBW = (CHANNEL_WIDTH)(CHNL_GetRegBWSupport(Adapter)?TRUE:FALSE); + + // Only processing recover flow if the STA support 40MHz bandwidth. + if(RegBW == CHANNEL_WIDTH_20) + return; + + // Only if the wireless mode is 2.4G. According to 802.11n spec chapter 11.14.12 "Switching between + // 40 MHz and 20 MHz", it mentions that AP is 2.4G mode. + if(!IS_WIRELESS_MODE_N_24G(Adapter)) + return; + + CHNL_SetBwChnlFromPeer(Adapter); +} |
