mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
62eb734b49
Remove misc typedefs. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
344 lines
9.5 KiB
C
344 lines
9.5 KiB
C
/*
|
|
*************************************************************************
|
|
* 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:
|
|
ee_efuse.c
|
|
|
|
Abstract:
|
|
Miniport generic portion header file
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
*/
|
|
|
|
#include "../rt_config.h"
|
|
|
|
#define EFUSE_USAGE_MAP_START 0x2d0
|
|
#define EFUSE_USAGE_MAP_END 0x2fc
|
|
#define EFUSE_USAGE_MAP_SIZE 45
|
|
|
|
#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin"
|
|
#define MAX_EEPROM_BIN_FILE_SIZE 1024
|
|
|
|
#define EFUSE_TAG 0x2fe
|
|
|
|
typedef union _EFUSE_CTRL_STRUC {
|
|
struct {
|
|
u32 EFSROM_AOUT:6;
|
|
u32 EFSROM_MODE:2;
|
|
u32 EFSROM_LDO_OFF_TIME:6;
|
|
u32 EFSROM_LDO_ON_TIME:2;
|
|
u32 EFSROM_AIN:10;
|
|
u32 RESERVED:4;
|
|
u32 EFSROM_KICK:1;
|
|
u32 SEL_EFUSE:1;
|
|
} field;
|
|
u32 word;
|
|
} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
|
|
|
|
/*
|
|
========================================================================
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Note:
|
|
|
|
========================================================================
|
|
*/
|
|
u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd,
|
|
u16 Offset, u16 Length, u16 * pData)
|
|
{
|
|
EFUSE_CTRL_STRUC eFuseCtrlStruc;
|
|
int i;
|
|
u16 efuseDataOffset;
|
|
u32 data;
|
|
|
|
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
|
|
|
|
/*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 < 500) {
|
|
/*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); */
|
|
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
|
|
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 (u8)eFuseCtrlStruc.field.EFSROM_AOUT;
|
|
|
|
}
|
|
|
|
/*
|
|
========================================================================
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Note:
|
|
|
|
========================================================================
|
|
*/
|
|
void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
|
|
u16 Offset,
|
|
u16 Length, u16 * pData)
|
|
{
|
|
EFUSE_CTRL_STRUC eFuseCtrlStruc;
|
|
int i;
|
|
u16 efuseDataOffset;
|
|
u32 data;
|
|
|
|
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
|
|
|
|
/*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 < 500) {
|
|
RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
|
|
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:
|
|
|
|
Note:
|
|
|
|
========================================================================
|
|
*/
|
|
static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd,
|
|
u16 *lpInBuffer,
|
|
unsigned long nInBufferSize,
|
|
u16 *lpOutBuffer, unsigned long nOutBufferSize)
|
|
{
|
|
u16 *pInBuf = (u16 *) lpInBuffer;
|
|
u16 *pOutBuf = (u16 *) lpOutBuffer;
|
|
|
|
u16 Offset = pInBuf[0]; /*addr */
|
|
u16 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:
|
|
|
|
Note:
|
|
|
|
========================================================================
|
|
*/
|
|
int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg)
|
|
{
|
|
u16 i;
|
|
u16 LogicalAddress;
|
|
u16 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 = (u8)(EFUSE_USAGE_MAP_END - i + 1);
|
|
break;
|
|
} else if (((LogicalAddress >> 8) & 0xff) == 0) {
|
|
efusefreenum = (u8)(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(struct rt_rtmp_adapter *pAd, char *arg)
|
|
{
|
|
u16 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 rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
|
|
u16 Offset, u16 * pValue)
|
|
{
|
|
eFuseReadRegisters(pAd, Offset, 2, pValue);
|
|
return (*pValue);
|
|
}
|
|
|
|
int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd)
|
|
{
|
|
u16 value;
|
|
|
|
if (IS_RT30xx(pAd)) {
|
|
eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
|
|
pAd->EFuseTag = (value & 0xff);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock)
|
|
{
|
|
u16 i;
|
|
u16 LogicalAddress;
|
|
if (!pAd->bUseEfuse) {
|
|
DBGPRINT(RT_DEBUG_TRACE,
|
|
("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
|
|
return;
|
|
}
|
|
for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
|
|
eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
|
|
if ((LogicalAddress & 0xff) == 0) {
|
|
*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i + 1);
|
|
break;
|
|
} else if (((LogicalAddress >> 8) & 0xff) == 0) {
|
|
*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i);
|
|
break;
|
|
}
|
|
|
|
if (i == EFUSE_USAGE_MAP_END)
|
|
*EfuseFreeBlock = 0;
|
|
}
|
|
DBGPRINT(RT_DEBUG_TRACE,
|
|
("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
|
|
}
|
|
|
|
int eFuse_init(struct rt_rtmp_adapter *pAd)
|
|
{
|
|
u32 EfuseFreeBlock = 0;
|
|
DBGPRINT(RT_DEBUG_ERROR,
|
|
("NVM is Efuse and its size =%x[%x-%x] \n",
|
|
EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START,
|
|
EFUSE_USAGE_MAP_END));
|
|
eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
|
|
|
|
return 0;
|
|
}
|