/**************************************************************************** * 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: tdls.h Abstract: Revision History: Who When What --------- ---------- ---------------------------------------------- Arvin Tai 17-04-2009 created for 802.11z */ #ifdef DOT11Z_TDLS_SUPPORT #include "rt_config.h" /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertActField( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT8 Category, IN UINT8 ActCode) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &Category, 1, &ActCode, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertStatusCode( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT16 StatusCode) { ULONG TempLen; StatusCode = cpu2le16(StatusCode); MakeOutgoingFrame( pFrameBuf, &TempLen, 2, &StatusCode, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertReasonCode( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT16 ReasonCode) { ULONG TempLen; ReasonCode = cpu2le16(ReasonCode); MakeOutgoingFrame( pFrameBuf, &TempLen, 2, &ReasonCode, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertDialogToken( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT8 DialogToken) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertLinkIdentifierIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PUCHAR pInitAddr, IN PUCHAR pRespAddr) { ULONG TempLen; UCHAR TDLS_IE = IE_TDLS_LINK_IDENTIFIER; UCHAR TDLS_IE_LEN = TDLS_ELM_LEN_LINK_IDENTIFIER; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &TDLS_IE, 1, &TDLS_IE_LEN, 6, pAd->CommonCfg.Bssid, 6, pInitAddr, 6, pRespAddr, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertCapIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 2, &pAd->StaActive.CapabilityInfo, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertSSIDIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &SsidIe, 1, &pAd->CommonCfg.SsidLen, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertSupportRateIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &SupRateIe, 1, &pAd->StaActive.SupRateLen, pAd->StaActive.SupRateLen, pAd->StaActive.SupRate, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertCountryIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { // add country IE, power constraint IE if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); // prepare channel information { UCHAR regclass; UCHAR RegluatoryRxtIdent = 221; UCHAR CoverageClass = 0; regclass = TDLS_GetRegulatoryClass(pAd, pAd->CommonCfg.RegTransmitSetting.field.BW, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &RegluatoryRxtIdent, 1, ®class, 1, &CoverageClass, END_OF_ARGS); TmpLen2 += TmpLen; } // need to do the padding bit check, and concatenate it if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2 + 4; MakeOutgoingFrame(pFrameBuf, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pFrameBuf, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } *pFrameLen = *pFrameLen + TmpLen; } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertSupportChannelIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { if (pAd->StaCfg.TdlsInfo.TdlsChSwitchSupp) { ULONG TempLen; UCHAR SupportChIe = IE_SUPP_CHANNELS; UCHAR FirstChannel = 1; UCHAR NumOfCh = 11; UCHAR Length = 2; if ((pAd->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11B) || (pAd->CommonCfg.PhyMode == PHY_11G) || (pAd->CommonCfg.PhyMode == PHY_11BGN_MIXED)) { MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &SupportChIe, 1, &Length, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } else if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)) { ULONG TempLen1; FirstChannel = 36; NumOfCh = 8; Length = 4; MakeOutgoingFrame(pFrameBuf, &TempLen1, 1, &SupportChIe, 1, &Length, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen1; FirstChannel = 149; NumOfCh = 4; MakeOutgoingFrame((pFrameBuf + TempLen1), &TempLen, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } else if ((pAd->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11BGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)) { ULONG TempLen1, TempLen2; Length = 6; MakeOutgoingFrame(pFrameBuf, &TempLen1, 1, &SupportChIe, 1, &Length, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen1; FirstChannel = 36; NumOfCh = 8; MakeOutgoingFrame((pFrameBuf + TempLen1), &TempLen2, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen2; FirstChannel = 149; NumOfCh = 4; MakeOutgoingFrame((pFrameBuf + TempLen1 + TempLen2), &TempLen, 1, &FirstChannel, 1, &NumOfCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertExtRateIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; if (pAd->StaActive.ExtRateLen != 0) { MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &ExtRateIe, 1, &pAd->StaActive.ExtRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.ExtRate, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertQosCapIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; /* if (WMODE_CAP_N(pAd->CommonCfg.PhyMode) || (pAd->CommonCfg.bWmmCapable)) */ if (pAd->CommonCfg.bWmmCapable) { UCHAR QOS_CAP_IE = 46; UCHAR QOS_CAP_IE_LEN = 1; QBSS_STA_INFO_PARM QosInfo; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); if (pAd->StaCfg.UapsdInfo.bAPSDCapable) { QosInfo.UAPSD_AC_BE = pAd->CommonCfg.TDLS_bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.TDLS_bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.TDLS_bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.TDLS_bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.TDLS_MaxSPLength; } MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &QOS_CAP_IE, 1, &QOS_CAP_IE_LEN, 1, &QosInfo, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertWMMIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN BOOLEAN bEnable) { ULONG TempLen; if (pAd->CommonCfg.bWmmCapable) { QBSS_STA_INFO_PARM QosInfo; UCHAR WmeParmIe[8] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); if (pAd->StaCfg.UapsdInfo.bAPSDCapable) { if (bEnable) { QosInfo.UAPSD_AC_BE = pAd->CommonCfg.TDLS_bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.TDLS_bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.TDLS_bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.TDLS_bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.TDLS_MaxSPLength; } DBGPRINT(RT_DEBUG_ERROR, ("tdls uapsd> UAPSD %d %d %d %d %d!\n", pAd->CommonCfg.TDLS_bAPSDAC_BE, pAd->CommonCfg.TDLS_bAPSDAC_BK, pAd->CommonCfg.TDLS_bAPSDAC_VI, pAd->CommonCfg.TDLS_bAPSDAC_VO, pAd->CommonCfg.TDLS_MaxSPLength)); } MakeOutgoingFrame(pFrameBuf, &TempLen, 8, WmeParmIe, 1, &QosInfo, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertEDCAParameterSetIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PRT_802_11_TDLS pTDLS) { ULONG TempLen; if ((WMODE_CAP_N(pAd->CommonCfg.PhyMode) || (pAd->CommonCfg.bWmmCapable)) && (pTDLS->bWmmCapable)) { USHORT idx; /* When the BSS is QoS capable, then the BSS QoS parameters shall be * used by the TDLS peer STAs on the AP's channel, and the values * indicated inside the TDLS Setup Confirm frame apply only for the * off-channel. The EDCA parameters for the off-channel should be * the same as those on the AP's channel when QoS is supported by the BSS, * because this may optimize the channel switching process. */ UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; /* Reset EdcaParam */ NdisZeroMemory(&pTDLS->EdcaParm, sizeof(EDCA_PARM)); /* Enable EdcaParm used in non-QBSS. */ pTDLS->EdcaParm.bValid = TRUE; pTDLS->EdcaParm.bQAck = FALSE; pTDLS->EdcaParm.bQueueRequest = FALSE; pTDLS->EdcaParm.bTxopRequest = FALSE; WmeParmIe[2] = ((UCHAR)pTDLS->EdcaParm.bQAck << 4) + ((UCHAR)pTDLS->EdcaParm.bQueueRequest << 5) + ((UCHAR)pTDLS->EdcaParm.bTxopRequest << 6); pTDLS->EdcaParm.EdcaUpdateCount = 1; WmeParmIe[8] = pTDLS->EdcaParm.EdcaUpdateCount & 0x0f; WmeParmIe[8] |= pTDLS->EdcaParm.bAPSDCapable << 7; /* By hardcoded */ pTDLS->EdcaParm.Aifsn[0] = 3; pTDLS->EdcaParm.Aifsn[1] = 7; pTDLS->EdcaParm.Aifsn[2] = 2; pTDLS->EdcaParm.Aifsn[3] = 2; pTDLS->EdcaParm.Cwmin[0] = 4; pTDLS->EdcaParm.Cwmin[1] = 4; pTDLS->EdcaParm.Cwmin[2] = 3; pTDLS->EdcaParm.Cwmin[3] = 2; pTDLS->EdcaParm.Cwmax[0] = 10; pTDLS->EdcaParm.Cwmax[1] = 10; pTDLS->EdcaParm.Cwmax[2] = 4; pTDLS->EdcaParm.Cwmax[3] = 3; pTDLS->EdcaParm.Txop[0] = 0; pTDLS->EdcaParm.Txop[1] = 0; pTDLS->EdcaParm.Txop[2] = 96; pTDLS->EdcaParm.Txop[3] = 48; for (idx=QID_AC_BE; idx<=QID_AC_VO; idx++) { WmeParmIe[10+ (idx*4)] = (idx << 5) + /* b5-6 is ACI */ ((UCHAR)pTDLS->EdcaParm.bACM[idx] << 4) + /* b4 is ACM */ (pTDLS->EdcaParm.Aifsn[idx] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (idx*4)] = (pTDLS->EdcaParm.Cwmax[idx] << 4) + /* b5-8 is CWMAX */ (pTDLS->EdcaParm.Cwmin[idx] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (idx*4)] = (UCHAR)(pTDLS->EdcaParm.Txop[idx] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (idx*4)] = (UCHAR)(pTDLS->EdcaParm.Txop[idx] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pFrameBuf, &TempLen, 26, WmeParmIe, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertWMMParameterIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) || (pAd->CommonCfg.bWmmCapable)) { QBSS_STA_INFO_PARM QosInfo; ULONG TempLen; USHORT idx; /* When the BSS is QoS capable, then the BSS QoS parameters shall be * used by the TDLS peer STAs on the AP's channel, and the values * indicated inside the TDLS Setup Confirm frame apply only for the * off-channel. The EDCA parameters for the off-channel should be * the same as those on the AP's channel when QoS is supported by the BSS, * because this may optimize the channel switching process. */ UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM)); if (pAd->StaCfg.UapsdInfo.bAPSDCapable) { QosInfo.UAPSD_AC_BE = pAd->CommonCfg.TDLS_bAPSDAC_BE; QosInfo.UAPSD_AC_BK = pAd->CommonCfg.TDLS_bAPSDAC_BK; QosInfo.UAPSD_AC_VI = pAd->CommonCfg.TDLS_bAPSDAC_VI; QosInfo.UAPSD_AC_VO = pAd->CommonCfg.TDLS_bAPSDAC_VO; QosInfo.MaxSPLength = pAd->CommonCfg.TDLS_MaxSPLength; DBGPRINT(RT_DEBUG_ERROR, ("tdls uapsd> UAPSD %d %d %d %d %d!\n", pAd->CommonCfg.TDLS_bAPSDAC_BE, pAd->CommonCfg.TDLS_bAPSDAC_BK, pAd->CommonCfg.TDLS_bAPSDAC_VI, pAd->CommonCfg.TDLS_bAPSDAC_VO, pAd->CommonCfg.TDLS_MaxSPLength)); } WmeParmIe[8] |= *(PUCHAR)&QosInfo; for (idx=QID_AC_BE; idx<=QID_AC_VO; idx++) { WmeParmIe[10+ (idx*4)] = (idx << 5) + // b5-6 is ACI ((UCHAR)pAd->CommonCfg.APEdcaParm.bACM[idx] << 4) + // b4 is ACM (pAd->CommonCfg.APEdcaParm.Aifsn[idx] & 0x0f); // b0-3 is AIFSN WmeParmIe[11+ (idx*4)] = (pAd->CommonCfg.APEdcaParm.Cwmax[idx] << 4) + // b5-8 is CWMAX (pAd->CommonCfg.APEdcaParm.Cwmin[idx] & 0x0f); // b0-3 is CWMIN WmeParmIe[12+ (idx*4)] = (UCHAR)(pAd->CommonCfg.APEdcaParm.Txop[idx] & 0xff); // low byte of TXOP WmeParmIe[13+ (idx*4)] = (UCHAR)(pAd->CommonCfg.APEdcaParm.Txop[idx] >> 8); // high byte of TXOP } MakeOutgoingFrame(pFrameBuf, &TempLen, 26, WmeParmIe, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } #ifdef DOT11_N_SUPPORT /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertHtCapIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; if (WMODE_CAP_N(pAd->CommonCfg.PhyMode)) { UCHAR HtLen; HT_CAPABILITY_IE HtCapabilityTmp; HtLen = sizeof(HT_CAPABILITY_IE); #ifndef RT_BIG_ENDIAN NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); HtCapabilityTmp.HtCapInfo.ChannelWidth = pAd->CommonCfg.RegTransmitSetting.field.BW; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS); #else NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE)); NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); HtCapabilityTmp.HtCapInfo.ChannelWidth = pAd->CommonCfg.RegTransmitSetting.field.BW; *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif *pFrameLen = *pFrameLen + TempLen; } return; } #ifdef DOT11N_DRAFT3 /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ /* 20/40 BSS Coexistence (7.3.2.61) */ VOID TDLS_InsertBSSCoexistenceIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; //if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1) { UCHAR Length = 1; BSS_2040_COEXIST_IE BssCoexistence; memset(&BssCoexistence, 0, sizeof(BSS_2040_COEXIST_IE)); BssCoexistence.field.InfoReq = 1; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &BssCoexistIe, 1, &Length, 1, &BssCoexistence.word, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } return; } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertExtCapIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; UCHAR Length = sizeof(EXT_CAP_INFO_ELEMENT); EXT_CAP_INFO_ELEMENT extCapInfo; Length = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, Length); #ifdef DOT11N_DRAFT3 if ((pAd->CommonCfg.bBssCoexEnable == TRUE) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14)) { extCapInfo.BssCoexistMgmtSupport = 1; } #endif // DOT11N_DRAFT3 // if (pAd->StaCfg.TdlsInfo.TdlsChSwitchSupp) extCapInfo.TDLSChSwitchSupport = 1; if (pAd->StaCfg.UapsdInfo.bAPSDCapable) extCapInfo.UAPSDBufSTASupport = 1; extCapInfo.TDLSSupport = 1; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &ExtCapIe, 1, &Length, sizeof(EXT_CAP_INFO_ELEMENT), &extCapInfo, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertFTIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT8 Length, IN FT_MIC_CTR_FIELD MICCtr, IN PUINT8 pMic, IN PUINT8 pANonce, IN PUINT8 pSNonce) { ULONG TempLen; UINT16 MICCtrBuf; UCHAR FTIE = IE_FT_FTIE; MICCtrBuf = cpu2le16(MICCtr.word); MakeOutgoingFrame( pFrameBuf, &TempLen, 1, &FTIE, 1, &Length, 2, (PUCHAR)&MICCtrBuf, 16, (PUCHAR)pMic, 32, (PUCHAR)pANonce, 32, (PUCHAR)pSNonce, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertTimeoutIntervalIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN FT_TIMEOUT_INTERVAL_TYPE Type, IN UINT32 TimeOutValue) { ULONG TempLen; UINT8 Length; UINT8 TimeOutIntervalIE; UINT8 TimeoutType; UINT32 TimeoutValueBuf; Length = 5; TimeOutIntervalIE = IE_FT_TIMEOUT_INTERVAL; TimeoutType = Type; TimeoutValueBuf = cpu2le32(TimeOutValue); MakeOutgoingFrame( pFrameBuf, &TempLen, 1, &TimeOutIntervalIE, 1, &Length, 1, (PUCHAR)&TimeoutType, 4, (PUCHAR)&TimeoutValueBuf, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertTargetChannel( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT8 TargetCh) { ULONG TempLen; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &TargetCh, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertRegulatoryClass( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UINT8 TargetCh, IN UINT8 ChWidth) { ULONG TempLen; UCHAR regclass; UCHAR BandWidth = 0; if (ChWidth != 0) BandWidth = 1; regclass = TDLS_GetRegulatoryClass(pAd, BandWidth, TargetCh); MakeOutgoingFrame(pFrameBuf, &TempLen, 1, ®class, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_InsertSecondaryChOffsetIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UCHAR Offset) { ULONG TempLen; UCHAR length = 1; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &NewExtChanIe, 1, &length, 1, &Offset, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } VOID TDLS_InsertChannelSwitchTimingIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN USHORT SwitchTime, IN USHORT SwitchTimeOut) { ULONG TempLen; UCHAR TDLS_IE = IE_TDLS_CHANNEL_SWITCH_TIMING; UCHAR TDLS_IE_LEN = 4; UINT16 SwitchTimeBuf = cpu2le16(SwitchTime); UINT16 SwitchTimeOutBuf = cpu2le16(SwitchTimeOut); MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &TDLS_IE, 1, &TDLS_IE_LEN, 2, &SwitchTimeBuf, 2, &SwitchTimeOutBuf, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } /* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_SupportedRegulatoryClasses( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen) { ULONG TempLen; UCHAR TDLS_IE = IE_SUPP_REG_CLASS; //UCHAR Length = 6; //UCHAR SuppClassesList[] = {1,2,3,32,33}; UCHAR Length = 16; UCHAR SuppClassesList[] = {1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33}; UCHAR regclass; regclass = TDLS_GetRegulatoryClass(pAd, pAd->CommonCfg.RegTransmitSetting.field.BW, pAd->CommonCfg.Channel); MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &TDLS_IE, 1, &Length, 1, ®class, 15, SuppClassesList, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; return; } #ifdef UAPSD_SUPPORT VOID TDLS_InsertPuBufferStatus( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN UCHAR *pPeerMac) { MAC_TABLE_ENTRY *pMacEntry; ULONG TempLen; UINT8 Length; UINT8 IeIdPuBufferStatus; UINT8 PuBufferStatus; UINT8 FlgIsAnyPktForBK, FlgIsAnyPktForBE; UINT8 FlgIsAnyPktForVI, FlgIsAnyPktForVO; /* get pEntry */ pMacEntry = MacTableLookup(pAd, pPeerMac); if (pMacEntry == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("tdls_cmd> ERROR! No such peer in %s!\n", __FUNCTION__)); return; } /* init */ Length = 1; IeIdPuBufferStatus = IE_TDLS_PU_BUFFER_STATUS; PuBufferStatus = 0; /* get queue status */ UAPSD_QueueStatusGet(pAd, pMacEntry, &FlgIsAnyPktForBK, &FlgIsAnyPktForBE, &FlgIsAnyPktForVI, &FlgIsAnyPktForVO); PuBufferStatus |= (FlgIsAnyPktForBK == TRUE)? 0x01: 0x00; PuBufferStatus |= (FlgIsAnyPktForBE == TRUE)? 0x02: 0x00; PuBufferStatus |= (FlgIsAnyPktForVI == TRUE)? 0x04: 0x00; PuBufferStatus |= (FlgIsAnyPktForVO == TRUE)? 0x08: 0x00; /* init element */ MakeOutgoingFrame( pFrameBuf, &TempLen, 1, &IeIdPuBufferStatus, 1, &Length, 1, &PuBufferStatus, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; } #endif /* UAPSD_SUPPORT */ #endif /* DOT11Z_TDLS_SUPPORT */