⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 ralink最新rt3070 usb wifi 无线网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2007, Ralink Technology, Inc. * * This program is free software; you can redistribute it and/or modify  *  * it under the terms of the GNU General Public License as published by  *  * the Free Software Foundation; either version 2 of the License, or     *  * (at your option) any later version.                                   *  *                                                                       *  * This program is distributed in the hope that it will be useful,       *  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *  * GNU General Public License for more details.                          *  *                                                                       *  * You should have received a copy of the GNU General Public License     *  * along with this program; if not, write to the                         *  * Free Software Foundation, Inc.,                                       *  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *  *                                                                       *  *************************************************************************	Module Name:	eeprom.c	Abstract:	Revision History:	Who			When			What	--------	----------		----------------------------------------------	Name		Date			Modification logs*/#include	"rt_config.h"// IRQL = PASSIVE_LEVELVOID RaiseClock(    IN	PRTMP_ADAPTER	pAd,    IN  UINT32 *x){    *x = *x | EESK;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);    RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition }// IRQL = PASSIVE_LEVELVOID LowerClock(    IN	PRTMP_ADAPTER	pAd,    IN  UINT32 *x){    *x = *x & ~EESK;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);    RTMPusecDelay(1);}// IRQL = PASSIVE_LEVELUSHORT ShiftInBits(    IN	PRTMP_ADAPTER	pAd){    UINT32		x,i;	USHORT      data=0;    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~( EEDO | EEDI);        for(i=0; i<16; i++)    {        data = data << 1;        RaiseClock(pAd, &x);		        RTMP_IO_READ32(pAd, E2PROM_CSR, &x);		LowerClock(pAd, &x); //prevent read failed        x &= ~(EEDI);        if(x & EEDO)            data |= 1;    }    return data;}// IRQL = PASSIVE_LEVELVOID ShiftOutBits(    IN	PRTMP_ADAPTER	pAd,    IN  USHORT data,    IN  USHORT count){    UINT32       x,mask;    mask = 0x01 << (count - 1);    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~(EEDO | EEDI);    do    {        x &= ~EEDI;        if(data & mask)		x |= EEDI;        RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);        RaiseClock(pAd, &x);        LowerClock(pAd, &x);        mask = mask >> 1;    } while(mask);    x &= ~EEDI;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);}// IRQL = PASSIVE_LEVELVOID EEpromCleanup(    IN	PRTMP_ADAPTER	pAd){    UINT32 x;    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);	    x &= ~(EECS | EEDI);    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);    RaiseClock(pAd, &x);    LowerClock(pAd, &x);	}VOID EWEN(	IN	PRTMP_ADAPTER	pAd){    UINT32	x;    // reset bits and set EECS    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~(EEDI | EEDO | EESK);    x |= EECS;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);	// kick a pulse	RaiseClock(pAd, &x);	LowerClock(pAd, &x);    // output the read_opcode and six pulse in that order        ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);    ShiftOutBits(pAd, 0, 6);    EEpromCleanup(pAd);    }VOID EWDS(	IN	PRTMP_ADAPTER	pAd){    UINT32	x;    // reset bits and set EECS    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~(EEDI | EEDO | EESK);    x |= EECS;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);	// kick a pulse	RaiseClock(pAd, &x);	LowerClock(pAd, &x);    // output the read_opcode and six pulse in that order        ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);    ShiftOutBits(pAd, 0, 6);    EEpromCleanup(pAd);    }// IRQL = PASSIVE_LEVELUSHORT RTMP_EEPROM_READ16(    IN	PRTMP_ADAPTER	pAd,    IN  USHORT Offset){    UINT32		x;    USHORT		data;	if (pAd->NicConfig2.field.AntDiversity)    {    	pAd->EepromAccess = TRUE;    }//2008/09/11:KH add to support efuse<--//2008/09/11:KH add to support efuse-->{    Offset /= 2;    // reset bits and set EECS    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~(EEDI | EEDO | EESK);    x |= EECS;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);	// patch can not access e-Fuse issue    if (!IS_RT3090(pAd))    {	// kick a pulse	RaiseClock(pAd, &x);	LowerClock(pAd, &x);    }    // output the read_opcode and register number in that order        ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);    // Now read the data (16 bits) in from the selected EEPROM word    data = ShiftInBits(pAd);    EEpromCleanup(pAd);	// 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);    }}	    return data;}	//ReadEEpromVOID RTMP_EEPROM_WRITE16(    IN	PRTMP_ADAPTER	pAd,    IN  USHORT Offset,    IN  USHORT Data){    UINT32 x;		if (pAd->NicConfig2.field.AntDiversity)    {    	pAd->EepromAccess = TRUE;    }	//2008/09/11:KH add to support efuse<--//2008/09/11:KH add to support efuse-->	{	Offset /= 2;	EWEN(pAd);    // reset bits and set EECS    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);    x &= ~(EEDI | EEDO | EESK);    x |= EECS;    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);	// patch can not access e-Fuse issue    if (!IS_RT3090(pAd))    {	// kick a pulse	RaiseClock(pAd, &x);	LowerClock(pAd, &x);    }    // output the read_opcode ,register number and data in that order        ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);	ShiftOutBits(pAd, Data, 16);		// 16-bit access    // read DO status    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);	EEpromCleanup(pAd);	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms			EWDS(pAd);    EEpromCleanup(pAd);	// 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);    }}}//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.#ifdef RT_BIG_ENDIAN		data = data << (8*((Offset & 0x3)^0x2));		  #else		data = data >> (8*(Offset & 0x3)); 				  #endif				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);#ifdef RT_BIG_ENDIAN		data = data << (8*((Offset & 0x3)^0x2));	#else	data = data >> (8*(Offset & 0x3));#endif			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:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -