1110 lines
29 KiB
C
1110 lines
29 KiB
C
/*
|
|
***************************************************************************
|
|
* Ralink Tech Inc.
|
|
* 4F, No. 2 Technology 5th Rd.
|
|
* Science-based Industrial Park
|
|
* Hsin-chu, Taiwan, R.O.C.
|
|
*
|
|
* (c) Copyright 2002-2004, 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:
|
|
rtmp_mcu.c
|
|
|
|
Abstract:
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
*/
|
|
|
|
#ifdef MT76XX_BTCOEX_SUPPORT
|
|
#include "rt_config.h"
|
|
|
|
VOID SendAndesCoexFrameInfo(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN ULONG TriggerNumber)
|
|
{
|
|
INT ret;
|
|
struct cmd_msg *msg;
|
|
//struct CMD_UNIT CmdUnit;
|
|
COEX_PROTECTION_FRAME_INFO coexProtectionFrameInfo = {0};
|
|
USHORT coexProtectionFrameInfoLength = 0;
|
|
|
|
printk("%s: -->\n", __FUNCTION__);
|
|
|
|
coexProtectionFrameInfo.CoexOperation = TypeProtectionFrame;
|
|
coexProtectionFrameInfo.Triggernumber = pAd->NullFrameSpace[TriggerNumber].Triggernumber;
|
|
coexProtectionFrameInfo.Valid = pAd->NullFrameSpace[TriggerNumber].Valid;
|
|
coexProtectionFrameInfo.NodeType = pAd->NullFrameSpace[TriggerNumber].NodeType;
|
|
coexProtectionFrameInfo.BssHashID = pAd->NullFrameSpace[TriggerNumber].BssHashID;
|
|
coexProtectionFrameInfo.FrameType = pAd->NullFrameSpace[TriggerNumber].FrameType;
|
|
|
|
coexProtectionFrameInfoLength = sizeof(coexProtectionFrameInfo);
|
|
|
|
printk("%s: Triggernumber = %d, Valid = %d, NodeType = %d, BssHashID = %d, , FrameType = %d, CmdParametersLength = %d\n",
|
|
__FUNCTION__,
|
|
coexProtectionFrameInfo.Triggernumber,
|
|
coexProtectionFrameInfo.Valid,
|
|
coexProtectionFrameInfo.NodeType,
|
|
coexProtectionFrameInfo.BssHashID,
|
|
coexProtectionFrameInfo.FrameType,
|
|
coexProtectionFrameInfoLength
|
|
);
|
|
|
|
msg = AndesAllocCmdMsg(pAd, coexProtectionFrameInfoLength);
|
|
AndesInitCmdMsg(msg, PKT_CMD_TYPE_COEX_OP, FALSE, 0, TRUE, FALSE, 0, NULL, NULL);
|
|
AndesAppendCmdMsg(msg, (char *)&coexProtectionFrameInfo,coexProtectionFrameInfoLength);
|
|
ret = AndesSendCmdMsg(pAd, msg);
|
|
#if 0
|
|
TxPktCmd(pAd, PKT_CMD_TYPE_COEX_OP, NO_PKT_CMD_RSP_EVENT,
|
|
&coexProtectionFrameInfo, coexProtectionFrameInfoLength, 0);
|
|
|
|
NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
|
|
CmdUnit.u.ANDES.Type = PKT_CMD_TYPE_COEX_OP;
|
|
CmdUnit.u.ANDES.CmdPayloadLen = coexProtectionFrameInfoLength;
|
|
CmdUnit.u.ANDES.CmdPayload = &coexProtectionFrameInfo;
|
|
|
|
CmdUnit.u.ANDES.NeedRsp = FALSE;
|
|
CmdUnit.u.ANDES.NeedWait = FALSE;
|
|
CmdUnit.u.ANDES.Timeout = 0;
|
|
|
|
ret = AsicSendCmdToAndes(pAd, &CmdUnit);
|
|
#endif
|
|
printk("%s: <--\n", __FUNCTION__);
|
|
|
|
}
|
|
|
|
|
|
VOID UpdateAndesNullFrameSpace(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
char iter = 0;
|
|
for (iter=0; iter < NULLFRAMESPACE; iter++ )
|
|
{
|
|
if (pAd->NullFrameSpace[iter].Occupied != 0 )
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Coex: Send protection frame %d\n",iter));
|
|
SendAndesCoexFrameInfo(pAd, iter);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID SendAndesAFH(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR BBPCurrentBW,
|
|
IN UCHAR Channel,
|
|
IN UCHAR CentralChannel,
|
|
IN BOOLEAN Disable,
|
|
IN ULONG BssHashID)
|
|
{
|
|
|
|
COEX_AFH coexAFH = {0};
|
|
USHORT coexAFHLength = 0;
|
|
INT ret;
|
|
//struct CMD_UNIT CmdUnit;
|
|
struct cmd_msg *msg;
|
|
printk("%s: -->\n", __FUNCTION__);
|
|
coexAFH.CoexOperation = TypeAFH;
|
|
if (!IS_MT76XXBTCOMBO(pAd))
|
|
return;
|
|
|
|
if (BBPCurrentBW == BW_40)
|
|
{
|
|
coexAFH.BW= BW_40 + COEXNOZEROSHIFT ;
|
|
coexAFH.Channel= CentralChannel;
|
|
}
|
|
else if (BBPCurrentBW == BW_20)
|
|
{
|
|
coexAFH.BW= BW_20 + COEXNOZEROSHIFT;
|
|
coexAFH.Channel= Channel;
|
|
}
|
|
else if (BBPCurrentBW == BW_80)
|
|
{
|
|
coexAFH.BW= BW_80 + COEXNOZEROSHIFT;
|
|
coexAFH.Channel= Channel;
|
|
}
|
|
|
|
if (Channel > 14)
|
|
{
|
|
coexAFH.BW= 0;
|
|
}
|
|
|
|
if (Disable == FALSE)
|
|
{
|
|
coexAFH.LinkStatus = COEX_WIFI_LINK_UP;
|
|
}
|
|
else
|
|
{
|
|
coexAFH.LinkStatus = COEX_WIFI_LINK_DOWN;
|
|
}
|
|
|
|
|
|
coexAFH.BssHashID = BssHashID;
|
|
|
|
coexAFHLength = sizeof(coexAFH);
|
|
|
|
msg = AndesAllocCmdMsg(pAd, coexAFHLength);
|
|
AndesInitCmdMsg(msg, PKT_CMD_TYPE_COEX_OP, FALSE, 0, TRUE, FALSE, 0, NULL, NULL);
|
|
AndesAppendCmdMsg(msg, (char *)&coexAFH,coexAFHLength);
|
|
ret = AndesSendCmdMsg(pAd, msg);
|
|
|
|
printk("%s: LinkStatus = %d, BW = %d, Channel = %d\n, BssHashID = %d PktLength = %d\n",
|
|
__FUNCTION__,
|
|
coexAFH.LinkStatus,
|
|
coexAFH.BW,
|
|
coexAFH.Channel,
|
|
coexAFH.BssHashID,
|
|
coexAFHLength
|
|
);
|
|
#if 0
|
|
NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
|
|
CmdUnit.u.ANDES.Type = PKT_CMD_TYPE_COEX_OP;
|
|
CmdUnit.u.ANDES.CmdPayloadLen = coexAFHLength;
|
|
CmdUnit.u.ANDES.CmdPayload = &coexAFH;
|
|
|
|
CmdUnit.u.ANDES.NeedRsp = FALSE;
|
|
CmdUnit.u.ANDES.NeedWait = FALSE;
|
|
CmdUnit.u.ANDES.Timeout = 0;
|
|
|
|
ret = AsicSendCmdToAndes(pAd, &CmdUnit);
|
|
|
|
TxPktCmd(pAd, PKT_CMD_TYPE_COEX_OP, NO_PKT_CMD_RSP_EVENT,
|
|
&coexAFH, coexAFHLength, 0);
|
|
#endif
|
|
printk("%s: <--\n", __FUNCTION__);
|
|
|
|
}
|
|
|
|
|
|
VOID BtAFHCtl(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR BBPCurrentBW,
|
|
IN UCHAR Channel,
|
|
IN UCHAR CentralChannel,
|
|
IN BOOLEAN Disable)
|
|
{
|
|
UCHAR Kstart = 0, Kend = 0;
|
|
BT_FUN_INFO_STRUC btFunInfo={0};
|
|
|
|
if (!(IS_MT76XXBTCOMBO(pAd) || Channel>14))
|
|
return;
|
|
|
|
if (BBPCurrentBW == BW_40)
|
|
{
|
|
if (CentralChannel <= 4 )
|
|
{
|
|
Kstart = 0;
|
|
Kend = 53;
|
|
}
|
|
else if (CentralChannel >=10)
|
|
{
|
|
Kstart = 25;
|
|
Kend = 78;
|
|
}
|
|
else
|
|
{
|
|
Kstart = 2 + (CentralChannel-5)*5;
|
|
Kend = Kstart + 55;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Channel <= 3 )
|
|
{
|
|
Kstart = 0;
|
|
Kend = 47;
|
|
}
|
|
else if (Channel >=10)
|
|
{
|
|
Kstart = 31;
|
|
Kend = 78;
|
|
}
|
|
else
|
|
{
|
|
Kstart = 1 + (Channel-4)*5;
|
|
Kend = Kstart + 48;
|
|
}
|
|
}
|
|
|
|
RTMP_IO_READ32(pAd, BT_FUN_INFO, &btFunInfo.word);
|
|
btFunInfo.word &= ~(0x3FFFFFFF); //Clear Power and AFH but keep active bit
|
|
if (!Disable)
|
|
{
|
|
btFunInfo.field.AFH_START_CH = Kstart;
|
|
btFunInfo.field.AFH_END_CH = Kend;
|
|
/* These Code and Definition are gone
|
|
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
|
|
//0x04 // -14
|
|
btFunInfo.field.BTPower0 = 0x0c; //-8
|
|
else
|
|
btFunInfo.field.BTPower0 = 0x1c; //-2
|
|
*/
|
|
}
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("%s: COEX AFH Start Ch = %d, AFH End Ch = %d, Channel = %d, CentralChannel = %d\n",
|
|
__FUNCTION__,
|
|
btFunInfo.field.AFH_START_CH,
|
|
btFunInfo.field.AFH_END_CH,
|
|
Channel,
|
|
CentralChannel));
|
|
|
|
RTMP_IO_WRITE32(pAd, BT_FUN_INFO, btFunInfo.word);
|
|
// Hook andes AFH command
|
|
|
|
// High BT Priority Mode
|
|
//RTMP_IO_WRITE32(pAd, 0x5c, 0x8000);
|
|
}
|
|
|
|
|
|
ULONG QueryHashID(
|
|
IN PRTMP_ADAPTER pAd,
|
|
PUCHAR pAddr,
|
|
BOOLEAN RemoveBSS)
|
|
{
|
|
ULONG HashIdx;
|
|
UCHAR i,j = 0;
|
|
|
|
for(j = 1; j < NULLFRAMESPACE; j++)
|
|
{
|
|
if (MAC_ADDR_EQUAL(&pAd->HASH_BSSID[j][0],pAddr))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: j = %d\n",j));
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Find BSSID Address = %02X:%02X:%02X:%02X:%02X:%02X\n",pAd->HASH_BSSID[j][0],pAd->HASH_BSSID[j][1],
|
|
pAd->HASH_BSSID[j][2],pAd->HASH_BSSID[j][3],
|
|
pAd->HASH_BSSID[j][4], pAd->HASH_BSSID[j][5]));
|
|
HashIdx = j;
|
|
if (RemoveBSS == TRUE)
|
|
{
|
|
pAd->HASH_BSSID[j][MAC_ADDR_LEN] = 0;
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Remove BSSID Address = %02X:%02X:%02X:%02X:%02X:%02X\n",pAd->HASH_BSSID[j][0],pAd->HASH_BSSID[j][1],
|
|
pAd->HASH_BSSID[j][2],pAd->HASH_BSSID[j][3],
|
|
pAd->HASH_BSSID[j][4], pAd->HASH_BSSID[j][5]));
|
|
|
|
}
|
|
return HashIdx;
|
|
}
|
|
//MAC_ADDR_EQUAL(&pAd->HASH_BSSID[j][0],)
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX:Miss search j = %d\n",j));
|
|
}
|
|
for(j = 1; j < NULLFRAMESPACE; j++)
|
|
{
|
|
if (pAd->HASH_BSSID[j][MAC_ADDR_LEN] == 0)
|
|
{
|
|
COPY_MAC_ADDR(&pAd->HASH_BSSID[j][0], pAddr);
|
|
pAd->HASH_BSSID[j][MAC_ADDR_LEN] = 1;
|
|
HashIdx = j;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: free space j = %d\n",j));
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Insert MAC Address = %02X:%02X:%02X:%02X:%02X:%02X\n",pAd->HASH_BSSID[j][0],pAd->HASH_BSSID[j][1],
|
|
pAd->HASH_BSSID[j][2],pAd->HASH_BSSID[j][3],
|
|
pAd->HASH_BSSID[j][4], pAd->HASH_BSSID[j][5]));
|
|
return HashIdx;
|
|
}
|
|
//debug if there is an overflow issue
|
|
if (j == (NULLFRAMESPACE -1 ))
|
|
{
|
|
COPY_MAC_ADDR(&pAd->HASH_BSSID[j][0], pAddr);
|
|
pAd->HASH_BSSID[1][MAC_ADDR_LEN] = 1;
|
|
pAd->HASH_BSSID[2][MAC_ADDR_LEN] = 0;
|
|
pAd->HASH_BSSID[3][MAC_ADDR_LEN] = 0;
|
|
HashIdx = 1;
|
|
|
|
return HashIdx;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID RemoveProtectionFrameSpace(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PUCHAR pAddr
|
|
)
|
|
{
|
|
ULONG BssHashID = QueryHashID(pAd, pAddr, FALSE);
|
|
UCHAR iter = 0;
|
|
for (iter=0; iter < NULLFRAMESPACE; iter++ )
|
|
{
|
|
if (pAd->NullFrameSpace[iter].BssHashID = BssHashID)
|
|
{
|
|
pAd->NullFrameSpace[iter].Occupied = FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID FillProtectionFrameSpace(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN ULONG Triggernumber,
|
|
IN ULONG Valid,
|
|
IN ULONG NodeType,
|
|
IN PUCHAR pAddr,
|
|
IN ULONG FrameType
|
|
)
|
|
{
|
|
pAd->NullFrameSpace[Triggernumber].Occupied = TRUE;
|
|
pAd->NullFrameSpace[Triggernumber].Triggernumber = Triggernumber;
|
|
pAd->NullFrameSpace[Triggernumber].Valid = Valid;
|
|
pAd->NullFrameSpace[Triggernumber].NodeType = NodeType;
|
|
pAd->NullFrameSpace[Triggernumber].BssHashID = QueryHashID(pAd, pAddr, FALSE);
|
|
pAd->NullFrameSpace[Triggernumber].FrameType= FrameType;
|
|
|
|
}
|
|
|
|
|
|
VOID PrepareProtectionFrame(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN ULONG Type,
|
|
IN ULONG Number,
|
|
IN ULONG NAV,
|
|
IN ULONG OPMode,
|
|
IN PMAC_TABLE_ENTRY pEntry)
|
|
{
|
|
HEADER_802_11 ProtectionFrame ={0};
|
|
TXWI_STRUC ProtectionFrameTxWI ={0};
|
|
TXWI_STRUC *pTxWI;
|
|
UCHAR *ptr = NULL;
|
|
UINT i = 0;
|
|
//PHY_CFG PhyCfg = {0};
|
|
UCHAR Wcid = 0;
|
|
UCHAR Length = 0;
|
|
ULONG FrameAddress = 0;
|
|
BOOLEAN Ack = FALSE;
|
|
MAC_TX_INFO mac_info;
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("==>PrepareProtectionFrame\n"));
|
|
|
|
NdisZeroMemory(&ProtectionFrameTxWI,pAd->chipCap.TXWISize);
|
|
NdisZeroMemory(&ProtectionFrame, sizeof(HEADER_802_11));
|
|
|
|
//ProtectionFrame.FC.Type = BTYPE_DATA;
|
|
switch (Type){
|
|
|
|
case CTSTOSELF:
|
|
ProtectionFrame.FC.Type =FC_TYPE_CNTL;
|
|
ProtectionFrame.FC.SubType = SUBTYPE_CTS;
|
|
break;
|
|
|
|
case CFEND:
|
|
ProtectionFrame.FC.Type = FC_TYPE_CNTL;
|
|
ProtectionFrame.FC.SubType = SUBTYPE_CFEND;
|
|
break;
|
|
|
|
case POWERSAVE1:
|
|
ProtectionFrame.FC.Type =FC_TYPE_DATA;
|
|
ProtectionFrame.FC.SubType = SUBTYPE_DATA_NULL;
|
|
ProtectionFrame.FC.PwrMgmt = PWR_SAVE;
|
|
ProtectionFrame.FC.ToDs = 1;
|
|
ProtectionFrame.FC.FrDs = 0;
|
|
break;
|
|
|
|
case POWERSAVE0:
|
|
ProtectionFrame.FC.Type =FC_TYPE_DATA;
|
|
ProtectionFrame.FC.SubType = SUBTYPE_DATA_NULL;
|
|
ProtectionFrame.FC.PwrMgmt = PWR_ACTIVE;
|
|
ProtectionFrame.FC.ToDs = 1;
|
|
ProtectionFrame.FC.FrDs = 0;
|
|
break;
|
|
}
|
|
|
|
if (Type == CTSTOSELF)
|
|
{
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr1, pAd->CurrentAddress);
|
|
ProtectionFrame.Duration = (USHORT)NAV;
|
|
Wcid = 0xff;
|
|
Length = 10;
|
|
}
|
|
else if (Type == CFEND)
|
|
{
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr1, BROADCAST_ADDR);
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr2, pAd->CurrentAddress);
|
|
ProtectionFrame.Duration = 0;
|
|
Wcid = 0xff;
|
|
Length = 16;
|
|
}
|
|
else
|
|
{
|
|
pAd->Sequence = (pAd->Sequence+1) & MAXSEQ;//((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
|
|
ProtectionFrame.Sequence = pAd->Sequence;
|
|
ProtectionFrame.Duration = RTMPCalcDuration(pAd, RATE_1, 14);
|
|
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr1, pEntry->Addr);
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr2, pAd->CurrentAddress);
|
|
COPY_MAC_ADDR(ProtectionFrame.Addr3, pAd->CommonCfg.Bssid);
|
|
Ack =TRUE;
|
|
Wcid = BSSID_WCID;
|
|
Length = sizeof(HEADER_802_11) ;
|
|
}
|
|
|
|
pTxWI = (TXWI_STRUC *)&ProtectionFrameTxWI;
|
|
|
|
NdisZeroMemory((UCHAR *)&mac_info, sizeof(mac_info));
|
|
mac_info.FRAG = FALSE;
|
|
|
|
mac_info.CFACK = FALSE;
|
|
mac_info.InsTimestamp = FALSE;
|
|
mac_info.AMPDU = FALSE;
|
|
|
|
mac_info.BM = IS_BM_MAC_ADDR(ProtectionFrame.Addr1);
|
|
mac_info.Ack = FALSE; // why don't use "Ack" paramter checked in previous?
|
|
mac_info.NSeq = FALSE;
|
|
mac_info.BASize = 0;
|
|
|
|
mac_info.WCID = pEntry->Aid;
|
|
mac_info.Length = Length;
|
|
mac_info.PID = 0;
|
|
|
|
mac_info.TID = 0;
|
|
mac_info.TxRate = (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS;
|
|
mac_info.Txopmode = IFS_HTTXOP;
|
|
mac_info.Preamble = LONG_PREAMBLE;
|
|
mac_info.q_idx = Q_IDX_AC0;
|
|
|
|
write_tmac_info(pAd, (UCHAR *)pTxWI, &mac_info, &pAd->CommonCfg.MlmeTransmit);
|
|
|
|
pTxWI->TXWI_N.PHYMODE = MODE_CCK;
|
|
pTxWI->TXWI_N.MCS= 0;
|
|
|
|
if (Number == 0)
|
|
{
|
|
FrameAddress = HW_NULL_BASE + 0x4000;
|
|
}
|
|
else if (Number == 1)
|
|
{
|
|
FrameAddress = HW_NULL2_BASE + 0x4000;
|
|
}
|
|
else
|
|
{
|
|
//trigger number 0/1 is belong to null number address
|
|
//Beacon address from D000
|
|
FrameAddress = 0xD000 + (0x200*(Number-2));
|
|
}
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Protection FrameAddress =%x \n",FrameAddress));
|
|
//
|
|
// Move TXWI and frame content to on-chip memory
|
|
//
|
|
ptr = (PUCHAR)&ProtectionFrameTxWI;
|
|
for (i=0; i<pAd->chipCap.TXWISize; i+=4) // 24-byte TXINFO field
|
|
{
|
|
RTMP_IO_WRITE32(pAd, FrameAddress + i, *((UINT32 *)ptr));
|
|
ptr +=4 ;
|
|
}
|
|
|
|
|
|
ptr = (PUCHAR)&ProtectionFrame;
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Type =%x \n",Type));
|
|
hex_dump("PrepareProtectionFrame" ,ptr, Length);
|
|
for (i = 0; i < Length; i+=4)
|
|
{
|
|
RTMP_IO_WRITE32(pAd, FrameAddress + pAd->chipCap.TXWISize + i, *((UINT32 *)ptr));
|
|
ptr +=4;
|
|
}
|
|
}
|
|
|
|
|
|
VOID InvalidProtectionFrameSpace(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PUCHAR pAddr
|
|
)
|
|
{
|
|
ULONG BssHashID = QueryHashID(pAd, pAddr, FALSE);
|
|
UCHAR iter = 0;
|
|
for (iter=0; iter < NULLFRAMESPACE; iter++ )
|
|
{
|
|
if (pAd->NullFrameSpace[iter].BssHashID = BssHashID)
|
|
{
|
|
pAd->NullFrameSpace[iter].Valid= FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
UCHAR CheckAvailableNullFrameSpace(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
char iter = 0;
|
|
for (iter=0; iter < NULLFRAMESPACE; iter++ )
|
|
{
|
|
if ((pAd->NullFrameSpace[iter].Occupied) == 0 )
|
|
{
|
|
return iter;
|
|
}
|
|
|
|
}
|
|
|
|
return NULLFRAMESPACE;
|
|
|
|
}
|
|
|
|
|
|
VOID EstablishFrameBundle(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PUCHAR pAddr,
|
|
IN ULONG OPMode,
|
|
IN PMAC_TABLE_ENTRY pEntry
|
|
)
|
|
{
|
|
|
|
UCHAR n0, n1, n2, n3 = 0;
|
|
n0 = CheckAvailableNullFrameSpace(pAd);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Protection FrameBaseNumber=%d\n",n0));
|
|
if (n0 != NULLFRAMESPACE)
|
|
{
|
|
PrepareProtectionFrame(pAd, CTSTOSELF, n0, 2500, OPMode, pEntry);
|
|
FillProtectionFrameSpace(pAd, n0, PROTECTIONFRAMEREADY , OPMode, pAddr, CTSTOSELF);
|
|
}
|
|
n1 = CheckAvailableNullFrameSpace(pAd);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Protection FrameBaseNumber=%d\n",n1));
|
|
if (n1 != NULLFRAMESPACE)
|
|
{
|
|
PrepareProtectionFrame(pAd, POWERSAVE1, n1, 0, OPMode, pEntry);
|
|
FillProtectionFrameSpace(pAd, n1, PROTECTIONFRAMEREADY , OPMode, pAddr, POWERSAVE1);
|
|
}
|
|
n2 = CheckAvailableNullFrameSpace(pAd);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Protection FrameBaseNumber=%d\n",n2));
|
|
if (n2 != NULLFRAMESPACE)
|
|
{
|
|
PrepareProtectionFrame(pAd, CFEND, n2, 0, OPMode, pEntry);
|
|
FillProtectionFrameSpace(pAd, n2, PROTECTIONFRAMEREADY , OPMode, pAddr, CFEND);
|
|
}
|
|
n3 = CheckAvailableNullFrameSpace(pAd);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Protection FrameBaseNumber=%d\n",n3));
|
|
if (n3 != NULLFRAMESPACE)
|
|
{
|
|
PrepareProtectionFrame(pAd, POWERSAVE0, n3, 0, OPMode, pEntry);
|
|
FillProtectionFrameSpace(pAd, n3, PROTECTIONFRAMEREADY , OPMode, pAddr, POWERSAVE0);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
VOID SendAndesWLANStatus(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR WlanStatus,
|
|
IN ULONG PrivilegeTime,
|
|
IN ULONG BssHashID
|
|
)
|
|
{
|
|
|
|
COEX_WLAN_STATUS wlanStatus = {0};
|
|
USHORT wlanStatusLength = 0;
|
|
INT ret;
|
|
//struct CMD_UNIT CmdUnit;
|
|
struct cmd_msg *msg;
|
|
printk("%s: -->\n", __FUNCTION__);
|
|
wlanStatus.CoexOperation = TypeWiFiStatus;
|
|
wlanStatus.WLANStatus= WlanStatus;
|
|
wlanStatus.PrivilegeTime= PrivilegeTime;
|
|
wlanStatus.BssHashID = BssHashID;
|
|
wlanStatusLength = sizeof(wlanStatus);
|
|
|
|
|
|
msg = AndesAllocCmdMsg(pAd, wlanStatusLength);
|
|
AndesInitCmdMsg(msg, PKT_CMD_TYPE_COEX_OP, FALSE, 0, FALSE, FALSE, 0, NULL, NULL);
|
|
AndesAppendCmdMsg(msg, (char *)&wlanStatus, wlanStatusLength);
|
|
ret = AndesSendCmdMsg(pAd, msg);
|
|
|
|
printk("%s: CoexOperation = %d, WlanStatus = %d, PrivilegeTime = %d,BssHashID = %d, PktLength = %d\n",
|
|
__FUNCTION__,
|
|
wlanStatus.CoexOperation,
|
|
wlanStatus.WLANStatus,
|
|
wlanStatus.PrivilegeTime,
|
|
wlanStatus.BssHashID,
|
|
wlanStatusLength
|
|
);
|
|
#if 0
|
|
NdisZeroMemory(&CmdUnit, sizeof(CmdUnit));
|
|
CmdUnit.u.ANDES.Type = PKT_CMD_TYPE_COEX_OP;
|
|
CmdUnit.u.ANDES.CmdPayloadLen = wlanStatusLength;
|
|
CmdUnit.u.ANDES.CmdPayload = &wlanStatus;
|
|
|
|
CmdUnit.u.ANDES.NeedRsp = FALSE;
|
|
CmdUnit.u.ANDES.NeedWait = FALSE;
|
|
CmdUnit.u.ANDES.Timeout = 0;
|
|
|
|
ret = AsicSendCmdToAndes(pAd, &CmdUnit);
|
|
|
|
TxPktCmd(pAd, PKT_CMD_TYPE_COEX_OP, NO_PKT_CMD_RSP_EVENT,
|
|
&wlanStatus, wlanStatusLength, 0);
|
|
#endif
|
|
printk("%s: <--\n", __FUNCTION__);
|
|
|
|
}
|
|
|
|
|
|
VOID CoexFDDRXAGCGain(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN CHAR rssi)
|
|
{
|
|
///the following code block shoule not be enabled.
|
|
#if 0
|
|
CHAR LMthreshold, MHthreshold = 0;
|
|
UCHAR idx = 0;
|
|
UINT32 bbp_val, bbp_reg = AGC1_R8;
|
|
|
|
if (pAd->coexRXManualAGCGain.bEnable)
|
|
{
|
|
LMthreshold = pAd->coexRXManualAGCGain.LMthreshold;
|
|
MHthreshold = pAd->coexRXManualAGCGain.MHthreshold;
|
|
}
|
|
else
|
|
{
|
|
LMthreshold = -pAd->CommonCfg.CoexRXAGCLMTreshold;
|
|
MHthreshold = -pAd->CommonCfg.CoexRXAGCMHTreshold;
|
|
}
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: LMthreshold = %d, MHthreshold = %d\n",LMthreshold,MHthreshold));
|
|
if (pAd->coexRXManualAGCGain.bStopAGC)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Stop AGC "));
|
|
}
|
|
else
|
|
{
|
|
|
|
if (rssi > LMthreshold)
|
|
{
|
|
RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
|
|
BTCOEX_BB_BITWISE_WRITE(bbp_val, (BIT6+BIT7), BIT6);
|
|
RTMP_BBP_IO_WRITE32(pAd, bbp_reg, bbp_val);
|
|
}
|
|
else if ((rssi <= LMthreshold) &&(rssi > MHthreshold))
|
|
{
|
|
RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
|
|
BTCOEX_BB_BITWISE_WRITE(bbp_val, (BIT6+BIT7), BIT7);
|
|
RTMP_BBP_IO_WRITE32(pAd, bbp_reg, bbp_val);
|
|
}
|
|
else
|
|
{
|
|
RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
|
|
BTCOEX_BB_BITWISE_WRITE(bbp_val, (BIT6+BIT7), (BIT6+BIT7));
|
|
RTMP_BBP_IO_WRITE32(pAd, bbp_reg, bbp_val);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
VOID CoexTDDRXAGCGain(
|
|
IN PRTMP_ADAPTER pAd
|
|
)
|
|
{
|
|
UCHAR idx = 0;
|
|
UINT32 bbp_val, bbp_reg = AGC1_R8;
|
|
|
|
if (pAd->coexRXManualAGCGain.bStopAGC)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: Stop AGC "));
|
|
}
|
|
else
|
|
{
|
|
RTMP_BBP_IO_READ32(pAd, bbp_reg, &bbp_val);
|
|
BTCOEX_BB_BITWISE_WRITE(bbp_val, (BIT6+BIT7), (BIT6+BIT7));
|
|
RTMP_BBP_IO_WRITE32(pAd, bbp_reg, bbp_val);
|
|
}
|
|
}
|
|
|
|
|
|
VOID TDDFDDCoexBACapability(
|
|
IN PRTMP_ADAPTER pAd,
|
|
UCHAR CoexMode )
|
|
{
|
|
//PRTMP_PORT pPort = RTMPGetActivePort(pAd);
|
|
MAC_TABLE_ENTRY *pEntry;
|
|
pEntry = &pAd->MacTab.Content[BSSID_WCID];
|
|
|
|
if (!(IS_MT7650(pAd) || IS_MT7630(pAd) || IS_MT76x2(pAd)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!(INFRA_ON(pAd)))
|
|
return;
|
|
|
|
if (CoexMode == COEX_MODE_TDD)
|
|
{
|
|
if (BT_STATUS_TEST_FLAG(pAd, fBTSTATUS_BT_BWL))
|
|
{
|
|
// Update BAWinLimit
|
|
if (pAd->CommonCfg.BACapability.field.RxBAWinLimit != COEX_BARXSIZE_A2DP)
|
|
{
|
|
pAd->CommonCfg.BACapability.field.RxBAWinLimit = COEX_BARXSIZE_A2DP;
|
|
//pAd->CommonCfg.BACapability.field.TxBAWinLimit = 0x40;
|
|
|
|
//pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
|
|
|
|
//BATableTearRECEntry(pAd, pPort, 0, BSSID_WCID,TRUE);
|
|
//BATableTearORIEntry(pAd, pPort, 0, BSSID_WCID, TRUE, TRUE);
|
|
BAOriSessionTearDown(pAd, BSSID_WCID, 0, FALSE, FALSE);
|
|
BARecSessionTearDown(pAd, BSSID_WCID, 0, FALSE);
|
|
//expect to build BA
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: TDD mode: Set RxBASize to %d\n", pAd->CoexMode.RxBAWinLimit));
|
|
BAOriSessionSetUp(pAd, pEntry, 0, 0, 100, TRUE);
|
|
}
|
|
}
|
|
else if (BT_STATUS_TEST_FLAG(pAd, fBTSTATUS_BT_SYNC))
|
|
{
|
|
// Update BAWinLimit
|
|
if (pAd->CommonCfg.BACapability.field.RxBAWinLimit != COEX_BARXSIZE_SCO_ESCO)
|
|
{
|
|
pAd->CommonCfg.BACapability.field.RxBAWinLimit = COEX_BARXSIZE_SCO_ESCO;
|
|
//pAd->CommonCfg.BACapability.field.TxBAWinLimit = 0x40;
|
|
|
|
//pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
|
|
|
|
//BATableTearRECEntry(pAd, pPort, 0, BSSID_WCID,TRUE);
|
|
//BATableTearORIEntry(pAd, pPort, 0, BSSID_WCID, TRUE, TRUE);
|
|
BAOriSessionTearDown(pAd, BSSID_WCID, 0, FALSE, FALSE);
|
|
BARecSessionTearDown(pAd, BSSID_WCID, 0, FALSE);
|
|
//expect to build BA
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: TDD mode: Set RxBASize to %d\n", pAd->CoexMode.RxBAWinLimit));
|
|
BAOriSessionSetUp(pAd, pEntry, 0, 0, 100, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Update BAWinLimit
|
|
if (pAd->CommonCfg.BACapability.field.RxBAWinLimit != COEX_BARXSIZE_OPP)
|
|
{
|
|
pAd->CommonCfg.BACapability.field.RxBAWinLimit = COEX_BARXSIZE_OPP;
|
|
//pAd->CommonCfg.BACapability.field.TxBAWinLimit = 0x40;
|
|
|
|
//pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
|
|
|
|
//BATableTearRECEntry(pAd, pPort, 0, BSSID_WCID,TRUE);
|
|
//BATableTearORIEntry(pAd, pPort, 0, BSSID_WCID, TRUE, TRUE);
|
|
BAOriSessionTearDown(pAd, BSSID_WCID, 0, FALSE, FALSE);
|
|
BARecSessionTearDown(pAd, BSSID_WCID, 0, FALSE);
|
|
//expect to build BA
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: TDD mode: Set RxBASize to %d\n", pAd->CoexMode.RxBAWinLimit));
|
|
BAOriSessionSetUp(pAd, pEntry, 0, 0, 100, TRUE);
|
|
}
|
|
}
|
|
// Need to consider 5G cases
|
|
}
|
|
else if (CoexMode == COEX_MODE_FDD || CoexMode == COEX_MODE_RESET)
|
|
{
|
|
// Update BAWinLimit
|
|
if (pAd->CommonCfg.BACapability.field.RxBAWinLimit != pAd->CommonCfg.REGBACapability.field.RxBAWinLimit )
|
|
{
|
|
pAd->CommonCfg.BACapability.field.RxBAWinLimit = pAd->CommonCfg.REGBACapability.field.RxBAWinLimit;
|
|
pAd->CommonCfg.BACapability.field.TxBAWinLimit = pAd->CommonCfg.REGBACapability.field.TxBAWinLimit;
|
|
|
|
//pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
|
|
|
|
//BATableTearRECEntry(pAd, pPort, 0, BSSID_WCID,TRUE);
|
|
//BATableTearORIEntry(pAd, pPort, 0, BSSID_WCID, TRUE, TRUE);
|
|
BAOriSessionTearDown(pAd, BSSID_WCID, 0, FALSE, FALSE);
|
|
BARecSessionTearDown(pAd, BSSID_WCID, 0, FALSE);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: FDD (Reset)mode: Set RxBASize to %d\n", pAd->CoexMode.RxBAWinLimit));
|
|
//expect to build BA
|
|
BAOriSessionSetUp(pAd, pEntry, 0, 0, 100, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID TDDFDDExclusiveRequest(
|
|
IN PRTMP_ADAPTER pAd,
|
|
UCHAR CoexMode
|
|
)
|
|
{
|
|
if (CoexMode == COEX_MODE_FDD)
|
|
{
|
|
pAd->CoexMode.FDDRequest = TRUE;
|
|
pAd->CoexMode.TDDRequest = FALSE;
|
|
}
|
|
else if (CoexMode == COEX_MODE_TDD)
|
|
{
|
|
pAd->CoexMode.FDDRequest = FALSE;
|
|
pAd->CoexMode.TDDRequest = TRUE;
|
|
}
|
|
else if (CoexMode == COEX_MODE_RESET)
|
|
{
|
|
pAd->CoexMode.FDDRequest = FALSE;
|
|
pAd->CoexMode.TDDRequest = FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID SendAndesTFSWITCH(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR CoexMode
|
|
)
|
|
{
|
|
|
|
COEX_TF_SWITCH coexTF = {0};
|
|
USHORT coexTFLength = 0;
|
|
INT ret;
|
|
//struct CMD_UNIT CmdUnit;
|
|
struct cmd_msg *msg;
|
|
printk("%s: CoexMode=%d-->\n", __FUNCTION__, CoexMode);
|
|
coexTF.CoexOperation = TypeTFSwitch;
|
|
coexTF.CoexMode = CoexMode;
|
|
|
|
coexTFLength = sizeof(coexTF);
|
|
|
|
msg = AndesAllocCmdMsg(pAd, coexTFLength);
|
|
AndesInitCmdMsg(msg, PKT_CMD_TYPE_COEX_OP, FALSE, 0, TRUE, FALSE, 0, NULL, NULL);
|
|
|
|
AndesAppendCmdMsg(msg, (char *)&coexTF,coexTFLength);
|
|
|
|
ret = AndesSendCmdMsg(pAd, msg);
|
|
|
|
DBGPRINT(RT_DEBUG_OFF, ("%s: CoexOperation = %d, CoexMode = %d\n, PktLength = %d\n",
|
|
__FUNCTION__,
|
|
coexTF.CoexOperation,
|
|
coexTF.CoexMode,
|
|
coexTFLength
|
|
));
|
|
|
|
TDDFDDExclusiveRequest(pAd, CoexMode);
|
|
printk("%s: <--\n", __FUNCTION__);
|
|
|
|
|
|
}
|
|
|
|
|
|
VOID InitBTCoexistence(
|
|
IN PRTMP_ADAPTER pAd)
|
|
{
|
|
if(pAd == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IS_MT7650(pAd) || IS_MT7630(pAd) || IS_MT76x2(pAd))
|
|
{
|
|
pAd->CommonCfg.CoexFDDRSSITreshold = 70;
|
|
pAd->CommonCfg.CoexTDDRSSITreshold = 76;
|
|
pAd ->CommonCfg.CoexRXAGCLMTreshold = 51;
|
|
pAd ->CommonCfg.CoexRXAGCMHTreshold = 66;
|
|
pAd ->CommonCfg.CoexWLANPrivilegeTime = 0x50000044;
|
|
//Coex paramter
|
|
pAd->CommonCfg.CoexDefaultMode = COEX_MODE_TDD;
|
|
if (pAd->CommonCfg.CoexDefaultMode & 0xF0000000)
|
|
{
|
|
pAd->CoexMode.DefaultMode = (pAd->CommonCfg.CoexDefaultMode & 0x0FFFFFFF);
|
|
}
|
|
else
|
|
{
|
|
pAd->CoexMode.DefaultMode = pAd->CommonCfg.CoexDefaultMode;
|
|
}
|
|
|
|
printk("==>InitBTCoexistence CoexMode.DefaultMode(%d)\n",pAd->CoexMode.DefaultMode);
|
|
pAd->CoexMode.CurrentMode = pAd->CoexMode.DefaultMode;
|
|
pAd->CoexMode.CoexFDDRSSITreshold = -pAd->CommonCfg.CoexFDDRSSITreshold;
|
|
pAd->CoexMode.CoexTDDRSSITreshold = -pAd->CommonCfg.CoexTDDRSSITreshold;
|
|
pAd->coexRXManualAGCGain.LMthreshold = -pAd ->CommonCfg.CoexRXAGCLMTreshold;
|
|
pAd->coexRXManualAGCGain.MHthreshold = -pAd ->CommonCfg.CoexRXAGCMHTreshold;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID MLMEHook(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN UCHAR WlanStatus,
|
|
IN ULONG BssHashID
|
|
)
|
|
{
|
|
ULONG unit = ((pAd->CommonCfg.CoexWLANPrivilegeTime & 0xF0000000)>>28)*100; //5ms*100 = 500
|
|
ULONG times = 0;
|
|
|
|
if (!(IS_MT7650(pAd) || IS_MT7630(pAd) || IS_MT7662(pAd) || IS_MT7632(pAd)))
|
|
{
|
|
return;
|
|
}
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: CoexWLANPrivilegeTime = %x\n", pAd->CommonCfg.CoexWLANPrivilegeTime));
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: unit = %x\n", unit));
|
|
|
|
switch (WlanStatus)
|
|
{
|
|
case WLAN_Device_ON :
|
|
SendAndesWLANStatus(pAd, WlanStatus, 0, 0);
|
|
break;
|
|
|
|
case WLAN_CONNECTION_START :
|
|
times = (pAd->CommonCfg.CoexWLANPrivilegeTime & 0xF0)>>4;
|
|
SendAndesWLANStatus(pAd, WlanStatus, unit*times, BssHashID);
|
|
break;
|
|
#if 0
|
|
case BT_HCI_Create_Physical_Link :
|
|
case BT_MAC_Start_Completed :
|
|
times = pAd->CommonCfg.CoexWLANPrivilegeTime & 0xF;
|
|
if (pAd->BTMode == BTMODE_RESPONDER)
|
|
{
|
|
SendAndesWLANStatus(pAd, WlanStatus, unit*times, BssHashID);
|
|
}
|
|
else if (pAd->BTMode == BTMODE_INITIATOR)
|
|
{
|
|
SendAndesWLANStatus(pAd, WlanStatus, 0, BssHashID);
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
SendAndesWLANStatus(pAd, WlanStatus, 0, BssHashID);
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
//COEX periodic checking
|
|
//
|
|
VOID CoexistencePeriodicRoutine(
|
|
IN PRTMP_ADAPTER pAd
|
|
)
|
|
{
|
|
WLAN_FUN_INFO_STRUC wlanFunInfo = {.word = 0};
|
|
RTMP_IO_READ32(pAd, WLAN_FUN_INFO, &wlanFunInfo.word);
|
|
|
|
//DBGPRINT(RT_DEBUG_TRACE,("COEX: StaCfg.AvgRssi0 = %d\n",pAd->StaCfg.RssiSample.AvgRssi0));
|
|
//DBGPRINT(RT_DEBUG_TRACE,("COEX:CoexMode = %d\n",pAd->CoexMode.CurrentMode));
|
|
|
|
//Process Block Ack for aggregation
|
|
if (IS_MT76XXBTCOMBO(pAd) && (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_ACTIVE)))
|
|
{
|
|
if (pAd->CoexMode.CurrentMode == COEX_MODE_FDD)
|
|
{
|
|
TDDFDDCoexBACapability(pAd, COEX_MODE_FDD);
|
|
}
|
|
else if (pAd->CoexMode.CurrentMode == COEX_MODE_TDD)
|
|
{
|
|
TDDFDDCoexBACapability(pAd, COEX_MODE_TDD);
|
|
}
|
|
else
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR,("!!COEX:Strange CoexMode = %d\n",pAd->CoexMode.CurrentMode));
|
|
}
|
|
}
|
|
else if ((IS_MT7650(pAd) || IS_MT7630(pAd) || IS_MT76x2(pAd)))
|
|
{
|
|
TDDFDDCoexBACapability(pAd, COEX_MODE_RESET);
|
|
}
|
|
|
|
//Process TDD/FDD CR
|
|
if ((IS_MT7650(pAd) || IS_MT7630(pAd) || IS_MT76x2(pAd)) && INFRA_ON(pAd))
|
|
{
|
|
DBGPRINT(RT_DEBUG_INFO,("COEX: pAd->CoexMode.CoexTDDRSSITreshold = %d\n",pAd->CoexMode.CoexTDDRSSITreshold));
|
|
DBGPRINT(RT_DEBUG_INFO,("COEX: pAd->CoexMode.CoexFDDRSSITreshold = %d\n",pAd->CoexMode.CoexFDDRSSITreshold));
|
|
//MT76xx coex RX LNA gain adjustment
|
|
if (pAd->CoexMode.CurrentMode == COEX_MODE_FDD)
|
|
{
|
|
if (pAd->StaCfg.RssiSample.AvgRssi0 < (pAd->CoexMode.CoexTDDRSSITreshold) )
|
|
{
|
|
if (pAd->CoexMode.TDDRequest == FALSE)
|
|
{
|
|
//SendAndesTFSWITCH(pAd, COEX_MODE_TDD);
|
|
}
|
|
|
|
}
|
|
if (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->CoexMode.CoexFDDRSSITreshold) )
|
|
{
|
|
if (pAd->CoexMode.FDDRequest == FALSE)
|
|
{
|
|
//SendAndesTFSWITCH(pAd, COEX_MODE_FDD);
|
|
}
|
|
|
|
}
|
|
CoexFDDRXAGCGain(pAd, pAd->StaCfg.RssiSample.AvgRssi0);
|
|
}
|
|
else if (pAd->CoexMode.CurrentMode == COEX_MODE_TDD)
|
|
{
|
|
if (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->CoexMode.CoexFDDRSSITreshold) )
|
|
{
|
|
if (pAd->CoexMode.FDDRequest == FALSE)
|
|
{
|
|
/* 20130523-sarick
|
|
Do not set to FDD now. */
|
|
//SendAndesTFSWITCH(pAd, COEX_MODE_FDD);
|
|
}
|
|
}
|
|
if (pAd->StaCfg.RssiSample.AvgRssi0 < (pAd->CoexMode.CoexTDDRSSITreshold) )
|
|
{
|
|
if (pAd->CoexMode.TDDRequest == FALSE)
|
|
{
|
|
//SendAndesTFSWITCH(pAd, COEX_MODE_TDD);
|
|
}
|
|
}
|
|
CoexTDDRXAGCGain(pAd);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID COEXLinkDown(
|
|
IN PRTMP_ADAPTER pAd,
|
|
PUCHAR pAddr
|
|
)
|
|
{
|
|
//Coex release protection frame
|
|
InvalidProtectionFrameSpace(pAd, pAddr);
|
|
UpdateAndesNullFrameSpace(pAd);
|
|
RemoveProtectionFrameSpace(pAd, pAddr);
|
|
TDDFDDExclusiveRequest(pAd,COEX_MODE_RESET);
|
|
{
|
|
BtAFHCtl(pAd, pAd->CommonCfg.BBPCurrentBW, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, TRUE);
|
|
SendAndesAFH(pAd, pAd->CommonCfg.BBPCurrentBW, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel, TRUE, QueryHashID(pAd, pAddr, FALSE));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID CoexParseBTStatus(
|
|
IN PRTMP_ADAPTER pAd
|
|
)
|
|
{
|
|
PBT_STATUS_REPORT_STRUC pBtstatus =(PBT_STATUS_REPORT_STRUC) &(pAd->BTStatusFlags);
|
|
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_ACTIVE))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: BT ACTIVE !!!! \n"));
|
|
}
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_BWL))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: bandwidth-limited link such as A2DP\n"));
|
|
}
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_BE))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: best effort to serve non-QoS-guaranteed link such as PAN, FTP\n"));
|
|
}
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_SYNC))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: synchronous link(s) such as SCO, eSCO\n"));
|
|
}
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_SNIFF))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: periodic transport(s) such as SNIFF, LE_CONN, LE_ADV\n"));
|
|
}
|
|
if (BT_STATUS_TEST_FLAG(pAd,fBTSTATUS_BT_SCATTER))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: scatter operation either PAGE or INQUIRY\n"));
|
|
}
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("COEX: BT_LINK_CNT = %d, BTE_LINK_CNT= %d, TotalCount = %d, BT_SLAVE_IND = %d\n",
|
|
pBtstatus->field.BT_LINK_CNT,
|
|
pBtstatus->field.BLE_LINK_CNT,
|
|
pBtstatus->field.BT_LINK_CNT + pBtstatus->field.BLE_LINK_CNT,
|
|
pBtstatus->field.BT_SLAVE_IND));
|
|
|
|
}
|
|
|
|
#endif /* MT76XX_BTCOEX_SUPPORT */
|