]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
Staging: rt2860: prepare for rt28[67]0/common/*.[ch] merge
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Sun, 26 Apr 2009 14:06:28 +0000 (16:06 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 19 Jun 2009 18:00:50 +0000 (11:00 -0700)
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/rt2860/common/action.c
drivers/staging/rt2860/common/ba_action.c
drivers/staging/rt2860/common/cmm_data.c
drivers/staging/rt2860/common/cmm_info.c
drivers/staging/rt2860/common/cmm_sync.c
drivers/staging/rt2860/common/cmm_wpa.c
drivers/staging/rt2860/common/eeprom.c
drivers/staging/rt2860/common/mlme.c
drivers/staging/rt2860/common/rtmp_init.c
drivers/staging/rt2860/common/spectrum.c

index c270ccda2c1195da4bfd7b948128468cdb6040e3..a4d9fdc0736e1b0c828c68b0c391ffc7b77dbd5f 100644 (file)
@@ -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);
                }
index 6b0898dc20871804064bfe8d916b52e33fdba9dc..b95a341caacd77f6ed4a7a2011d246c814826350 100644 (file)
@@ -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;
        }
index d857d06fd772b2edd17af44145b48a896650e4e7..66eca202eae4d3e5b60dd0f01e950c37c8bd2db8 100644 (file)
@@ -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);
 
index ea76f5b252cfbc64312f03df3a6f9856a407695a..306c3a21f90557c2964bdb88dcb7ed2d5960a4d5 100644 (file)
@@ -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
        }
 }
 
index 360b3bcb97d3c0b35d7a7dfc59c1473adcd2bf0c..a6e1b6ddfe57ef669d88019a036d9922a846b27d 100644 (file)
@@ -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);
index e206077e278a46e5e6ee38c5062a843f3cd16a41..d467f5338c456d4f9660adf75cbd6db83a330f4d 100644 (file)
 // 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);
index bed2d666629c130d3f2373f96c522688166a6d73..9729323baca5e04f7ea74883ba7f65d26c55a745 100644 (file)
@@ -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-->
index 51468689a3827bf159e51de31449ce4e6494f2d9..e9e69c539e6f951d850d069fa808b3e4972c9b73 100644 (file)
@@ -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 //
 }
 
index d79877e1e82a628fba758facf7f900b0f7132713..c2facac5cf88137c42198ec2c97d7d93453a2fe1 100644 (file)
     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 @@ retry:
 
        // 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 @@ retry:
        }
 
 
+#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 @@ retry:
        // 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 @@ retry:
        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 @@ retry:
 
        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
        {
index c658bf3082c31debc547042722966327939839c2..101c2923ca370f3e9af0b053cb2a75e6e54903c5 100644 (file)
@@ -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;
        }