Browse Source

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

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Bartlomiej Zolnierkiewicz 16 years ago
parent
commit
59fe2d89b6

+ 6 - 0
drivers/staging/rt2860/common/action.c

@@ -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);
 		}

+ 62 - 1
drivers/staging/rt2860/common/ba_action.c

@@ -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;
 	}

+ 222 - 8
drivers/staging/rt2860/common/cmm_data.c

@@ -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);
 

+ 44 - 1
drivers/staging/rt2860/common/cmm_info.c

@@ -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
 	}
 }
 

+ 12 - 1
drivers/staging/rt2860/common/cmm_sync.c

@@ -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);

+ 10 - 2
drivers/staging/rt2860/common/cmm_wpa.c

@@ -39,10 +39,14 @@
 // WPA OUI
 UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
 UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
+#ifndef RT30xx
 UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
+#endif
 UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
 UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
+#ifndef RT30xx
 UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
+#endif
 UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
 UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
 // WPA2 OUI
@@ -51,7 +55,9 @@ UCHAR       OUI_WPA2_TKIP[4]        = {0x00, 0x0F, 0xAC, 0x02};
 UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
 UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
 UCHAR       OUI_WPA2_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x02};
+#ifndef RT30xx
 UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
+#endif
 // MSA OUI
 UCHAR   	OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};		// Not yet final - IEEE 802.11s-D1.06
 UCHAR   	OUI_MSA_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x06};		// Not yet final - IEEE 802.11s-D1.06
@@ -370,6 +376,7 @@ static VOID RTMPInsertRsnIeCipher(
                 break;
         }
 
+#ifndef RT30xx
 		if ((pAd->OpMode == OPMODE_STA) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
@@ -385,7 +392,7 @@ static VOID RTMPInsertRsnIeCipher(
 					break;
 			}
 		}
-
+#endif
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -446,6 +453,7 @@ static VOID RTMPInsertRsnIeCipher(
                 break;
         }
 
+#ifndef RT30xx
 		if ((pAd->OpMode == OPMODE_STA) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
@@ -461,7 +469,7 @@ static VOID RTMPInsertRsnIeCipher(
 					break;
 			}
 		}
-
+#endif
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);

+ 1267 - 1
drivers/staging/rt2860/common/eeprom.c

@@ -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-->

File diff suppressed because it is too large
+ 662 - 4
drivers/staging/rt2860/common/mlme.c


File diff suppressed because it is too large
+ 770 - 1
drivers/staging/rt2860/common/rtmp_init.c


+ 5 - 0
drivers/staging/rt2860/common/spectrum.c

@@ -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;
 	}
 

Some files were not shown because too many files changed in this diff