mirror of
https://github.com/YikeStone/MT7601u.git
synced 2025-08-02 10:54:08 +05:30
1103 lines
26 KiB
C
1103 lines
26 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:
|
|
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 */
|
|
|