158391efdSNathan Chancellor // SPDX-License-Identifier: GPL-2.0
2554c0a3aSHans de Goede /******************************************************************************
3554c0a3aSHans de Goede  *
4554c0a3aSHans de Goede  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5554c0a3aSHans de Goede  *
6554c0a3aSHans de Goede  ******************************************************************************/
7554c0a3aSHans de Goede #define _RTW_EFUSE_C_
8554c0a3aSHans de Goede 
9554c0a3aSHans de Goede #include <drv_types.h>
10554c0a3aSHans de Goede #include <rtw_debug.h>
11554c0a3aSHans de Goede #include <hal_data.h>
12554c0a3aSHans de Goede #include <linux/jiffies.h>
13554c0a3aSHans de Goede 
14554c0a3aSHans de Goede 
15e8466ea7SHenriette Hofmeier /* Define global variables */
16cbb2cb50SHenriette Hofmeier u8 fakeEfuseBank;
17cbb2cb50SHenriette Hofmeier u32 fakeEfuseUsedBytes;
18554c0a3aSHans de Goede u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
19554c0a3aSHans de Goede u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
20554c0a3aSHans de Goede u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
21554c0a3aSHans de Goede 
22cbb2cb50SHenriette Hofmeier u32 BTEfuseUsedBytes;
23554c0a3aSHans de Goede u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
24554c0a3aSHans de Goede u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
25554c0a3aSHans de Goede u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
26554c0a3aSHans de Goede 
27cbb2cb50SHenriette Hofmeier u32 fakeBTEfuseUsedBytes;
28554c0a3aSHans de Goede u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
29554c0a3aSHans de Goede u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
30554c0a3aSHans de Goede u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
31554c0a3aSHans de Goede 
32554c0a3aSHans de Goede #define REG_EFUSE_CTRL		0x0030
33554c0a3aSHans de Goede #define EFUSE_CTRL			REG_EFUSE_CTRL		/*  E-Fuse Control. */
34554c0a3aSHans de Goede 
35554c0a3aSHans de Goede bool
36554c0a3aSHans de Goede Efuse_Read1ByteFromFakeContent(
37554c0a3aSHans de Goede 	struct adapter *padapter,
38554c0a3aSHans de Goede 	u16 	Offset,
39554c0a3aSHans de Goede 	u8 *Value);
40554c0a3aSHans de Goede bool
41554c0a3aSHans de Goede Efuse_Read1ByteFromFakeContent(
42554c0a3aSHans de Goede 	struct adapter *padapter,
43554c0a3aSHans de Goede 	u16 	Offset,
44554c0a3aSHans de Goede 	u8 *Value)
45554c0a3aSHans de Goede {
46554c0a3aSHans de Goede 	if (Offset >= EFUSE_MAX_HW_SIZE) {
47554c0a3aSHans de Goede 		return false;
48554c0a3aSHans de Goede 	}
49554c0a3aSHans de Goede 	/* DbgPrint("Read fake content, offset = %d\n", Offset); */
50554c0a3aSHans de Goede 	if (fakeEfuseBank == 0)
51554c0a3aSHans de Goede 		*Value = fakeEfuseContent[Offset];
52554c0a3aSHans de Goede 	else
53554c0a3aSHans de Goede 		*Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
54554c0a3aSHans de Goede 	return true;
55554c0a3aSHans de Goede }
56554c0a3aSHans de Goede 
57554c0a3aSHans de Goede bool
58554c0a3aSHans de Goede Efuse_Write1ByteToFakeContent(
59554c0a3aSHans de Goede 	struct adapter *padapter,
60554c0a3aSHans de Goede 	u16 	Offset,
61554c0a3aSHans de Goede 	u8 Value);
62554c0a3aSHans de Goede bool
63554c0a3aSHans de Goede Efuse_Write1ByteToFakeContent(
64554c0a3aSHans de Goede 	struct adapter *padapter,
65554c0a3aSHans de Goede 	u16 	Offset,
66554c0a3aSHans de Goede 	u8 Value)
67554c0a3aSHans de Goede {
68554c0a3aSHans de Goede 	if (Offset >= EFUSE_MAX_HW_SIZE) {
69554c0a3aSHans de Goede 		return false;
70554c0a3aSHans de Goede 	}
71554c0a3aSHans de Goede 	if (fakeEfuseBank == 0)
72554c0a3aSHans de Goede 		fakeEfuseContent[Offset] = Value;
73554c0a3aSHans de Goede 	else {
74554c0a3aSHans de Goede 		fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
75554c0a3aSHans de Goede 	}
76554c0a3aSHans de Goede 	return true;
77554c0a3aSHans de Goede }
78554c0a3aSHans de Goede 
79554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
80554c0a3aSHans de Goede  * Function:	Efuse_PowerSwitch
81554c0a3aSHans de Goede  *
82554c0a3aSHans de Goede  * Overview:	When we want to enable write operation, we should change to
83554c0a3aSHans de Goede  *			pwr on state. When we stop write, we should switch to 500k mode
84554c0a3aSHans de Goede  *			and disable LDO 2.5V.
85554c0a3aSHans de Goede  *
86554c0a3aSHans de Goede  * Input:       NONE
87554c0a3aSHans de Goede  *
88554c0a3aSHans de Goede  * Output:      NONE
89554c0a3aSHans de Goede  *
90554c0a3aSHans de Goede  * Return:      NONE
91554c0a3aSHans de Goede  *
92554c0a3aSHans de Goede  * Revised History:
93554c0a3aSHans de Goede  * When			Who		Remark
94554c0a3aSHans de Goede  * 11/17/2008	MHC		Create Version 0.
95554c0a3aSHans de Goede  *
96554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
97554c0a3aSHans de Goede void
98554c0a3aSHans de Goede Efuse_PowerSwitch(
99554c0a3aSHans de Goede struct adapter *padapter,
100554c0a3aSHans de Goede u8 bWrite,
101554c0a3aSHans de Goede u8 PwrState)
102554c0a3aSHans de Goede {
103554c0a3aSHans de Goede 	padapter->HalFunc.EfusePowerSwitch(padapter, bWrite, PwrState);
104554c0a3aSHans de Goede }
105554c0a3aSHans de Goede 
106554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
107554c0a3aSHans de Goede  * Function:	Efuse_GetCurrentSize
108554c0a3aSHans de Goede  *
109554c0a3aSHans de Goede  * Overview:	Get current efuse size!!!
110554c0a3aSHans de Goede  *
111554c0a3aSHans de Goede  * Input:       NONE
112554c0a3aSHans de Goede  *
113554c0a3aSHans de Goede  * Output:      NONE
114554c0a3aSHans de Goede  *
115554c0a3aSHans de Goede  * Return:      NONE
116554c0a3aSHans de Goede  *
117554c0a3aSHans de Goede  * Revised History:
118554c0a3aSHans de Goede  * When			Who		Remark
119554c0a3aSHans de Goede  * 11/16/2008	MHC		Create Version 0.
120554c0a3aSHans de Goede  *
121554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
122554c0a3aSHans de Goede u16
123554c0a3aSHans de Goede Efuse_GetCurrentSize(
124554c0a3aSHans de Goede 	struct adapter *padapter,
125554c0a3aSHans de Goede 	u8 	efuseType,
126554c0a3aSHans de Goede 	bool		bPseudoTest)
127554c0a3aSHans de Goede {
1287997c367SPayal Kshirsagar 	return padapter->HalFunc.EfuseGetCurrentSize(padapter, efuseType,
1297997c367SPayal Kshirsagar 						     bPseudoTest);
130554c0a3aSHans de Goede }
131554c0a3aSHans de Goede 
132554c0a3aSHans de Goede /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
133554c0a3aSHans de Goede u8
134554c0a3aSHans de Goede Efuse_CalculateWordCnts(u8 word_en)
135554c0a3aSHans de Goede {
136554c0a3aSHans de Goede 	u8 word_cnts = 0;
137554c0a3aSHans de Goede 	if (!(word_en & BIT(0)))
138554c0a3aSHans de Goede 		word_cnts++; /*  0 : write enable */
139554c0a3aSHans de Goede 	if (!(word_en & BIT(1)))
140554c0a3aSHans de Goede 		word_cnts++;
141554c0a3aSHans de Goede 	if (!(word_en & BIT(2)))
142554c0a3aSHans de Goede 		word_cnts++;
143554c0a3aSHans de Goede 	if (!(word_en & BIT(3)))
144554c0a3aSHans de Goede 		word_cnts++;
145554c0a3aSHans de Goede 	return word_cnts;
146554c0a3aSHans de Goede }
147554c0a3aSHans de Goede 
148554c0a3aSHans de Goede /*  */
149554c0a3aSHans de Goede /* 	Description: */
150554c0a3aSHans de Goede /* 		1. Execute E-Fuse read byte operation according as map offset and */
151554c0a3aSHans de Goede /* 		    save to E-Fuse table. */
152a4b99f3dSXaralampos Mainas /* 		2. Referred from SD1 Richard. */
153554c0a3aSHans de Goede /*  */
154554c0a3aSHans de Goede /* 	Assumption: */
155554c0a3aSHans de Goede /* 		1. Boot from E-Fuse and successfully auto-load. */
156554c0a3aSHans de Goede /* 		2. PASSIVE_LEVEL (USB interface) */
157554c0a3aSHans de Goede /*  */
158554c0a3aSHans de Goede /* 	Created by Roger, 2008.10.21. */
159554c0a3aSHans de Goede /*  */
160554c0a3aSHans de Goede /* 	2008/12/12 MH	1. Reorganize code flow and reserve bytes. and add description. */
161554c0a3aSHans de Goede /* 					2. Add efuse utilization collect. */
162554c0a3aSHans de Goede /* 	2008/12/22 MH	Read Efuse must check if we write section 1 data again!!! Sec1 */
163554c0a3aSHans de Goede /* 					write addr must be after sec5. */
164554c0a3aSHans de Goede /*  */
165554c0a3aSHans de Goede 
166554c0a3aSHans de Goede void
167554c0a3aSHans de Goede efuse_ReadEFuse(
168554c0a3aSHans de Goede 	struct adapter *Adapter,
169554c0a3aSHans de Goede 	u8 efuseType,
170554c0a3aSHans de Goede 	u16 	_offset,
171554c0a3aSHans de Goede 	u16 	_size_byte,
172554c0a3aSHans de Goede 	u8 *pbuf,
173554c0a3aSHans de Goede bool	bPseudoTest
174554c0a3aSHans de Goede 	);
175554c0a3aSHans de Goede void
176554c0a3aSHans de Goede efuse_ReadEFuse(
177554c0a3aSHans de Goede 	struct adapter *Adapter,
178554c0a3aSHans de Goede 	u8 efuseType,
179554c0a3aSHans de Goede 	u16 	_offset,
180554c0a3aSHans de Goede 	u16 	_size_byte,
181554c0a3aSHans de Goede 	u8 *pbuf,
182554c0a3aSHans de Goede bool	bPseudoTest
183554c0a3aSHans de Goede 	)
184554c0a3aSHans de Goede {
185554c0a3aSHans de Goede 	Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
186554c0a3aSHans de Goede }
187554c0a3aSHans de Goede 
188554c0a3aSHans de Goede void
189554c0a3aSHans de Goede EFUSE_GetEfuseDefinition(
190554c0a3aSHans de Goede 	struct adapter *padapter,
191554c0a3aSHans de Goede 	u8 efuseType,
192554c0a3aSHans de Goede 	u8 type,
193554c0a3aSHans de Goede 	void 	*pOut,
194554c0a3aSHans de Goede 	bool		bPseudoTest
195554c0a3aSHans de Goede 	)
196554c0a3aSHans de Goede {
197554c0a3aSHans de Goede 	padapter->HalFunc.EFUSEGetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest);
198554c0a3aSHans de Goede }
199554c0a3aSHans de Goede 
200554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
201554c0a3aSHans de Goede  * Function:	EFUSE_Read1Byte
202554c0a3aSHans de Goede  *
203554c0a3aSHans de Goede  * Overview:	Copy from WMAC fot EFUSE read 1 byte.
204554c0a3aSHans de Goede  *
205554c0a3aSHans de Goede  * Input:       NONE
206554c0a3aSHans de Goede  *
207554c0a3aSHans de Goede  * Output:      NONE
208554c0a3aSHans de Goede  *
209554c0a3aSHans de Goede  * Return:      NONE
210554c0a3aSHans de Goede  *
211554c0a3aSHans de Goede  * Revised History:
212554c0a3aSHans de Goede  * When			Who		Remark
213554c0a3aSHans de Goede  * 09/23/2008	MHC		Copy from WMAC.
214554c0a3aSHans de Goede  *
215554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
216554c0a3aSHans de Goede u8
217554c0a3aSHans de Goede EFUSE_Read1Byte(
218554c0a3aSHans de Goede struct adapter *Adapter,
219554c0a3aSHans de Goede u16 	Address)
220554c0a3aSHans de Goede {
221554c0a3aSHans de Goede 	u8 Bytetemp = {0x00};
222554c0a3aSHans de Goede 	u8 temp = {0x00};
223554c0a3aSHans de Goede 	u32 k = 0;
224554c0a3aSHans de Goede 	u16 contentLen = 0;
225554c0a3aSHans de Goede 
226554c0a3aSHans de Goede 	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false);
227554c0a3aSHans de Goede 
228554c0a3aSHans de Goede 	if (Address < contentLen) {/* E-fuse 512Byte */
229554c0a3aSHans de Goede 		/* Write E-fuse Register address bit0~7 */
230554c0a3aSHans de Goede 		temp = Address & 0xFF;
231554c0a3aSHans de Goede 		rtw_write8(Adapter, EFUSE_CTRL+1, temp);
232554c0a3aSHans de Goede 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
233554c0a3aSHans de Goede 		/* Write E-fuse Register address bit8~9 */
234554c0a3aSHans de Goede 		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
235554c0a3aSHans de Goede 		rtw_write8(Adapter, EFUSE_CTRL+2, temp);
236554c0a3aSHans de Goede 
237554c0a3aSHans de Goede 		/* Write 0x30[31]= 0 */
238554c0a3aSHans de Goede 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
239554c0a3aSHans de Goede 		temp = Bytetemp & 0x7F;
240554c0a3aSHans de Goede 		rtw_write8(Adapter, EFUSE_CTRL+3, temp);
241554c0a3aSHans de Goede 
242554c0a3aSHans de Goede 		/* Wait Write-ready (0x30[31]= 1) */
243554c0a3aSHans de Goede 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
244554c0a3aSHans de Goede 		while (!(Bytetemp & 0x80)) {
245554c0a3aSHans de Goede 			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
246554c0a3aSHans de Goede 			k++;
247554c0a3aSHans de Goede 			if (k == 1000) {
248554c0a3aSHans de Goede 				k = 0;
249554c0a3aSHans de Goede 				break;
250554c0a3aSHans de Goede 			}
251554c0a3aSHans de Goede 		}
2527997c367SPayal Kshirsagar 		return rtw_read8(Adapter, EFUSE_CTRL);
253554c0a3aSHans de Goede 	} else
254554c0a3aSHans de Goede 		return 0xFF;
255554c0a3aSHans de Goede 
256554c0a3aSHans de Goede } /* EFUSE_Read1Byte */
257554c0a3aSHans de Goede 
258554c0a3aSHans de Goede /*  11/16/2008 MH Read one byte from real Efuse. */
259554c0a3aSHans de Goede u8
260554c0a3aSHans de Goede efuse_OneByteRead(
261554c0a3aSHans de Goede struct adapter *padapter,
262554c0a3aSHans de Goede u16 		addr,
263554c0a3aSHans de Goede u8 	*data,
264554c0a3aSHans de Goede bool		bPseudoTest)
265554c0a3aSHans de Goede {
266554c0a3aSHans de Goede 	u32 tmpidx = 0;
267554c0a3aSHans de Goede 	u8 bResult;
268554c0a3aSHans de Goede 	u8 readbyte;
269554c0a3aSHans de Goede 
270554c0a3aSHans de Goede 	/* DBG_871X("===> EFUSE_OneByteRead(), addr = %x\n", addr); */
271554c0a3aSHans de Goede 	/* DBG_871X("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */
272554c0a3aSHans de Goede 
273554c0a3aSHans de Goede 	if (bPseudoTest) {
274554c0a3aSHans de Goede 		bResult = Efuse_Read1ByteFromFakeContent(padapter, addr, data);
275554c0a3aSHans de Goede 		return bResult;
276554c0a3aSHans de Goede 	}
277554c0a3aSHans de Goede 
278554c0a3aSHans de Goede 	/*  <20130121, Kordan> For SMIC EFUSE specificatoin. */
279554c0a3aSHans de Goede 	/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
280554c0a3aSHans de Goede 	/* PHY_SetMacReg(padapter, 0x34, BIT11, 0); */
281554c0a3aSHans de Goede 	rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) & (~BIT11));
282554c0a3aSHans de Goede 
283554c0a3aSHans de Goede 	/*  -----------------e-fuse reg ctrl --------------------------------- */
284554c0a3aSHans de Goede 	/* address */
285554c0a3aSHans de Goede 	rtw_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xff));
286554c0a3aSHans de Goede 	rtw_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) |
287554c0a3aSHans de Goede 	(rtw_read8(padapter, EFUSE_CTRL+2)&0xFC));
288554c0a3aSHans de Goede 
289554c0a3aSHans de Goede 	/* rtw_write8(padapter, EFUSE_CTRL+3,  0x72); read cmd */
290554c0a3aSHans de Goede 	/* Write bit 32 0 */
291554c0a3aSHans de Goede 	readbyte = rtw_read8(padapter, EFUSE_CTRL+3);
292554c0a3aSHans de Goede 	rtw_write8(padapter, EFUSE_CTRL+3, (readbyte & 0x7f));
293554c0a3aSHans de Goede 
294554c0a3aSHans de Goede 	while (!(0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 1000)) {
295554c0a3aSHans de Goede 		mdelay(1);
296554c0a3aSHans de Goede 		tmpidx++;
297554c0a3aSHans de Goede 	}
298554c0a3aSHans de Goede 	if (tmpidx < 100) {
299554c0a3aSHans de Goede 		*data = rtw_read8(padapter, EFUSE_CTRL);
300554c0a3aSHans de Goede 		bResult = true;
301554c0a3aSHans de Goede 	} else {
302554c0a3aSHans de Goede 		*data = 0xff;
303554c0a3aSHans de Goede 		bResult = false;
304554c0a3aSHans de Goede 		DBG_871X("%s: [ERROR] addr = 0x%x bResult =%d time out 1s !!!\n", __func__, addr, bResult);
305554c0a3aSHans de Goede 		DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL));
306554c0a3aSHans de Goede 	}
307554c0a3aSHans de Goede 
308554c0a3aSHans de Goede 	return bResult;
309554c0a3aSHans de Goede }
310554c0a3aSHans de Goede 
311554c0a3aSHans de Goede /*  11/16/2008 MH Write one byte to reald Efuse. */
312554c0a3aSHans de Goede u8
313554c0a3aSHans de Goede efuse_OneByteWrite(
314554c0a3aSHans de Goede struct adapter *padapter,
315554c0a3aSHans de Goede u16 		addr,
316554c0a3aSHans de Goede u8 	data,
317554c0a3aSHans de Goede bool		bPseudoTest)
318554c0a3aSHans de Goede {
319554c0a3aSHans de Goede 	u8 tmpidx = 0;
320554c0a3aSHans de Goede 	u8 bResult = false;
321554c0a3aSHans de Goede 	u32 efuseValue = 0;
322554c0a3aSHans de Goede 
323554c0a3aSHans de Goede 	/* DBG_871X("===> EFUSE_OneByteWrite(), addr = %x data =%x\n", addr, data); */
324554c0a3aSHans de Goede 	/* DBG_871X("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */
325554c0a3aSHans de Goede 
326554c0a3aSHans de Goede 	if (bPseudoTest) {
327554c0a3aSHans de Goede 		bResult = Efuse_Write1ByteToFakeContent(padapter, addr, data);
328554c0a3aSHans de Goede 		return bResult;
329554c0a3aSHans de Goede 	}
330554c0a3aSHans de Goede 
331554c0a3aSHans de Goede 
332554c0a3aSHans de Goede 	/*  -----------------e-fuse reg ctrl --------------------------------- */
333554c0a3aSHans de Goede 	/* address */
334554c0a3aSHans de Goede 
335554c0a3aSHans de Goede 
336554c0a3aSHans de Goede 	efuseValue = rtw_read32(padapter, EFUSE_CTRL);
337554c0a3aSHans de Goede 	efuseValue |= (BIT21|BIT31);
338554c0a3aSHans de Goede 	efuseValue &= ~(0x3FFFF);
339554c0a3aSHans de Goede 	efuseValue |= ((addr<<8 | data) & 0x3FFFF);
340554c0a3aSHans de Goede 
341554c0a3aSHans de Goede 
342554c0a3aSHans de Goede 	/*  <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */
343554c0a3aSHans de Goede 
344554c0a3aSHans de Goede 	/*  <20130121, Kordan> For SMIC EFUSE specificatoin. */
345554c0a3aSHans de Goede 	/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
346554c0a3aSHans de Goede 	/* PHY_SetMacReg(padapter, 0x34, BIT11, 1); */
347554c0a3aSHans de Goede 	rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) | (BIT11));
348554c0a3aSHans de Goede 	rtw_write32(padapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data)));
349554c0a3aSHans de Goede 
350554c0a3aSHans de Goede 	while ((0x80 &  rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100)) {
351554c0a3aSHans de Goede 		mdelay(1);
352554c0a3aSHans de Goede 		tmpidx++;
353554c0a3aSHans de Goede 	}
354554c0a3aSHans de Goede 
355554c0a3aSHans de Goede 	if (tmpidx < 100) {
356554c0a3aSHans de Goede 		bResult = true;
357554c0a3aSHans de Goede 	} else {
358554c0a3aSHans de Goede 		bResult = false;
359554c0a3aSHans de Goede 		DBG_871X("%s: [ERROR] addr = 0x%x , efuseValue = 0x%x , bResult =%d time out 1s !!!\n",
360554c0a3aSHans de Goede 					__func__, addr, efuseValue, bResult);
361554c0a3aSHans de Goede 		DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL));
362554c0a3aSHans de Goede 	}
363554c0a3aSHans de Goede 
364554c0a3aSHans de Goede 	/*  disable Efuse program enable */
365554c0a3aSHans de Goede 	PHY_SetMacReg(padapter, EFUSE_TEST, BIT(11), 0);
366554c0a3aSHans de Goede 
367554c0a3aSHans de Goede 	return bResult;
368554c0a3aSHans de Goede }
369554c0a3aSHans de Goede 
370554c0a3aSHans de Goede int
371554c0a3aSHans de Goede Efuse_PgPacketRead(struct adapter *padapter,
372554c0a3aSHans de Goede 				u8 	offset,
373554c0a3aSHans de Goede 				u8 	*data,
374554c0a3aSHans de Goede 				bool		bPseudoTest)
375554c0a3aSHans de Goede {
3767997c367SPayal Kshirsagar 	return padapter->HalFunc.Efuse_PgPacketRead(padapter, offset, data,
3777997c367SPayal Kshirsagar 						    bPseudoTest);
378554c0a3aSHans de Goede }
379554c0a3aSHans de Goede 
380554c0a3aSHans de Goede int
381554c0a3aSHans de Goede Efuse_PgPacketWrite(struct adapter *padapter,
382554c0a3aSHans de Goede 				u8 	offset,
383554c0a3aSHans de Goede 				u8 	word_en,
384554c0a3aSHans de Goede 				u8 	*data,
385554c0a3aSHans de Goede 				bool		bPseudoTest)
386554c0a3aSHans de Goede {
3877997c367SPayal Kshirsagar 	return padapter->HalFunc.Efuse_PgPacketWrite(padapter, offset, word_en,
3887997c367SPayal Kshirsagar 						     data, bPseudoTest);
389554c0a3aSHans de Goede }
390554c0a3aSHans de Goede 
391554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
392554c0a3aSHans de Goede  * Function:	efuse_WordEnableDataRead
393554c0a3aSHans de Goede  *
394554c0a3aSHans de Goede  * Overview:	Read allowed word in current efuse section data.
395554c0a3aSHans de Goede  *
396554c0a3aSHans de Goede  * Input:       NONE
397554c0a3aSHans de Goede  *
398554c0a3aSHans de Goede  * Output:      NONE
399554c0a3aSHans de Goede  *
400554c0a3aSHans de Goede  * Return:      NONE
401554c0a3aSHans de Goede  *
402554c0a3aSHans de Goede  * Revised History:
403554c0a3aSHans de Goede  * When			Who		Remark
404554c0a3aSHans de Goede  * 11/16/2008	MHC		Create Version 0.
405554c0a3aSHans de Goede  * 11/21/2008	MHC		Fix Write bug when we only enable late word.
406554c0a3aSHans de Goede  *
407554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
408554c0a3aSHans de Goede void
409554c0a3aSHans de Goede efuse_WordEnableDataRead(u8 word_en,
410554c0a3aSHans de Goede 						u8 *sourdata,
411554c0a3aSHans de Goede 						u8 *targetdata)
412554c0a3aSHans de Goede {
413554c0a3aSHans de Goede 	if (!(word_en&BIT(0))) {
414554c0a3aSHans de Goede 		targetdata[0] = sourdata[0];
415554c0a3aSHans de Goede 		targetdata[1] = sourdata[1];
416554c0a3aSHans de Goede 	}
417554c0a3aSHans de Goede 	if (!(word_en&BIT(1))) {
418554c0a3aSHans de Goede 		targetdata[2] = sourdata[2];
419554c0a3aSHans de Goede 		targetdata[3] = sourdata[3];
420554c0a3aSHans de Goede 	}
421554c0a3aSHans de Goede 	if (!(word_en&BIT(2))) {
422554c0a3aSHans de Goede 		targetdata[4] = sourdata[4];
423554c0a3aSHans de Goede 		targetdata[5] = sourdata[5];
424554c0a3aSHans de Goede 	}
425554c0a3aSHans de Goede 	if (!(word_en&BIT(3))) {
426554c0a3aSHans de Goede 		targetdata[6] = sourdata[6];
427554c0a3aSHans de Goede 		targetdata[7] = sourdata[7];
428554c0a3aSHans de Goede 	}
429554c0a3aSHans de Goede }
430554c0a3aSHans de Goede 
431554c0a3aSHans de Goede 
432554c0a3aSHans de Goede u8
433554c0a3aSHans de Goede Efuse_WordEnableDataWrite(struct adapter *padapter,
434554c0a3aSHans de Goede 						u16 	efuse_addr,
435554c0a3aSHans de Goede 						u8 word_en,
436554c0a3aSHans de Goede 						u8 *data,
437554c0a3aSHans de Goede 						bool		bPseudoTest)
438554c0a3aSHans de Goede {
4397997c367SPayal Kshirsagar 	return padapter->HalFunc.Efuse_WordEnableDataWrite(padapter, efuse_addr,
4407997c367SPayal Kshirsagar 							   word_en, data,
4417997c367SPayal Kshirsagar 							   bPseudoTest);
442554c0a3aSHans de Goede }
443554c0a3aSHans de Goede 
444554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
445554c0a3aSHans de Goede  * Function:	Efuse_ReadAllMap
446554c0a3aSHans de Goede  *
447554c0a3aSHans de Goede  * Overview:	Read All Efuse content
448554c0a3aSHans de Goede  *
449554c0a3aSHans de Goede  * Input:       NONE
450554c0a3aSHans de Goede  *
451554c0a3aSHans de Goede  * Output:      NONE
452554c0a3aSHans de Goede  *
453554c0a3aSHans de Goede  * Return:      NONE
454554c0a3aSHans de Goede  *
455554c0a3aSHans de Goede  * Revised History:
456554c0a3aSHans de Goede  * When			Who		Remark
457554c0a3aSHans de Goede  * 11/11/2008	MHC		Create Version 0.
458554c0a3aSHans de Goede  *
459554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
460554c0a3aSHans de Goede void
461554c0a3aSHans de Goede Efuse_ReadAllMap(
462554c0a3aSHans de Goede 	struct adapter *padapter,
463554c0a3aSHans de Goede 	u8 efuseType,
464554c0a3aSHans de Goede 	u8 *Efuse,
465554c0a3aSHans de Goede 	bool		bPseudoTest);
466554c0a3aSHans de Goede void
467554c0a3aSHans de Goede Efuse_ReadAllMap(
468554c0a3aSHans de Goede 	struct adapter *padapter,
469554c0a3aSHans de Goede 	u8 efuseType,
470554c0a3aSHans de Goede 	u8 *Efuse,
471554c0a3aSHans de Goede 	bool		bPseudoTest)
472554c0a3aSHans de Goede {
473554c0a3aSHans de Goede 	u16 mapLen = 0;
474554c0a3aSHans de Goede 
475554c0a3aSHans de Goede 	Efuse_PowerSwitch(padapter, false, true);
476554c0a3aSHans de Goede 
477554c0a3aSHans de Goede 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
478554c0a3aSHans de Goede 
479554c0a3aSHans de Goede 	efuse_ReadEFuse(padapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
480554c0a3aSHans de Goede 
481554c0a3aSHans de Goede 	Efuse_PowerSwitch(padapter, false, false);
482554c0a3aSHans de Goede }
483554c0a3aSHans de Goede 
484554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
485554c0a3aSHans de Goede  * Function:	efuse_ShadowRead1Byte
486554c0a3aSHans de Goede  *		efuse_ShadowRead2Byte
487554c0a3aSHans de Goede  *		efuse_ShadowRead4Byte
488554c0a3aSHans de Goede  *
489554c0a3aSHans de Goede  * Overview:	Read from efuse init map by one/two/four bytes !!!!!
490554c0a3aSHans de Goede  *
491554c0a3aSHans de Goede  * Input:       NONE
492554c0a3aSHans de Goede  *
493554c0a3aSHans de Goede  * Output:      NONE
494554c0a3aSHans de Goede  *
495554c0a3aSHans de Goede  * Return:      NONE
496554c0a3aSHans de Goede  *
497554c0a3aSHans de Goede  * Revised History:
498554c0a3aSHans de Goede  * When			Who		Remark
499554c0a3aSHans de Goede  * 11/12/2008	MHC		Create Version 0.
500554c0a3aSHans de Goede  *
501554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
502554c0a3aSHans de Goede static void
503554c0a3aSHans de Goede efuse_ShadowRead1Byte(
504554c0a3aSHans de Goede struct adapter *padapter,
505554c0a3aSHans de Goede u16 	Offset,
506554c0a3aSHans de Goede 	u8 *Value)
507554c0a3aSHans de Goede {
508554c0a3aSHans de Goede 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
509554c0a3aSHans de Goede 
510554c0a3aSHans de Goede 	*Value = pEEPROM->efuse_eeprom_data[Offset];
511554c0a3aSHans de Goede 
512554c0a3aSHans de Goede }	/*  EFUSE_ShadowRead1Byte */
513554c0a3aSHans de Goede 
514554c0a3aSHans de Goede /* Read Two Bytes */
515554c0a3aSHans de Goede static void
516554c0a3aSHans de Goede efuse_ShadowRead2Byte(
517554c0a3aSHans de Goede struct adapter *padapter,
518554c0a3aSHans de Goede u16 	Offset,
519554c0a3aSHans de Goede 	u16 	*Value)
520554c0a3aSHans de Goede {
521554c0a3aSHans de Goede 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
522554c0a3aSHans de Goede 
523554c0a3aSHans de Goede 	*Value = pEEPROM->efuse_eeprom_data[Offset];
524554c0a3aSHans de Goede 	*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
525554c0a3aSHans de Goede 
526554c0a3aSHans de Goede }	/*  EFUSE_ShadowRead2Byte */
527554c0a3aSHans de Goede 
528554c0a3aSHans de Goede /* Read Four Bytes */
529554c0a3aSHans de Goede static void
530554c0a3aSHans de Goede efuse_ShadowRead4Byte(
531554c0a3aSHans de Goede struct adapter *padapter,
532554c0a3aSHans de Goede u16 	Offset,
533554c0a3aSHans de Goede 	u32 	*Value)
534554c0a3aSHans de Goede {
535554c0a3aSHans de Goede 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
536554c0a3aSHans de Goede 
537554c0a3aSHans de Goede 	*Value = pEEPROM->efuse_eeprom_data[Offset];
538554c0a3aSHans de Goede 	*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
539554c0a3aSHans de Goede 	*Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
540554c0a3aSHans de Goede 	*Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
541554c0a3aSHans de Goede 
542554c0a3aSHans de Goede }	/*  efuse_ShadowRead4Byte */
543554c0a3aSHans de Goede 
544554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
545554c0a3aSHans de Goede  * Function:	EFUSE_ShadowMapUpdate
546554c0a3aSHans de Goede  *
547554c0a3aSHans de Goede  * Overview:	Transfer current EFUSE content to shadow init and modify map.
548554c0a3aSHans de Goede  *
549554c0a3aSHans de Goede  * Input:       NONE
550554c0a3aSHans de Goede  *
551554c0a3aSHans de Goede  * Output:      NONE
552554c0a3aSHans de Goede  *
553554c0a3aSHans de Goede  * Return:      NONE
554554c0a3aSHans de Goede  *
555554c0a3aSHans de Goede  * Revised History:
556554c0a3aSHans de Goede  * When			Who		Remark
557554c0a3aSHans de Goede  * 11/13/2008	MHC		Create Version 0.
558554c0a3aSHans de Goede  *
559554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
560554c0a3aSHans de Goede void EFUSE_ShadowMapUpdate(
561554c0a3aSHans de Goede 	struct adapter *padapter,
562554c0a3aSHans de Goede 	u8 efuseType,
563554c0a3aSHans de Goede 	bool	bPseudoTest)
564554c0a3aSHans de Goede {
565554c0a3aSHans de Goede 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
566554c0a3aSHans de Goede 	u16 mapLen = 0;
567554c0a3aSHans de Goede 
568554c0a3aSHans de Goede 	EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest);
569554c0a3aSHans de Goede 
570d2ab9916SMichael Straube 	if (pEEPROM->bautoload_fail_flag)
571554c0a3aSHans de Goede 		memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
572d2ab9916SMichael Straube 	else
573554c0a3aSHans de Goede 		Efuse_ReadAllMap(padapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest);
574554c0a3aSHans de Goede 
575554c0a3aSHans de Goede 	/* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
576554c0a3aSHans de Goede 	/* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
577554c0a3aSHans de Goede } /*  EFUSE_ShadowMapUpdate */
578554c0a3aSHans de Goede 
579554c0a3aSHans de Goede 
580554c0a3aSHans de Goede /*-----------------------------------------------------------------------------
581554c0a3aSHans de Goede  * Function:	EFUSE_ShadowRead
582554c0a3aSHans de Goede  *
583554c0a3aSHans de Goede  * Overview:	Read from efuse init map !!!!!
584554c0a3aSHans de Goede  *
585554c0a3aSHans de Goede  * Input:       NONE
586554c0a3aSHans de Goede  *
587554c0a3aSHans de Goede  * Output:      NONE
588554c0a3aSHans de Goede  *
589554c0a3aSHans de Goede  * Return:      NONE
590554c0a3aSHans de Goede  *
591554c0a3aSHans de Goede  * Revised History:
592554c0a3aSHans de Goede  * When			Who		Remark
593554c0a3aSHans de Goede  * 11/12/2008	MHC		Create Version 0.
594554c0a3aSHans de Goede  *
595554c0a3aSHans de Goede  *---------------------------------------------------------------------------*/
596554c0a3aSHans de Goede void
597554c0a3aSHans de Goede EFUSE_ShadowRead(
598554c0a3aSHans de Goede 	struct adapter *padapter,
599554c0a3aSHans de Goede 	u8 Type,
600554c0a3aSHans de Goede 	u16 	Offset,
601554c0a3aSHans de Goede 	u32 	*Value)
602554c0a3aSHans de Goede {
603554c0a3aSHans de Goede 	if (Type == 1)
604554c0a3aSHans de Goede 		efuse_ShadowRead1Byte(padapter, Offset, (u8 *)Value);
605554c0a3aSHans de Goede 	else if (Type == 2)
606554c0a3aSHans de Goede 		efuse_ShadowRead2Byte(padapter, Offset, (u16 *)Value);
607554c0a3aSHans de Goede 	else if (Type == 4)
608554c0a3aSHans de Goede 		efuse_ShadowRead4Byte(padapter, Offset, (u32 *)Value);
609554c0a3aSHans de Goede 
610554c0a3aSHans de Goede }	/* EFUSE_ShadowRead*/
611