1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
6 ******************************************************************************/
10 #include <rtw_debug.h>
12 #include <linux/jiffies.h>
15 /* Define global variables */
17 u32 fakeEfuseUsedBytes;
18 u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
19 u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
20 u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
23 u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
24 u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
25 u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
27 u32 fakeBTEfuseUsedBytes;
28 u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
29 u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
30 u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
32 #define REG_EFUSE_CTRL 0x0030
33 #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
36 Efuse_Read1ByteFromFakeContent(
37 struct adapter *padapter,
41 Efuse_Read1ByteFromFakeContent(
42 struct adapter *padapter,
46 if (Offset >= EFUSE_MAX_HW_SIZE)
48 /* DbgPrint("Read fake content, offset = %d\n", Offset); */
49 if (fakeEfuseBank == 0)
50 *Value = fakeEfuseContent[Offset];
52 *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
57 Efuse_Write1ByteToFakeContent(
58 struct adapter *padapter,
62 Efuse_Write1ByteToFakeContent(
63 struct adapter *padapter,
67 if (Offset >= EFUSE_MAX_HW_SIZE)
69 if (fakeEfuseBank == 0)
70 fakeEfuseContent[Offset] = Value;
72 fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
76 /*-----------------------------------------------------------------------------
77 * Function: Efuse_PowerSwitch
79 * Overview: When we want to enable write operation, we should change to
80 * pwr on state. When we stop write, we should switch to 500k mode
81 * and disable LDO 2.5V.
91 * 11/17/2008 MHC Create Version 0.
93 *---------------------------------------------------------------------------*/
96 struct adapter *padapter,
100 padapter->HalFunc.EfusePowerSwitch(padapter, bWrite, PwrState);
103 /*-----------------------------------------------------------------------------
104 * Function: Efuse_GetCurrentSize
106 * Overview: Get current efuse size!!!
116 * 11/16/2008 MHC Create Version 0.
118 *---------------------------------------------------------------------------*/
120 Efuse_GetCurrentSize(
121 struct adapter *padapter,
125 return padapter->HalFunc.EfuseGetCurrentSize(padapter, efuseType,
129 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
131 Efuse_CalculateWordCnts(u8 word_en)
134 if (!(word_en & BIT(0)))
135 word_cnts++; /* 0 : write enable */
136 if (!(word_en & BIT(1)))
138 if (!(word_en & BIT(2)))
140 if (!(word_en & BIT(3)))
147 /* 1. Execute E-Fuse read byte operation according as map offset and */
148 /* save to E-Fuse table. */
149 /* 2. Referred from SD1 Richard. */
152 /* 1. Boot from E-Fuse and successfully auto-load. */
153 /* 2. PASSIVE_LEVEL (USB interface) */
155 /* Created by Roger, 2008.10.21. */
157 /* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */
158 /* 2. Add efuse utilization collect. */
159 /* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */
160 /* write addr must be after sec5. */
165 struct adapter *Adapter,
174 struct adapter *Adapter,
182 Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
186 EFUSE_GetEfuseDefinition(
187 struct adapter *padapter,
194 padapter->HalFunc.EFUSEGetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest);
197 /*-----------------------------------------------------------------------------
198 * Function: EFUSE_Read1Byte
200 * Overview: Copy from WMAC fot EFUSE read 1 byte.
210 * 09/23/2008 MHC Copy from WMAC.
212 *---------------------------------------------------------------------------*/
215 struct adapter *Adapter,
218 u8 Bytetemp = {0x00};
223 EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
225 if (Address < contentLen) {/* E-fuse 512Byte */
226 /* Write E-fuse Register address bit0~7 */
227 temp = Address & 0xFF;
228 rtw_write8(Adapter, EFUSE_CTRL+1, temp);
229 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
230 /* Write E-fuse Register address bit8~9 */
231 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
232 rtw_write8(Adapter, EFUSE_CTRL+2, temp);
234 /* Write 0x30[31]= 0 */
235 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
236 temp = Bytetemp & 0x7F;
237 rtw_write8(Adapter, EFUSE_CTRL+3, temp);
239 /* Wait Write-ready (0x30[31]= 1) */
240 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
241 while (!(Bytetemp & 0x80)) {
242 Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
247 return rtw_read8(Adapter, EFUSE_CTRL);
251 } /* EFUSE_Read1Byte */
253 /* 11/16/2008 MH Read one byte from real Efuse. */
256 struct adapter *padapter,
265 /* DBG_871X("===> EFUSE_OneByteRead(), addr = %x\n", addr); */
266 /* DBG_871X("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */
269 return Efuse_Read1ByteFromFakeContent(padapter, addr, data);
272 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
273 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
274 /* PHY_SetMacReg(padapter, 0x34, BIT11, 0); */
275 rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) & (~BIT11));
277 /* -----------------e-fuse reg ctrl --------------------------------- */
279 rtw_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xff));
280 rtw_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
281 (rtw_read8(padapter, EFUSE_CTRL+2)&0xFC));
283 /* rtw_write8(padapter, EFUSE_CTRL+3, 0x72); read cmd */
285 readbyte = rtw_read8(padapter, EFUSE_CTRL+3);
286 rtw_write8(padapter, EFUSE_CTRL+3, (readbyte & 0x7f));
288 while (!(0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 1000)) {
293 *data = rtw_read8(padapter, EFUSE_CTRL);
298 DBG_871X("%s: [ERROR] addr = 0x%x bResult =%d time out 1s !!!\n", __func__, addr, bResult);
299 DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL));
305 /* 11/16/2008 MH Write one byte to reald Efuse. */
308 struct adapter *padapter,
317 /* DBG_871X("===> EFUSE_OneByteWrite(), addr = %x data =%x\n", addr, data); */
318 /* DBG_871X("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */
321 return Efuse_Write1ByteToFakeContent(padapter, addr, data);
325 /* -----------------e-fuse reg ctrl --------------------------------- */
329 efuseValue = rtw_read32(padapter, EFUSE_CTRL);
330 efuseValue |= (BIT21|BIT31);
331 efuseValue &= ~(0x3FFFF);
332 efuseValue |= ((addr<<8 | data) & 0x3FFFF);
335 /* <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */
337 /* <20130121, Kordan> For SMIC EFUSE specificatoin. */
338 /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
339 /* PHY_SetMacReg(padapter, 0x34, BIT11, 1); */
340 rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) | (BIT11));
341 rtw_write32(padapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data)));
343 while ((0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100)) {
352 DBG_871X("%s: [ERROR] addr = 0x%x , efuseValue = 0x%x , bResult =%d time out 1s !!!\n",
353 __func__, addr, efuseValue, bResult);
354 DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL));
357 /* disable Efuse program enable */
358 PHY_SetMacReg(padapter, EFUSE_TEST, BIT(11), 0);
364 Efuse_PgPacketRead(struct adapter *padapter,
369 return padapter->HalFunc.Efuse_PgPacketRead(padapter, offset, data,
374 Efuse_PgPacketWrite(struct adapter *padapter,
380 return padapter->HalFunc.Efuse_PgPacketWrite(padapter, offset, word_en,
384 /*-----------------------------------------------------------------------------
385 * Function: efuse_WordEnableDataRead
387 * Overview: Read allowed word in current efuse section data.
397 * 11/16/2008 MHC Create Version 0.
398 * 11/21/2008 MHC Fix Write bug when we only enable late word.
400 *---------------------------------------------------------------------------*/
402 efuse_WordEnableDataRead(u8 word_en,
406 if (!(word_en&BIT(0))) {
407 targetdata[0] = sourdata[0];
408 targetdata[1] = sourdata[1];
410 if (!(word_en&BIT(1))) {
411 targetdata[2] = sourdata[2];
412 targetdata[3] = sourdata[3];
414 if (!(word_en&BIT(2))) {
415 targetdata[4] = sourdata[4];
416 targetdata[5] = sourdata[5];
418 if (!(word_en&BIT(3))) {
419 targetdata[6] = sourdata[6];
420 targetdata[7] = sourdata[7];
426 Efuse_WordEnableDataWrite(struct adapter *padapter,
432 return padapter->HalFunc.Efuse_WordEnableDataWrite(padapter, efuse_addr,
437 /*-----------------------------------------------------------------------------
438 * Function: Efuse_ReadAllMap
440 * Overview: Read All Efuse content
450 * 11/11/2008 MHC Create Version 0.
452 *---------------------------------------------------------------------------*/
455 struct adapter *padapter,
461 struct adapter *padapter,
468 Efuse_PowerSwitch(padapter, false, true);
470 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
472 efuse_ReadEFuse(padapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
474 Efuse_PowerSwitch(padapter, false, false);
477 /*-----------------------------------------------------------------------------
478 * Function: efuse_ShadowRead1Byte
479 * efuse_ShadowRead2Byte
480 * efuse_ShadowRead4Byte
482 * Overview: Read from efuse init map by one/two/four bytes !!!!!
492 * 11/12/2008 MHC Create Version 0.
494 *---------------------------------------------------------------------------*/
496 efuse_ShadowRead1Byte(
497 struct adapter *padapter,
501 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
503 *Value = pEEPROM->efuse_eeprom_data[Offset];
505 } /* EFUSE_ShadowRead1Byte */
509 efuse_ShadowRead2Byte(
510 struct adapter *padapter,
514 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
516 *Value = pEEPROM->efuse_eeprom_data[Offset];
517 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
519 } /* EFUSE_ShadowRead2Byte */
521 /* Read Four Bytes */
523 efuse_ShadowRead4Byte(
524 struct adapter *padapter,
528 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
530 *Value = pEEPROM->efuse_eeprom_data[Offset];
531 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
532 *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
533 *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
535 } /* efuse_ShadowRead4Byte */
537 /*-----------------------------------------------------------------------------
538 * Function: EFUSE_ShadowMapUpdate
540 * Overview: Transfer current EFUSE content to shadow init and modify map.
550 * 11/13/2008 MHC Create Version 0.
552 *---------------------------------------------------------------------------*/
553 void EFUSE_ShadowMapUpdate(
554 struct adapter *padapter,
558 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
561 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
563 if (pEEPROM->bautoload_fail_flag)
564 memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
566 Efuse_ReadAllMap(padapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest);
568 /* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
569 /* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
570 } /* EFUSE_ShadowMapUpdate */
573 /*-----------------------------------------------------------------------------
574 * Function: EFUSE_ShadowRead
576 * Overview: Read from efuse init map !!!!!
586 * 11/12/2008 MHC Create Version 0.
588 *---------------------------------------------------------------------------*/
591 struct adapter *padapter,
597 efuse_ShadowRead1Byte(padapter, Offset, (u8 *)Value);
599 efuse_ShadowRead2Byte(padapter, Offset, (u16 *)Value);
601 efuse_ShadowRead4Byte(padapter, Offset, (u32 *)Value);
603 } /* EFUSE_ShadowRead*/