diff options
author | Phillip Potter <phil@philpotter.co.uk> | 2021-07-28 02:22:14 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-07-28 21:16:08 +0300 |
commit | 15865124feed880978b79839c756ef6cbb4ec6b3 (patch) | |
tree | 3baede88385aaf963b33af1fec5e5240ac25e0a4 /drivers/staging/r8188eu/core/rtw_efuse.c | |
parent | 5c872e1d25958aaa9102c57ab8bc4ca591b0e363 (diff) | |
download | linux-15865124feed880978b79839c756ef6cbb4ec6b3.tar.xz |
staging: r8188eu: introduce new core dir for RTL8188eu driver
This patchset is split in order to keep the file sizes down. This core
directory is part of the newer/better driver from GitHub modified by
Larry Finger. Import this as the basis for all future work going
forward.
Suggested-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20210727232219.2948-2-phil@philpotter.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/r8188eu/core/rtw_efuse.c')
-rw-r--r-- | drivers/staging/r8188eu/core/rtw_efuse.c | 872 |
1 files changed, 872 insertions, 0 deletions
diff --git a/drivers/staging/r8188eu/core/rtw_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c new file mode 100644 index 000000000000..53b73f442699 --- /dev/null +++ b/drivers/staging/r8188eu/core/rtw_efuse.c @@ -0,0 +1,872 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#define _RTW_EFUSE_C_ + +#include <osdep_service.h> +#include <drv_types.h> +#include <rtw_efuse.h> + +/*------------------------Define local variable------------------------------*/ +u8 fakeEfuseBank; +u32 fakeEfuseUsedBytes; +u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0}; +u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0}; +u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0}; + +u32 BTEfuseUsedBytes; +u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; + +u32 fakeBTEfuseUsedBytes; +u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +/*------------------------Define local variable------------------------------*/ + +/* */ +#define REG_EFUSE_CTRL 0x0030 +#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ +/* */ + +bool +Efuse_Read1ByteFromFakeContent( + struct adapter *pAdapter, + u16 Offset, + u8 *Value); +bool +Efuse_Read1ByteFromFakeContent( + struct adapter *pAdapter, + u16 Offset, + u8 *Value) +{ + if (Offset >= EFUSE_MAX_HW_SIZE) + return false; + if (fakeEfuseBank == 0) + *Value = fakeEfuseContent[Offset]; + else + *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset]; + return true; +} + +static bool +Efuse_Write1ByteToFakeContent( + struct adapter *pAdapter, + u16 Offset, + u8 Value) +{ + if (Offset >= EFUSE_MAX_HW_SIZE) + return false; + if (fakeEfuseBank == 0) { + fakeEfuseContent[Offset] = Value; + } else { + fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value; + } + return true; +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_PowerSwitch + * + * Overview: When we want to enable write operation, we should change to + * pwr on state. When we stop write, we should switch to 500k mode + * and disable LDO 2.5V. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/17/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +Efuse_PowerSwitch( + struct adapter *pAdapter, + u8 write, + u8 PwrState) +{ + pAdapter->HalFunc.EfusePowerSwitch(pAdapter, write, PwrState); +} + +/*----------------------------------------------------------------------------- + * Function: efuse_GetCurrentSize + * + * Overview: Get current efuse size!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u16 +Efuse_GetCurrentSize( + struct adapter *pAdapter, + u8 efuseType, + bool pseudo) +{ + u16 ret = 0; + + ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, pseudo); + + return ret; +} + +/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ +u8 +Efuse_CalculateWordCnts(u8 word_en) +{ + u8 word_cnts = 0; + if (!(word_en & BIT(0))) + word_cnts++; /* 0 : write enable */ + if (!(word_en & BIT(1))) + word_cnts++; + if (!(word_en & BIT(2))) + word_cnts++; + if (!(word_en & BIT(3))) + word_cnts++; + return word_cnts; +} + +/* */ +/* Description: */ +/* Execute E-Fuse read byte operation. */ +/* Referred from SD1 Richard. */ +/* */ +/* Assumption: */ +/* 1. Boot from E-Fuse and successfully auto-load. */ +/* 2. PASSIVE_LEVEL (USB interface) */ +/* */ +/* Created by Roger, 2008.10.21. */ +/* */ +void +ReadEFuseByte( + struct adapter *Adapter, + u16 _offset, + u8 *pbuf, + bool pseudo) +{ + u32 value32; + u8 readbyte; + u16 retry; + + if (pseudo) { + Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); + return; + } + + /* Write Address */ + rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff)); + readbyte = rtw_read8(Adapter, EFUSE_CTRL+2); + rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); + + /* Write bit 32 0 */ + readbyte = rtw_read8(Adapter, EFUSE_CTRL+3); + rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f)); + + /* Check bit 32 read-ready */ + retry = 0; + value32 = rtw_read32(Adapter, EFUSE_CTRL); + while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) { + value32 = rtw_read32(Adapter, EFUSE_CTRL); + retry++; + } + + /* 20100205 Joseph: Add delay suggested by SD1 Victor. */ + /* This fix the problem that Efuse read error in high temperature condition. */ + /* Designer says that there shall be some delay after ready bit is set, or the */ + /* result will always stay on last data we read. */ + rtw_udelay_os(50); + value32 = rtw_read32(Adapter, EFUSE_CTRL); + + *pbuf = (u8)(value32 & 0xff); +} + +/* */ +/* Description: */ +/* 1. Execute E-Fuse read byte operation according as map offset and */ +/* save to E-Fuse table. */ +/* 2. Referred from SD1 Richard. */ +/* */ +/* Assumption: */ +/* 1. Boot from E-Fuse and successfully auto-load. */ +/* 2. PASSIVE_LEVEL (USB interface) */ +/* */ +/* Created by Roger, 2008.10.21. */ +/* */ +/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */ +/* 2. Add efuse utilization collect. */ +/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */ +/* write addr must be after sec5. */ +/* */ + +static void efuse_ReadEFuse(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool pseudo) +{ + Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, pseudo); +} + +void EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool pseudo + ) +{ + pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, pseudo); +} + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Read1Byte + * + * Overview: Copy from WMAC fot EFUSE read 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ +u8 EFUSE_Read1Byte(struct adapter *Adapter, u16 Address) +{ + u8 data; + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k = 0; + u16 contentLen = 0; + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false); + + if (Address < contentLen) { /* E-fuse 512Byte */ + /* Write E-fuse Register address bit0~7 */ + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + /* Write E-fuse Register address bit8~9 */ + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + /* Write 0x30[31]= 0 */ + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp & 0x7F; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + /* Wait Write-ready (0x30[31]= 1) */ + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while (!(Bytetemp & 0x80)) { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if (k == 1000) { + k = 0; + break; + } + } + data = rtw_read8(Adapter, EFUSE_CTRL); + return data; + } else { + return 0xFF; + } + +} /* EFUSE_Read1Byte */ + +/* 11/16/2008 MH Read one byte from real Efuse. */ +u8 efuse_OneByteRead(struct adapter *pAdapter, u16 addr, u8 *data, bool pseudo) +{ + u8 tmpidx = 0; + u8 result; + + if (pseudo) { + result = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data); + return result; + } + /* -----------------e-fuse reg ctrl --------------------------------- */ + /* address */ + rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr & 0xff)); + rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) | + (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC)); + + rtw_write8(pAdapter, EFUSE_CTRL+3, 0x72);/* read cmd */ + + while (!(0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100)) + tmpidx++; + if (tmpidx < 100) { + *data = rtw_read8(pAdapter, EFUSE_CTRL); + result = true; + } else { + *data = 0xff; + result = false; + } + return result; +} + +/* 11/16/2008 MH Write one byte to reald Efuse. */ +u8 efuse_OneByteWrite(struct adapter *pAdapter, u16 addr, u8 data, bool pseudo) +{ + u8 tmpidx = 0; + u8 result; + + if (pseudo) { + result = Efuse_Write1ByteToFakeContent(pAdapter, addr, data); + return result; + } + + /* -----------------e-fuse reg ctrl --------------------------------- */ + /* address */ + rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff)); + rtw_write8(pAdapter, EFUSE_CTRL+2, + (rtw_read8(pAdapter, EFUSE_CTRL+2) & 0xFC) | + (u8)((addr>>8) & 0x03)); + rtw_write8(pAdapter, EFUSE_CTRL, data);/* data */ + + rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);/* write cmd */ + + while ((0x80 & rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx < 100)) + tmpidx++; + + if (tmpidx < 100) + result = true; + else + result = false; + + return result; +} + +int Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool pseudo) +{ + int ret = 0; + + ret = pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, pseudo); + + return ret; +} + +int Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) +{ + int ret; + + ret = pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, pseudo); + + return ret; +} + +static int Efuse_PgPacketWrite_BT(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool pseudo) +{ + int ret; + + ret = pAdapter->HalFunc.Efuse_PgPacketWrite_BT(pAdapter, offset, word_en, data, pseudo); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: efuse_WordEnableDataRead + * + * Overview: Read allowed word in current efuse section data. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * 11/21/2008 MHC Fix Write bug when we only enable late word. + * + *---------------------------------------------------------------------------*/ +void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata) +{ + if (!(word_en&BIT(0))) { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + if (!(word_en&BIT(1))) { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + if (!(word_en&BIT(2))) { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + if (!(word_en&BIT(3))) { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + +u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool pseudo) +{ + u8 ret = 0; + + ret = pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, pseudo); + + return ret; +} + +static u8 efuse_read8(struct adapter *padapter, u16 address, u8 *value) +{ + return efuse_OneByteRead(padapter, address, value, false); +} + +static u8 efuse_write8(struct adapter *padapter, u16 address, u8 *value) +{ + return efuse_OneByteWrite(padapter, address, *value, false); +} + +/* + * read/wirte raw efuse data + */ +u8 rtw_efuse_access(struct adapter *padapter, u8 write, u16 start_addr, u16 cnts, u8 *data) +{ + int i = 0; + u16 real_content_len = 0, max_available_size = 0; + u8 res = _FAIL ; + u8 (*rw8)(struct adapter *, u16, u8*); + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false); + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); + + if (start_addr > real_content_len) + return _FAIL; + + if (write) { + if ((start_addr + cnts) > max_available_size) + return _FAIL; + rw8 = &efuse_write8; + } else { + rw8 = &efuse_read8; + } + + Efuse_PowerSwitch(padapter, write, true); + + /* e-fuse one byte read / write */ + for (i = 0; i < cnts; i++) { + if (start_addr >= real_content_len) { + res = _FAIL; + break; + } + + res = rw8(padapter, start_addr++, data++); + if (_FAIL == res) + break; + } + + Efuse_PowerSwitch(padapter, write, false); + + return res; +} +/* */ +u16 efuse_GetMaxSize(struct adapter *padapter) +{ + u16 max_size; + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false); + return max_size; +} +/* */ +u8 efuse_GetCurrentSize(struct adapter *padapter, u16 *size) +{ + Efuse_PowerSwitch(padapter, false, true); + *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false); + Efuse_PowerSwitch(padapter, false, false); + + return _SUCCESS; +} +/* */ +u8 rtw_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) +{ + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); + + if ((addr + cnts) > mapLen) + return _FAIL; + + Efuse_PowerSwitch(padapter, false, true); + + efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false); + + Efuse_PowerSwitch(padapter, false, false); + + return _SUCCESS; +} + +u8 rtw_BT_efuse_map_read(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) +{ + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); + + if ((addr + cnts) > mapLen) + return _FAIL; + + Efuse_PowerSwitch(padapter, false, true); + + efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false); + + Efuse_PowerSwitch(padapter, false, false); + + return _SUCCESS; +} +/* */ +u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) +{ + u8 offset, word_en; + u8 *map; + u8 newdata[PGPKT_DATA_SIZE + 1]; + s32 i, idx; + u8 ret = _SUCCESS; + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); + + if ((addr + cnts) > mapLen) + return _FAIL; + + map = rtw_zmalloc(mapLen); + if (map == NULL) + return _FAIL; + + ret = rtw_efuse_map_read(padapter, 0, mapLen, map); + if (ret == _FAIL) + goto exit; + + Efuse_PowerSwitch(padapter, true, true); + + offset = (addr >> 3); + word_en = 0xF; + memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); + i = addr & 0x7; /* index of one package */ + idx = 0; /* data index */ + + if (i & 0x1) { + /* odd start */ + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i-1] = map[addr+idx-1]; + newdata[i] = data[idx]; + } + i++; + idx++; + } + do { + for (; i < PGPKT_DATA_SIZE; i += 2) { + if (cnts == idx) + break; + if ((cnts - idx) == 1) { + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = map[addr+idx+1]; + } + idx++; + break; + } else { + if ((data[idx] != map[addr+idx]) || + (data[idx+1] != map[addr+idx+1])) { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = data[idx + 1]; + } + idx += 2; + } + if (idx == cnts) + break; + } + + if (word_en != 0xF) { + ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false); + DBG_88E("offset=%x\n", offset); + DBG_88E("word_en=%x\n", word_en); + + for (i = 0; i < PGPKT_DATA_SIZE; i++) + DBG_88E("data=%x \t", newdata[i]); + if (ret == _FAIL) + break; + } + + if (idx == cnts) + break; + + offset++; + i = 0; + word_en = 0xF; + memset(newdata, 0xFF, PGPKT_DATA_SIZE); + } while (1); + + Efuse_PowerSwitch(padapter, true, false); +exit: + kfree(map); + return ret; +} + +/* */ +u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data) +{ + u8 offset, word_en; + u8 *map; + u8 newdata[PGPKT_DATA_SIZE + 1]; + s32 i, idx; + u8 ret = _SUCCESS; + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); + + if ((addr + cnts) > mapLen) + return _FAIL; + + map = rtw_zmalloc(mapLen); + if (map == NULL) + return _FAIL; + + ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map); + if (ret == _FAIL) + goto exit; + + Efuse_PowerSwitch(padapter, true, true); + + offset = (addr >> 3); + word_en = 0xF; + memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1); + i = addr & 0x7; /* index of one package */ + idx = 0; /* data index */ + + if (i & 0x1) { + /* odd start */ + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i-1] = map[addr+idx-1]; + newdata[i] = data[idx]; + } + i++; + idx++; + } + do { + for (; i < PGPKT_DATA_SIZE; i += 2) { + if (cnts == idx) + break; + if ((cnts - idx) == 1) { + if (data[idx] != map[addr+idx]) { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = map[addr+idx+1]; + } + idx++; + break; + } else { + if ((data[idx] != map[addr+idx]) || + (data[idx+1] != map[addr+idx+1])) { + word_en &= ~BIT(i >> 1); + newdata[i] = data[idx]; + newdata[i+1] = data[idx + 1]; + } + idx += 2; + } + if (idx == cnts) + break; + } + + if (word_en != 0xF) { + DBG_88E("%s: offset=%#X\n", __func__, offset); + DBG_88E("%s: word_en=%#X\n", __func__, word_en); + DBG_88E("%s: data=", __func__); + for (i = 0; i < PGPKT_DATA_SIZE; i++) + DBG_88E("0x%02X ", newdata[i]); + DBG_88E("\n"); + + ret = Efuse_PgPacketWrite_BT(padapter, offset, word_en, newdata, false); + if (ret == _FAIL) + break; + } + + if (idx == cnts) + break; + + offset++; + i = 0; + word_en = 0xF; + memset(newdata, 0xFF, PGPKT_DATA_SIZE); + } while (1); + + Efuse_PowerSwitch(padapter, true, false); + +exit: + + kfree(map); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: efuse_ShadowRead1Byte + * efuse_ShadowRead2Byte + * efuse_ShadowRead4Byte + * + * Overview: Read from efuse init map by one/two/four bytes !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static void +efuse_ShadowRead1Byte( + struct adapter *pAdapter, + u16 Offset, + u8 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + +} /* EFUSE_ShadowRead1Byte */ + +/* Read Two Bytes */ +static void +efuse_ShadowRead2Byte( + struct adapter *pAdapter, + u16 Offset, + u16 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + +} /* EFUSE_ShadowRead2Byte */ + +/* Read Four Bytes */ +static void +efuse_ShadowRead4Byte( + struct adapter *pAdapter, + u16 Offset, + u32 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16; + *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24; + +} /* efuse_ShadowRead4Byte */ + +/*----------------------------------------------------------------------------- + * Function: Efuse_ReadAllMap + * + * Overview: Read All Efuse content + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/11/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static void Efuse_ReadAllMap(struct adapter *pAdapter, u8 efuseType, u8 *Efuse, bool pseudo) +{ + u16 mapLen = 0; + + Efuse_PowerSwitch(pAdapter, false, true); + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); + + efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, pseudo); + + Efuse_PowerSwitch(pAdapter, false, false); +} + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowMapUpdate + * + * Overview: Transfer current EFUSE content to shadow init and modify map. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/13/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void EFUSE_ShadowMapUpdate( + struct adapter *pAdapter, + u8 efuseType, + bool pseudo) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter); + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, pseudo); + + if (pEEPROM->bautoload_fail_flag) + memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); + else + Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, pseudo); +} /* EFUSE_ShadowMapUpdate */ + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowRead + * + * Overview: Read from efuse init map !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void EFUSE_ShadowRead(struct adapter *pAdapter, u8 Type, u16 Offset, u32 *Value) +{ + if (Type == 1) + efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value); + else if (Type == 2) + efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value); + else if (Type == 4) + efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value); + +} /* EFUSE_ShadowRead */ |