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

📄 eeprom.c

📁 ralink最新rt3070 usb wifi 无线网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	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;	}	orgfsuid = current->fsuid;	orgfsgid = current->fsgid;	current->fsuid=current->fsgid = 0;    	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);	current->fsuid = orgfsuid;	current->fsgid = orgfsgid;	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-->

⌨️ 快捷键说明

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