blob: 051cfdee2a157961a4540b4ea75b86512d7a5367 [file] [log] [blame]
/*
*************************************************************************
* 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_prom.c
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
// IRQL = PASSIVE_LEVEL
static inline VOID 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_LEVEL
static inline VOID LowerClock(
IN PRTMP_ADAPTER pAd,
IN UINT32 *x)
{
*x = *x & ~EESK;
RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
RTMPusecDelay(1);
}
// IRQL = PASSIVE_LEVEL
static inline USHORT 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_LEVEL
static inline VOID 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_LEVEL
static inline VOID 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);
}
static inline 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);
}
static inline 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_LEVEL
int rtmp_ee_prom_read16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
OUT USHORT *pValue)
{
UINT32 x;
USHORT data;
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
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) || IS_RT3572(pAd) || IS_RT3390(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 RT30xx
#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
if ((pAd->NicConfig2.field.AntDiversity)/* || (pAd->RfIcType == RFIC_3020)*/)
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
*pValue = data;
return NDIS_STATUS_SUCCESS;
}
int rtmp_ee_prom_write16(
IN PRTMP_ADAPTER pAd,
IN USHORT Offset,
IN USHORT Data)
{
UINT32 x;
#ifdef RT30xx
#ifdef ANT_DIVERSITY_SUPPORT
if (pAd->NicConfig2.field.AntDiversity)
{
pAd->EepromAccess = TRUE;
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
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) || IS_RT3572(pAd) || IS_RT3390(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 RT30xx
#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
if ((pAd->NicConfig2.field.AntDiversity) /*|| (pAd->RfIcType == RFIC_3020)*/)
{
pAd->EepromAccess = FALSE;
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
}
#endif // ANT_DIVERSITY_SUPPORT //
#endif // RT30xx //
return NDIS_STATUS_SUCCESS;
}