1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
10 #include <linux/jiffies.h>
13 /* Define global variables */
15 u32 fakeEfuseUsedBytes;
16 u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
17 u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
18 u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
21 u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
22 u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
23 u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
25 u32 fakeBTEfuseUsedBytes;
26 u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
27 u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
28 u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
30 #define REG_EFUSE_CTRL 0x0030
31 #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
34 Efuse_Read1ByteFromFakeContent(u16 Offset, u8 *Value)
36 if (Offset >= EFUSE_MAX_HW_SIZE)
38 if (fakeEfuseBank == 0)
39 *Value = fakeEfuseContent[Offset];
41 *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
46 Efuse_Write1ByteToFakeContent(u16 Offset, u8 Value)
48 if (Offset >= EFUSE_MAX_HW_SIZE)
50 if (fakeEfuseBank == 0)
51 fakeEfuseContent[Offset] = Value;
53 fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
57 /*-----------------------------------------------------------------------------
58 * Function: Efuse_PowerSwitch
60 * Overview: When we want to enable write operation, we should change to
61 * pwr on state. When we stop write, we should switch to 500k mode
62 * and disable LDO 2.5V.
72 * 11/17/2008 MHC Create Version 0.
74 *---------------------------------------------------------------------------*/
77 struct adapter *padapter,
81 padapter->HalFunc.EfusePowerSwitch(padapter, bWrite, PwrState);
84 /*-----------------------------------------------------------------------------
85 * Function: Efuse_GetCurrentSize
87 * Overview: Get current efuse size!!!
97 * 11/16/2008 MHC Create Version 0.
99 *---------------------------------------------------------------------------*/
101 Efuse_GetCurrentSize(
102 struct adapter *padapter,
106 return padapter->HalFunc.EfuseGetCurrentSize(padapter, efuseType,
110 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
112 Efuse_CalculateWordCnts(u8 word_en)
115 if (!(word_en & BIT(0)))
116 word_cnts++; /* 0 : write enable */
117 if (!(word_en & BIT(1)))
119 if (!(word_en & BIT(2)))
121 if (!(word_en & BIT(3)))
128 /* 1. Execute E-Fuse read byte operation according as map offset and */
129 /* save to E-Fuse table. */
130 /* 2. Referred from SD1 Richard. */
133 /* 1. Boot from E-Fuse and successfully auto-load. */
134 /* 2. PASSIVE_LEVEL (USB interface) */
136 /* Created by Roger, 2008.10.21. */
138 /* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */
139 /* 2. Add efuse utilization collect. */
140 /* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */
141 /* write addr must be after sec5. */
146 struct adapter *Adapter,
155 struct adapter *Adapter,
163 Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
167 EFUSE_GetEfuseDefinition(
168 struct adapter *padapter,
175 padapter->HalFunc.EFUSEGetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest);
178 /*-----------------------------------------------------------------------------
179 * Function: EFUSE_Read1Byte
181 * Overview: Copy from WMAC fot EFUSE read 1 byte.
191 * 09/23/2008 MHC Copy from WMAC.
193 *---------------------------------------------------------------------------*/
196 struct adapter *Adapter,
199 u8 Bytetemp = {0x00};
204 EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
206 if (Address < contentLen) {/* E-fuse 512Byte */
207 /* Write E-fuse Register address bit0~7 */
208 temp = Address & 0xFF;
209 rtw_write8(Adapter, EFUSE_CTRL+1, temp);
210 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
211 /* Write E-fuse Register address bit8~9 */
212 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
213 rtw_write8(Adapter, EFUSE_CTRL+2, temp);
215 /* Write 0x30[31]= 0 */
216 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
217 temp = Bytetemp & 0x7F;
218 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
220 /* Wait Write-ready (0x30[31]= 1) */
221 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
222 while (!(Bytetemp & 0x80)) {
223 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
228 return rtw_read8(Adapter, EFUSE_CTRL);
232 } /* EFUSE_Read1Byte */
234 /* 11/16/2008 MH Read one byte from real Efuse. */
237 struct adapter *padapter,
247 return Efuse_Read1ByteFromFakeContent(addr, data);
249 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
250 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
251 /* PHY_SetMacReg(padapter, 0x34, BIT11, 0); */
252 rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) & (~BIT11));
254 /* -----------------e-fuse reg ctrl --------------------------------- */
256 rtw_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xff));
257 rtw_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
258 (rtw_read8(padapter, EFUSE_CTRL+2)&0xFC));
260 /* rtw_write8(padapter, EFUSE_CTRL+3, 0x72); read cmd */
262 readbyte = rtw_read8(padapter, EFUSE_CTRL+3);
263 rtw_write8(padapter, EFUSE_CTRL+3, (readbyte & 0x7f));
265 while (!(0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 1000)) {
270 *data = rtw_read8(padapter, EFUSE_CTRL);
280 /* 11/16/2008 MH Write one byte to reald Efuse. */
281 u8 efuse_OneByteWrite(struct adapter *padapter, u16 addr, u8 data, bool bPseudoTest)
288 return Efuse_Write1ByteToFakeContent(addr, data);
291 /* -----------------e-fuse reg ctrl --------------------------------- */
295 efuseValue = rtw_read32(padapter, EFUSE_CTRL);
296 efuseValue |= (BIT21|BIT31);
297 efuseValue &= ~(0x3FFFF);
298 efuseValue |= ((addr<<8 | data) & 0x3FFFF);
301 /* <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */
303 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
304 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
305 /* PHY_SetMacReg(padapter, 0x34, BIT11, 1); */
306 rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) | (BIT11));
307 rtw_write32(padapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data)));
309 while ((0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100)) {
319 /* disable Efuse program enable */
320 PHY_SetMacReg(padapter, EFUSE_TEST, BIT(11), 0);
326 Efuse_PgPacketRead(struct adapter *padapter,
331 return padapter->HalFunc.Efuse_PgPacketRead(padapter, offset, data,
336 Efuse_PgPacketWrite(struct adapter *padapter,
342 return padapter->HalFunc.Efuse_PgPacketWrite(padapter, offset, word_en,
346 /*-----------------------------------------------------------------------------
347 * Function: efuse_WordEnableDataRead
349 * Overview: Read allowed word in current efuse section data.
359 * 11/16/2008 MHC Create Version 0.
360 * 11/21/2008 MHC Fix Write bug when we only enable late word.
362 *---------------------------------------------------------------------------*/
364 efuse_WordEnableDataRead(u8 word_en,
368 if (!(word_en&BIT(0))) {
369 targetdata[0] = sourdata[0];
370 targetdata[1] = sourdata[1];
372 if (!(word_en&BIT(1))) {
373 targetdata[2] = sourdata[2];
374 targetdata[3] = sourdata[3];
376 if (!(word_en&BIT(2))) {
377 targetdata[4] = sourdata[4];
378 targetdata[5] = sourdata[5];
380 if (!(word_en&BIT(3))) {
381 targetdata[6] = sourdata[6];
382 targetdata[7] = sourdata[7];
388 Efuse_WordEnableDataWrite(struct adapter *padapter,
394 return padapter->HalFunc.Efuse_WordEnableDataWrite(padapter, efuse_addr,
399 /*-----------------------------------------------------------------------------
400 * Function: Efuse_ReadAllMap
402 * Overview: Read All Efuse content
412 * 11/11/2008 MHC Create Version 0.
414 *---------------------------------------------------------------------------*/
417 struct adapter *padapter,
421 void Efuse_ReadAllMap(struct adapter *padapter, u8 efuseType, u8 *Efuse, bool bPseudoTest)
425 Efuse_PowerSwitch(padapter, false, true);
427 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
429 efuse_ReadEFuse(padapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
431 Efuse_PowerSwitch(padapter, false, false);
434 /*-----------------------------------------------------------------------------
435 * Function: efuse_ShadowRead1Byte
436 * efuse_ShadowRead2Byte
437 * efuse_ShadowRead4Byte
439 * Overview: Read from efuse init map by one/two/four bytes !!!!!
449 * 11/12/2008 MHC Create Version 0.
451 *---------------------------------------------------------------------------*/
452 static void efuse_ShadowRead1Byte(struct adapter *padapter, u16 Offset, u8 *Value)
454 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
456 *Value = pEEPROM->efuse_eeprom_data[Offset];
458 } /* EFUSE_ShadowRead1Byte */
461 static void efuse_ShadowRead2Byte(struct adapter *padapter, u16 Offset, u16 *Value)
463 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
465 *Value = pEEPROM->efuse_eeprom_data[Offset];
466 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
468 } /* EFUSE_ShadowRead2Byte */
470 /* Read Four Bytes */
471 static void efuse_ShadowRead4Byte(struct adapter *padapter, u16 Offset, u32 *Value)
473 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
475 *Value = pEEPROM->efuse_eeprom_data[Offset];
476 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
477 *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
478 *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
480 } /* efuse_ShadowRead4Byte */
482 /*-----------------------------------------------------------------------------
483 * Function: EFUSE_ShadowMapUpdate
485 * Overview: Transfer current EFUSE content to shadow init and modify map.
495 * 11/13/2008 MHC Create Version 0.
497 *---------------------------------------------------------------------------*/
498 void EFUSE_ShadowMapUpdate(struct adapter *padapter, u8 efuseType, bool bPseudoTest)
500 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
503 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
505 if (pEEPROM->bautoload_fail_flag)
506 memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
508 Efuse_ReadAllMap(padapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest);
510 /* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
511 /* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
512 } /* EFUSE_ShadowMapUpdate */
515 /*-----------------------------------------------------------------------------
516 * Function: EFUSE_ShadowRead
518 * Overview: Read from efuse init map !!!!!
528 * 11/12/2008 MHC Create Version 0.
530 *---------------------------------------------------------------------------*/
531 void EFUSE_ShadowRead(struct adapter *padapter, u8 Type, u16 Offset, u32 *Value)
534 efuse_ShadowRead1Byte(padapter, Offset, (u8 *)Value);
536 efuse_ShadowRead2Byte(padapter, Offset, (u16 *)Value);
538 efuse_ShadowRead4Byte(padapter, Offset, (u32 *)Value);
540 } /* EFUSE_ShadowRead*/