538 lines
13 KiB
C
538 lines
13 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_flash.c
|
|
|
|
Abstract:
|
|
Miniport generic portion header file
|
|
|
|
Revision History:
|
|
Who When What
|
|
-------- ---------- ----------------------------------------------
|
|
*/
|
|
|
|
#ifdef RTMP_FLASH_SUPPORT
|
|
|
|
#include "rt_config.h"
|
|
|
|
#ifdef RT3090
|
|
#define EEPROM_FILE_NAME "RT3092_PCIe_LNA_2T2R_ALC_V1_2.bin"
|
|
#endif /* RT3090 */
|
|
|
|
#ifdef RT3593
|
|
#ifdef RTMP_MAC_PCI
|
|
#define EEPROM_FILE_NAME "HMC_RT3593_PCIe_3T3R_V1_3.bin"
|
|
#endif /* RTMP_MAC_PCI */
|
|
#endif /* RT3593 */
|
|
|
|
#if defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392)
|
|
#define EEPROM_FILE_NAME "RT5392_PCIe_2T2R_ALC_V1_3.bin"
|
|
#endif /* defined(RT5370) || defined(RT5372) || defined(RT5390) || defined(RT5392) */
|
|
|
|
#ifdef RT5592
|
|
#ifdef RTMP_MAC_PCI
|
|
#define EEPROM_FILE_NAME "RT5592_PCIe_2T2R_V1_5.bin"
|
|
#endif /* RTMP_MAC_PCI */
|
|
|
|
#ifdef RTMP_MAC_USB
|
|
#define EEPROM_FILE_NAME "RT5572_USB_2T2R_V1_3.BIN"
|
|
#endif /* RTMP_MAC_USB */
|
|
#endif /* RT5592 */
|
|
|
|
#ifdef MT76x0
|
|
#ifdef RTMP_MAC_PCI
|
|
#define EEPROM_FILE_NAME_7610E "MT7610E.bin"
|
|
#endif /* RTMP_MAC_PCI */
|
|
|
|
#ifdef RTMP_MAC_USB
|
|
#define EEPROM_FILE_NAME_7610U "RT2870AP/MT7610U_ePA_V0_3.bin"
|
|
#endif /* RTMP_MAC_USB */
|
|
|
|
#endif /* MT76x0 */
|
|
|
|
#define EEPROM_DFT_FILE_DIR "/etc_ro/wlan/"
|
|
#ifdef EEPROM_1ST_FILE_DIR
|
|
#undef EEPROM_1ST_FILE_DIR
|
|
#define EEPROM_1ST_FILE_DIR "/etc_ro/Wireless/RT2860/"
|
|
#endif
|
|
#define EEPROM_2ND_FILE_DIR "/etc_ro/Wireless/iNIC/"
|
|
|
|
|
|
|
|
static NDIS_STATUS rtmp_ee_flash_init(PRTMP_ADAPTER pAd, PUCHAR start);
|
|
|
|
static USHORT EE_FLASH_ID_LIST[]={
|
|
#ifdef RT2860
|
|
0x2860,
|
|
#endif /* RT2860 */
|
|
#ifdef RT2880
|
|
0x2880,
|
|
#endif /* RT2880 */
|
|
#ifdef RT2883
|
|
0x2883,
|
|
0x2880,
|
|
#endif /* RT2883 */
|
|
#ifdef RT3883
|
|
0x3662,
|
|
0x3883,
|
|
#endif /* RT3883 */
|
|
#ifdef RT305x
|
|
0x3052,
|
|
0x3051,
|
|
0x3050,
|
|
0x3350,
|
|
#endif /* RT305x */
|
|
#ifdef RT3352
|
|
0x3352,
|
|
#endif /* RT3352 */
|
|
#ifdef RT5350
|
|
0x5350,
|
|
#endif /* RT5350 */
|
|
#ifdef RT35xx
|
|
0x3572,
|
|
#endif /* RT35xx */
|
|
#ifdef RT3090
|
|
0x3090,
|
|
0x3091,
|
|
0x3092,
|
|
#endif /* RT3090 */
|
|
#ifdef RT5390
|
|
0x5390,
|
|
0x5392,
|
|
#endif /* RT5390 */
|
|
#ifdef RT5592
|
|
#ifdef RTMP_MAC_PCI
|
|
0x5592,
|
|
#endif /* RTMP_MAC_PCI */
|
|
|
|
#ifdef RTMP_MAC_USB
|
|
0x5572,
|
|
#endif /* RTMP_MAC_USB */
|
|
#endif /* RT5592 */
|
|
|
|
#ifdef RT6352
|
|
0x6352,
|
|
0x7620,
|
|
#endif /* RT6352 */
|
|
|
|
#ifdef RT3593
|
|
#ifdef RTMP_MAC_PCI
|
|
0x3593,
|
|
#endif /* RTMP_MAC_PCI */
|
|
#endif /* RT3593 */
|
|
|
|
#ifdef MT76x0
|
|
#ifdef RTMP_MAC_PCI
|
|
0x7610,
|
|
#endif /* RTMP_MAC_PCI */
|
|
#endif /* MT76x0 */
|
|
|
|
#ifdef MT76x2
|
|
#ifdef RTMP_MAC_PCI
|
|
0x7662,
|
|
#endif /* RTMP_MAC_PCI */
|
|
#endif /* MT76x0 */
|
|
|
|
#ifdef MT7603
|
|
0x7603,
|
|
#endif
|
|
#ifdef MT7628
|
|
0x7628,
|
|
0x7603,
|
|
#endif
|
|
};
|
|
|
|
#ifndef EE_FLASH_ID_NUM
|
|
#define EE_FLASH_ID_NUM (sizeof(EE_FLASH_ID_LIST) / sizeof(USHORT))
|
|
#endif
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Flash-based EEPROM read/write procedures.
|
|
* some chips use the flash memory instead of internal EEPROM to save the
|
|
* calibration info, we need these functions to do the read/write.
|
|
*
|
|
******************************************************************************/
|
|
BOOLEAN rtmp_ee_flash_read(PRTMP_ADAPTER pAd, UINT16 Offset, UINT16 *pValue)
|
|
{
|
|
BOOLEAN IsEmpty = 0;
|
|
|
|
if (!pAd->chipCap.ee_inited)
|
|
{
|
|
*pValue = 0xffff;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pValue, pAd->eebuf + Offset, 2);
|
|
}
|
|
|
|
if ((*pValue == 0xffff) || (*pValue == 0x0000))
|
|
IsEmpty = 1;
|
|
|
|
return IsEmpty;
|
|
}
|
|
|
|
|
|
int rtmp_ee_flash_write(PRTMP_ADAPTER pAd, USHORT Offset, USHORT Data)
|
|
{
|
|
if (pAd->chipCap.ee_inited)
|
|
{
|
|
memcpy(pAd->eebuf + Offset, &Data, 2);
|
|
/*rt_nv_commit();*/
|
|
/*rt_cfg_commit();*/
|
|
#ifdef MULTIPLE_CARD_SUPPORT
|
|
DBGPRINT(RT_DEBUG_TRACE, ("rtmp_ee_flash_write:pAd->MC_RowID = %d\n", pAd->MC_RowID));
|
|
DBGPRINT(RT_DEBUG_TRACE, ("E2P_OFFSET = 0x%08x\n", pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]));
|
|
if ((pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]==0x48000) || (pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]==0x40000))
|
|
RtmpFlashWrite(pAd->eebuf, pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID], EEPROM_SIZE);
|
|
#else
|
|
RtmpFlashWrite(pAd->eebuf, pAd->flash_offset, EEPROM_SIZE);
|
|
#endif /* MULTIPLE_CARD_SUPPORT */
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID rtmp_ee_flash_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
|
|
{
|
|
if (!pAd->chipCap.ee_inited)
|
|
return;
|
|
|
|
memcpy(Data, pAd->eebuf, EEPROM_SIZE);
|
|
}
|
|
|
|
|
|
VOID rtmp_ee_flash_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
|
|
{
|
|
if (!pAd->chipCap.ee_inited)
|
|
return;
|
|
memcpy(pAd->eebuf, Data, EEPROM_SIZE);
|
|
#ifdef MULTIPLE_CARD_SUPPORT
|
|
DBGPRINT(RT_DEBUG_TRACE, ("rtmp_ee_flash_write_all:pAd->MC_RowID = %d\n", pAd->MC_RowID));
|
|
DBGPRINT(RT_DEBUG_TRACE, ("E2P_OFFSET = 0x%08x\n", pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]));
|
|
if ((pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]==0x48000) || (pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]==0x40000))
|
|
RtmpFlashWrite(pAd->eebuf, pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID], EEPROM_SIZE);
|
|
#else
|
|
RtmpFlashWrite(pAd->eebuf, pAd->flash_offset, EEPROM_SIZE);
|
|
#endif /* MULTIPLE_CARD_SUPPORT */
|
|
}
|
|
|
|
|
|
static NDIS_STATUS rtmp_ee_flash_reset(RTMP_ADAPTER *pAd, UCHAR *start)
|
|
{
|
|
PUCHAR src;
|
|
RTMP_OS_FS_INFO osFsInfo;
|
|
RTMP_OS_FD srcf;
|
|
INT retval;
|
|
|
|
#ifdef RT_SOC_SUPPORT
|
|
#ifdef MULTIPLE_CARD_SUPPORT
|
|
RTMP_STRING BinFilePath[128];
|
|
RTMP_STRING *pBinFileName = NULL;
|
|
UINT32 ChipVerion = (pAd->MACVersion >> 16);
|
|
|
|
if (rtmp_get_default_bin_file_by_chip(pAd, ChipVerion, &pBinFileName) == TRUE)
|
|
{
|
|
if (pAd->MC_RowID > 0)
|
|
sprintf(BinFilePath, "%s%s", EEPROM_2ND_FILE_DIR, pBinFileName);
|
|
else
|
|
sprintf(BinFilePath, "%s%s", EEPROM_1ST_FILE_DIR, pBinFileName);
|
|
|
|
src = BinFilePath;
|
|
DBGPRINT(RT_DEBUG_TRACE, ("%s(): src = %s\n", __FUNCTION__, src));
|
|
}
|
|
else
|
|
#endif /* MULTIPLE_CARD_SUPPORT */
|
|
#endif /* RT_SOC_SUPPORT */
|
|
{
|
|
#ifdef MT7603
|
|
if (IS_MT7603(pAd))
|
|
{
|
|
src = EEPROM_DEFAULT_7603_FILE_PATH;
|
|
}
|
|
else
|
|
#endif /* MT_MAC */
|
|
{
|
|
src = EEPROM_DEFAULT_FILE_PATH;
|
|
}
|
|
}
|
|
|
|
RtmpOSFSInfoChange(&osFsInfo, TRUE);
|
|
|
|
if (src && *src)
|
|
{
|
|
srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
|
|
if (IS_FILE_OPEN_ERR(srcf))
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("--> Error opening file %s\n", src));
|
|
if ( pAd->chipCap.EEPROM_DEFAULT_BIN != NULL )
|
|
{
|
|
NdisMoveMemory(start, pAd->chipCap.EEPROM_DEFAULT_BIN,
|
|
pAd->chipCap.EEPROM_DEFAULT_BIN_SIZE > MAX_EEPROM_BUFFER_SIZE?MAX_EEPROM_BUFFER_SIZE:pAd->chipCap.EEPROM_DEFAULT_BIN_SIZE);
|
|
DBGPRINT(RT_DEBUG_TRACE, ("Load EEPROM Buffer from default BIN.\n"));
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
/* The object must have a read method*/
|
|
NdisZeroMemory(start, EEPROM_SIZE);
|
|
|
|
retval = RtmpOSFileRead(srcf, start, EEPROM_SIZE);
|
|
if (retval < 0)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
|
|
}
|
|
else
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("--> rtmp_ee_flash_reset copy %s to eeprom buffer\n", src));
|
|
}
|
|
|
|
retval = RtmpOSFileClose(srcf);
|
|
if (retval)
|
|
{
|
|
DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
|
|
}
|
|
}
|
|
}
|
|
|
|
RtmpOSFSInfoChange(&osFsInfo, FALSE);
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
#ifdef LINUX
|
|
/* 0 -- Show ee buffer */
|
|
/* 1 -- force reset to default */
|
|
/* 2 -- Change ee settings */
|
|
int Set_EECMD_Proc(
|
|
IN PRTMP_ADAPTER pAd,
|
|
IN PUCHAR arg)
|
|
{
|
|
USHORT i;
|
|
|
|
i = simple_strtol(arg, 0, 10);
|
|
switch(i)
|
|
{
|
|
case 0:
|
|
{
|
|
USHORT value, k;
|
|
for (k = 0; k < EEPROM_SIZE; k+=2)
|
|
{
|
|
RT28xx_EEPROM_READ16(pAd, k, value);
|
|
DBGPRINT(RT_DEBUG_OFF, ("%4.4x ", value));
|
|
if (((k+2) % 0x20) == 0)
|
|
DBGPRINT(RT_DEBUG_OFF,("\n"));
|
|
}
|
|
|
|
}
|
|
break;
|
|
case 1:
|
|
if (pAd->infType == RTMP_DEV_INF_RBUS)
|
|
{
|
|
DBGPRINT(RT_DEBUG_OFF, ("EEPROM reset to default......\n"));
|
|
DBGPRINT(RT_DEBUG_OFF, ("The last byte of MAC address will be re-generated...\n"));
|
|
if (rtmp_ee_flash_reset(pAd, pAd->eebuf) != NDIS_STATUS_SUCCESS)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("Set_EECMD_Proc: rtmp_ee_flash_reset() failed\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
/* Random number for the last bytes of MAC address*/
|
|
{
|
|
USHORT Addr45;
|
|
|
|
rtmp_ee_flash_read(pAd, 0x08, &Addr45);
|
|
Addr45 = Addr45 & 0xff;
|
|
Addr45 = Addr45 | (RandomByte(pAd)&0xf8) << 8;
|
|
DBGPRINT(RT_DEBUG_OFF, ("Addr45 = %4x\n", Addr45));
|
|
rtmp_ee_flash_write(pAd, 0x08, Addr45);
|
|
}
|
|
|
|
rtmp_ee_flash_read(pAd, 0, &i);
|
|
|
|
if ((i != 0x2880) && (i != 0x2860))
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("Set_EECMD_Proc: invalid eeprom\n"));
|
|
return FALSE;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
USHORT offset, value = 0;
|
|
PUCHAR p;
|
|
|
|
p = arg+2;
|
|
offset = simple_strtol(p, 0, 10);
|
|
p+=2;
|
|
while (*p != '\0')
|
|
{
|
|
if (*p >= '0' && *p <= '9')
|
|
value = (value << 4) + (*p - 0x30);
|
|
else if (*p >= 'a' && *p <= 'f')
|
|
value = (value << 4) + (*p - 0x57);
|
|
else if (*p >= 'A' && *p <= 'F')
|
|
value = (value << 4) + (*p - 0x37);
|
|
p++;
|
|
}
|
|
RT28xx_EEPROM_WRITE16(pAd, offset, value);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
#endif /* LINUX */
|
|
|
|
|
|
static BOOLEAN validFlashEepromID(RTMP_ADAPTER *pAd)
|
|
{
|
|
USHORT eeFlashId;
|
|
int listIdx;
|
|
|
|
rtmp_ee_flash_read(pAd, 0, &eeFlashId);
|
|
for(listIdx =0 ; listIdx < EE_FLASH_ID_NUM; listIdx++)
|
|
{
|
|
if (eeFlashId == EE_FLASH_ID_LIST[listIdx])
|
|
{
|
|
#ifdef MT7603
|
|
if (IS_MT7603(pAd))
|
|
{
|
|
if (eeFlashId != 0x7603)
|
|
return FALSE;
|
|
}
|
|
#endif /* MT7603 */
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static NDIS_STATUS rtmp_ee_flash_init(PRTMP_ADAPTER pAd, PUCHAR start)
|
|
{
|
|
pAd->chipCap.ee_inited = 1;
|
|
|
|
if (validFlashEepromID(pAd) == FALSE)
|
|
{
|
|
if (rtmp_ee_flash_reset(pAd, start) != NDIS_STATUS_SUCCESS)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("rtmp_ee_init(): rtmp_ee_flash_init() failed\n"));
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
/* Random number for the last bytes of MAC address*/
|
|
{
|
|
USHORT Addr45;
|
|
|
|
rtmp_ee_flash_read(pAd, 0x08, &Addr45);
|
|
Addr45 = Addr45 & 0xff;
|
|
Addr45 = Addr45 | (RandomByte(pAd)&0xf8) << 8;
|
|
|
|
rtmp_ee_flash_write(pAd, 0x08, Addr45);
|
|
DBGPRINT(RT_DEBUG_ERROR, ("The EEPROM in Flash is wrong, use default\n"));
|
|
}
|
|
|
|
if (validFlashEepromID(pAd) == FALSE)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("rtmp_ee_flash_init(): invalid eeprom\n"));
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
}
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NDIS_STATUS rtmp_nv_init(RTMP_ADAPTER *pAd)
|
|
{
|
|
#ifdef MULTIPLE_CARD_SUPPORT
|
|
UCHAR *eepromBuf;
|
|
#endif /* MULTIPLE_CARD_SUPPORT */
|
|
|
|
DBGPRINT(RT_DEBUG_TRACE, ("--> rtmp_nv_init\n"));
|
|
|
|
#ifdef __ECOS
|
|
int stat;
|
|
if ((stat = cyg_flash_init(NULL)) != 0)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("FLASH: driver init failed: %s\n", cyg_flash_errmsg(stat)));
|
|
return -1;
|
|
}
|
|
|
|
{
|
|
UCHAR *eepromBuf;
|
|
|
|
if (os_alloc_mem(pAd, &eepromBuf, EEPROM_SIZE) == NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisZeroMemory(eepromBuf, EEPROM_SIZE);
|
|
NdisMoveMemory(eepromBuf, pAd->eebuf, EEPROM_SIZE);
|
|
RtmpFlashRead(pAd->eebuf, pAd->flash_offset, EEPROM_SIZE);
|
|
pAd->chipCap.ee_inited = 1;
|
|
if (validFlashEepromID(pAd) == FALSE)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("The EEPROM in Flash are wrong, use default\n"));
|
|
NdisMoveMemory(pAd->eebuf, eepromBuf, EEPROM_SIZE);
|
|
}
|
|
os_free_mem(pAd, eepromBuf);
|
|
}
|
|
}
|
|
return NDIS_STATUS_SUCCESS;
|
|
#else
|
|
|
|
/*
|
|
if (pAd->chipCap.EEPROMImage == NULL)
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR, ("pAd->chipCap.EEPROMImage == NULL!!!\n"));
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
*/
|
|
|
|
/* ASSERT((pAd->eebuf == NULL)); */
|
|
pAd->eebuf = pAd->EEPROMImage;
|
|
#ifdef MULTIPLE_CARD_SUPPORT
|
|
DBGPRINT(RT_DEBUG_OFF, ("rtmp_nv_init:pAd->MC_RowID = %d\n", pAd->MC_RowID));
|
|
os_alloc_mem(pAd, &eepromBuf, EEPROM_SIZE);
|
|
if (eepromBuf)
|
|
{
|
|
pAd->eebuf = eepromBuf;
|
|
NdisMoveMemory(pAd->eebuf, pAd->chipCap.EEPROM_DEFAULT_BIN, EEPROM_SIZE);
|
|
}
|
|
else
|
|
{
|
|
DBGPRINT(RT_DEBUG_ERROR,("rtmp_nv_init:Alloc memory for pAd->MC_RowID[%d] failed! used default one!\n", pAd->MC_RowID));
|
|
}
|
|
DBGPRINT(RT_DEBUG_OFF, ("E2P_OFFSET = 0x%08x\n", pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID]));
|
|
RtmpFlashRead(pAd->eebuf, pAd->E2P_OFFSET_IN_FLASH[pAd->MC_RowID], EEPROM_SIZE);
|
|
#else
|
|
RtmpFlashRead(pAd->eebuf, pAd->flash_offset, EEPROM_SIZE);
|
|
#endif /* MULTIPLE_CARD_SUPPORT */
|
|
|
|
return rtmp_ee_flash_init(pAd, pAd->eebuf);
|
|
#endif /* __ECOS */
|
|
}
|
|
|
|
#endif /* RTMP_FLASH_SUPPORT */
|
|
|