Commit 59fe2d89 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Greg Kroah-Hartman

Staging: rt2860: prepare for rt28[67]0/common/*.[ch] merge

Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3fb468ab
......@@ -527,9 +527,15 @@ VOID SendRefreshBAR(
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(FRAME_BAR), &FrameBar,
END_OF_ARGS);
if (1) // Now we always send BAR.
{
#ifndef RT30xx
MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
#endif
#ifdef RT30xx
MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
#endif
}
MlmeFreeMemory(pAd, pOutBuffer);
}
......
......@@ -531,6 +531,13 @@ VOID BAOriSessionSetUp(
pBAEntry->TimeOutValue = TimeOut;
pBAEntry->pAdapter = pAd;
#ifdef RT30xx
DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
,TID,isForced,pEntry->Aid));
#endif
if (!(pEntry->TXBAbitmap & (1<<TID)))
{
RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
......@@ -1071,8 +1078,16 @@ VOID BAOriSessionSetupTimeout(
AddbaReq.Token = pBAEntry->Token;
MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
RT28XX_MLME_HANDLER(pAd);
#ifndef RT30xx
DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
#endif
#ifdef RT30xx
DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
,pBAEntry->Token
,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
,pBAEntry->TID,pEntry->Aid));
#endif
pBAEntry->Token++;
RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
}
......@@ -1376,6 +1391,10 @@ VOID SendPSMPAction(
//ULONG Idx;
FRAME_PSMP_ACTION Frame;
ULONG FrameLen;
#ifdef RT30xx
UCHAR bbpdata=0;
UINT32 macdata;
#endif // RT30xx //
NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
......@@ -1391,12 +1410,54 @@ VOID SendPSMPAction(
switch (Psmp)
{
case MMPS_ENABLE:
#ifdef RT30xx
if (IS_RT3090(pAd))
{
// disable MMPS BBP control register
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
bbpdata &= ~(0x04); //bit 2
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
// disable MMPS MAC control register
RTMP_IO_READ32(pAd, 0x1210, &macdata);
macdata &= ~(0x09); //bit 0, 3
RTMP_IO_WRITE32(pAd, 0x1210, macdata);
}
#endif // RT30xx //
Frame.Psmp = 0;
break;
case MMPS_DYNAMIC:
#ifdef RT30xx
if (IS_RT3090(pAd))
{
// enable MMPS BBP control register
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
bbpdata |= 0x04; //bit 2
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
// enable MMPS MAC control register
RTMP_IO_READ32(pAd, 0x1210, &macdata);
macdata |= 0x09; //bit 0, 3
RTMP_IO_WRITE32(pAd, 0x1210, macdata);
}
#endif // RT30xx //
Frame.Psmp = 3;
break;
case MMPS_STATIC:
#ifdef RT30xx
if (IS_RT3090(pAd))
{
// enable MMPS BBP control register
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
bbpdata |= 0x04; //bit 2
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
// enable MMPS MAC control register
RTMP_IO_READ32(pAd, 0x1210, &macdata);
macdata |= 0x09; //bit 0, 3
RTMP_IO_WRITE32(pAd, 0x1210, macdata);
}
#endif // RT30xx //
Frame.Psmp = 1;
break;
}
......
......@@ -105,7 +105,9 @@ NDIS_STATUS MiniportMMRequest(
PNDIS_PACKET pPacket;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ULONG FreeNum;
#ifdef RT2860
unsigned long IrqFlags = 0;
#endif
UCHAR IrqState;
UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
......@@ -117,9 +119,10 @@ NDIS_STATUS MiniportMMRequest(
IrqState = pAd->irq_disabled;
#ifdef RT2860
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
#endif
do
{
// Reset is in progress, stop immediately
......@@ -172,14 +175,15 @@ NDIS_STATUS MiniportMMRequest(
} while (FALSE);
#ifdef RT2860
// 2860C use Tx Ring
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
#endif
return Status;
}
#ifdef RT2860
NDIS_STATUS MiniportMMRequestUnlock(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
......@@ -247,8 +251,116 @@ NDIS_STATUS MiniportMMRequestUnlock(
return Status;
}
#endif
#ifdef RT30xx
NDIS_STATUS MlmeDataHardTransmit(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN PNDIS_PACKET pPacket);
#define MAX_DATAMM_RETRY 3
/*
========================================================================
Routine Description:
API for MLME to transmit management frame to AP (BSS Mode)
or station (IBSS Mode)
Arguments:
pAd Pointer to our adapter
pData Pointer to the outgoing 802.11 frame
Length Size of outgoing management frame
Return Value:
NDIS_STATUS_FAILURE
NDIS_STATUS_PENDING
NDIS_STATUS_SUCCESS
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
NDIS_STATUS MiniportDataMMRequest(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN PUCHAR pData,
IN UINT Length)
{
PNDIS_PACKET pPacket;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ULONG FreeNum;
int retry = 0;
UCHAR IrqState;
UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
// 2860C use Tx Ring
IrqState = pAd->irq_disabled;
do
{
// Reset is in progress, stop immediately
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
{
Status = NDIS_STATUS_FAILURE;
break;
}
// Check Free priority queue
// Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
// 2860C use Tx Ring
// free Tx(QueIdx) resources
FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
if ((FreeNum > 0))
{
// We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
if (Status != NDIS_STATUS_SUCCESS)
{
DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
break;
}
//pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
//pAd->CommonCfg.MlmeRate = RATE_2;
Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
if (Status != NDIS_STATUS_SUCCESS)
RTMPFreeNdisPacket(pAd, pPacket);
retry = MAX_DATAMM_RETRY;
}
else
{
retry ++;
printk("retry %d\n", retry);
pAd->RalinkCounters.MgmtRingFullCount++;
if (retry >= MAX_DATAMM_RETRY)
{
DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
}
}
} while (retry < MAX_DATAMM_RETRY);
return Status;
}
#endif /* RT30xx */
/*
========================================================================
......@@ -283,14 +395,16 @@ NDIS_STATUS MlmeHardTransmit(
return NDIS_STATUS_FAILURE;
}
#ifdef RT2860
if ( pAd->MACVersion == 0x28600100 )
return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
else
#endif
return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
}
#ifdef RT2860
NDIS_STATUS MlmeHardTransmitTxRing(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
......@@ -472,7 +586,25 @@ NDIS_STATUS MlmeHardTransmitTxRing(
return NDIS_STATUS_SUCCESS;
}
#endif /* RT2860 */
#ifdef RT30xx
NDIS_STATUS MlmeDataHardTransmit(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
IN PNDIS_PACKET pPacket)
{
if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
)
{
return NDIS_STATUS_FAILURE;
}
#ifdef RT2870
return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
#endif // RT2870 //
}
#endif /* RT30xx */
NDIS_STATUS MlmeHardTransmitMgmtRing(
IN PRTMP_ADAPTER pAd,
......@@ -500,7 +632,12 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
// outgoing frame always wakeup PHY to prevent frame lost
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#ifdef RT2860
AsicForceWakeup(pAd, FROM_TX);
#endif
#ifdef RT2870
AsicForceWakeup(pAd, TRUE);
#endif
pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
......@@ -823,7 +960,13 @@ BOOLEAN RTMP_FillTxBlkInfo(
{
// If support WMM, enable it.
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
#endif
#ifdef RT2870
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
#endif
TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
}
......@@ -870,6 +1013,11 @@ BOOLEAN RTMP_FillTxBlkInfo(
}
return TRUE;
#ifdef RT30xx
FillTxBlkErr:
return FALSE;
#endif
}
......@@ -957,6 +1105,7 @@ VOID RTMPDeQueuePacket(
if (QIdx == NUM_OF_TX_RING)
{
sQIdx = 0;
//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
eQIdx = 3; // 4 ACs, start from 0.
}
else
......@@ -999,7 +1148,7 @@ VOID RTMPDeQueuePacket(
DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
break;
}
#ifdef RT2860
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
#ifdef DBG_DIAGNOSE
......@@ -1024,7 +1173,7 @@ VOID RTMPDeQueuePacket(
RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
}
#endif /* RT2860 */
// probe the Queue Head
pQueue = &pAd->TxSwQueue[QueIdx];
if ((pEntry = pQueue->Head) == NULL)
......@@ -1093,19 +1242,29 @@ VOID RTMPDeQueuePacket(
pTxBlk->TxFrameType = TX_LEGACY_FRAME;
}
#ifdef RT2870
DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
#endif // RT2870 //
Count += pTxBlk->TxPacketList.Number;
// Do HardTransmit now.
Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
#ifdef RT2860
DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
// static rate also need NICUpdateFifoStaCounters() function.
//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
NICUpdateFifoStaCounters(pAd);
#endif
}
RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
#ifdef RT2870
if (!hasTxDesc)
RTUSBKickBulkOut(pAd);
#endif // RT2870 //
}
}
......@@ -1633,7 +1792,7 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
return (NULL);
}
#ifdef RT2860
BOOLEAN RTMPFreeTXDUponTxDmaDone(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx)
......@@ -2016,6 +2175,7 @@ VOID DBGPRINT_RX_RING(
DBGPRINT_RAW(RT_DEBUG_TRACE,(" RxSwReadIdx [%d]=", AC0freeIdx));
DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
}
#endif /* RT2860 */
/*
========================================================================
......@@ -2075,7 +2235,15 @@ VOID RTMPResumeMsduTransmission(
{
DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
#ifdef RT30xx
// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
// R66 should not be 0
if (pAd->BbpTuning.R66CurrentValue == 0)
{
pAd->BbpTuning.R66CurrentValue = 0x38;
DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
}
#endif
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
......@@ -2298,7 +2466,9 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
pEntry->AuthMode = pAd->StaCfg.AuthMode;
pEntry->WepStatus = pAd->StaCfg.WepStatus;
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
#ifdef RT2860
AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
#endif
}
}
......@@ -2306,10 +2476,12 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
pEntry->PairwiseKey.KeyLen = 0;
pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
#ifdef RT2860
if ((pAd->OpMode == OPMODE_STA) &&
(pAd->StaCfg.BssType == BSS_ADHOC))
pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
else
#endif
pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
......@@ -2445,7 +2617,12 @@ BOOLEAN MacTableDeleteEntry(
if (pAd->MacTab.Size == 0)
{
pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
#ifndef RT30xx
AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
#endif
#ifdef RT30xx
RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
#endif
}
return TRUE;
......@@ -2469,7 +2646,9 @@ VOID MacTableReset(
for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
{
#ifdef RT2860
RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
#endif
if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
{
// free resources of BA
......@@ -2479,6 +2658,10 @@ VOID MacTableReset(
#ifdef RT2870
NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
#endif // RT2870 //
//AsicDelWcidTab(pAd, i);
}
......@@ -2791,6 +2974,37 @@ VOID Indicate_Legacy_Packet(
STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
#ifdef RT2870
if (pAd->CommonCfg.bDisableReordering == 0)
{
PBA_REC_ENTRY pBAEntry;
ULONG Now32;
UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
UCHAR TID = pRxBlk->pRxWI->TID;
USHORT Idx;
#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
if (Wcid < MAX_LEN_OF_MAC_TABLE)
{
Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
if (Idx != 0)
{
pBAEntry = &pAd->BATable.BARecEntry[Idx];
// update last rx time
NdisGetSystemUpTime(&Now32);
if ((pBAEntry->list.qlen > 0) &&
RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
)
{
printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
}
}
}
}
#endif // RT2870 //
wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
......
......@@ -762,6 +762,7 @@ INT Show_DescInfo_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
#ifdef RT2860
INT i, QueIdx=0;
PRT28XX_RXD_STRUC pRxD;
PTXD_STRUC pTxD;
......@@ -792,7 +793,7 @@ INT Show_DescInfo_Proc(
hex_dump("Rx Descriptor", (char *)pRxD, 16);
printk("pRxD->DDONE = %x\n", pRxD->DDONE);
}
#endif /* RT2860 */
return TRUE;
}
......@@ -1418,6 +1419,16 @@ VOID RTMPSetHT(
pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
}
#ifndef RT30xx
#ifdef RT2870
/* Frank recommend ,If not, Tx maybe block in high power. Rx has no problem*/
if(IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
{
pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 0;
pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
}
#endif // RT2870 //
#endif
if(pHTPhyMode->SHORTGI == GI_400)
{
......@@ -1696,7 +1707,12 @@ VOID RTMPAddWcidAttributeEntry(
}
// For key index and ext IV bit, so only need to update the position(offset+3).
#ifdef RT2860
RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
#endif
#ifdef RT2870
RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
#endif // RT2870 //
DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
......@@ -2473,13 +2489,26 @@ INT Set_HtAutoBa_Proc(
Value = simple_strtol(arg, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
#ifdef RT30xx
pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
#endif
}
else if (Value == 1)
{
pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
#ifdef RT30xx
pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
#endif
}
else
return FALSE; //Invalid argument
pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
#ifdef RT30xx
pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
#endif
SetCommonHT(pAd);
DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
......@@ -2696,7 +2725,9 @@ PCHAR RTMPGetRalinkAuthModeStr(
{
case Ndis802_11AuthModeOpen:
return "OPEN";
#if defined(RT2860) || defined(RT30xx)
default:
#endif
case Ndis802_11AuthModeWPAPSK:
return "WPAPSK";
case Ndis802_11AuthModeShared:
......@@ -2711,8 +2742,14 @@ PCHAR RTMPGetRalinkAuthModeStr(
return "WPAPSKWPA2PSK";
case Ndis802_11AuthModeWPA1WPA2:
return "WPA1WPA2";
#ifndef RT30xx
case Ndis802_11AuthModeWPANone:
return "WPANONE";
#ifdef RT2870
default:
return "UNKNOW";
#endif
#endif
}
}
......@@ -2721,7 +2758,9 @@ PCHAR RTMPGetRalinkEncryModeStr(
{
switch(encryMode)
{
#if defined(RT2860) || defined(RT30xx)
default:
#endif
case Ndis802_11WEPDisabled:
return "NONE";
case Ndis802_11WEPEnabled:
......@@ -2732,6 +2771,10 @@ PCHAR RTMPGetRalinkEncryModeStr(
return "AES";
case Ndis802_11Encryption4Enabled:
return "TKIPAES";
#if !defined(RT2860) && !defined(RT30xx)
default:
return "UNKNOW";
#endif
}
}
......
......@@ -440,13 +440,24 @@ VOID ScanNextChannel(
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
}
#ifdef RT2870
else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
{
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
}
#endif // RT2870 //
else
{
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#ifdef RT2860
AsicForceWakeup(pAd, FROM_TX);
#endif
#ifdef RT2870
AsicForceWakeup(pAd, TRUE);
#endif
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
MlmeSetPsmBit(pAd, PWR_ACTIVE);
......
......@@ -39,10 +39,14 @@
// WPA OUI
UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
#ifndef RT30xx
UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
#endif
UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
#ifndef RT30xx
UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
#endif
UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
// WPA2 OUI
......@@ -51,7 +55,9 @@ UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
#ifndef RT30xx
UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
#endif
// MSA OUI
UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
......@@ -370,6 +376,7 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
#ifndef RT30xx
if ((pAd->OpMode == OPMODE_STA) &&
(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
......@@ -385,7 +392,7 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
}
#endif
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
......@@ -446,6 +453,7 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
#ifndef RT30xx
if ((pAd->OpMode == OPMODE_STA) &&
(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
......@@ -461,7 +469,7 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
}
#endif
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
......
......@@ -73,12 +73,16 @@ USHORT ShiftInBits(
RaiseClock(pAd, &x);
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
#ifdef RT30xx
LowerClock(pAd, &x); //prevent read failed
#endif
x &= ~(EEDI);
if(x & EEDO)
data |= 1;
#ifndef RT30xx
LowerClock(pAd, &x);
#endif
}
return data;
......@@ -181,6 +185,15 @@ USHORT RTMP_EEPROM_READ16(
UINT32 x;
USHORT data;
#ifdef RT30xx
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
//2008/09/11:KH add to support efuse<--
//2008/09/11:KH add to support efuse-->
{
#endif
Offset /= 2;
// reset bits and set EECS
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
......@@ -188,9 +201,17 @@ USHORT RTMP_EEPROM_READ16(
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
#ifdef RT30xx
// patch can not access e-Fuse issue
if (!IS_RT3090(pAd))
{
#endif
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
#ifdef RT30xx
}
#endif
// output the read_opcode and register number in that order
ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
......@@ -201,6 +222,17 @@ USHORT RTMP_EEPROM_READ16(
EEpromCleanup(pAd);
#ifdef RT30xx
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
}
#endif
return data;
} //ReadEEprom
......@@ -211,6 +243,15 @@ VOID RTMP_EEPROM_WRITE16(
{
UINT32 x;
#ifdef RT30xx
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
//2008/09/11:KH add to support efuse<--
//2008/09/11:KH add to support efuse-->
{
#endif
Offset /= 2;
EWEN(pAd);
......@@ -221,9 +262,17 @@ VOID RTMP_EEPROM_WRITE16(
x |= EECS;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
#ifdef RT30xx
// patch can not access e-Fuse issue
if (!IS_RT3090(pAd))
{
#endif
// kick a pulse
RaiseClock(pAd, &x);
LowerClock(pAd, &x);
#ifdef RT30xx
}
#endif
// output the read_opcode ,register number and data in that order
ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
......@@ -240,5 +289,1222 @@ VOID RTMP_EEPROM_WRITE16(
EWDS(pAd);
EEpromCleanup(pAd);
#ifdef RT30xx
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
}
#endif
}
//2008/09/11:KH add to support efuse<--
#ifdef RT30xx
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
UCHAR eFuseReadRegisters(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Length,
OUT USHORT* pData)
{
EFUSE_CTRL_STRUC eFuseCtrlStruc;
int i;
USHORT efuseDataOffset;
UINT32 data;
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
//Use the eeprom logical address and covert to address to block number
eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
eFuseCtrlStruc.field.EFSROM_MODE = 0;
//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
i = 0;
while(i < 100)
{
//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
{
break;
}
RTMPusecDelay(2);
i++;
}
//if EFSROM_AOUT is not found in physical address, write 0xffff
if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
{
for(i=0; i<Length/2; i++)
*(pData+2*i) = 0xffff;
}
else
{
//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
//data hold 4 bytes data.
//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
RTMP_IO_READ32(pAd, efuseDataOffset, &data);
//Decide the upper 2 bytes or the bottom 2 bytes.
// Little-endian S | S Big-endian
// addr 3 2 1 0 | 0 1 2 3
// Ori-V D C B A | A B C D
//After swapping
// D C B A | D C B A
//Return 2-bytes
//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
data = data >> (8*(Offset & 0x3));
NdisMoveMemory(pData, &data, Length);
}
return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID eFusePhysicalReadRegisters(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Length,
OUT USHORT* pData)
{
EFUSE_CTRL_STRUC eFuseCtrlStruc;
int i;
USHORT efuseDataOffset;
UINT32 data;
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
//Read in physical view
eFuseCtrlStruc.field.EFSROM_MODE = 1;
//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
i = 0;
while(i < 100)
{
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
break;
RTMPusecDelay(2);
i++;
}
//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
//Decide which EFUSE_DATA to read
//590:F E D C
//594:B A 9 8
//598:7 6 5 4
//59C:3 2 1 0
efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
RTMP_IO_READ32(pAd, efuseDataOffset, &data);
data = data >> (8*(Offset & 0x3));
NdisMoveMemory(pData, &data, Length);
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID eFuseReadPhysical(
IN PRTMP_ADAPTER pAd,
IN PUSHORT lpInBuffer,
IN ULONG nInBufferSize,
OUT PUSHORT lpOutBuffer,
IN ULONG nOutBufferSize
)
{
USHORT* pInBuf = (USHORT*)lpInBuffer;
USHORT* pOutBuf = (USHORT*)lpOutBuffer;
USHORT Offset = pInBuf[0]; //addr
USHORT Length = pInBuf[1]; //length
int i;
for(i=0; i<Length; i+=2)
{
eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
}
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NTSTATUS eFuseRead(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
OUT PUCHAR pData,
IN USHORT Length)
{
USHORT* pOutBuf = (USHORT*)pData;
NTSTATUS Status = STATUS_SUCCESS;
UCHAR EFSROM_AOUT;
int i;
for(i=0; i<Length; i+=2)
{
EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
}
return Status;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID eFusePhysicalWriteRegisters(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Length,
OUT USHORT* pData)
{
EFUSE_CTRL_STRUC eFuseCtrlStruc;
int i;
USHORT efuseDataOffset;
UINT32 data, eFuseDataBuffer[4];
//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
/////////////////////////////////////////////////////////////////
//read current values of 16-byte block
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
eFuseCtrlStruc.field.EFSROM_MODE = 1;
//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
i = 0;
while(i < 100)
{
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
break;
RTMPusecDelay(2);
i++;
}
//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
efuseDataOffset = EFUSE_DATA3;
for(i=0; i< 4; i++)
{
RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
efuseDataOffset -= 4;
}
//Update the value, the offset is multiple of 2, length is 2
efuseDataOffset = (Offset & 0xc) >> 2;
data = pData[0] & 0xffff;
//The offset should be 0x***10 or 0x***00
if((Offset % 4) != 0)
{
eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
}
else
{
eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
}
efuseDataOffset = EFUSE_DATA3;
for(i=0; i< 4; i++)
{
RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
efuseDataOffset -= 4;
}
/////////////////////////////////////////////////////////////////
//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
eFuseCtrlStruc.field.EFSROM_MODE = 3;
//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
i = 0;
while(i < 100)
{
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
break;
RTMPusecDelay(2);
i++;
}
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NTSTATUS eFuseWriteRegisters(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Length,
IN USHORT* pData)
{
USHORT i;
USHORT eFuseData;
USHORT LogicalAddress, BlkNum = 0xffff;
UCHAR EFSROM_AOUT;
USHORT addr,tmpaddr, InBuf[3], tmpOffset;
USHORT buffer[8];
BOOLEAN bWriteSuccess = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
//Step 0. find the entry in the mapping table
//The address of EEPROM is 2-bytes alignment.
//The last bit is used for alignment, so it must be 0.
tmpOffset = Offset & 0xfffe;
EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
if( EFSROM_AOUT == 0x3f)
{ //find available logical address pointer
//the logical address does not exist, find an empty one
//from the first address of block 45=16*45=0x2d0 to the last address of block 47
//==>48*16-3(reserved)=2FC
for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
{
//Retrive the logical block nubmer form each logical address pointer
//It will access two logical address pointer each time.
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
if( (LogicalAddress & 0xff) == 0)
{//Not used logical address pointer
BlkNum = i-EFUSE_USAGE_MAP_START;
break;
}
else if(( (LogicalAddress >> 8) & 0xff) == 0)
{//Not used logical address pointer
if (i != EFUSE_USAGE_MAP_END)
{
BlkNum = i-EFUSE_USAGE_MAP_START+1;
}
break;
}
}
}
else
{
BlkNum = EFSROM_AOUT;
}
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
if(BlkNum == 0xffff)
{
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
return FALSE;
}
//Step 1. Save data of this block which is pointed by the avaible logical address pointer
// read and save the original block data
for(i =0; i<8; i++)
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+2*i;
InBuf[1] = 2;
InBuf[2] = 0x0;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
buffer[i] = InBuf[2];
}
//Step 2. Update the data in buffer, and write the data to Efuse
buffer[ (Offset >> 1) % 8] = pData[0];
do
{
//Step 3. Write the data to Efuse
if(!bWriteSuccess)
{
for(i =0; i<8; i++)
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+2*i;
InBuf[1] = 2;
InBuf[2] = buffer[i];
eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
}
}
else
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+(Offset % 16);
InBuf[1] = 2;
InBuf[2] = pData[0];
eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
}
//Step 4. Write mapping table
addr = EFUSE_USAGE_MAP_START+BlkNum;
tmpaddr = addr;
if(addr % 2 != 0)
addr = addr -1;
InBuf[0] = addr;
InBuf[1] = 2;
//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
tmpOffset = Offset;
tmpOffset >>= 4;
tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
// write the logical address
if(tmpaddr%2 != 0)
InBuf[2] = tmpOffset<<8;
else
InBuf[2] = tmpOffset;
eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
bWriteSuccess = TRUE;
for(i =0; i<8; i++)
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+2*i;
InBuf[1] = 2;
InBuf[2] = 0x0;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
if(buffer[i] != InBuf[2])
{
bWriteSuccess = FALSE;
break;
}
}
//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
if (!bWriteSuccess)
{
DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
// the offset of current mapping entry
addr = EFUSE_USAGE_MAP_START+BlkNum;
//find a new mapping entry
BlkNum = 0xffff;
for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
{
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
if( (LogicalAddress & 0xff) == 0)
{
BlkNum = i-EFUSE_USAGE_MAP_START;
break;
}
else if(( (LogicalAddress >> 8) & 0xff) == 0)
{
if (i != EFUSE_USAGE_MAP_END)
{
BlkNum = i+1-EFUSE_USAGE_MAP_START;
}
break;
}
}
DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
if(BlkNum == 0xffff)
{
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
return FALSE;
}
//invalidate the original mapping entry if new entry is not found
tmpaddr = addr;
if(addr % 2 != 0)
addr = addr -1;
InBuf[0] = addr;
InBuf[1] = 2;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
// write the logical address
if(tmpaddr%2 != 0)
{
// Invalidate the high byte
for (i=8; i<15; i++)
{
if( ( (InBuf[2] >> i) & 0x01) == 0)
{
InBuf[2] |= (0x1 <<i);
break;
}
}
}
else
{
// invalidate the low byte
for (i=0; i<8; i++)
{
if( ( (InBuf[2] >> i) & 0x01) == 0)
{
InBuf[2] |= (0x1 <<i);
break;
}
}
}
eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
}
}
while(!bWriteSuccess);
return TRUE;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
VOID eFuseWritePhysical(
IN PRTMP_ADAPTER pAd,
PUSHORT lpInBuffer,
ULONG nInBufferSize,
PUCHAR lpOutBuffer,
ULONG nOutBufferSize
)
{
USHORT* pInBuf = (USHORT*)lpInBuffer;
int i;
//USHORT* pOutBuf = (USHORT*)ioBuffer;
USHORT Offset = pInBuf[0]; //addr
USHORT Length = pInBuf[1]; //length
USHORT* pValueX = &pInBuf[2]; //value ...
// Little-endian S | S Big-endian
// addr 3 2 1 0 | 0 1 2 3
// Ori-V D C B A | A B C D
//After swapping
// D C B A | D C B A
//Both the little and big-endian use the same sequence to write data.
//Therefore, we only need swap data when read the data.
for(i=0; i<Length; i+=2)
{
eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
}
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NTSTATUS eFuseWrite(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN PUCHAR pData,
IN USHORT length)
{
int i;
USHORT* pValueX = (PUSHORT) pData; //value ...
//The input value=3070 will be stored as following
// Little-endian S | S Big-endian
// addr 1 0 | 0 1
// Ori-V 30 70 | 30 70
//After swapping
// 30 70 | 70 30
//Casting
// 3070 | 7030 (x)
//The swapping should be removed for big-endian
for(i=0; i<length; i+=2)
{
eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
}
return TRUE;
}
/*
========================================================================
Routine Description:
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
INT set_eFuseGetFreeBlockCount_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
USHORT i;
USHORT LogicalAddress;
USHORT efusefreenum=0;
if(!pAd->bUseEfuse)
return FALSE;
for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
{
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
if( (LogicalAddress & 0xff) == 0)
{
efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
break;
}
else if(( (LogicalAddress >> 8) & 0xff) == 0)
{
efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
break;
}
if(i == EFUSE_USAGE_MAP_END)
efusefreenum = 0;
}
printk("efuseFreeNumber is %d\n",efusefreenum);
return TRUE;
}
INT set_eFusedump_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
USHORT InBuf[3];
INT i=0;
if(!pAd->bUseEfuse)
return FALSE;
for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
{
InBuf[0] = 2*i;
InBuf[1] = 2;
InBuf[2] = 0x0;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
if(i%4==0)
printk("\nBlock %x:",i/8);
printk("%04x ",InBuf[2]);
}
return TRUE;
}
INT set_eFuseLoadFromBin_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
CHAR *src;
struct file *srcf;
INT retval, orgfsuid, orgfsgid;
mm_segment_t orgfs;
UCHAR *buffer;
UCHAR BinFileSize=0;
INT i = 0,j=0,k=1;
USHORT *PDATA;
USHORT DATA;
BinFileSize=strlen("RT30xxEEPROM.bin");
src = kmalloc(128, MEM_ALLOC_FLAG);
NdisZeroMemory(src, 128);
if(strlen(arg)>0)
{
NdisMoveMemory(src, arg, strlen(arg));
}
else
{
NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
}
DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
if(buffer == NULL)
{
kfree(src);
return FALSE;
}
PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
if(PDATA==NULL)
{
kfree(src);
kfree(buffer);
return FALSE;
}
/* Don't change to uid 0, let the file be opened as the "normal" user */
#if 0
orgfsuid = current->fsuid;
orgfsgid = current->fsgid;
current->fsuid=current->fsgid = 0;
#endif
orgfs = get_fs();
set_fs(KERNEL_DS);
if (src && *src)
{
srcf = filp_open(src, O_RDONLY, 0);
if (IS_ERR(srcf))
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
return FALSE;
}
else
{
// The object must have a read method
if (srcf->f_op && srcf->f_op->read)
{
memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
{
DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
if((i+1)%8==0)
DBGPRINT(RT_DEBUG_TRACE, ("\n"));
i++;
if(i>=MAX_EEPROM_BIN_FILE_SIZE)
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
kfree(PDATA);
kfree(buffer);
kfree(src);
return FALSE;
}
}
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
kfree(PDATA);
kfree(buffer);
kfree(src);
return FALSE;
}
}
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
kfree(PDATA);
kfree(buffer);
return FALSE;
}
retval=filp_close(srcf,NULL);
if (retval)
{
DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
}
set_fs(orgfs);
#if 0
current->fsuid = orgfsuid;
current->fsgid = orgfsgid;
#endif
for(j=0;j<i;j++)
{
DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
if((j+1)%2==0)
PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
if(j%16==0)
{
k=buffer[j];
}
else
{
k&=buffer[j];
if((j+1)%16==0)
{
DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
if(k!=0xff)
eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
else
{
if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
}
/*
for(l=0;l<8;l++)
printk("%04x ",PDATA[l]);
printk("\n");
*/
NdisZeroMemory(PDATA,16);
}
}
}
kfree(PDATA);
kfree(buffer);
kfree(src);
return TRUE;
}
NTSTATUS eFuseWriteRegistersFromBin(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Length,
IN USHORT* pData)
{
USHORT i;
USHORT eFuseData;
USHORT LogicalAddress, BlkNum = 0xffff;
UCHAR EFSROM_AOUT,Loop=0;
EFUSE_CTRL_STRUC eFuseCtrlStruc;
USHORT efuseDataOffset;
UINT32 data,tempbuffer;
USHORT addr,tmpaddr, InBuf[3], tmpOffset;
UINT32 buffer[4];
BOOLEAN bWriteSuccess = TRUE;
BOOLEAN bNotWrite=TRUE;
BOOLEAN bAllocateNewBlk=TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
do
{
//Step 0. find the entry in the mapping table
//The address of EEPROM is 2-bytes alignment.
//The last bit is used for alignment, so it must be 0.
Loop++;
tmpOffset = Offset & 0xfffe;
EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
if( EFSROM_AOUT == 0x3f)
{ //find available logical address pointer
//the logical address does not exist, find an empty one
//from the first address of block 45=16*45=0x2d0 to the last address of block 47
//==>48*16-3(reserved)=2FC
bAllocateNewBlk=TRUE;
for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
{
//Retrive the logical block nubmer form each logical address pointer
//It will access two logical address pointer each time.
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
if( (LogicalAddress & 0xff) == 0)
{//Not used logical address pointer
BlkNum = i-EFUSE_USAGE_MAP_START;
break;
}
else if(( (LogicalAddress >> 8) & 0xff) == 0)
{//Not used logical address pointer
if (i != EFUSE_USAGE_MAP_END)
{
BlkNum = i-EFUSE_USAGE_MAP_START+1;
}
break;
}
}
}
else
{
bAllocateNewBlk=FALSE;
BlkNum = EFSROM_AOUT;
}
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
if(BlkNum == 0xffff)
{
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
return FALSE;
}
//Step 1.1.0
//If the block is not existing in mapping table, create one
//and write down the 16-bytes data to the new block
if(bAllocateNewBlk)
{
DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
efuseDataOffset = EFUSE_DATA3;
for(i=0; i< 4; i++)
{
DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
efuseDataOffset -= 4;
}
/////////////////////////////////////////////////////////////////
//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
eFuseCtrlStruc.field.EFSROM_MODE = 3;
//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
i = 0;
while(i < 100)
{
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
break;
RTMPusecDelay(2);
i++;
}
}
else
{ //Step1.2.
//If the same logical number is existing, check if the writting data and the data
//saving in this block are the same.
/////////////////////////////////////////////////////////////////
//read current values of 16-byte block
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
eFuseCtrlStruc.field.EFSROM_MODE = 0;
//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
eFuseCtrlStruc.field.EFSROM_KICK = 1;
NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
i = 0;
while(i < 100)
{
RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
break;
RTMPusecDelay(2);
i++;
}
//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
efuseDataOffset = EFUSE_DATA3;
for(i=0; i< 4; i++)
{
RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
efuseDataOffset -= 4;
}
//Step1.2.5. Check if the data of efuse and the writing data are the same.
for(i =0; i<4; i++)
{
tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
bNotWrite&=TRUE;
else
{
bNotWrite&=FALSE;
break;
}
}
if(!bNotWrite)
{
printk("The data is not the same\n");
for(i =0; i<8; i++)
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+2*i;
InBuf[1] = 2;
InBuf[2] = pData[i];
eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
}
}
else
return TRUE;
}
//Step 2. Write mapping table
addr = EFUSE_USAGE_MAP_START+BlkNum;
tmpaddr = addr;
if(addr % 2 != 0)
addr = addr -1;
InBuf[0] = addr;
InBuf[1] = 2;
//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
tmpOffset = Offset;
tmpOffset >>= 4;
tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
// write the logical address
if(tmpaddr%2 != 0)
InBuf[2] = tmpOffset<<8;
else
InBuf[2] = tmpOffset;
eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
bWriteSuccess = TRUE;
for(i =0; i<8; i++)
{
addr = BlkNum * 0x10 ;
InBuf[0] = addr+2*i;
InBuf[1] = 2;
InBuf[2] = 0x0;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
if(pData[i] != InBuf[2])
{
bWriteSuccess = FALSE;
break;
}
}
//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
if (!bWriteSuccess&&Loop<2)
{
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
// the offset of current mapping entry
addr = EFUSE_USAGE_MAP_START+BlkNum;
//find a new mapping entry
BlkNum = 0xffff;
for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
{
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
if( (LogicalAddress & 0xff) == 0)
{
BlkNum = i-EFUSE_USAGE_MAP_START;
break;
}
else if(( (LogicalAddress >> 8) & 0xff) == 0)
{
if (i != EFUSE_USAGE_MAP_END)
{
BlkNum = i+1-EFUSE_USAGE_MAP_START;
}
break;
}
}
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
if(BlkNum == 0xffff)
{
DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
return FALSE;
}
//invalidate the original mapping entry if new entry is not found
tmpaddr = addr;
if(addr % 2 != 0)
addr = addr -1;
InBuf[0] = addr;
InBuf[1] = 2;
eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
// write the logical address
if(tmpaddr%2 != 0)
{
// Invalidate the high byte
for (i=8; i<15; i++)
{
if( ( (InBuf[2] >> i) & 0x01) == 0)
{
InBuf[2] |= (0x1 <<i);
break;
}
}
}
else
{
// invalidate the low byte
for (i=0; i<8; i++)
{
if( ( (InBuf[2] >> i) & 0x01) == 0)
{
InBuf[2] |= (0x1 <<i);
break;
}
}
}
eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
}
}
while(!bWriteSuccess&&Loop<2);
return TRUE;
}
#endif // RT30xx //
//2008/09/11:KH add to support efuse-->
......@@ -338,6 +338,9 @@ UCHAR WpaIe = IE_WPA;
UCHAR Wpa2Ie = IE_WPA2;
UCHAR IbssIe = IE_IBSS_PARM;
UCHAR Ccx2Ie = IE_CCX_V2;
#ifdef RT2870
UCHAR WapiIe = IE_WAPI;
#endif
extern UCHAR WPA_OUI[];
......@@ -446,7 +449,13 @@ FREQUENCY_ITEM FreqItems3020[] =
{13, 247, 2, 2},
{14, 248, 2, 4},
};
#ifndef RT30xx
#define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
#endif
#ifdef RT30xx
//2008/07/10:KH Modified to share this variable
UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
#endif
/*
==========================================================================
......@@ -504,6 +513,7 @@ NDIS_STATUS MlmeInit(
// software-based RX Antenna diversity
RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
#ifdef RT2860
{
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
......@@ -512,6 +522,7 @@ NDIS_STATUS MlmeInit(
RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
}
}
#endif
} while (FALSE);
DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
......@@ -566,6 +577,16 @@ VOID MlmeHandler(
//From message type, determine which state machine I should drive
if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
{
#ifdef RT2870
if (Elem->MsgType == MT2_RESET_CONF)
{
DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
MlmeRestartStateMachine(pAd);
Elem->Occupied = FALSE;
Elem->MsgLen = 0;
continue;
}
#endif // RT2870 //
// if dequeue success
switch (Elem->Machine)
......@@ -636,6 +657,9 @@ VOID MlmeHalt(
IN PRTMP_ADAPTER pAd)
{
BOOLEAN Cancelled;
#ifdef RT3070
UINT32 TxPinCfg = 0x00050F0F;
#endif // RT3070 //
DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
......@@ -653,11 +677,13 @@ VOID MlmeHalt(
RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
}
#endif
}
RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
......@@ -670,6 +696,27 @@ VOID MlmeHalt(
// Set LED
RTMPSetLED(pAd, LED_HALT);
RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
#ifdef RT2870
{
LED_CFG_STRUC LedCfg;
RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
LedCfg.field.LedPolar = 0;
LedCfg.field.RLedMode = 0;
LedCfg.field.GLedMode = 0;
LedCfg.field.YLedMode = 0;
RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
}
#endif // RT2870 //
#ifdef RT3070
//
// Turn off LNA_PE
//
if (IS_RT3070(pAd) || IS_RT3071(pAd))
{
TxPinCfg &= 0xFFFFF0F0;
RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
}
#endif // RT3070 //
}
RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
......@@ -740,6 +787,7 @@ VOID MlmePeriodicExec(
ULONG TxTotalCnt;
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
#ifdef RT2860
//Baron 2008/07/10
//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
......@@ -792,6 +840,7 @@ VOID MlmePeriodicExec(
}
}
}
#endif /* RT2860 */
// Do nothing if the driver is starting halt state.
// This might happen when timer already been fired before cancel timer with mlmehalt
......@@ -801,6 +850,7 @@ VOID MlmePeriodicExec(
fRTMP_ADAPTER_RESET_IN_PROGRESS))))
return;
#ifdef RT2860
{
if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
{
......@@ -838,7 +888,7 @@ VOID MlmePeriodicExec(
AsicResetFromDMABusy(pAd);
}
}
#endif /* RT2860 */
RT28XX_MLME_PRE_SANITY_CHECK(pAd);
{
......@@ -871,6 +921,10 @@ VOID MlmePeriodicExec(
// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
pAd->Mlme.PeriodicRound ++;
#ifdef RT3070
// execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
NICUpdateFifoStaCounters(pAd);
#endif // RT3070 //
// execute every 500ms
if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
{
......@@ -919,6 +973,10 @@ VOID MlmePeriodicExec(
// the dynamic tuning mechanism below are based on most up-to-date information
NICUpdateRawCounters(pAd);
#ifdef RT2870
RT2870_WatchDog(pAd);
#endif // RT2870 //
// Need statistics after read counter. So put after NICUpdateRawCounters
ORIBATimerTimeout(pAd);
......@@ -929,6 +987,7 @@ VOID MlmePeriodicExec(
pAd->RalinkCounters.OneSecTxRetryOkCount +
pAd->RalinkCounters.OneSecTxFailCount;
// dynamic adjust antenna evaluation period according to the traffic
if (TxTotalCnt > 50)
{
if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
......@@ -950,7 +1009,9 @@ VOID MlmePeriodicExec(
MlmeResetRalinkCounters(pAd);
{
#ifdef RT2860
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
#endif
{
// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
// and sending CTS-to-self over and over.
......@@ -976,14 +1037,19 @@ VOID MlmePeriodicExec(
RT28XX_MLME_HANDLER(pAd);
}
pAd->bUpdateBcnCntDone = FALSE;
}
VOID STAMlmePeriodicExec(
PRTMP_ADAPTER pAd)
{
#ifdef RT2860
ULONG TxTotalCnt;
#endif
#ifdef RT2870
ULONG TxTotalCnt;
int i;
#endif
if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
{
......@@ -992,6 +1058,7 @@ VOID STAMlmePeriodicExec(
pAd->StaCfg.bBlockAssoc = FALSE;
}
#ifdef RT2860
//Baron 2008/07/10
//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
......@@ -1004,6 +1071,7 @@ VOID STAMlmePeriodicExec(
{
pAd->StaCfg.WpaSupplicantUP = 1;
}
#endif
if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
{
......@@ -1014,6 +1082,7 @@ VOID STAMlmePeriodicExec(
pAd->PreMediaState = pAd->IndicateMediaState;
}
#ifdef RT2860
if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
(pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
......@@ -1023,6 +1092,7 @@ VOID STAMlmePeriodicExec(
{
RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
}
#endif
......@@ -1119,6 +1189,7 @@ VOID STAMlmePeriodicExec(
}
else if (ADHOC_ON(pAd))
{
#ifdef RT2860
// 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
// the "TX BEACON competition" for the entire past 1 sec.
// So that even when ASIC's BEACONgen engine been blocked
......@@ -1159,6 +1230,7 @@ VOID STAMlmePeriodicExec(
pAd->StaCfg.Adhoc20NJoined = FALSE;
}
}
#endif /* RT2860 */
//radar detect
if ((pAd->CommonCfg.Channel > 14)
......@@ -1183,6 +1255,19 @@ VOID STAMlmePeriodicExec(
MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
}
#ifdef RT2870
for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
{
MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
if (pEntry->ValidAsCLI == FALSE)
continue;
if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
}
#endif
}
else // no INFRA nor ADHOC connection
{
......@@ -1350,10 +1435,16 @@ VOID MlmeSelectTxRateTable(
if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
{
if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
#ifdef RT2860
!pAd->StaCfg.AdhocBOnlyJoined &&
!pAd->StaCfg.AdhocBGJoined &&
(pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
#endif
#ifdef RT2870
(pEntry->HTCapability.MCSSet[0] == 0xff) &&
((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
#endif
{// 11N 1S Adhoc
*ppTable = RateSwitchTable11N1S;
*pTableSize = RateSwitchTable11N1S[0];
......@@ -1361,10 +1452,16 @@ VOID MlmeSelectTxRateTable(
}
else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
#ifdef RT2860
!pAd->StaCfg.AdhocBOnlyJoined &&
!pAd->StaCfg.AdhocBGJoined &&
(pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
(pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
#endif
#ifdef RT2870
(pEntry->HTCapability.MCSSet[0] == 0xff) &&
(pEntry->HTCapability.MCSSet[1] == 0xff) &&
#endif
(pAd->Antenna.field.TxPath == 2))
{// 11N 2S Adhoc
if (pAd->LatchRfRegs.Channel <= 14)
......@@ -1382,6 +1479,7 @@ VOID MlmeSelectTxRateTable(
}
else
#ifdef RT2860
if (pAd->CommonCfg.PhyMode == PHY_11B)
{
*ppTable = RateSwitchTable11B;
......@@ -1390,6 +1488,12 @@ VOID MlmeSelectTxRateTable(
}
else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
#endif
#ifdef RT2870
if ((pEntry->RateLen == 4)
&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
)
#endif
{
// USe B Table when Only b-only Station in my IBSS .
*ppTable = RateSwitchTable11B;
......@@ -1473,7 +1577,10 @@ VOID MlmeSelectTxRateTable(
//else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
if ((pEntry->RateLen == 4)
#ifndef RT30xx
//Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
#endif
)
{// B only AP
*ppTable = RateSwitchTable11B;
......@@ -1934,7 +2041,15 @@ VOID MlmeDynamicTxRateSwitching(
if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
{
#ifdef RT2860
Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
#endif
#ifdef RT2870
Rssi = RTMPMaxRssi(pAd,
pAd->StaCfg.RssiSample.AvgRssi0,
pAd->StaCfg.RssiSample.AvgRssi1,
pAd->StaCfg.RssiSample.AvgRssi2);
#endif
// Update statistic counter
RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
......@@ -1964,7 +2079,21 @@ VOID MlmeDynamicTxRateSwitching(
}
else
{
#ifdef RT2860
Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
#endif
#ifdef RT2870
if (INFRA_ON(pAd) && (i == 1))
Rssi = RTMPMaxRssi(pAd,
pAd->StaCfg.RssiSample.AvgRssi0,
pAd->StaCfg.RssiSample.AvgRssi1,
pAd->StaCfg.RssiSample.AvgRssi2);
else
Rssi = RTMPMaxRssi(pAd,
pEntry->RssiSample.AvgRssi0,
pEntry->RssiSample.AvgRssi1,
pEntry->RssiSample.AvgRssi2);
#endif
TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
pEntry->OneSecTxRetryOkCount +
......@@ -2388,7 +2517,12 @@ VOID StaQuickResponeForRateUpExec(
UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
ULONG TxTotalCnt;
ULONG TxErrorRatio = 0;
#ifdef RT2860
BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
#endif
#ifdef RT2870
BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
#endif
PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
PUCHAR pTable;
UCHAR TableSize = 0;
......@@ -2413,11 +2547,25 @@ VOID StaQuickResponeForRateUpExec(
if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
continue;
#ifdef RT2860
//Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
if (pAd->Antenna.field.TxPath > 1)
Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
else
Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
#endif
#ifdef RT2870
if (INFRA_ON(pAd) && (i == 1))
Rssi = RTMPMaxRssi(pAd,
pAd->StaCfg.RssiSample.AvgRssi0,
pAd->StaCfg.RssiSample.AvgRssi1,
pAd->StaCfg.RssiSample.AvgRssi2);
else
Rssi = RTMPMaxRssi(pAd,
pEntry->RssiSample.AvgRssi0,
pEntry->RssiSample.AvgRssi1,
pEntry->RssiSample.AvgRssi2);
#endif
CurrRateIdx = pAd->CommonCfg.TxRateIndex;
......@@ -2557,6 +2705,9 @@ VOID StaQuickResponeForRateUpExec(
pAd->DrsCounters.TxRateUpPenalty = 0;
NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
#ifdef RT2870
bTxRateChanged = TRUE;
#endif
}
// if rate-down happen, only clear DownRate's bad history
else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
......@@ -2566,6 +2717,9 @@ VOID StaQuickResponeForRateUpExec(
pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
#ifdef RT2870
bTxRateChanged = TRUE;
#endif
}
else
{
......@@ -2621,7 +2775,13 @@ VOID MlmeCheckPsmChange(
if (INFRA_ON(pAd) &&
(PowerMode != Ndis802_11PowerModeCAM) &&
(pAd->StaCfg.Psm == PWR_ACTIVE) &&
#ifdef RT2860
RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
#endif
#if !defined(RT2860) && !defined(RT30xx)
(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
#endif
#ifndef RT30xx
{
NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
pAd->RalinkCounters.RxCountSinceLastNULL = 0;
......@@ -2635,6 +2795,42 @@ VOID MlmeCheckPsmChange(
RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
}
}
#endif
#ifdef RT30xx
// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
(pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
(pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
{
// add by johnli, use Rx OK data count per second to calculate throughput
// If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
// Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
/* Iverson mark
(pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
*/
(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
/* Iverson mark
(pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
*/
(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
{
// Get this time
NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
pAd->RalinkCounters.RxCountSinceLastNULL = 0;
MlmeSetPsmBit(pAd, PWR_SAVE);
if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
{
RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
}
else
{
RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
}
}
}
#endif
}
// IRQL = PASSIVE_LEVEL
......@@ -2649,7 +2845,9 @@ VOID MlmeSetPsmBit(
RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
#ifndef RT30xx
DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
#endif
}
// IRQL = DISPATCH_LEVEL
......@@ -3679,9 +3877,18 @@ ULONG BssTableSetEntry(
}
else
{
#ifdef RT30xx
/* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
(NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
{
#endif
BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
#ifdef RT30xx
}
#endif
}
return Idx;
......@@ -3742,9 +3949,14 @@ VOID BssTableSsidSort(
continue;
// check group cipher
#ifndef RT30xx
if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
#endif
#ifdef RT30xx
if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
#endif
continue;
// check pairwise cipher, skip if none matched
......@@ -3763,9 +3975,14 @@ VOID BssTableSsidSort(
continue;
// check group cipher
#ifndef RT30xx
if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
#endif
#ifdef RT30xx
if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
#endif
continue;
// check pairwise cipher, skip if none matched
......@@ -4043,10 +4260,16 @@ VOID BssCipherParse(
switch (*pTmp)
{
case 1:
#ifndef RT30xx
pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
break;
case 5:
pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
#endif
#ifdef RT30xx
case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
#endif
break;
case 2:
pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
......@@ -4133,7 +4356,6 @@ VOID BssCipherParse(
pBss->AuthMode = Ndis802_11AuthModeWPANone;
pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
pBss->WepStatus = pBss->WPA.GroupCipher;
// Patched bugs for old driver
if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
}
......@@ -4163,10 +4385,16 @@ VOID BssCipherParse(
switch (pCipher->Type)
{
case 1:
#ifndef RT30xx
pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
break;
case 5:
pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
#endif
#ifdef RT30xx
case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
#endif
break;
case 2:
pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
......@@ -4260,7 +4488,6 @@ VOID BssCipherParse(
pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
pBss->WepStatus = pBss->WPA.GroupCipher;
// Patched bugs for old driver
if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
}
......@@ -4619,11 +4846,14 @@ BOOLEAN MlmeDequeue(
VOID MlmeRestartStateMachine(
IN PRTMP_ADAPTER pAd)
{
#ifdef RT2860
MLME_QUEUE_ELEM *Elem = NULL;
#endif
BOOLEAN Cancelled;
DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
#ifdef RT2860
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
if(pAd->Mlme.bRunning)
{
......@@ -4651,6 +4881,7 @@ VOID MlmeRestartStateMachine(
DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
}
}
#endif /* RT2860 */
{
// Cancel all timer events
......@@ -4680,10 +4911,12 @@ VOID MlmeRestartStateMachine(
pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
}
#ifdef RT2860
// Remove running state
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
pAd->Mlme.bRunning = FALSE;
NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
#endif
}
/*! \brief test if the MLME Queue is empty
......@@ -5402,6 +5635,276 @@ VOID AsicUpdateProtect(
}
}
#ifdef RT30xx
/*
========================================================================
Routine Description: Write RT30xx RF register through MAC
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NTSTATUS RT30xxWriteRFRegister(
IN PRTMP_ADAPTER pAd,
IN UCHAR RegID,
IN UCHAR Value)
{
RF_CSR_CFG_STRUC rfcsr;
UINT i = 0;
do
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (!rfcsr.field.RF_CSR_KICK)
break;
i++;
}
while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
return STATUS_UNSUCCESSFUL;
}
rfcsr.field.RF_CSR_WR = 1;
rfcsr.field.RF_CSR_KICK = 1;
rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
rfcsr.field.RF_CSR_DATA = Value;
RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
return STATUS_SUCCESS;
}
/*
========================================================================
Routine Description: Read RT30xx RF register through MAC
Arguments:
Return Value:
IRQL =
Note:
========================================================================
*/
NTSTATUS RT30xxReadRFRegister(
IN PRTMP_ADAPTER pAd,
IN UCHAR RegID,
IN PUCHAR pValue)
{
RF_CSR_CFG_STRUC rfcsr;
UINT i=0, k=0;
for (i=0; i<MAX_BUSY_COUNT; i++)
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (rfcsr.field.RF_CSR_KICK == BUSY)
{
continue;
}
rfcsr.word = 0;
rfcsr.field.RF_CSR_WR = 0;
rfcsr.field.RF_CSR_KICK = 1;
rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
for (k=0; k<MAX_BUSY_COUNT; k++)
{
RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
if (rfcsr.field.RF_CSR_KICK == IDLE)
break;
}
if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
(rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
{
*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
break;
}
}
if (rfcsr.field.RF_CSR_KICK == BUSY)
{
DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
#endif // RT30xx //
#ifdef RT30xx
// add by johnli, RF power sequence setup
/*
==========================================================================
Description:
Load RF normal operation-mode setup
==========================================================================
*/
VOID RT30xxLoadRFNormalModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue = (RFValue & (~0x0C)) | 0x31;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// TX_LO2_en, RF R15 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
// TX_LO1_en, RF R17 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
// to fix rx long range issue
if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
{
RFValue |= 0x20;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
// RX_LO1_en, RF R20 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
// RX_LO2_en, RF R21 register Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x08);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
// LDORF_VC, RF R27 register Bit 2 to 0
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
/* end johnli */
}
/*
==========================================================================
Description:
Load RF sleep-mode setup
==========================================================================
*/
VOID RT30xxLoadRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
// RF_BLOCK_en. RF R1 register Bit 0 to 0
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue &= (~0x01);
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue &= (~0x30);
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue &= (~0x0E);
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 0
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue &= (~0x80);
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
// LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
RFValue |= 0x77;
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue |= 0x1D000000;
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
/*
==========================================================================
Description:
Reverse RF sleep-mode setup
==========================================================================
*/
VOID RT30xxReverseRFSleepModeSetup(
IN PRTMP_ADAPTER pAd)
{
UCHAR RFValue;
UINT32 MACValue;
// RF_BLOCK_en, RF R1 register Bit 0 to 1
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
RFValue |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue |= 0x30;
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
RFValue |= 0x0E;
RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
// RX_CTB_en, RF R21 register Bit 7 to 1
RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
RFValue |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
// LDORF_VC, RF R27 register Bit 2 to 0
RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
if ((pAd->MACVersion & 0xffff) < 0x0211)
RFValue = (RFValue & (~0x77)) | 0x3;
else
RFValue = (RFValue & (~0x77));
RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
// RT3071 version E has fixed this issue
if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
{
// patch tx EVM issue temporarily
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
else
{
RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
}
}
// end johnli
#endif // RT30xx //
/*
==========================================================================
Description:
......@@ -5423,6 +5926,21 @@ VOID AsicSwitchChannel(
RTMP_RF_REGS *RFRegTable;
// Search Tx power value
#ifdef RT30xx
// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
// in ChannelList, so use TxPower array instead.
//
for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
{
if (Channel == pAd->TxPower[index].Channel)
{
TxPwer = pAd->TxPower[index].Power;
TxPwer2 = pAd->TxPower[index].Power2;
break;
}
}
#endif
#ifndef RT30xx
for (index = 0; index < pAd->ChannelListNum; index++)
{
if (Channel == pAd->ChannelList[index].Channel)
......@@ -5432,12 +5950,152 @@ VOID AsicSwitchChannel(
break;
}
}
#endif
if (index == MAX_NUM_OF_CHANNELS)
{
#ifndef RT30xx
DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
#endif
#ifdef RT30xx
DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
#endif
}
#ifdef RT2870
// The RF programming sequence is difference between 3xxx and 2xxx
#ifdef RT30xx
if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
#endif
#ifndef RT30xx
if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
#endif
{
/* modify by WY for Read RF Reg. error */
UCHAR RFValue;
for (index = 0; index < NUM_OF_3020_CHNL; index++)
{
if (Channel == FreqItems3020[index].Channel)
{
// Programming channel parameters
RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
#ifndef RT30xx
RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
// Set Tx Power
RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
RFValue = (RFValue & 0xE0) | TxPwer;
RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
// Set RF offset
RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
#endif
#ifdef RT30xx
RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
// Set Tx0 Power
RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
RFValue = (RFValue & 0xE0) | TxPwer;
RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
// Set Tx1 Power
RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
RFValue = (RFValue & 0xE0) | TxPwer2;
RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
// Tx/Rx Stream setting
RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
//if (IS_RT3090(pAd))
// RFValue |= 0x01; // Enable RF block.
RFValue &= 0x03; //clear bit[7~2]
if (pAd->Antenna.field.TxPath == 1)
RFValue |= 0xA0;
else if (pAd->Antenna.field.TxPath == 2)
RFValue |= 0x80;
if (pAd->Antenna.field.RxPath == 1)
RFValue |= 0x50;
else if (pAd->Antenna.field.RxPath == 2)
RFValue |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
// Set RF offset
RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
#endif
// Set BW
if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
{
RFValue = pAd->Mlme.CaliBW40RfR24;
//DISABLE_11N_CHECK(pAd);
}
else
{
RFValue = pAd->Mlme.CaliBW20RfR24;
}
#ifndef RT30xx
RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
// Enable RF tuning
RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
RFValue = RFValue | 0x1;
RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
// latch channel for future usage.
pAd->LatchRfRegs.Channel = Channel;
#endif
#ifdef RT30xx
RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
// Enable RF tuning
RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
RFValue = RFValue | 0x1;
RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
// latch channel for future usage.
pAd->LatchRfRegs.Channel = Channel;
DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
Channel,
pAd->RfIcType,
TxPwer,
TxPwer2,
pAd->Antenna.field.TxPath,
FreqItems3020[index].N,
FreqItems3020[index].K,
FreqItems3020[index].R));
#endif
break;
}
}
#ifndef RT30xx
DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
Channel,
pAd->RfIcType,
TxPwer,
TxPwer2,
pAd->Antenna.field.TxPath,
FreqItems3020[index].N,
FreqItems3020[index].K,
FreqItems3020[index].R));
#endif
}
else
#endif // RT2870 //
{
RFRegTable = RF2850RegTable;
......@@ -5691,6 +6349,53 @@ VOID AsicAntennaSelect(
IN PRTMP_ADAPTER pAd,
IN UCHAR Channel)
{
#ifdef RT30xx
if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
{
// patch for AsicSetRxAnt failed
pAd->RxAnt.EvaluatePeriod = 0;
// check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
// valid indication of the distance between this AP and its clients.
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
{
SHORT realavgrssi1;
// if no traffic then reset average rssi to trigger evaluation
if (pAd->StaCfg.NumOfAvgRssiSample < 5)
{
pAd->RxAnt.Pair1LastAvgRssi = (-99);
pAd->RxAnt.Pair2LastAvgRssi = (-99);
DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
}
pAd->StaCfg.NumOfAvgRssiSample = 0;
realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
// if the difference between two rssi is larger or less than 5, then evaluate the other antenna
if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
{
pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
AsicEvaluateRxAnt(pAd);
}
}
else
{
// if not connected, always switch antenna to try to connect
UCHAR temp;
temp = pAd->RxAnt.Pair1PrimaryRxAnt;
pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
pAd->RxAnt.Pair1SecondaryRxAnt = temp;
DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
}
#endif /* RT30xx */
}
/*
......@@ -5760,11 +6465,13 @@ VOID AsicAdjustTxPower(
ULONG TxPwr[5];
CHAR Value;
#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
|| (pAd->bPCIclkOff == TRUE)
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
return;
#endif
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
{
......@@ -6020,10 +6727,20 @@ VOID AsicForceSleep(
*/
VOID AsicForceWakeup(
IN PRTMP_ADAPTER pAd,
#ifdef RT2860
IN UCHAR Level)
#endif
#ifdef RT2870
IN BOOLEAN bFromTx)
#endif
{
DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
#ifdef RT2860
RT28XX_STA_FORCE_WAKEUP(pAd, Level);
#endif
#ifdef RT2870
RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
#endif
}
/*
......@@ -6234,6 +6951,7 @@ VOID AsicEnableIbssSync(
csr9.field.bTsfTicking = 0;
RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
#ifdef RT2860
// move BEACON TXD and frame content to on-chip memory
ptr = (PUCHAR)&pAd->BeaconTxWI;
for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
......@@ -6251,6 +6969,24 @@ VOID AsicEnableIbssSync(
RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
ptr +=4;
}
#endif
#ifdef RT2870
// move BEACON TXD and frame content to on-chip memory
ptr = (PUCHAR)&pAd->BeaconTxWI;
for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
{
RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
ptr += 2;
}
// start right after the 16-byte TXWI field
ptr = pAd->BeaconBuf;
for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
{
RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
ptr +=2;
}
#endif // RT2870 //
// start sending BEACON
csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
......@@ -6406,13 +7142,21 @@ VOID AsicSetEdcaParm(
Ac2Cfg.field.Aifsn -= 1;
// Tuning for TGn Wi-Fi 5.2.32
// STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
if (STA_TGN_WIFI_ON(pAd) &&
pEdcaParm->Aifsn[QID_AC_VI] == 10)
{
Ac0Cfg.field.Aifsn = 3;
Ac2Cfg.field.AcTxop = 5;
}
#ifdef RT30xx
if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
{
// Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
Ac2Cfg.field.Aifsn = 5;
}
#endif // RT30xx //
}
Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
......@@ -6479,16 +7223,24 @@ VOID AsicSetEdcaParm(
AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
// Tuning for TGn Wi-Fi 5.2.32
// STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
if (STA_TGN_WIFI_ON(pAd) &&
pEdcaParm->Aifsn[QID_AC_VI] == 10)
{
AifsnCsr.field.Aifsn0 = 3;
AifsnCsr.field.Aifsn2 = 7;
}
#ifdef RT2870
if (INFRA_ON(pAd))
CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
#endif
}
AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
#ifdef RT30xx
if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
#endif // RT30xx //
RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
......@@ -6551,6 +7303,7 @@ VOID AsicSetSlotTime(
SlotTime = (bUseShortSlotTime)? 9 : 20;
{
#ifndef RT30xx
// force using short SLOT time for FAE to demo performance when TxBurst is ON
if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
......@@ -6560,6 +7313,10 @@ VOID AsicSetSlotTime(
// And we will not set to short slot when bEnableTxBurst is TRUE.
}
else if (pAd->CommonCfg.bEnableTxBurst)
#endif
#ifdef RT30xx
if (pAd->CommonCfg.bEnableTxBurst)
#endif
SlotTime = 9;
}
......@@ -6600,7 +7357,9 @@ VOID AsicAddSharedKeyEntry(
{
ULONG offset; //, csr0;
SHAREDKEY_MODE_STRUC csr1;
#ifdef RT2860
INT i;
#endif
DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
//============================================================================================
......@@ -6622,28 +7381,43 @@ VOID AsicAddSharedKeyEntry(
//
// fill key material - key + TX MIC + RX MIC
//
offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
#ifdef RT2860
for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
#endif
offset += MAX_LEN_OF_SHARE_KEY;
if (pTxMic)
{
#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pTxMic, 8);
#endif
}
offset += 8;
if (pRxMic)
{
#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pRxMic, 8);
#endif
}
......@@ -6819,7 +7593,9 @@ VOID AsicAddKeyEntry(
PUCHAR pTxtsc = pCipherKey->TxTsc;
UCHAR CipherAlg = pCipherKey->CipherAlg;
SHAREDKEY_MODE_STRUC csr1;
#ifdef RT2860
UCHAR i;
#endif
DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
//
......@@ -6834,10 +7610,15 @@ VOID AsicAddKeyEntry(
// 2.) Set Key to Asic
//
//for (i = 0; i < KeyLen; i++)
#ifdef RT2860
for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
#endif
offset += MAX_LEN_OF_PEER_KEY;
//
......@@ -6845,19 +7626,29 @@ VOID AsicAddKeyEntry(
//
if (pTxMic)
{
#ifdef RT2860
for (i = 0; i < 8; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pTxMic, 8);
#endif
}
offset += LEN_TKIP_TXMICK;
if (pRxMic)
{
#ifdef RT2860
for (i = 0; i < 8; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, pRxMic, 8);
#endif
}
......@@ -6867,6 +7658,7 @@ VOID AsicAddKeyEntry(
//
if (bTxKey)
{
#ifdef RT2860
offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
//
// Write IV
......@@ -6890,6 +7682,26 @@ VOID AsicAddKeyEntry(
RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
}
#endif
#ifdef RT2870
UINT32 tmpVal;
//
// Write IV
//
IV4 = (KeyIdx << 6);
if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
IV4 |= 0x20; // turn on extension bit means EIV existence
tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
RTMP_IO_WRITE32(pAd, offset, tmpVal);
//
// Write EIV
//
offset += 4;
RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
#endif // RT2870 //
AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
}
......@@ -6954,10 +7766,15 @@ VOID AsicAddPairwiseKeyEntry(
// EKEY
offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
#ifdef RT2860
for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
#endif // RT2870 //
for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
{
UINT32 Value;
......@@ -6969,18 +7786,28 @@ VOID AsicAddPairwiseKeyEntry(
// MIC KEY
if (pTxMic)
{
#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
#endif // RT2870 //
}
offset += 8;
if (pRxMic)
{
#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
}
#endif
#ifdef RT2870
RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
#endif // RT2870 //
}
DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
......@@ -7042,6 +7869,7 @@ BOOLEAN AsicSendCommandToMcu(
if (i >= 100)
{
{
#ifdef RT2860
UINT32 Data;
// Reset DMA
......@@ -7063,9 +7891,13 @@ BOOLEAN AsicSendCommandToMcu(
RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
Data &= 0xfffffffd;
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
#endif /* RT2860 */
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
}
//return FALSE;
#ifdef RT2870
return FALSE;
#endif
}
H2MMailbox.field.Owner = 1; // pass ownership to MCU
......@@ -7085,6 +7917,7 @@ BOOLEAN AsicSendCommandToMcu(
return TRUE;
}
#ifdef RT2860
BOOLEAN AsicCheckCommanOk(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command)
......@@ -7149,6 +7982,7 @@ BOOLEAN AsicCheckCommanOk(
return FALSE;
}
#endif /* RT8260 */
/*
========================================================================
......@@ -7497,6 +8331,58 @@ CHAR RTMPMaxRssi(
return larger;
}
#ifdef RT30xx
// Antenna divesity use GPIO3 and EESK pin for control
// Antenna and EEPROM access are both using EESK pin,
// Therefor we should avoid accessing EESK at the same time
// Then restore antenna after EEPROM access
VOID AsicSetRxAnt(
IN PRTMP_ADAPTER pAd,
IN UCHAR Ant)
{
#ifdef RT30xx
UINT32 Value;
UINT32 x;
if ((pAd->EepromAccess) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
{
return;
}
// the antenna selection is through firmware and MAC register(GPIO3)
if (Ant == 0)
{
// Main antenna
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x |= (EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
}
else
{
// Aux antenna
RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
x &= ~(EESK);
RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
Value &= ~(0x0808);
Value |= 0x08;
RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
}
#endif // RT30xx //
}
#endif /* RT30xx */
/*
========================================================================
Routine Description:
......@@ -7515,6 +8401,7 @@ VOID AsicEvaluateRxAnt(
{
UCHAR BBPR3 = 0;
#ifndef RT30xx
{
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
fRTMP_ADAPTER_HALT_IN_PROGRESS |
......@@ -7543,7 +8430,92 @@ VOID AsicEvaluateRxAnt(
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
#ifdef RT2860
pAd->StaCfg.BBPR3 = BBPR3;
#endif
#ifdef RT2870
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
{
ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
pAd->RalinkCounters.OneSecTxRetryOkCount +
pAd->RalinkCounters.OneSecTxFailCount;
if (TxTotalCnt > 50)
{
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
pAd->Mlme.bLowThroughput = FALSE;
}
else
{
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
pAd->Mlme.bLowThroughput = TRUE;
}
}
#endif
#endif /* RT30xx */
#ifdef RT30xx
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_RADIO_OFF |
fRTMP_ADAPTER_NIC_NOT_EXIST |
fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
#ifdef RT30xx
|| (pAd->EepromAccess)
#endif // RT30xx //
)
return;
{
//if (pAd->StaCfg.Psm == PWR_SAVE)
// return;
}
// two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
// one is antenna diversity:there is only one antenna can rx and tx
// the other is failed antenna remove:two physical antenna can rx and tx
if (pAd->NicConfig2.field.AntDiversity)
{
DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
// a one-shot timer to end the evalution
// dynamic adjust antenna evaluation period according to the traffic
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
else
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
}
else
{
if (pAd->StaCfg.Psm == PWR_SAVE)
return;
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
BBPR3 &= (~0x18);
if(pAd->Antenna.field.RxPath == 3)
{
BBPR3 |= (0x10);
}
else if(pAd->Antenna.field.RxPath == 2)
{
BBPR3 |= (0x8);
}
else if(pAd->Antenna.field.RxPath == 1)
{
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
}
#endif /* RT30xx */
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
......@@ -7552,6 +8524,7 @@ VOID AsicEvaluateRxAnt(
pAd->RalinkCounters.OneSecTxRetryOkCount +
pAd->RalinkCounters.OneSecTxFailCount;
// dynamic adjust antenna evaluation period according to the traffic
if (TxTotalCnt > 50)
{
RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
......@@ -7588,6 +8561,7 @@ VOID AsicRxAntEvalTimeout(
UCHAR BBPR3 = 0;
CHAR larger = -127, rssi0, rssi1, rssi2;
#ifndef RT30xx
{
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
......@@ -7645,8 +8619,111 @@ VOID AsicRxAntEvalTimeout(
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
#ifdef RT2860
pAd->StaCfg.BBPR3 = BBPR3;
#endif
}
#endif /* RT30xx */
#ifdef RT30xx
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
fRTMP_ADAPTER_HALT_IN_PROGRESS |
fRTMP_ADAPTER_RADIO_OFF |
fRTMP_ADAPTER_NIC_NOT_EXIST) ||
OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
#ifdef RT30xx
|| (pAd->EepromAccess)
#endif // RT30xx //
)
return;
{
//if (pAd->StaCfg.Psm == PWR_SAVE)
// return;
if (pAd->NicConfig2.field.AntDiversity)
{
if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
{
UCHAR temp;
//
// select PrimaryRxAntPair
// Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
// Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
//
temp = pAd->RxAnt.Pair1PrimaryRxAnt;
pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
pAd->RxAnt.Pair1SecondaryRxAnt = temp;
pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
pAd->RxAnt.EvaluateStableCnt = 0;
}
else
{
// if the evaluated antenna is not better than original, switch back to original antenna
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
pAd->RxAnt.EvaluateStableCnt ++;
}
pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
}
else
{
if (pAd->StaCfg.Psm == PWR_SAVE)
return;
// if the traffic is low, use average rssi as the criteria
if (pAd->Mlme.bLowThroughput == TRUE)
{
rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
}
else
{
rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
}
if(pAd->Antenna.field.RxPath == 3)
{
larger = max(rssi0, rssi1);
if (larger > (rssi2 + 20))
pAd->Mlme.RealRxPath = 2;
else
pAd->Mlme.RealRxPath = 3;
}
else if(pAd->Antenna.field.RxPath == 2)
{
if (rssi0 > (rssi1 + 20))
pAd->Mlme.RealRxPath = 1;
else
pAd->Mlme.RealRxPath = 2;
}
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
BBPR3 &= (~0x18);
if(pAd->Mlme.RealRxPath == 3)
{
BBPR3 |= (0x10);
}
else if(pAd->Mlme.RealRxPath == 2)
{
BBPR3 |= (0x8);
}
else if(pAd->Mlme.RealRxPath == 1)
{
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
}
}
#endif /* RT30xx */
}
......@@ -7845,7 +8922,12 @@ VOID AsicStaBbpTuning(
&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
#ifdef RT2860
&& (pAd->bPCIclkOff == FALSE))
#endif
#ifdef RT2870
)
#endif
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
R66 = OrigR66Value;
......@@ -7857,6 +8939,45 @@ VOID AsicStaBbpTuning(
if (pAd->LatchRfRegs.Channel <= 14)
{ //BG band
#ifdef RT2870
// RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
// Otherwise, it will have some throughput side effect when low RSSI
#ifndef RT30xx
if (IS_RT3070(pAd))
#endif
#ifdef RT30xx
if (IS_RT30xx(pAd))
#endif
{
if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
{
R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
if (OrigR66Value != R66)
{
#ifndef RT30xx
RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
#endif
#ifdef RT30xx
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
#endif
}
}
else
{
R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
if (OrigR66Value != R66)
{
#ifndef RT30xx
RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
#endif
#ifdef RT30xx
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
#endif
}
}
}
else
#endif // RT2870 //
{
if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
{
......@@ -7922,6 +9043,7 @@ VOID AsicStaBbpTuning(
}
}
#ifdef RT2860
VOID AsicResetFromDMABusy(
IN PRTMP_ADAPTER pAd)
{
......@@ -8021,6 +9143,7 @@ VOID AsicResetPBF(
DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
}
}
#endif /* RT2860 */
VOID RTMPSetAGCInitValue(
IN PRTMP_ADAPTER pAd,
......@@ -8059,6 +9182,15 @@ VOID AsicTurnOffRFClk(
UCHAR index;
RTMP_RF_REGS *RFRegTable;
#ifdef RT30xx
// The RF programming sequence is difference between 3xxx and 2xxx
if (IS_RT3090(pAd))
{
RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
}
else
{
#endif // RT30xx //
RFRegTable = RF2850RegTable;
switch (pAd->RfIcType)
......@@ -8100,6 +9232,10 @@ VOID AsicTurnOffRFClk(
default:
break;
}
#ifdef RT30xx
}
#endif // RT30xx //
}
......@@ -8113,6 +9249,14 @@ VOID AsicTurnOnRFClk(
UCHAR index;
RTMP_RF_REGS *RFRegTable;
#ifdef RT30xx
// The RF programming sequence is difference between 3xxx and 2xxx
if (IS_RT3090(pAd))
{
}
else
{
#endif // RT30xx //
RFRegTable = RF2850RegTable;
switch (pAd->RfIcType)
......@@ -8159,9 +9303,14 @@ VOID AsicTurnOnRFClk(
break;
}
#ifndef RT30xx
DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
Channel,
pAd->RfIcType,
R2));
#endif
#ifdef RT30xx
}
#endif // RT30xx //
}
......@@ -38,8 +38,18 @@
Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
*/
#include "../rt_config.h"
#include "firmware.h"
#ifndef RT30xx
#ifdef RT2860
#include "firmware.h"
#include <linux/bitrev.h>
#endif
#ifdef RT2870
#include "../../rt2870/common/firmware.h"
#endif
#endif
#ifdef RT30xx
#include "../../rt3070/firmware.h"
#endif
UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
......@@ -90,6 +100,22 @@ const unsigned short ccitt_16Table[] = {
#define ByteCRC16(v, crc) \
(unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
#ifdef RT2870
unsigned char BitReverse(unsigned char x)
{
int i;
unsigned char Temp=0;
for(i=0; ; i++)
{
if(x & 0x80) Temp |= 0x80;
if(i==7) break;
x <<= 1;
Temp >>= 1;
}
return Temp;
}
#endif
//
// BBP register initialization set
//
......@@ -114,6 +140,38 @@ REG_PAIR BBPRegTable[] = {
//
// RF register initialization set
//
#ifdef RT2870
REG_PAIR RT30xx_RFRegTable[] = {
{RF_R04, 0x40},
{RF_R05, 0x03},
{RF_R06, 0x02},
{RF_R07, 0x70},
{RF_R09, 0x0F},
#ifndef RT30xx
{RF_R10, 0x71},
#endif
#ifdef RT30xx
{RF_R10, 0x41},
#endif
{RF_R11, 0x21},
{RF_R12, 0x7B},
{RF_R14, 0x90},
{RF_R15, 0x58},
{RF_R16, 0xB3},
{RF_R17, 0x92},
{RF_R18, 0x2C},
{RF_R19, 0x02},
{RF_R20, 0xBA},
{RF_R21, 0xDB},
{RF_R24, 0x16},
{RF_R25, 0x01},
#ifndef RT30xx
{RF_R27, 0x03},
#endif
{RF_R29, 0x1F},
};
#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
#endif // RT2870 //
//
// ASIC register initialization sets
......@@ -146,10 +204,18 @@ RTMP_REG_PAIR MACRegTable[] = {
{AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
{CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
{OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
#ifdef RT2870
{PBF_CFG, 0xf40006}, // Only enable Queue 2
{MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
{WPDMA_GLO_CFG, 0x00000030},
#endif // RT2870 //
{GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
{GF40_PROT_CFG, 0x03F44084},
{MM20_PROT_CFG, 0x01744004},
#ifdef RT2860
{MM40_PROT_CFG, 0x03F54084},
#endif
{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
{TX_RTS_CFG, 0x00092b20},
{EXP_ACK_TIME, 0x002400ca}, // default value
......@@ -172,6 +238,13 @@ RTMP_REG_PAIR STAMACRegTable[] = {
#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
#ifdef RT2870
//
// RT2870 Firmware Spec only used 1 oct for version expression
//
#define FIRMWARE_MINOR_VERSION 7
#endif // RT2870 //
// New 8k byte firmware size for RT3071/RT3072
#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
......@@ -181,7 +254,9 @@ RTMP_REG_PAIR STAMACRegTable[] = {
#define FIRMWAREIMAGEV1_LENGTH 0x1000
#define FIRMWAREIMAGEV2_LENGTH 0x1000
#ifdef RT2860
#define FIRMWARE_MINOR_VERSION 2
#endif
/*
......@@ -239,7 +314,9 @@ NDIS_STATUS RTMPAllocAdapterBlock(
// Init spin locks
NdisAllocateSpinLock(&pAd->MgmtRingLock);
#ifdef RT2860
NdisAllocateSpinLock(&pAd->RxRingLock);
#endif
for (index =0 ; index < NUM_OF_TX_RING; index++)
{
......@@ -1005,6 +1082,425 @@ NDIS_STATUS NICReadRegParameters(
}
#ifdef RT2870
/*
========================================================================
Routine Description:
For RF filter calibration purpose
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
========================================================================
*/
#ifndef RT30xx
VOID RTUSBFilterCalibration(
IN PRTMP_ADAPTER pAd)
{
UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue;
UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
UCHAR RF_R24_Value = 0;
// Give bbp filter initial value
pAd->Mlme.CaliBW20RfR24 = 0x16;
pAd->Mlme.CaliBW40RfR24 = 0x36; //Bit[5] must be 1 for BW 40
do
{
if (loop == 1) //BandWidth = 40 MHz
{
// Write 0x27 to RF_R24 to program filter
RF_R24_Value = 0x27;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
FilterTarget = 0x19;
// when calibrate BW40, BBP mask must set to BW40.
RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
BBPValue|= (0x10);
RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
}
else //BandWidth = 20 MHz
{
// Write 0x07 to RF_R24 to program filter
RF_R24_Value = 0x07;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
FilterTarget = 0x16;
}
// Write 0x01 to RF_R22 to enable baseband loopback mode
RT30xxReadRFRegister(pAd, RF_R22, &value);
value |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R22, value);
// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
do
{
// Write 0x90 to BBP_R25 to transmit test tone
RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
RTMPusecDelay(1000);
// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
RTUSBReadBBPRegister(pAd, BBP_R55, &value);
R55x = value & 0xFF;
} while ((ReTry++ < 100) && (R55x == 0));
// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
RTUSBWriteBBPRegister(pAd, BBP_R24, 0x06);
while(TRUE)
{
// Write 0x90 to BBP_R25 to transmit test tone
RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
//We need to wait for calibration
RTMPusecDelay(1000);
RTUSBReadBBPRegister(pAd, BBP_R55, &value);
value &= 0xFF;
if ((R55x - value) < FilterTarget)
{
RF_R24_Value ++;
}
else if ((R55x - value) == FilterTarget)
{
RF_R24_Value ++;
count ++;
}
else
{
break;
}
// prevent infinite loop cause driver hang.
if (loopcnt++ > 100)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTUSBFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
break;
}
// Write RF_R24 to program filter
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
}
if (count > 0)
{
RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
}
// Store for future usage
if (loopcnt < 100)
{
if (loop++ == 0)
{
//BandWidth = 20 MHz
pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
}
else
{
//BandWidth = 40 MHz
pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
break;
}
}
else
break;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
// reset count
count = 0;
} while(TRUE);
//
// Set back to initial state
//
RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
RT30xxReadRFRegister(pAd, RF_R22, &value);
value &= ~(0x01);
RT30xxWriteRFRegister(pAd, RF_R22, value);
// set BBP back to BW20
RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("RTUSBFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
}
#endif /* RT30xx */
#ifdef RT30xx
VOID RTMPFilterCalibration(
IN PRTMP_ADAPTER pAd)
{
UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
UCHAR RF_R24_Value = 0;
// Give bbp filter initial value
pAd->Mlme.CaliBW20RfR24 = 0x1F;
pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
do
{
if (loop == 1) //BandWidth = 40 MHz
{
// Write 0x27 to RF_R24 to program filter
RF_R24_Value = 0x27;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd))
FilterTarget = 0x15;
else
FilterTarget = 0x19;
// when calibrate BW40, BBP mask must set to BW40.
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
BBPValue|= (0x10);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
// set to BW40
RT30xxReadRFRegister(pAd, RF_R31, &value);
value |= 0x20;
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
else //BandWidth = 20 MHz
{
// Write 0x07 to RF_R24 to program filter
RF_R24_Value = 0x07;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
if (IS_RT3090(pAd))
FilterTarget = 0x13;
else
FilterTarget = 0x16;
// set to BW20
RT30xxReadRFRegister(pAd, RF_R31, &value);
value &= (~0x20);
RT30xxWriteRFRegister(pAd, RF_R31, value);
}
// Write 0x01 to RF_R22 to enable baseband loopback mode
RT30xxReadRFRegister(pAd, RF_R22, &value);
value |= 0x01;
RT30xxWriteRFRegister(pAd, RF_R22, value);
// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
do
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
RTMPusecDelay(1000);
// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
R55x = value & 0xFF;
} while ((ReTry++ < 100) && (R55x == 0));
// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
while(TRUE)
{
// Write 0x90 to BBP_R25 to transmit test tone
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
//We need to wait for calibration
RTMPusecDelay(1000);
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
value &= 0xFF;
if ((R55x - value) < FilterTarget)
{
RF_R24_Value ++;
}
else if ((R55x - value) == FilterTarget)
{
RF_R24_Value ++;
count ++;
}
else
{
break;
}
// prevent infinite loop cause driver hang.
if (loopcnt++ > 100)
{
DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
break;
}
// Write RF_R24 to program filter
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
}
if (count > 0)
{
RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
}
// Store for future usage
if (loopcnt < 100)
{
if (loop++ == 0)
{
//BandWidth = 20 MHz
pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
}
else
{
//BandWidth = 40 MHz
pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
break;
}
}
else
break;
RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
// reset count
count = 0;
} while(TRUE);
//
// Set back to initial state
//
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
RT30xxReadRFRegister(pAd, RF_R22, &value);
value &= ~(0x01);
RT30xxWriteRFRegister(pAd, RF_R22, value);
// set BBP back to BW20
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
BBPValue&= (~0x18);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
}
#endif /* RT30xx */
VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
{
INT i;
// Driver must read EEPROM to get RfIcType before initial RF registers
// Initialize RF register to default value
#ifndef RT30xx
if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) ||(pAd->RfIcType == RFIC_2020)))
{
// Init RF calibration
// Driver should toggle RF R30 bit7 before init RF registers
ULONG RfReg = 0;
RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
// Initialize RF register to default value
for (i = 0; i < NUM_RF_REG_PARMS; i++)
{
RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
}
//For RF filter Calibration
RTUSBFilterCalibration(pAd);
}
#endif
#ifdef RT30xx
if (IS_RT3070(pAd) || IS_RT3071(pAd))
{
// Init RF calibration
// Driver should toggle RF R30 bit7 before init RF registers
UINT32 RfReg = 0;
UINT32 data;
RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
RfReg |= 0x80;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
RTMPusecDelay(1000);
RfReg &= 0x7F;
RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
// Initialize RF register to default value
for (i = 0; i < NUM_RF_REG_PARMS; i++)
{
RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
}
// add by johnli
if (IS_RT3070(pAd))
{
// Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
data = ((data & 0xF0FFFFFF) | 0x0D000000);
RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
}
else if (IS_RT3071(pAd))
{
// Driver should set RF R6 bit6 on before init RF registers
RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
RfReg |= 0x40;
RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
// init R31
RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
// RT3071 version E has fixed this issue
if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
{
// patch tx EVM issue temporarily
RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
data = ((data & 0xE0FFFFFF) | 0x0D000000);
RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
}
else
{
RTMP_IO_READ32(pAd, LDO_CFG0, &data);
data = ((data & 0xE0FFFFFF) | 0x01000000);
RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
}
// patch LNA_PE_G1 failed issue
RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
data &= ~(0x20);
RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
}
//For RF filter Calibration
RTMPFilterCalibration(pAd);
// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
if ((pAd->MACVersion & 0xffff) < 0x0211)
RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
// set led open drain enable
RTUSBReadMACRegister(pAd, OPT_14, &data);
data |= 0x01;
RTUSBWriteMACRegister(pAd, OPT_14, data);
if (IS_RT3071(pAd))
{
// add by johnli, RF power sequence setup, load RF normal operation-mode setup
RT30xxLoadRFNormalModeSetup(pAd);
}
}
#endif
}
#endif // RT2870 //
/*
......@@ -1179,11 +1675,25 @@ VOID NICReadEEPROMParameters(
Antenna.word = pAd->EEPROMDefaultValue[0];
if (Antenna.word == 0xFFFF)
{
#ifdef RT30xx
if(IS_RT3090(pAd))
{
Antenna.word = 0;
Antenna.field.RfIcType = RFIC_3020;
Antenna.field.TxPath = 1;
Antenna.field.RxPath = 1;
}
else
{
#endif // RT30xx //
Antenna.word = 0;
Antenna.field.RfIcType = RFIC_2820;
Antenna.field.TxPath = 1;
Antenna.field.RxPath = 2;
DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
#ifdef RT30xx
}
#endif // RT30xx //
}
// Choose the desired Tx&Rx stream.
......@@ -1212,7 +1722,9 @@ VOID NICReadEEPROMParameters(
NicConfig2.word = pAd->EEPROMDefaultValue[1];
{
#ifndef RT30xx
NicConfig2.word = 0;
#endif
if ((NicConfig2.word & 0x00ff) == 0xff)
{
NicConfig2.word &= 0xff00;
......@@ -1405,6 +1917,14 @@ VOID NICReadEEPROMParameters(
RTMPReadTxPwrPerRate(pAd);
#ifdef RT30xx
if (IS_RT30xx(pAd))
{
eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
pAd->EFuseTag = (value & 0xff);
}
#endif // RT30xx //
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
}
......@@ -1449,16 +1969,49 @@ VOID NICInitAsicFromEEPROM(
}
}
#ifndef RT30xx
Antenna.word = pAd->Antenna.word;
#endif
#ifdef RT30xx
Antenna.word = pAd->EEPROMDefaultValue[0];
if (Antenna.word == 0xFFFF)
{
DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
BUG_ON(Antenna.word == 0xFFFF);
}
#endif
pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
#ifdef RT30xx
DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
// Save the antenna for future use
pAd->Antenna.word = Antenna.word;
#endif
NicConfig2.word = pAd->EEPROMDefaultValue[1];
#ifdef RT30xx
{
if ((NicConfig2.word & 0x00ff) == 0xff)
{
NicConfig2.word &= 0xff00;
}
if ((NicConfig2.word >> 8) == 0xff)
{
NicConfig2.word &= 0x00ff;
}
}
#endif
// Save the antenna for future use
pAd->NicConfig2.word = NicConfig2.word;
#ifdef RT30xx
// set default antenna as main
if (pAd->RfIcType == RFIC_3020)
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
#endif
//
// Send LED Setting to MCU.
//
......@@ -1467,7 +2020,13 @@ VOID NICInitAsicFromEEPROM(
pAd->LedCntl.word = 0x01;
pAd->Led1 = 0x5555;
pAd->Led2 = 0x2221;
#ifdef RT2860
pAd->Led3 = 0xA9F8;
#endif
#ifdef RT2870
pAd->Led3 = 0x5627;
#endif // RT2870 //
}
AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
......@@ -1501,10 +2060,12 @@ VOID NICInitAsicFromEEPROM(
else
{
RTMPSetLED(pAd, LED_RADIO_ON);
#ifdef RT2860
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
// 2-1. wait command ok.
AsicCheckCommanOk(pAd, PowerWakeCID);
#endif
}
}
......@@ -1579,8 +2140,10 @@ NDIS_STATUS NICInitializeAdapter(
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
WPDMA_GLO_CFG_STRUC GloCfg;
#ifdef RT2860
UINT32 Value;
DELAY_INT_CFG_STRUC IntCfg;
#endif
ULONG i =0, j=0;
AC_TXOP_CSR0_STRUC csr0;
......@@ -1619,9 +2182,11 @@ NDIS_STATUS NICInitializeAdapter(
// asic simulation sequence put this ahead before loading firmware.
// pbf hardware reset
#ifdef RT2860
RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings.
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
#endif
// Initialze ASIC for TX & Rx operation
if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
......@@ -1635,6 +2200,7 @@ NDIS_STATUS NICInitializeAdapter(
}
#ifdef RT2860
// Write AC_BK base address register
Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
......@@ -1707,6 +2273,7 @@ NDIS_STATUS NICInitializeAdapter(
// Write RX_RING_CSR register
Value = RX_RING_SIZE;
RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
#endif /* RT2860 */
// WMM parameter
......@@ -1725,6 +2292,7 @@ NDIS_STATUS NICInitializeAdapter(
RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
#ifdef RT2860
// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
i = 0;
do
......@@ -1743,6 +2311,7 @@ NDIS_STATUS NICInitializeAdapter(
IntCfg.word = 0;
RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
#endif
// reset action
......@@ -1778,33 +2347,134 @@ NDIS_STATUS NICInitializeAsic(
ULONG Index = 0;
UCHAR R0 = 0xff;
UINT32 MacCsr12 = 0, Counter = 0;
#ifdef RT2870
UINT32 MacCsr0 = 0;
NTSTATUS Status;
UCHAR Value = 0xff;
#endif // RT2870 //
#ifdef RT30xx
UINT32 eFuseCtrl;
#endif // RT30xx //
USHORT KeyIdx;
INT i,apidx;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
#ifdef RT2860
if (bHardReset == TRUE)
{
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
}
else
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
#endif
#ifdef RT2870
//
// Make sure MAC gets ready after NICLoadFirmware().
//
Index = 0;
//To avoid hang-on issue when interface up in kernel 2.4,
//we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
do
{
RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
break;
RTMPusecDelay(10);
} while (Index++ < 100);
pAd->MACVersion = MacCsr0;
DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
// turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
MacCsr12 &= (~0x2000);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
Status = RTUSBVenderReset(pAd);
#endif
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
// Initialize MAC register to default value
#ifdef RT2860
for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
{
RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
}
#endif
#ifdef RT2870
for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
{
#ifdef RT3070
if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
{
MACRegTable[Index].Value = 0x00000400;
}
#endif // RT3070 //
RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
}
#ifndef RT30xx
if(IS_RT3070(pAd))
{
// According to Frank Hsu (from Gary Tsao)
RTMP_IO_WRITE32(pAd, (USHORT)TX_SW_CFG0, 0x00000400);
// Initialize RT3070 serial MAC registers which is different from RT2870 serial
RTUSBWriteMACRegister(pAd, TX_SW_CFG1, 0);
RTUSBWriteMACRegister(pAd, TX_SW_CFG2, 0);
}
#endif
#endif // RT2870 //
{
for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
{
#ifdef RT2860
RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
#endif
#ifdef RT2870
RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
#endif
}
}
#ifdef RT30xx
// Initialize RT3070 serial MAc registers which is different from RT2870 serial
if (IS_RT3090(pAd))
{
RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
// RT3071 version E has fixed this issue
if ((pAd->MACVersion & 0xffff) < 0x0211)
{
if (pAd->NicConfig2.field.DACTestBit == 1)
{
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
}
else
{
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); // To fix throughput drop drastically
}
}
else
{
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
}
}
else if (IS_RT3070(pAd))
{
RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
}
#endif // RT30xx //
//
// Before program BBP, we need to wait BBP/RF get wake up.
//
......@@ -1844,11 +2514,69 @@ NDIS_STATUS NICInitializeAsic(
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
}
#ifndef RT30xx
// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
if ((pAd->MACVersion&0xffff) != 0x0101)
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
#ifdef RT2870
//write RT3070 BBP wchich different with 2870 after write RT2870 BBP
if (IS_RT3070(pAd))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x99);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x05);
}
#endif // RT2870 //
#endif
#ifdef RT30xx
// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
// RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
// add by johnli, RF power sequence setup
if (IS_RT30xx(pAd))
{ //update for RT3070/71/72/90/91/92.
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
}
if (IS_RT3090(pAd))
{
UCHAR bbpreg=0;
// enable DC filter
if ((pAd->MACVersion & 0xffff) >= 0x0211)
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
}
// improve power consumption
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
if (pAd->Antenna.field.TxPath == 1)
{
// turn off tx DAC_1
bbpreg = (bbpreg | 0x20);
}
if (pAd->Antenna.field.RxPath == 1)
{
// turn off tx ADC_1
bbpreg &= (~0x2);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
// improve power consumption in RT3071 Ver.E
if ((pAd->MACVersion & 0xffff) >= 0x0211)
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
bbpreg &= (~0x3);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
}
}
#endif
if (pAd->MACVersion == 0x28600100)
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
......@@ -1865,6 +2593,18 @@ NDIS_STATUS NICInitializeAsic(
RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
}
#ifdef RT2870
{
UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
//Initialize WCID table
Value = 0xff;
for(Index =0 ;Index < 254;Index++)
{
RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
}
}
#endif // RT2870 //
// Add radio off control
{
......@@ -1912,6 +2652,35 @@ NDIS_STATUS NICInitializeAsic(
RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
}
}
#ifdef RT2870
AsicDisableSync(pAd);
// Clear raw counters
RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
// Default PCI clock cycle per ms is different as default setting, which is based on PCI.
RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
Counter&=0xffffff00;
Counter|=0x000001e;
RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
#endif // RT2870 //
#ifdef RT30xx
pAd->bUseEfuse=FALSE;
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
if(pAd->bUseEfuse)
{
DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
}
#endif // RT30xx //
{
// for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
......@@ -1924,6 +2693,7 @@ NDIS_STATUS NICInitializeAsic(
}
#ifdef RT2860
VOID NICRestoreBBPValue(
IN PRTMP_ADAPTER pAd)
{
......@@ -2047,6 +2817,7 @@ VOID NICRestoreBBPValue(
DBGPRINT(RT_DEBUG_TRACE, ("<--- NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
}
#endif /* RT2860 */
/*
========================================================================
......@@ -2299,6 +3070,22 @@ VOID NICUpdateRawCounters(
// Update RX Overflow counter
pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
#ifdef RT2870
if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
{
pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
pAd->watchDogRxOverFlowCnt = 0;
}
else
{
if (RxStaCnt2.field.RxFifoOverflowCount)
pAd->watchDogRxOverFlowCnt++;
else
pAd->watchDogRxOverFlowCnt = 0;
}
#endif // RT2870 //
if (!pAd->bUpdateBcnCntDone)
{
// Update BEACON sent count
......@@ -2531,9 +3318,40 @@ NDIS_STATUS NICLoadFirmware(
ULONG FileLength, Index;
//ULONG firm;
UINT32 MacReg = 0;
#ifdef RT2870
UINT32 Version = (pAd->MACVersion >> 16);
#endif // RT2870 //
pFirmwareImage = FirmwareImage;
FileLength = sizeof(FirmwareImage);
#ifdef RT2870
// New 8k byte firmware size for RT3071/RT3072
//printk("Usb Chip\n");
if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
//The firmware image consists of two parts. One is the origianl and the other is the new.
//Use Second Part
{
if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
{ // Use Firmware V2.
//printk("KH:Use New Version,part2\n");
pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
FileLength = FIRMWAREIMAGEV2_LENGTH;
}
else
{
//printk("KH:Use New Version,part1\n");
pFirmwareImage = FirmwareImage;
FileLength = FIRMWAREIMAGEV1_LENGTH;
}
}
else
{
DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
Status = NDIS_STATUS_FAILURE;
}
#endif // RT2870 //
RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
/* check if MCU is ready */
......@@ -2799,6 +3617,31 @@ VOID UserCfgInit(
//
// part I. intialize common configuration
//
#ifdef RT2870
pAd->BulkOutReq = 0;
pAd->BulkOutComplete = 0;
pAd->BulkOutCompleteOther = 0;
pAd->BulkOutCompleteCancel = 0;
pAd->BulkInReq = 0;
pAd->BulkInComplete = 0;
pAd->BulkInCompleteFail = 0;
//pAd->QuickTimerP = 100;
//pAd->TurnAggrBulkInCount = 0;
pAd->bUsbTxBulkAggre = 0;
// init as unsed value to ensure driver will set to MCU once.
pAd->LedIndicatorStregth = 0xFF;
pAd->CommonCfg.MaxPktOneTxBulk = 2;
pAd->CommonCfg.TxBulkFactor = 1;
pAd->CommonCfg.RxBulkFactor =1;
pAd->CommonCfg.TxPower = 100; //mW
NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
#endif // RT2870 //
for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
{
......@@ -2809,14 +3652,19 @@ VOID UserCfgInit(
}
}
#ifdef RT30xx
pAd->EepromAccess = FALSE;
#endif
pAd->Antenna.word = 0;
pAd->CommonCfg.BBPCurrentBW = BW_20;
pAd->LedCntl.word = 0;
#ifdef RT2860
pAd->LedIndicatorStregth = 0;
pAd->RLnkCtrlOffset = 0;
pAd->HostLnkCtrlOffset = 0;
pAd->CheckDmaBusyCount = 0;
#endif
pAd->bAutoTxAgcA = FALSE; // Default is OFF
pAd->bAutoTxAgcG = FALSE; // Default is OFF
......@@ -3020,9 +3868,11 @@ VOID UserCfgInit(
NdisAllocateSpinLock(&pAd->MacTabLock);
pAd->CommonCfg.bWiFiTest = FALSE;
#ifdef RT2860
pAd->bPCIclkOff = FALSE;
RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
#endif
DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
}
......@@ -3124,6 +3974,9 @@ VOID RTMPInitTimer(
pTimer->State = FALSE;
pTimer->cookie = (ULONG) pData;
#ifdef RT2870
pTimer->pAd = pAd;
#endif // RT2870 //
RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
}
......@@ -3250,6 +4103,12 @@ VOID RTMPCancelTimer(
if (*pCancelled == TRUE)
pTimer->State = TRUE;
#ifdef RT2870
// We need to go-through the TimerQ to findout this timer handler and remove it if
// it's still waiting for execution.
RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
#endif // RT2870 //
}
else
{
......
......@@ -1570,7 +1570,12 @@ static VOID PeerMeasureReportAction(
if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
{
#ifndef RT30xx
DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
#endif
#ifdef RT30xx
DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
#endif
return;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment