344 lines
7.4 KiB
C
344 lines
7.4 KiB
C
/*
|
|
***************************************************************************
|
|
* Ralink Tech Inc.
|
|
* 4F, No. 2 Technology 5th Rd.
|
|
* Science-based Industrial Park
|
|
* Hsin-chu, Taiwan, R.O.C.
|
|
*
|
|
* (c) Copyright 2002-2004, Ralink Technology, Inc.
|
|
*
|
|
* All rights reserved. Ralink's source code is an unpublished work and the
|
|
* use of a copyright notice does not imply otherwise. This source code
|
|
* contains confidential trade secret material of Ralink Tech. Any attemp
|
|
* or participation in deciphering, decoding, reverse engineering or in any
|
|
* way altering the source code is stricitly prohibited, unless the prior
|
|
* written consent of Ralink Technology, Inc. is obtained.
|
|
***************************************************************************
|
|
|
|
Module Name:
|
|
ee_prom.c
|
|
|
|
Abstract:
|
|
Miniport generic portion header file
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
*/
|
|
|
|
|
|
#include "rt_config.h"
|
|
|
|
|
|
|
|
/* IRQL = PASSIVE_LEVEL*/
|
|
static inline VOID RaiseClock(RTMP_ADAPTER *pAd, UINT32 *x)
|
|
{
|
|
*x = *x | EESK;
|
|
RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
|
|
RtmpusecDelay(1); /* Max frequency = 1MHz in Spec. definition */
|
|
}
|
|
|
|
|
|
/* IRQL = PASSIVE_LEVEL*/
|
|
static inline VOID LowerClock(RTMP_ADAPTER *pAd, UINT32 *x)
|
|
{
|
|
*x = *x & ~EESK;
|
|
RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
|
|
RtmpusecDelay(1);
|
|
}
|
|
|
|
|
|
/* IRQL = PASSIVE_LEVEL*/
|
|
static inline USHORT ShiftInBits(RTMP_ADAPTER *pAd)
|
|
{
|
|
UINT32 x,i;
|
|
UINT16 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_LEVEL*/
|
|
static inline VOID ShiftOutBits(RTMP_ADAPTER *pAd, USHORT data, 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_LEVEL*/
|
|
static inline VOID EEpromCleanup(RTMP_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);
|
|
}
|
|
|
|
|
|
static inline VOID EWEN(RTMP_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);
|
|
}
|
|
|
|
|
|
static inline VOID EWDS(RTMP_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_LEVEL*/
|
|
BOOLEAN rtmp_ee_prom_read16(RTMP_ADAPTER *pAd, UINT16 Offset, UINT16 *pValue)
|
|
{
|
|
UINT32 x;
|
|
UINT16 data;
|
|
BOOLEAN IsEmpty = 0;
|
|
|
|
#ifdef ANT_DIVERSITY_SUPPORT
|
|
/*
|
|
Old chips use single circuit to contorl EEPROM and AntDiversity, so need protect.
|
|
AntDiversity of RT5390 is independence internal circuit, so doesn't need protect.
|
|
*/
|
|
if (pAd->NicConfig2.field.AntDiversity)
|
|
{
|
|
pAd->EepromAccess = TRUE;
|
|
}
|
|
#endif /* ANT_DIVERSITY_SUPPORT */
|
|
|
|
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*/
|
|
#ifdef RELEASE_EXCLUDE
|
|
/*
|
|
The is patch is only for e-fuse chips. The efuse support chips should not
|
|
raise/lower clock again.
|
|
2860,2870, 2880,3052,3352,5350
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
#if 0
|
|
if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd) || IS_RT3593(pAd) || IS_RT5390(pAd) || IS_RT5392(pAd)))
|
|
#endif
|
|
if (IS_RT2860(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);
|
|
|
|
#ifdef ANT_DIVERSITY_SUPPORT
|
|
/*
|
|
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
|
|
AntDiversity of RT5390 is independence internal circuit, so doesn't need protect.
|
|
*/
|
|
if ((pAd->NicConfig2.field.AntDiversity)
|
|
#ifdef RT3290
|
|
&& (!IS_RT3290(pAd))
|
|
#endif /* RT3290 */
|
|
)
|
|
{
|
|
pAd->EepromAccess = FALSE;
|
|
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
|
|
}
|
|
#endif /* ANT_DIVERSITY_SUPPORT */
|
|
|
|
*pValue = data;
|
|
|
|
if ((IsEmpty == 0xff) || (IsEmpty == 0x0000))
|
|
IsEmpty = 1;
|
|
|
|
return IsEmpty;
|
|
}
|
|
|
|
|
|
int rtmp_ee_prom_write16(RTMP_ADAPTER *pAd, USHORT Offset, UINT16 Data)
|
|
{
|
|
UINT32 x;
|
|
|
|
|
|
#ifdef ANT_DIVERSITY_SUPPORT
|
|
/*
|
|
Old chips use single circuit to contorl EEPROM and AntDiversity, so need protect.
|
|
AntDiversity of RT5390 is independence internal circuit, so doesn't need protect.
|
|
*/
|
|
if (pAd->NicConfig2.field.AntDiversity)
|
|
{
|
|
pAd->EepromAccess = TRUE;
|
|
}
|
|
#endif /* ANT_DIVERSITY_SUPPORT */
|
|
|
|
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*/
|
|
#ifdef RELEASE_EXCLUDE
|
|
/*
|
|
The is patch is only for e-fuse chips. The efuse support chips should not
|
|
raise/lower clock again.
|
|
2860,2870, 2880,3052,3352,5350
|
|
*/
|
|
#endif /* RELEASE_EXCLUDE */
|
|
if (IS_RT2860(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);
|
|
|
|
#ifdef ANT_DIVERSITY_SUPPORT
|
|
/* 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*/
|
|
/* AntDiversity of RT5390 is independence internal circuit, so doesn't need protect. */
|
|
if ((pAd->NicConfig2.field.AntDiversity)
|
|
#ifdef RT3290
|
|
&& (!IS_RT3290(pAd))
|
|
#endif /* RT3290 */
|
|
)
|
|
{
|
|
pAd->EepromAccess = FALSE;
|
|
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
|
|
}
|
|
#endif /* ANT_DIVERSITY_SUPPORT */
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
INT rtmp_ee_write_to_prom(RTMP_ADAPTER *pAd)
|
|
{
|
|
USHORT value, offset = 0;
|
|
|
|
#ifdef RTMP_USB_SUPPORT
|
|
if (pAd->infType == RTMP_DEV_INF_USB)
|
|
RTUSBWriteEEPROM(pAd, offset, (PUCHAR)pAd->EEPROMImage, EEPROM_SIZE);
|
|
else
|
|
#endif /* RTMP_USB_SUPPORT */
|
|
{
|
|
for (offset = 0; offset < (EEPROM_SIZE >> 1);)
|
|
{
|
|
value = ((PUSHORT)pAd->EEPROMImage)[offset];
|
|
RT28xx_EEPROM_WRITE16(pAd, (offset << 1), value);
|
|
offset++;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|