2017-01-30 18:45:14 +00:00
//============================================================
// Description:
//
// This file is for TXBF interface mechanism
//
//============================================================
# include "mp_precomp.h"
# include "../phydm_precomp.h"
# if (BEAMFORMING_SUPPORT == 1)
# if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
VOID
Beamforming_GidPAid (
PADAPTER Adapter ,
PRT_TCB pTcb
)
{
u1Byte Idx = 0 ;
u1Byte RA [ 6 ] = { 0 } ;
pu1Byte pHeader = GET_FRAME_OF_FIRST_FRAG ( Adapter , pTcb ) ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( Adapter ) ;
PDM_ODM_T pDM_Odm = & pHalData - > DM_OutSrc ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
if ( Adapter - > HardwareType < HARDWARE_TYPE_RTL8192EE )
return ;
else if ( IS_WIRELESS_MODE_N ( Adapter ) = = FALSE )
return ;
# if (SUPPORT_MU_BF == 1)
if ( pTcb - > TxBFPktType = = RT_BF_PKT_TYPE_BROADCAST_NDPA ) { /* MU NDPA */
# else
if ( 0 ) {
# endif
/* Fill G_ID and P_AID */
pTcb - > G_ID = 63 ;
if ( pBeamInfo - > FirstMUBFeeIndex < BEAMFORMEE_ENTRY_NUM ) {
pTcb - > P_AID = pBeamInfo - > BeamformeeEntry [ pBeamInfo - > FirstMUBFeeIndex ] . P_AID ;
RT_DISP ( FBEAM , FBEAM_FUN , ( " [David]@%s End, G_ID=0x%X, P_AID=0x%X \n " , __func__ , pTcb - > G_ID , pTcb - > P_AID ) ) ;
}
} else {
GET_80211_HDR_ADDRESS1 ( pHeader , & RA ) ;
// VHT SU PPDU carrying one or more group addressed MPDUs or
// Transmitting a VHT NDP intended for multiple recipients
if ( MacAddr_isBcst ( RA ) | | MacAddr_isMulticast ( RA ) | | pTcb - > macId = = MAC_ID_STATIC_FOR_BROADCAST_MULTICAST ) {
pTcb - > G_ID = 63 ;
pTcb - > P_AID = 0 ;
} else if ( ACTING_AS_AP ( Adapter ) ) {
u2Byte AID = ( u2Byte ) ( MacIdGetOwnerAssociatedClientAID ( Adapter , pTcb - > macId ) & 0x1ff ) ; /*AID[0:8]*/
/*RT_DISP(FBEAM, FBEAM_FUN, ("@%s pTcb->macId=0x%X, AID=0x%X\n", __func__, pTcb->macId, AID));*/
pTcb - > G_ID = 63 ;
if ( AID = = 0 ) /*A PPDU sent by an AP to a non associated STA*/
pTcb - > P_AID = 0 ;
else { /*Sent by an AP and addressed to a STA associated with that AP*/
u2Byte BSSID = 0 ;
GET_80211_HDR_ADDRESS2 ( pHeader , & RA ) ;
BSSID = ( ( RA [ 5 ] & 0xf0 ) > > 4 ) ^ ( RA [ 5 ] & 0xf ) ; /*BSSID[44:47] xor BSSID[40:43]*/
pTcb - > P_AID = ( AID + BSSID * 32 ) & 0x1ff ; /*(dec(A) + dec(B)*32) mod 512*/
}
} else if ( ACTING_AS_IBSS ( Adapter ) ) {
pTcb - > G_ID = 63 ;
/*P_AID for infrasturcture mode; MACID for ad-hoc mode. */
pTcb - > P_AID = pTcb - > macId ;
} else if ( MgntLinkStatusQuery ( Adapter ) ) { /*Addressed to AP*/
pTcb - > G_ID = 0 ;
GET_80211_HDR_ADDRESS1 ( pHeader , & RA ) ;
pTcb - > P_AID = RA [ 5 ] ; /*RA[39:47]*/
pTcb - > P_AID = ( pTcb - > P_AID < < 1 ) | ( RA [ 4 ] > > 7 ) ;
} else {
pTcb - > G_ID = 63 ;
pTcb - > P_AID = 0 ;
}
/*RT_DISP(FBEAM, FBEAM_FUN, ("[David]@%s End, G_ID=0x%X, P_AID=0x%X\n", __func__, pTcb->G_ID, pTcb->P_AID));*/
}
}
RT_STATUS
Beamforming_GetReportFrame (
IN PADAPTER Adapter ,
IN PRT_RFD pRfd ,
IN POCTET_STRING pPduOS
)
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( Adapter ) ;
PDM_ODM_T pDM_Odm = & pHalData - > DM_OutSrc ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL ;
pu1Byte pMIMOCtrlField , pCSIReport , pCSIMatrix ;
u1Byte Idx , Nc , Nr , CH_W ;
u2Byte CSIMatrixLen = 0 ;
ACT_PKT_TYPE pktType = ACT_PKT_TYPE_UNKNOWN ;
//Memory comparison to see if CSI report is the same with previous one
pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , Frame_Addr2 ( * pPduOS ) , & Idx ) ;
if ( pBeamformEntry = = NULL ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " Beamforming_GetReportFrame: Cannot find entry by addr \n " ) ) ;
return RT_STATUS_FAILURE ;
}
pktType = PacketGetActionFrameType ( pPduOS ) ;
//-@ Modified by David
if ( pktType = = ACT_PKT_VHT_COMPRESSED_BEAMFORMING ) {
pMIMOCtrlField = pPduOS - > Octet + 26 ;
Nc = ( ( * pMIMOCtrlField ) & 0x7 ) + 1 ;
Nr = ( ( ( * pMIMOCtrlField ) & 0x38 ) > > 3 ) + 1 ;
CH_W = ( ( ( * pMIMOCtrlField ) & 0xC0 ) > > 6 ) ;
pCSIMatrix = pMIMOCtrlField + 3 + Nc ; //24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField) +SNR(Nc=2)
CSIMatrixLen = pPduOS - > Length - 26 - 3 - Nc ;
} else if ( pktType = = ACT_PKT_HT_COMPRESSED_BEAMFORMING ) {
pMIMOCtrlField = pPduOS - > Octet + 26 ;
Nc = ( ( * pMIMOCtrlField ) & 0x3 ) + 1 ;
Nr = ( ( ( * pMIMOCtrlField ) & 0xC ) > > 2 ) + 1 ;
CH_W = ( ( ( * pMIMOCtrlField ) & 0x10 ) > > 4 ) ;
pCSIMatrix = pMIMOCtrlField + 6 + Nr ; //24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField) +SNR(Nc=2)
CSIMatrixLen = pPduOS - > Length - 26 - 6 - Nr ;
} else
return RT_STATUS_SUCCESS ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] idx=%d, pkt type=%d, Nc=%d, Nr=%d, CH_W=%d \n " , __func__ , Idx , pktType , Nc , Nr , CH_W ) ) ;
return RT_STATUS_SUCCESS ;
}
VOID
ConstructHTNDPAPacket (
PADAPTER Adapter ,
pu1Byte RA ,
pu1Byte Buffer ,
pu4Byte pLength ,
CHANNEL_WIDTH BW
)
{
u2Byte Duration = 0 ;
PMGNT_INFO pMgntInfo = & ( Adapter - > MgntInfo ) ;
OCTET_STRING pNDPAFrame , ActionContent ;
u1Byte ActionHdr [ 4 ] = { ACT_CAT_VENDOR , 0x00 , 0xe0 , 0x4c } ;
PlatformZeroMemory ( Buffer , 32 ) ;
SET_80211_HDR_FRAME_CONTROL ( Buffer , 0 ) ;
SET_80211_HDR_ORDER ( Buffer , 1 ) ;
SET_80211_HDR_TYPE_AND_SUBTYPE ( Buffer , Type_Action_No_Ack ) ;
SET_80211_HDR_ADDRESS1 ( Buffer , RA ) ;
SET_80211_HDR_ADDRESS2 ( Buffer , Adapter - > CurrentAddress ) ;
SET_80211_HDR_ADDRESS3 ( Buffer , pMgntInfo - > Bssid ) ;
Duration = 2 * aSifsTime + 40 ;
if ( BW = = CHANNEL_WIDTH_40 )
Duration + = 87 ;
else
Duration + = 180 ;
SET_80211_HDR_DURATION ( Buffer , Duration ) ;
//HT control field
SET_HT_CTRL_CSI_STEERING ( Buffer + sMacHdrLng , 3 ) ;
SET_HT_CTRL_NDP_ANNOUNCEMENT ( Buffer + sMacHdrLng , 1 ) ;
FillOctetString ( pNDPAFrame , Buffer , sMacHdrLng + sHTCLng ) ;
FillOctetString ( ActionContent , ActionHdr , 4 ) ;
PacketAppendData ( & pNDPAFrame , ActionContent ) ;
* pLength = 32 ;
}
BOOLEAN
SendFWHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u4Byte BufLen ;
pu1Byte BufAddr ;
u1Byte DescLen = 0 , Idx = 0 , NDPTxRate ;
PADAPTER pDefAdapter = GetDefaultAdapter ( Adapter ) ;
PRT_BEAMFORMING_INFO pBeamInfo = & pDM_Odm - > BeamformingInfo ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( Adapter ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start! \n " , __func__ ) ) ;
if ( pBeamformEntry = = NULL )
return FALSE ;
NDPTxRate = Beamforming_GetHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetFWBuffer ( pDefAdapter , & pTcb , & pBuf ) ) {
# if(DEV_BUS_TYPE != RT_PCI_INTERFACE)
DescLen = Adapter - > HWDescHeadLength - pHalData - > USBALLDummyLength ;
# endif
BufAddr = pBuf - > Buffer . VirtualAddress + DescLen ;
ConstructHTNDPAPacket (
Adapter ,
RA ,
BufAddr ,
& BufLen ,
BW
) ;
pTcb - > PacketLength = BufLen + DescLen ;
pTcb - > bTxEnableSwCalcDur = TRUE ;
pTcb - > BWOfPacket = BW ;
if ( ACTING_AS_IBSS ( Adapter ) | | ACTING_AS_AP ( Adapter ) )
pTcb - > G_ID = 63 ;
pTcb - > P_AID = pBeamformEntry - > P_AID ;
pTcb - > DataRate = NDPTxRate ; /*rate of NDP decide by Nr*/
Adapter - > HalFunc . CmdSendPacketHandler ( Adapter , pTcb , pBuf , pTcb - > PacketLength , DESC_PACKET_TYPE_NORMAL , FALSE ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
BOOLEAN
SendSWHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u1Byte Idx = 0 , NDPTxRate = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & pDM_Odm - > BeamformingInfo ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start! \n " , __func__ ) ) ;
NDPTxRate = Beamforming_GetHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetBuffer ( Adapter , & pTcb , & pBuf ) ) {
ConstructHTNDPAPacket (
Adapter ,
RA ,
pBuf - > Buffer . VirtualAddress ,
& pTcb - > PacketLength ,
BW
) ;
pTcb - > bTxEnableSwCalcDur = TRUE ;
pTcb - > BWOfPacket = BW ;
MgntSendPacket ( Adapter , pTcb , pBuf , pTcb - > PacketLength , NORMAL_QUEUE , NDPTxRate ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
VOID
ConstructVHTNDPAPacket (
IN PDM_ODM_T pDM_Odm ,
pu1Byte RA ,
u2Byte AID ,
pu1Byte Buffer ,
pu4Byte pLength ,
CHANNEL_WIDTH BW
)
{
u2Byte Duration = 0 ;
u1Byte Sequence = 0 ;
pu1Byte pNDPAFrame = Buffer ;
RT_NDPA_STA_INFO STAInfo ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
u1Byte Idx = 0 ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
// Frame control.
SET_80211_HDR_FRAME_CONTROL ( pNDPAFrame , 0 ) ;
SET_80211_HDR_TYPE_AND_SUBTYPE ( pNDPAFrame , Type_NDPA ) ;
SET_80211_HDR_ADDRESS1 ( pNDPAFrame , RA ) ;
SET_80211_HDR_ADDRESS2 ( pNDPAFrame , pBeamformEntry - > MyMacAddr ) ;
Duration = 2 * aSifsTime + 44 ;
if ( BW = = CHANNEL_WIDTH_80 )
Duration + = 40 ;
else if ( BW = = CHANNEL_WIDTH_40 )
Duration + = 87 ;
else
Duration + = 180 ;
SET_80211_HDR_DURATION ( pNDPAFrame , Duration ) ;
Sequence = * ( pDM_Odm - > pSoundingSeq ) < < 2 ;
ODM_MoveMemory ( pDM_Odm , pNDPAFrame + 16 , & Sequence , 1 ) ;
if ( phydm_actingDetermine ( pDM_Odm , PhyDM_ACTING_AS_IBSS ) | | phydm_actingDetermine ( pDM_Odm , PhyDM_ACTING_AS_AP ) = = FALSE )
AID = 0 ;
STAInfo . AID = AID ;
STAInfo . FeedbackType = 0 ;
STAInfo . NcIndex = 0 ;
ODM_MoveMemory ( pDM_Odm , pNDPAFrame + 17 , ( pu1Byte ) & STAInfo , 2 ) ;
* pLength = 19 ;
}
BOOLEAN
SendFWVHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN u2Byte AID ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u4Byte BufLen ;
pu1Byte BufAddr ;
u1Byte DescLen = 0 , Idx = 0 , NDPTxRate = 0 ;
PADAPTER pDefAdapter = GetDefaultAdapter ( Adapter ) ;
PRT_BEAMFORMING_INFO pBeamInfo = & pDM_Odm - > BeamformingInfo ;
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( Adapter ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start! \n " , __func__ ) ) ;
if ( pBeamformEntry = = NULL )
return FALSE ;
NDPTxRate = Beamforming_GetVHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetFWBuffer ( pDefAdapter , & pTcb , & pBuf ) ) {
# if(DEV_BUS_TYPE != RT_PCI_INTERFACE)
DescLen = Adapter - > HWDescHeadLength - pHalData - > USBALLDummyLength ;
# endif
BufAddr = pBuf - > Buffer . VirtualAddress + DescLen ;
ConstructVHTNDPAPacket (
pDM_Odm ,
RA ,
AID ,
BufAddr ,
& BufLen ,
BW
) ;
pTcb - > PacketLength = BufLen + DescLen ;
pTcb - > bTxEnableSwCalcDur = TRUE ;
pTcb - > BWOfPacket = BW ;
if ( phydm_actingDetermine ( pDM_Odm , PhyDM_ACTING_AS_IBSS ) | | phydm_actingDetermine ( pDM_Odm , PhyDM_ACTING_AS_AP ) )
pTcb - > G_ID = 63 ;
pTcb - > P_AID = pBeamformEntry - > P_AID ;
pTcb - > DataRate = NDPTxRate ; /*decide by Nr*/
Adapter - > HalFunc . CmdSendPacketHandler ( Adapter , pTcb , pBuf , pTcb - > PacketLength , DESC_PACKET_TYPE_NORMAL , FALSE ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] End, ret=%d \n " , __func__ , ret ) ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
BOOLEAN
SendSWVHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN u2Byte AID ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u1Byte Idx = 0 , NDPTxRate = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
NDPTxRate = Beamforming_GetVHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetBuffer ( Adapter , & pTcb , & pBuf ) ) {
ConstructVHTNDPAPacket (
pDM_Odm ,
RA ,
AID ,
pBuf - > Buffer . VirtualAddress ,
& pTcb - > PacketLength ,
BW
) ;
pTcb - > bTxEnableSwCalcDur = TRUE ;
pTcb - > BWOfPacket = BW ;
/*rate of NDP decide by Nr*/
MgntSendPacket ( Adapter , pTcb , pBuf , pTcb - > PacketLength , NORMAL_QUEUE , NDPTxRate ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
# ifdef SUPPORT_MU_BF
# if (SUPPORT_MU_BF == 1)
/*
// Description: On VHT GID management frame by an MU beamformee.
//
// 2015.05.20. Created by tynli.
*/
RT_STATUS
Beamforming_GetVHTGIDMgntFrame (
IN PADAPTER Adapter ,
IN PRT_RFD pRfd ,
IN POCTET_STRING pPduOS
)
{
HAL_DATA_TYPE * pHalData = GET_HAL_DATA ( Adapter ) ;
PDM_ODM_T pDM_Odm = & pHalData - > DM_OutSrc ;
RT_STATUS rtStatus = RT_STATUS_SUCCESS ;
pu1Byte pBuffer = NULL ;
pu1Byte pRaddr = NULL ;
u1Byte MemStatus [ 8 ] = { 0 } , UserPos [ 16 ] = { 0 } ;
u1Byte idx ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMER_ENTRY pBeamformEntry = & pBeamInfo - > BeamformerEntry [ pBeamInfo - > mu_ap_index ] ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] On VHT GID mgnt frame! \n " , __func__ ) ) ;
/* Check length*/
if ( pPduOS - > Length < ( FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY + 16 ) ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " Beamforming_GetVHTGIDMgntFrame(): Invalid length (%d) \n " , pPduOS - > Length ) ) ;
return RT_STATUS_INVALID_LENGTH ;
}
/* Check RA*/
pRaddr = ( pu1Byte ) ( pPduOS - > Octet ) + 4 ;
if ( ! eqMacAddr ( pRaddr , Adapter - > CurrentAddress ) ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " Beamforming_GetVHTGIDMgntFrame(): Drop because of RA error. \n " ) ) ;
return RT_STATUS_PKT_DROP ;
}
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " On VHT GID Mgnt Frame ==>: \n " , pPduOS - > Octet , pPduOS - > Length ) ;
/*Parsing Membership Status Array*/
pBuffer = pPduOS - > Octet + FRAME_OFFSET_VHT_GID_MGNT_MEMBERSHIP_STATUS_ARRAY ;
for ( idx = 0 ; idx < 8 ; idx + + ) {
MemStatus [ idx ] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS ( pBuffer + idx ) ;
pBeamformEntry - > gid_valid [ idx ] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS ( pBuffer + idx ) ;
}
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " MemStatus: " , MemStatus , 8 ) ;
/* Parsing User Position Array*/
pBuffer = pPduOS - > Octet + FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY ;
for ( idx = 0 ; idx < 16 ; idx + + ) {
UserPos [ idx ] = GET_VHT_GID_MGNT_INFO_USER_POSITION ( pBuffer + idx ) ;
pBeamformEntry - > user_position [ idx ] = GET_VHT_GID_MGNT_INFO_USER_POSITION ( pBuffer + idx ) ;
}
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " UserPos: " , UserPos , 16 ) ;
/* Group ID detail printed*/
{
u1Byte i , j ;
u1Byte tmpVal ;
u2Byte tmpVal2 ;
for ( i = 0 ; i < 8 ; i + + ) {
tmpVal = MemStatus [ i ] ;
tmpVal2 = ( ( UserPos [ i * 2 + 1 ] < < 8 ) & 0xFF00 ) + ( UserPos [ i * 2 ] & 0xFF ) ;
for ( j = 0 ; j < 8 ; j + + ) {
if ( ( tmpVal > > j ) & BIT0 ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " Use Group ID (%d), User Position (%d) \n " ,
( i * 8 + j ) , ( tmpVal2 > > 2 * j ) & 0x3 ) ) ;
}
}
}
}
/* Indicate GID frame to IHV service. */
{
u1Byte Indibuffer [ 24 ] = { 0 } ;
u1Byte Indioffset = 0 ;
PlatformMoveMemory ( Indibuffer + Indioffset , pBeamformEntry - > gid_valid , 8 ) ;
Indioffset + = 8 ;
PlatformMoveMemory ( Indibuffer + Indioffset , pBeamformEntry - > user_position , 16 ) ;
Indioffset + = 16 ;
PlatformIndicateCustomStatus (
Adapter ,
RT_CUSTOM_EVENT_VHT_RECV_GID_MGNT_FRAME ,
RT_CUSTOM_INDI_TARGET_IHV ,
Indibuffer ,
Indioffset ) ;
}
/* Config HW GID table */
halComTxbf_ConfigGtab ( pDM_Odm ) ;
return rtStatus ;
}
/*
// Description: Construct VHT Group ID (GID) management frame.
//
// 2015.05.20. Created by tynli.
*/
VOID
ConstructVHTGIDMgntFrame (
IN PDM_ODM_T pDM_Odm ,
IN pu1Byte RA ,
IN PRT_BEAMFORMEE_ENTRY pBeamformEntry ,
OUT pu1Byte Buffer ,
OUT pu4Byte pLength
)
{
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
OCTET_STRING osFTMFrame , tmp ;
FillOctetString ( osFTMFrame , Buffer , 0 ) ;
* pLength = 0 ;
ConstructMaFrameHdr (
Adapter ,
RA ,
ACT_CAT_VHT ,
ACT_VHT_GROUPID_MANAGEMENT ,
& osFTMFrame ) ;
/* Membership Status Array*/
FillOctetString ( tmp , pBeamformEntry - > gid_valid , 8 ) ;
PacketAppendData ( & osFTMFrame , tmp ) ;
/* User Position Array*/
FillOctetString ( tmp , pBeamformEntry - > user_position , 16 ) ;
PacketAppendData ( & osFTMFrame , tmp ) ;
* pLength = osFTMFrame . Length ;
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " ConstructVHTGIDMgntFrame(): \n " , Buffer , * pLength ) ;
}
BOOLEAN
SendSWVHTGIDMgntFrame (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN u1Byte Idx
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u1Byte DataRate = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = & pBeamInfo - > BeamformeeEntry [ Idx ] ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start! \n " , __func__ ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetBuffer ( Adapter , & pTcb , & pBuf ) ) {
ConstructVHTGIDMgntFrame (
pDM_Odm ,
RA ,
pBeamformEntry ,
pBuf - > Buffer . VirtualAddress ,
& pTcb - > PacketLength
) ;
pTcb - > BWOfPacket = CHANNEL_WIDTH_20 ;
DataRate = MGN_6M ;
MgntSendPacket ( Adapter , pTcb , pBuf , pTcb - > PacketLength , NORMAL_QUEUE , DataRate ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
/*
// Description: Construct VHT beamforming report poll.
//
// 2015.05.20. Created by tynli.
*/
VOID
ConstructVHTBFReportPoll (
IN PDM_ODM_T pDM_Odm ,
IN pu1Byte RA ,
OUT pu1Byte Buffer ,
OUT pu4Byte pLength
)
{
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
pu1Byte pBFRptPoll = Buffer ;
/* Frame control*/
SET_80211_HDR_FRAME_CONTROL ( pBFRptPoll , 0 ) ;
SET_80211_HDR_TYPE_AND_SUBTYPE ( pBFRptPoll , Type_Beamforming_Report_Poll ) ;
/* Duration*/
SET_80211_HDR_DURATION ( pBFRptPoll , 100 ) ;
/* RA*/
SET_VHT_BF_REPORT_POLL_RA ( pBFRptPoll , RA ) ;
/* TA*/
SET_VHT_BF_REPORT_POLL_TA ( pBFRptPoll , Adapter - > CurrentAddress ) ;
/* Feedback Segment Retransmission Bitmap*/
SET_VHT_BF_REPORT_POLL_FEEDBACK_SEG_RETRAN_BITMAP ( pBFRptPoll , 0xFF ) ;
* pLength = 17 ;
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " ConstructVHTBFReportPoll(): \n " , Buffer , * pLength ) ;
}
BOOLEAN
SendSWVHTBFReportPoll (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN BOOLEAN bFinalPoll
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u1Byte Idx = 0 , DataRate = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start! \n " , __func__ ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetBuffer ( Adapter , & pTcb , & pBuf ) ) {
ConstructVHTBFReportPoll (
pDM_Odm ,
RA ,
pBuf - > Buffer . VirtualAddress ,
& pTcb - > PacketLength
) ;
pTcb - > bTxEnableSwCalcDur = TRUE ; /* <tynli_note> need?*/
pTcb - > BWOfPacket = CHANNEL_WIDTH_20 ;
if ( bFinalPoll )
pTcb - > TxBFPktType = RT_BF_PKT_TYPE_FINAL_BF_REPORT_POLL ;
else
pTcb - > TxBFPktType = RT_BF_PKT_TYPE_BF_REPORT_POLL ;
DataRate = MGN_6M ; /* Legacy OFDM rate*/
MgntSendPacket ( Adapter , pTcb , pBuf , pTcb - > PacketLength , NORMAL_QUEUE , DataRate ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " SendSWVHTBFReportPoll(): \n " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
/*
// Description: Construct VHT MU NDPA packet.
// <Note> We should combine this function with ConstructVHTNDPAPacket() in the future.
//
// 2015.05.21. Created by tynli.
*/
VOID
ConstructVHTMUNDPAPacket (
IN PDM_ODM_T pDM_Odm ,
IN CHANNEL_WIDTH BW ,
OUT pu1Byte Buffer ,
OUT pu4Byte pLength
)
{
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
u2Byte Duration = 0 ;
u1Byte Sequence = 0 ;
pu1Byte pNDPAFrame = Buffer ;
RT_NDPA_STA_INFO STAInfo ;
u1Byte idx ;
u1Byte DestAddr [ 6 ] = { 0 } ;
PRT_BEAMFORMEE_ENTRY pEntry = NULL ;
/* Fill the first MU BFee entry (STA1) MAC addr to destination address then
HW will change A1 to broadcast addr . 2015.05 .28 . Suggested by SD1 Chunchu . */
for ( idx = 0 ; idx < BEAMFORMEE_ENTRY_NUM ; idx + + ) {
pEntry = & ( pBeamInfo - > BeamformeeEntry [ idx ] ) ;
if ( pEntry - > is_mu_sta ) {
cpMacAddr ( DestAddr , pEntry - > MacAddr ) ;
break ;
}
}
if ( pEntry = = NULL )
return ;
/* Frame control.*/
SET_80211_HDR_FRAME_CONTROL ( pNDPAFrame , 0 ) ;
SET_80211_HDR_TYPE_AND_SUBTYPE ( pNDPAFrame , Type_NDPA ) ;
SET_80211_HDR_ADDRESS1 ( pNDPAFrame , DestAddr ) ;
SET_80211_HDR_ADDRESS2 ( pNDPAFrame , pEntry - > MyMacAddr ) ;
/*--------------------------------------------*/
/* <Note> Need to modify "Duration" to MU consideration. */
Duration = 2 * aSifsTime + 44 ;
if ( BW = = CHANNEL_WIDTH_80 )
Duration + = 40 ;
else if ( BW = = CHANNEL_WIDTH_40 )
Duration + = 87 ;
else
Duration + = 180 ;
/*--------------------------------------------*/
SET_80211_HDR_DURATION ( pNDPAFrame , Duration ) ;
Sequence = * ( pDM_Odm - > pSoundingSeq ) < < 2 ;
ODM_MoveMemory ( pDM_Odm , pNDPAFrame + 16 , & Sequence , 1 ) ;
* pLength = 17 ;
/* Construct STA info. for multiple STAs*/
for ( idx = 0 ; idx < BEAMFORMEE_ENTRY_NUM ; idx + + ) {
pEntry = & ( pBeamInfo - > BeamformeeEntry [ idx ] ) ;
if ( pEntry - > is_mu_sta ) {
STAInfo . AID = pEntry - > AID ;
STAInfo . FeedbackType = 1 ; /* 1'b1: MU*/
STAInfo . NcIndex = 0 ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Get BeamformeeEntry idx(%d), AID =%d \n " , __func__ , idx , pEntry - > AID ) ) ;
ODM_MoveMemory ( pDM_Odm , pNDPAFrame + ( * pLength ) , ( pu1Byte ) & STAInfo , 2 ) ;
* pLength + = 2 ;
}
}
}
BOOLEAN
SendSWVHTMUNDPAPacket (
IN PVOID pDM_VOID ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PRT_TCB pTcb ;
PRT_TX_LOCAL_BUFFER pBuf ;
BOOLEAN ret = TRUE ;
u1Byte NDPTxRate = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PADAPTER Adapter = pBeamInfo - > SourceAdapter ;
NDPTxRate = MGN_VHT2SS_MCS0 ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
PlatformAcquireSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( MgntGetBuffer ( Adapter , & pTcb , & pBuf ) ) {
ConstructVHTMUNDPAPacket (
pDM_Odm ,
BW ,
pBuf - > Buffer . VirtualAddress ,
& pTcb - > PacketLength
) ;
pTcb - > bTxEnableSwCalcDur = TRUE ;
pTcb - > BWOfPacket = BW ;
pTcb - > TxBFPktType = RT_BF_PKT_TYPE_BROADCAST_NDPA ;
/*rate of NDP decide by Nr*/
MgntSendPacket ( Adapter , pTcb , pBuf , pTcb - > PacketLength , NORMAL_QUEUE , NDPTxRate ) ;
} else
ret = FALSE ;
PlatformReleaseSpinLock ( Adapter , RT_TX_SPINLOCK ) ;
if ( ret )
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " " , pBuf - > Buffer . VirtualAddress , pTcb - > PacketLength ) ;
return ret ;
}
# endif /*#if (SUPPORT_MU_BF == 1)*/
# endif /*#ifdef SUPPORT_MU_BF*/
# elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
u4Byte
Beamforming_GetReportFrame (
IN PVOID pDM_VOID ,
union recv_frame * precv_frame
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
u4Byte ret = _SUCCESS ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = NULL ;
pu1Byte pframe = precv_frame - > u . hdr . rx_data ;
u4Byte frame_len = precv_frame - > u . hdr . len ;
pu1Byte TA ;
u1Byte Idx , offset ;
/*DBG_871X("beamforming_get_report_frame\n");*/
/*Memory comparison to see if CSI report is the same with previous one*/
TA = GetAddr2Ptr ( pframe ) ;
pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , TA , & Idx ) ;
if ( pBeamformEntry - > BeamformEntryCap & BEAMFORMER_CAP_VHT_SU )
offset = 31 ; /*24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/
else if ( pBeamformEntry - > BeamformEntryCap & BEAMFORMER_CAP_HT_EXPLICIT )
offset = 34 ; /*24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/
else
return ret ;
/*DBG_871X("%s MacId %d offset=%d\n", __FUNCTION__, pBeamformEntry->mac_id, offset);*/
return ret ;
}
BOOLEAN
SendFWHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
struct rtw_ieee80211_hdr * pwlanhdr ;
struct xmit_priv * pxmitpriv = & ( Adapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & Adapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u1Byte ActionHdr [ 4 ] = { ACT_CAT_VENDOR , 0x00 , 0xe0 , 0x4c } ;
u1Byte * pframe ;
u2Byte * fctrl ;
u2Byte duration = 0 ;
u1Byte aSifsTime = 0 , NDPTxRate = 0 , Idx = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL ) {
DBG_871X ( " %s, alloc mgnt frame fail \n " , __func__ ) ;
return _FALSE ;
}
//update attribute
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( Adapter , pattrib ) ;
pattrib - > qsel = QSLT_BEACON ;
NDPTxRate = Beamforming_GetHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
pattrib - > rate = NDPTxRate ;
pattrib - > bwmode = BW ;
pattrib - > order = 1 ;
pattrib - > subtype = WIFI_ACTION_NOACK ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & pwlanhdr - > frame_ctl ;
* ( fctrl ) = 0 ;
SetOrderBit ( pframe ) ;
SetFrameSubType ( pframe , WIFI_ACTION_NOACK ) ;
_rtw_memcpy ( pwlanhdr - > addr1 , RA , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr2 , pBeamformEntry - > MyMacAddr , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
if ( pmlmeext - > cur_wireless_mode = = WIRELESS_11B )
aSifsTime = 10 ;
else
aSifsTime = 16 ;
duration = 2 * aSifsTime + 40 ;
if ( BW = = CHANNEL_WIDTH_40 )
duration + = 87 ;
else
duration + = 180 ;
SetDuration ( pframe , duration ) ;
//HT control field
SET_HT_CTRL_CSI_STEERING ( pframe + 24 , 3 ) ;
SET_HT_CTRL_NDP_ANNOUNCEMENT ( pframe + 24 , 1 ) ;
_rtw_memcpy ( pframe + 28 , ActionHdr , 4 ) ;
pattrib - > pktlen = 32 ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( Adapter , pmgntframe ) ;
return _TRUE ;
}
BOOLEAN
SendSWHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
struct rtw_ieee80211_hdr * pwlanhdr ;
struct xmit_priv * pxmitpriv = & ( Adapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & Adapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
u1Byte ActionHdr [ 4 ] = { ACT_CAT_VENDOR , 0x00 , 0xe0 , 0x4c } ;
pu1Byte pframe ;
pu2Byte fctrl ;
u2Byte duration = 0 ;
u1Byte aSifsTime = 0 , NDPTxRate = 0 , Idx = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
NDPTxRate = Beamforming_GetHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL ) {
DBG_871X ( " %s, alloc mgnt frame fail \n " , __func__ ) ;
return _FALSE ;
}
/*update attribute*/
pattrib = & pmgntframe - > attrib ;
update_mgntframe_attrib ( Adapter , pattrib ) ;
pattrib - > qsel = QSLT_MGNT ;
pattrib - > rate = NDPTxRate ;
pattrib - > bwmode = BW ;
pattrib - > order = 1 ;
pattrib - > subtype = WIFI_ACTION_NOACK ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & pwlanhdr - > frame_ctl ;
* ( fctrl ) = 0 ;
SetOrderBit ( pframe ) ;
SetFrameSubType ( pframe , WIFI_ACTION_NOACK ) ;
_rtw_memcpy ( pwlanhdr - > addr1 , RA , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr2 , pBeamformEntry - > MyMacAddr , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr3 , get_my_bssid ( & ( pmlmeinfo - > network ) ) , ETH_ALEN ) ;
if ( pmlmeext - > cur_wireless_mode = = WIRELESS_11B )
aSifsTime = 10 ;
else
aSifsTime = 16 ;
duration = 2 * aSifsTime + 40 ;
if ( BW = = CHANNEL_WIDTH_40 )
duration + = 87 ;
else
duration + = 180 ;
SetDuration ( pframe , duration ) ;
/*HT control field*/
SET_HT_CTRL_CSI_STEERING ( pframe + 24 , 3 ) ;
SET_HT_CTRL_NDP_ANNOUNCEMENT ( pframe + 24 , 1 ) ;
_rtw_memcpy ( pframe + 28 , ActionHdr , 4 ) ;
pattrib - > pktlen = 32 ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( Adapter , pmgntframe ) ;
return _TRUE ;
}
BOOLEAN
SendFWVHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN u2Byte AID ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
struct rtw_ieee80211_hdr * pwlanhdr ;
struct xmit_priv * pxmitpriv = & ( Adapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & Adapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct mlme_priv * pmlmepriv = & ( Adapter - > mlmepriv ) ;
pu1Byte pframe ;
pu2Byte fctrl ;
u2Byte duration = 0 ;
u1Byte sequence = 0 , aSifsTime = 0 , NDPTxRate = 0 , Idx = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
RT_NDPA_STA_INFO sta_info ;
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL ) {
DBG_871X ( " %s, alloc mgnt frame fail \n " , __func__ ) ;
return _FALSE ;
}
//update attribute
pattrib = & pmgntframe - > attrib ;
_rtw_memcpy ( pattrib - > ra , RA , ETH_ALEN ) ;
update_mgntframe_attrib ( Adapter , pattrib ) ;
pattrib - > qsel = QSLT_BEACON ;
NDPTxRate = Beamforming_GetVHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
pattrib - > rate = NDPTxRate ;
pattrib - > bwmode = BW ;
pattrib - > subtype = WIFI_NDPA ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & pwlanhdr - > frame_ctl ;
* ( fctrl ) = 0 ;
SetFrameSubType ( pframe , WIFI_NDPA ) ;
_rtw_memcpy ( pwlanhdr - > addr1 , RA , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr2 , pBeamformEntry - > MyMacAddr , ETH_ALEN ) ;
if ( IsSupported5G ( pmlmeext - > cur_wireless_mode ) | | IsSupportedHT ( pmlmeext - > cur_wireless_mode ) )
aSifsTime = 16 ;
else
aSifsTime = 10 ;
duration = 2 * aSifsTime + 44 ;
if ( BW = = CHANNEL_WIDTH_80 )
duration + = 40 ;
else if ( BW = = CHANNEL_WIDTH_40 )
duration + = 87 ;
else
duration + = 180 ;
SetDuration ( pframe , duration ) ;
sequence = pBeamInfo - > SoundingSequence < < 2 ;
if ( pBeamInfo - > SoundingSequence > = 0x3f )
pBeamInfo - > SoundingSequence = 0 ;
else
pBeamInfo - > SoundingSequence + + ;
_rtw_memcpy ( pframe + 16 , & sequence , 1 ) ;
if ( ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE ) | | ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE ) )
AID = 0 ;
sta_info . AID = AID ;
sta_info . FeedbackType = 0 ;
sta_info . NcIndex = 0 ;
_rtw_memcpy ( pframe + 17 , ( u8 * ) & sta_info , 2 ) ;
pattrib - > pktlen = 19 ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( Adapter , pmgntframe ) ;
return _TRUE ;
}
BOOLEAN
SendSWVHTNDPAPacket (
IN PVOID pDM_VOID ,
IN pu1Byte RA ,
IN u2Byte AID ,
IN CHANNEL_WIDTH BW
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
struct xmit_frame * pmgntframe ;
struct pkt_attrib * pattrib ;
struct rtw_ieee80211_hdr * pwlanhdr ;
struct xmit_priv * pxmitpriv = & ( Adapter - > xmitpriv ) ;
struct mlme_ext_priv * pmlmeext = & Adapter - > mlmeextpriv ;
struct mlme_ext_info * pmlmeinfo = & ( pmlmeext - > mlmext_info ) ;
struct mlme_priv * pmlmepriv = & ( Adapter - > mlmepriv ) ;
RT_NDPA_STA_INFO ndpa_sta_info ;
u1Byte NDPTxRate = 0 , sequence = 0 , aSifsTime = 0 , Idx = 0 ;
pu1Byte pframe ;
pu2Byte fctrl ;
u2Byte duration = 0 ;
PRT_BEAMFORMING_INFO pBeamInfo = & ( pDM_Odm - > BeamformingInfo ) ;
PRT_BEAMFORMEE_ENTRY pBeamformEntry = phydm_Beamforming_GetBFeeEntryByAddr ( pDM_Odm , RA , & Idx ) ;
NDPTxRate = Beamforming_GetVHTNDPTxRate ( pDM_Odm , pBeamformEntry - > CompSteeringNumofBFer ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] NDPTxRate =%d \n " , __func__ , NDPTxRate ) ) ;
pmgntframe = alloc_mgtxmitframe ( pxmitpriv ) ;
if ( pmgntframe = = NULL ) {
DBG_871X ( " %s, alloc mgnt frame fail \n " , __func__ ) ;
return _FALSE ;
}
/*update attribute*/
pattrib = & pmgntframe - > attrib ;
_rtw_memcpy ( pattrib - > ra , RA , ETH_ALEN ) ;
update_mgntframe_attrib ( Adapter , pattrib ) ;
pattrib - > qsel = QSLT_MGNT ;
pattrib - > rate = NDPTxRate ;
pattrib - > bwmode = BW ;
pattrib - > subtype = WIFI_NDPA ;
_rtw_memset ( pmgntframe - > buf_addr , 0 , WLANHDR_OFFSET + TXDESC_OFFSET ) ;
pframe = ( u8 * ) ( pmgntframe - > buf_addr ) + TXDESC_OFFSET ;
pwlanhdr = ( struct rtw_ieee80211_hdr * ) pframe ;
fctrl = & pwlanhdr - > frame_ctl ;
* ( fctrl ) = 0 ;
SetFrameSubType ( pframe , WIFI_NDPA ) ;
_rtw_memcpy ( pwlanhdr - > addr1 , RA , ETH_ALEN ) ;
_rtw_memcpy ( pwlanhdr - > addr2 , pBeamformEntry - > MyMacAddr , ETH_ALEN ) ;
if ( IsSupported5G ( pmlmeext - > cur_wireless_mode ) | | IsSupportedHT ( pmlmeext - > cur_wireless_mode ) )
aSifsTime = 16 ;
else
aSifsTime = 10 ;
duration = 2 * aSifsTime + 44 ;
if ( BW = = CHANNEL_WIDTH_80 )
duration + = 40 ;
else if ( BW = = CHANNEL_WIDTH_40 )
duration + = 87 ;
else
duration + = 180 ;
SetDuration ( pframe , duration ) ;
sequence = pBeamInfo - > SoundingSequence < < 2 ;
if ( pBeamInfo - > SoundingSequence > = 0x3f )
pBeamInfo - > SoundingSequence = 0 ;
else
pBeamInfo - > SoundingSequence + + ;
_rtw_memcpy ( pframe + 16 , & sequence , 1 ) ;
if ( ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_ADHOC_STATE ) | | ( ( pmlmeinfo - > state & 0x03 ) = = WIFI_FW_AP_STATE ) )
AID = 0 ;
ndpa_sta_info . AID = AID ;
ndpa_sta_info . FeedbackType = 0 ;
ndpa_sta_info . NcIndex = 0 ;
_rtw_memcpy ( pframe + 17 , ( u8 * ) & ndpa_sta_info , 2 ) ;
pattrib - > pktlen = 19 ;
pattrib - > last_txcmdsz = pattrib - > pktlen ;
dump_mgntframe ( Adapter , pmgntframe ) ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] [%d] \n " , __func__ , __LINE__ ) ) ;
return _TRUE ;
}
# endif
VOID
Beamforming_GetNDPAFrame (
IN PVOID pDM_VOID ,
# if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
IN OCTET_STRING pduOS
# elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
union recv_frame * precv_frame
# endif
)
{
PDM_ODM_T pDM_Odm = ( PDM_ODM_T ) pDM_VOID ;
PADAPTER Adapter = pDM_Odm - > Adapter ;
pu1Byte TA ;
u1Byte Idx , Sequence ;
# if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
pu1Byte pNDPAFrame = pduOS . Octet ;
# elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
pu1Byte pNDPAFrame = precv_frame - > u . hdr . rx_data ;
# endif
PRT_BEAMFORMER_ENTRY pBeamformerEntry = NULL ; /*Modified By Jeffery @2014-10-29*/
# if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
RT_DISP_DATA ( FBEAM , FBEAM_DATA , " Beamforming_GetNDPAFrame \n " , pduOS . Octet , pduOS . Length ) ;
if ( IsCtrlNDPA ( pNDPAFrame ) = = FALSE )
# elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
if ( GetFrameSubType ( pNDPAFrame ) ! = WIFI_NDPA )
# endif
return ;
else if ( ! ( pDM_Odm - > SupportICType & ( ODM_RTL8812 | ODM_RTL8821 ) ) ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] not 8812 or 8821A, return \n " , __func__ ) ) ;
return ;
}
# if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
TA = Frame_Addr2 ( pduOS ) ;
# elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
TA = GetAddr2Ptr ( pNDPAFrame ) ;
# endif
/*Remove signaling TA. */
TA [ 0 ] = TA [ 0 ] & 0xFE ;
pBeamformerEntry = phydm_Beamforming_GetBFerEntryByAddr ( pDM_Odm , TA , & Idx ) ; // Modified By Jeffery @2014-10-29
/*Break options for Clock Reset*/
if ( pBeamformerEntry = = NULL )
return ;
else if ( ! ( pBeamformerEntry - > BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU ) )
return ;
/*LogSuccess: As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is NO LONGER needed !2015-04-10, Jeffery*/
/*ClockResetTimes: While BFer entry always doesn't receive our CSI, clock will reset again and again.So ClockResetTimes is limited to 5 times.2015-04-13, Jeffery*/
else if ( ( pBeamformerEntry - > LogSuccess = = 1 ) | | ( pBeamformerEntry - > ClockResetTimes = = 5 ) ) {
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, LogSuccess=%d, ClockResetTimes=%d, clock reset is no longer needed. \n " ,
__func__ , pBeamformerEntry - > LogSeq , pBeamformerEntry - > PreLogSeq , pBeamformerEntry - > LogRetryCnt , pBeamformerEntry - > LogSuccess , pBeamformerEntry - > ClockResetTimes ) ) ;
return ;
}
Sequence = ( pNDPAFrame [ 16 ] ) > > 2 ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Start, Sequence=%d, LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, ClockResetTimes=%d, LogSuccess=%d \n " ,
__func__ , Sequence , pBeamformerEntry - > LogSeq , pBeamformerEntry - > PreLogSeq , pBeamformerEntry - > LogRetryCnt , pBeamformerEntry - > ClockResetTimes , pBeamformerEntry - > LogSuccess ) ) ;
if ( ( pBeamformerEntry - > LogSeq ! = 0 ) & & ( pBeamformerEntry - > PreLogSeq ! = 0 ) ) {
/*Success condition*/
if ( ( pBeamformerEntry - > LogSeq ! = Sequence ) & & ( pBeamformerEntry - > PreLogSeq ! = pBeamformerEntry - > LogSeq ) ) {
/* break option for clcok reset, 2015-03-30, Jeffery */
pBeamformerEntry - > LogRetryCnt = 0 ;
/*As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is no longer needed.*/
/*That is, LogSuccess is NOT needed to be reset to zero, 2015-04-13, Jeffery*/
pBeamformerEntry - > LogSuccess = 1 ;
} else { /*Fail condition*/
if ( pBeamformerEntry - > LogRetryCnt = = 5 ) {
pBeamformerEntry - > ClockResetTimes + + ;
pBeamformerEntry - > LogRetryCnt = 0 ;
ODM_RT_TRACE ( pDM_Odm , PHYDM_COMP_TXBF , ODM_DBG_LOUD , ( " [%s] Clock Reset!!! ClockResetTimes=%d \n " ,
__func__ , pBeamformerEntry - > ClockResetTimes ) ) ;
HalComTxbf_Set ( pDM_Odm , TXBF_SET_SOUNDING_CLK , NULL ) ;
} else
pBeamformerEntry - > LogRetryCnt + + ;
}
}
/*Update LogSeq & PreLogSeq*/
pBeamformerEntry - > PreLogSeq = pBeamformerEntry - > LogSeq ;
pBeamformerEntry - > LogSeq = Sequence ;
}
# endif