1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 * Based on the r8180 driver, which is:
5 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 * The full GNU General Public License is included in this distribution in the
20 * file called LICENSE.
22 * Contact Information:
23 * wlanfae <wlanfae@realtek.com>
24 ******************************************************************************/
26 #include "r8192S_hw.h"
27 #include "r8192S_phy.h"
28 #include "r8192S_phyreg.h"
29 #include "r8192S_Efuse.h"
31 #include <linux/types.h>
32 #include <linux/ctype.h>
34 #define _POWERON_DELAY_
35 #define _PRE_EXECUTE_READ_CMD_
37 #define EFUSE_REPEAT_THRESHOLD_ 3
38 #define EFUSE_ERROE_HANDLE 1
40 typedef struct _EFUSE_MAP_A
{
43 u8 byte_start
; //0 or 1
46 }EFUSE_MAP
, *PEFUSE_MAP
;
48 typedef struct PG_PKT_STRUCT_A
{
52 }PGPKT_STRUCT
,*PPGPKT_STRUCT
;
54 typedef enum _EFUSE_DATA_ITEM
{
87 const u8 MAX_PGPKT_SIZE
= 9; //header+ 2* 4 words (BYTES)
88 const u8 PGPKT_DATA_SIZE
= 8; //BYTES sizeof(u8)*8
89 const u32 EFUSE_MAX_SIZE
= 512;
91 const u8 EFUSE_OOB_PROTECT_BYTES
= 14;
93 const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE
[]={
94 //offset word_s byte_start byte_cnts
95 /*ID*/ {0 ,0 ,0 ,2 }, // 00~01h
96 /*LDO Setting*/ {0 ,1 ,0 ,2 }, // 02~03h
97 /*CLK Setting*/ {0 ,2 ,0 ,2 }, // 04~05h
98 /*SDIO Setting*/ {1 ,0 ,0 ,1 }, // 08h
99 /*CCCR*/ {1 ,0 ,1 ,1 }, // 09h
100 /*SDIO MODE*/ {1 ,1 ,0 ,1 }, // 0Ah
101 /*OCR*/ {1 ,1 ,1 ,3 }, // 0B~0Dh
102 /*CCIS*/ {1 ,3 ,0 ,17 }, // 0E~1Eh 2...1
103 /*F1CIS*/ {3 ,3 ,1 ,48 }, // 1F~4Eh 6...0
104 /*MAC Addr*/ {10 ,0 ,0 ,6 }, // 50~55h
105 /*EEPROM ver*/ {10 ,3 ,0 ,1 }, // 56h
106 /*Channel plan*/ {10 ,3 ,1 ,1 }, // 57h
107 /*TxPwIndex */ {11 ,0 ,0 ,28 } // 58~73h 3...4
111 // From WMAC Efuse one byte R/W
114 EFUSE_Initialize(struct net_device
* dev
);
116 EFUSE_Read1Byte(struct net_device
* dev
, u16 Address
);
118 EFUSE_Write1Byte(struct net_device
* dev
, u16 Address
,u8 Value
);
121 // Efuse Shadow Area operation
124 efuse_ShadowRead1Byte(struct net_device
* dev
,u16 Offset
,u8
*Value
);
126 efuse_ShadowRead2Byte(struct net_device
* dev
, u16 Offset
,u16
*Value
);
128 efuse_ShadowRead4Byte(struct net_device
* dev
, u16 Offset
,u32
*Value
);
130 efuse_ShadowWrite1Byte(struct net_device
* dev
, u16 Offset
, u8 Value
);
132 efuse_ShadowWrite2Byte(struct net_device
* dev
, u16 Offset
,u16 Value
);
134 efuse_ShadowWrite4Byte(struct net_device
* dev
, u16 Offset
,u32 Value
);
137 // Real Efuse operation
140 efuse_OneByteRead(struct net_device
* dev
,u16 addr
,u8
*data
);
142 efuse_OneByteWrite(struct net_device
* dev
,u16 addr
, u8 data
);
145 // HW setting map file operation
148 efuse_ReadAllMap(struct net_device
* dev
,u8
*Efuse
);
151 efuse_WriteAllMap(struct net_device
* dev
,u8
*eeprom
,u32 eeprom_size
);
153 efuse_ParsingMap(char* szStr
,u32
* pu4bVal
,u32
* pu4bMove
);
156 // Reald Efuse R/W or other operation API.
159 efuse_PgPacketRead( struct net_device
* dev
,u8 offset
,u8
*data
);
161 efuse_PgPacketWrite(struct net_device
* dev
,u8 offset
,u8 word_en
,u8
*data
);
163 efuse_WordEnableDataRead( u8 word_en
,u8
*sourdata
,u8
*targetdata
);
165 efuse_WordEnableDataWrite( struct net_device
* dev
, u16 efuse_addr
, u8 word_en
, u8
*data
);
167 efuse_PowerSwitch(struct net_device
* dev
,u8 PwrState
);
169 efuse_GetCurrentSize(struct net_device
* dev
);
171 efuse_CalculateWordCnts(u8 word_en
);
173 // API for power on power off!!!
176 static void efuse_reg_ctrl(struct net_device
* dev
, u8 bPowerOn
);
181 /*-----------------------------------------------------------------------------
182 * Function: EFUSE_Initialize
184 * Overview: Copy from WMAC fot EFUSE testing setting init.
194 * 09/23/2008 MHC Copy from WMAC.
196 *---------------------------------------------------------------------------*/
198 EFUSE_Initialize(struct net_device
* dev
)
200 u8 Bytetemp
= {0x00};
203 //Enable Digital Core Vdd : 0x2[13]=1
204 Bytetemp
= read_nic_byte(dev
, SYS_FUNC_EN
+1);
205 temp
= Bytetemp
| 0x20;
206 write_nic_byte(dev
, SYS_FUNC_EN
+1, temp
);
208 //EE loader to retention path1: attach 0x0[8]=0
209 Bytetemp
= read_nic_byte(dev
, SYS_ISO_CTRL
+1);
210 temp
= Bytetemp
& 0xFE;
211 write_nic_byte(dev
, SYS_ISO_CTRL
+1, temp
);
214 //Enable E-fuse use 2.5V LDO : 0x37[7]=1
215 Bytetemp
= read_nic_byte(dev
, EFUSE_TEST
+3);
216 temp
= Bytetemp
| 0x80;
217 write_nic_byte(dev
, EFUSE_TEST
+3, temp
);
219 //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
220 write_nic_byte(dev
, 0x2F8, 0x3);
222 //Set E-fuse program time & read time : 0x30[30:24]=1110010b
223 write_nic_byte(dev
, EFUSE_CTRL
+3, 0x72);
227 /*-----------------------------------------------------------------------------
228 * Function: EFUSE_Read1Byte
230 * Overview: Copy from WMAC fot EFUSE read 1 byte.
240 * 09/23/2008 MHC Copy from WMAC.
242 *---------------------------------------------------------------------------*/
244 EFUSE_Read1Byte(struct net_device
* dev
, u16 Address
)
247 u8 Bytetemp
= {0x00};
251 if (Address
< EFUSE_MAC_LEN
) //E-fuse 512Byte
253 //Write E-fuse Register address bit0~7
254 temp
= Address
& 0xFF;
255 write_nic_byte(dev
, EFUSE_CTRL
+1, temp
);
256 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+2);
257 //Write E-fuse Register address bit8~9
258 temp
= ((Address
>> 8) & 0x03) | (Bytetemp
& 0xFC);
259 write_nic_byte(dev
, EFUSE_CTRL
+2, temp
);
262 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
263 temp
= Bytetemp
& 0x7F;
264 write_nic_byte(dev
, EFUSE_CTRL
+3, temp
);
266 //Wait Write-ready (0x30[31]=1)
267 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
268 while(!(Bytetemp
& 0x80))
270 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
278 data
=read_nic_byte(dev
, EFUSE_CTRL
);
287 /*-----------------------------------------------------------------------------
288 * Function: EFUSE_Write1Byte
290 * Overview: Copy from WMAC fot EFUSE write 1 byte.
300 * 09/23/2008 MHC Copy from WMAC.
302 *---------------------------------------------------------------------------*/
304 EFUSE_Write1Byte(struct net_device
* dev
, u16 Address
,u8 Value
)
306 u8 Bytetemp
= {0x00};
310 if( Address
< EFUSE_MAC_LEN
) //E-fuse 512Byte
312 write_nic_byte(dev
, EFUSE_CTRL
, Value
);
314 //Write E-fuse Register address bit0~7
315 temp
= Address
& 0xFF;
316 write_nic_byte(dev
, EFUSE_CTRL
+1, temp
);
317 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+2);
319 //Write E-fuse Register address bit8~9
320 temp
= ((Address
>> 8) & 0x03) | (Bytetemp
& 0xFC);
321 write_nic_byte(dev
, EFUSE_CTRL
+2, temp
);
324 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
325 temp
= Bytetemp
| 0x80;
326 write_nic_byte(dev
, EFUSE_CTRL
+3, temp
);
328 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
329 while(Bytetemp
& 0x80)
331 Bytetemp
= read_nic_byte(dev
, EFUSE_CTRL
+3);
343 #ifdef EFUSE_FOR_92SU
346 // 1. Process CR93C46 Data polling cycle.
347 // 2. Refered from SD1 Richard.
350 // 1. Boot from E-Fuse and successfully auto-load.
351 // 2. PASSIVE_LEVEL (USB interface)
353 // Created by Roger, 2008.10.21.
355 void do_93c46(struct net_device
* dev
, u8 addorvalue
)
357 u8 cs
[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
358 u8 cssk
[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
359 u8 csdi
[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
360 u8 csskdi
[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
363 for(count
=0 ; count
<8 ; count
++)
365 if((addorvalue
&0x80)!=0)
367 write_nic_byte(dev
, EPROM_CMD
, csdi
[0]);
368 write_nic_byte(dev
, EPROM_CMD
, csskdi
[0]);
372 write_nic_byte(dev
, EPROM_CMD
, cs
[0]);
373 write_nic_byte(dev
, EPROM_CMD
, cssk
[0]);
375 addorvalue
= addorvalue
<< 1;
382 // Process CR93C46 Data read polling cycle.
383 // Refered from SD1 Richard.
386 // 1. Boot from E-Fuse and successfully auto-load.
387 // 2. PASSIVE_LEVEL (USB interface)
389 // Created by Roger, 2008.10.21.
391 u16
Read93C46(struct net_device
* dev
, u16 Reg
)
394 u8 clear
[1] = {0x0}; // cs=0 , sk=0 , di=0 , do=0
395 u8 cs
[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
396 u8 cssk
[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
397 u8 csdi
[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
398 u8 csskdi
[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
399 u8 EepromSEL
[1]={0x00};
402 u16 storedataF
[1] = {0x0}; //93c46 data packet for 16bits
403 u8 t
,data
[1],storedata
[1];
408 *EepromSEL
= read_nic_byte(dev
, EPROM_CMD
);
410 if((*EepromSEL
& 0x10) == 0x10) // select 93c46
412 address
= address
| 0x80;
414 write_nic_byte(dev
, EPROM_CMD
, csdi
[0]);
415 write_nic_byte(dev
, EPROM_CMD
, csskdi
[0]);
416 do_93c46(dev
, address
);
420 for(t
=0 ; t
<16 ; t
++) //if read 93c46 , t=16
422 write_nic_byte(dev
, EPROM_CMD
, cs
[0]);
423 write_nic_byte(dev
, EPROM_CMD
, cssk
[0]);
424 *data
= read_nic_byte(dev
, EPROM_CMD
);
426 if(*data
& 0x8d) //original code
428 *data
= *data
& 0x01;
433 *data
= *data
& 0x01 ;
436 *storedataF
= (*storedataF
<< 1 ) + *storedata
;
438 write_nic_byte(dev
, EPROM_CMD
, cs
[0]);
439 write_nic_byte(dev
, EPROM_CMD
, clear
[0]);
447 // Execute E-Fuse read byte operation.
448 // Refered from SD1 Richard.
451 // 1. Boot from E-Fuse and successfully auto-load.
452 // 2. PASSIVE_LEVEL (USB interface)
454 // Created by Roger, 2008.10.21.
457 ReadEFuseByte(struct net_device
* dev
,u16 _offset
, u8
*pbuf
)
464 write_nic_byte(dev
, EFUSE_CTRL
+1, (_offset
& 0xff));
465 readbyte
= read_nic_byte(dev
, EFUSE_CTRL
+2);
466 write_nic_byte(dev
, EFUSE_CTRL
+2, ((_offset
>> 8) & 0x03) | (readbyte
& 0xfc));
469 readbyte
= read_nic_byte(dev
, EFUSE_CTRL
+3);
470 write_nic_byte(dev
, EFUSE_CTRL
+3, (readbyte
& 0x7f));
472 //Check bit 32 read-ready
474 value32
= read_nic_dword(dev
, EFUSE_CTRL
);
475 while(!(((value32
>> 24) & 0xff) & 0x80) && (retry
<10000))
477 value32
= read_nic_dword(dev
, EFUSE_CTRL
);
480 *pbuf
= (u8
)(value32
& 0xff);
484 #define EFUSE_READ_SWITCH 1
487 // 1. Execute E-Fuse read byte operation according as map offset and
488 // save to E-Fuse table.
489 // 2. Refered from SD1 Richard.
492 // 1. Boot from E-Fuse and successfully auto-load.
493 // 2. PASSIVE_LEVEL (USB interface)
495 // Created by Roger, 2008.10.21.
498 ReadEFuse(struct net_device
* dev
, u16 _offset
, u16 _size_byte
, u8
*pbuf
)
501 struct r8192_priv
*priv
= ieee80211_priv(dev
);
502 u8 efuseTbl
[EFUSE_MAP_LEN
];
507 u16 eFuseWord
[EFUSE_MAX_SECTION
][EFUSE_MAX_WORD_UNIT
];
508 u16 efuse_utilized
= 0;
511 if((_offset
+ _size_byte
)>EFUSE_MAP_LEN
)
513 printk("ReadEFuse(): Invalid offset with read bytes!!\n");
517 for(i
= 0; i
< EFUSE_MAX_SECTION
; i
++)
518 for(j
= 0; j
< EFUSE_MAX_WORD_UNIT
; j
++)
519 eFuseWord
[i
][j
]=0xFFFF;
521 #if (EFUSE_READ_SWITCH == 1)
522 ReadEFuseByte(dev
, eFuse_Addr
, rtemp8
);
524 rtemp8
[0] = EFUSE_Read1Byte(dev
, eFuse_Addr
);
528 RT_TRACE(COMP_EPROM
, "Addr=%d\n", eFuse_Addr
);
532 while((*rtemp8
!= 0xFF) && (eFuse_Addr
< EFUSE_REAL_CONTENT_LEN
))
534 offset
= ((*rtemp8
>> 4) & 0x0f);
535 if(offset
< EFUSE_MAX_SECTION
)
537 wren
= (*rtemp8
& 0x0f);
538 RT_TRACE(COMP_EPROM
, "Offset-%d Worden=%x\n", offset
, wren
);
540 for(i
= 0; i
< EFUSE_MAX_WORD_UNIT
; i
++)
544 RT_TRACE(COMP_EPROM
, "Addr=%d\n", eFuse_Addr
);
545 #if (EFUSE_READ_SWITCH == 1)
546 ReadEFuseByte(dev
, eFuse_Addr
, rtemp8
); eFuse_Addr
++;
548 rtemp8
[0] = EFUSE_Read1Byte(dev
, eFuse_Addr
); eFuse_Addr
++;
551 eFuseWord
[offset
][i
] = (*rtemp8
& 0xff);
552 if(eFuse_Addr
>= EFUSE_REAL_CONTENT_LEN
)
555 RT_TRACE(COMP_EPROM
, "Addr=%d\n", eFuse_Addr
);
556 #if (EFUSE_READ_SWITCH == 1)
557 ReadEFuseByte(dev
, eFuse_Addr
, rtemp8
); eFuse_Addr
++;
559 rtemp8
[0] = EFUSE_Read1Byte(dev
, eFuse_Addr
); eFuse_Addr
++;
562 eFuseWord
[offset
][i
] |= (((u16
)*rtemp8
<< 8) & 0xff00);
563 if(eFuse_Addr
>= EFUSE_REAL_CONTENT_LEN
)
570 RT_TRACE(COMP_EPROM
, "Addr=%d\n", eFuse_Addr
);
571 #if (EFUSE_READ_SWITCH == 1)
572 ReadEFuseByte(dev
, eFuse_Addr
, rtemp8
);
574 rtemp8
[0] = EFUSE_Read1Byte(dev
, eFuse_Addr
); eFuse_Addr
++;
576 if(*rtemp8
!= 0xFF && (eFuse_Addr
< 512))
583 for(i
=0; i
<EFUSE_MAX_SECTION
; i
++)
585 for(j
=0; j
<EFUSE_MAX_WORD_UNIT
; j
++)
587 efuseTbl
[(i
*8)+(j
*2)]=(eFuseWord
[i
][j
] & 0xff);
588 efuseTbl
[(i
*8)+((j
*2)+1)]=((eFuseWord
[i
][j
] >> 8) & 0xff);
591 for(i
=0; i
<_size_byte
; i
++)
592 pbuf
[i
] = efuseTbl
[_offset
+i
];
594 efuse_usage
= (u8
)((efuse_utilized
*100)/EFUSE_REAL_CONTENT_LEN
);
595 priv
->EfuseUsedBytes
= efuse_utilized
;
596 priv
->EfuseUsedPercentage
= (u8
)efuse_usage
;
601 EFUSE_ShadowUpdateChk(struct net_device
* dev
)
603 struct r8192_priv
*priv
= ieee80211_priv(dev
);
604 u8 SectionIdx
, i
, Base
;
605 u16 WordsNeed
= 0, HdrNum
= 0, TotalBytes
= 0, EfuseUsed
= 0;
606 bool bWordChanged
, bResult
= true;
608 for (SectionIdx
= 0; SectionIdx
< 16; SectionIdx
++)
610 Base
= SectionIdx
* 8;
611 bWordChanged
= false;
613 for (i
= 0; i
< 8; i
=i
+2)
615 if((priv
->EfuseMap
[EFUSE_INIT_MAP
][Base
+i
] !=
616 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Base
+i
]) ||
617 (priv
->EfuseMap
[EFUSE_INIT_MAP
][Base
+i
+1] !=
618 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Base
+i
+1]))
625 if( bWordChanged
==true )
629 TotalBytes
= HdrNum
+ WordsNeed
*2;
630 EfuseUsed
= priv
->EfuseUsedBytes
;
632 if( (TotalBytes
+ EfuseUsed
) >= (EFUSE_MAX_SIZE
-EFUSE_OOB_PROTECT_BYTES
))
635 RT_TRACE(COMP_EPROM
, "EFUSE_ShadowUpdateChk(): TotalBytes(%x), HdrNum(%x), WordsNeed(%x), EfuseUsed(%d)\n",
636 TotalBytes
, HdrNum
, WordsNeed
, EfuseUsed
);
641 /*-----------------------------------------------------------------------------
642 * Function: EFUSE_ShadowRead
644 * Overview: Read from efuse init map !!!!!
654 * 11/12/2008 MHC Create Version 0.
656 *---------------------------------------------------------------------------*/
658 EFUSE_ShadowRead( struct net_device
* dev
, u8 Type
, u16 Offset
, u32
*Value
)
661 efuse_ShadowRead1Byte(dev
, Offset
, (u8
*)Value
);
663 efuse_ShadowRead2Byte(dev
, Offset
, (u16
*)Value
);
665 efuse_ShadowRead4Byte(dev
, Offset
, (u32
*)Value
);
669 /*-----------------------------------------------------------------------------
670 * Function: EFUSE_ShadowWrite
672 * Overview: Write efuse modify map for later update operation to use!!!!!
682 * 11/12/2008 MHC Create Version 0.
684 *---------------------------------------------------------------------------*/
686 EFUSE_ShadowWrite( struct net_device
* dev
, u8 Type
, u16 Offset
,u32 Value
)
688 if (Offset
>= 0x18 && Offset
<= 0x1F)
692 efuse_ShadowWrite1Byte(dev
, Offset
, (u8
)Value
);
694 efuse_ShadowWrite2Byte(dev
, Offset
, (u16
)Value
);
696 efuse_ShadowWrite4Byte(dev
, Offset
, (u32
)Value
);
700 /*-----------------------------------------------------------------------------
701 * Function: EFUSE_ShadowUpdate
703 * Overview: Compare init and modify map to update Efuse!!!!!
713 * 11/12/2008 MHC Create Version 0.
715 *---------------------------------------------------------------------------*/
717 EFUSE_ShadowUpdate(struct net_device
* dev
)
719 struct r8192_priv
*priv
= ieee80211_priv(dev
);
720 u16 i
, offset
, base
= 0;
722 bool first_pg
= false;
724 RT_TRACE(COMP_EPROM
, "--->EFUSE_ShadowUpdate()\n");
726 if(!EFUSE_ShadowUpdateChk(dev
))
728 efuse_ReadAllMap(dev
, &priv
->EfuseMap
[EFUSE_INIT_MAP
][0]);
729 memcpy((void *)&priv
->EfuseMap
[EFUSE_MODIFY_MAP
][0],
730 (void *)&priv
->EfuseMap
[EFUSE_INIT_MAP
][0], HWSET_MAX_SIZE_92S
);
732 RT_TRACE(COMP_EPROM
, "<---EFUSE_ShadowUpdate(): Efuse out of capacity!!\n");
735 efuse_PowerSwitch(dev
, TRUE
);
738 // Efuse support 16 write are with PG header packet!!!!
740 for (offset
= 0; offset
< 16; offset
++)
742 // Offset 0x18-1F are reserved now!!!
747 // Decide Word Enable Bit for the Efuse section
748 // One section contain 4 words = 8 bytes!!!!!
750 for (i
= 0; i
< 8; i
++)
752 if (first_pg
== TRUE
)
754 word_en
&= ~(1<<(i
/2));
755 RT_TRACE(COMP_EPROM
,"Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
756 offset
, base
+i
, priv
->EfuseMap
[EFUSE_INIT_MAP
][base
+i
],
757 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][base
+i
],word_en
);
758 priv
->EfuseMap
[EFUSE_INIT_MAP
][base
+i
] =
759 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][base
+i
];
762 if ( priv
->EfuseMap
[EFUSE_INIT_MAP
][base
+i
] !=
763 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][base
+i
])
765 word_en
&= ~(EFUSE_BIT(i
/2));
766 RT_TRACE(COMP_EPROM
, "Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
767 offset
, base
+i
, priv
->EfuseMap
[0][base
+i
],
768 priv
->EfuseMap
[1][base
+i
],word_en
);
770 // Update init table!!!
771 priv
->EfuseMap
[EFUSE_INIT_MAP
][base
+i
] =
772 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][base
+i
];
778 // Call Efuse real write section !!!!
784 memcpy((void *)tmpdata
, (void *)&(priv
->EfuseMap
[EFUSE_MODIFY_MAP
][base
]), 8);
785 RT_TRACE(COMP_INIT
, "U-EFUSE\n");
787 if(!efuse_PgPacketWrite(dev
,(u8
)offset
,word_en
,tmpdata
))
789 RT_TRACE(COMP_EPROM
,"EFUSE_ShadowUpdate(): PG section(%x) fail!!\n", offset
);
795 // For warm reboot, we must resume Efuse clock to 500K.
797 efuse_PowerSwitch(dev
, FALSE
);
799 efuse_ReadAllMap(dev
, &priv
->EfuseMap
[EFUSE_INIT_MAP
][0]);
800 memcpy((void *)&priv
->EfuseMap
[EFUSE_MODIFY_MAP
][0],
801 (void *)&priv
->EfuseMap
[EFUSE_INIT_MAP
][0], HWSET_MAX_SIZE_92S
);
806 /*-----------------------------------------------------------------------------
807 * Function: EFUSE_ShadowMapUpdate
809 * Overview: Transfer current EFUSE content to shadow init and modify map.
819 * 11/13/2008 MHC Create Version 0.
821 *---------------------------------------------------------------------------*/
822 extern void EFUSE_ShadowMapUpdate(struct net_device
* dev
)
824 struct r8192_priv
*priv
= ieee80211_priv(dev
);
826 if (priv
->AutoloadFailFlag
== true){
827 memset(&(priv
->EfuseMap
[EFUSE_INIT_MAP
][0]), 0xff, 128);
829 efuse_ReadAllMap(dev
, &priv
->EfuseMap
[EFUSE_INIT_MAP
][0]);
831 memcpy((void *)&priv
->EfuseMap
[EFUSE_MODIFY_MAP
][0],
832 (void *)&priv
->EfuseMap
[EFUSE_INIT_MAP
][0], HWSET_MAX_SIZE_92S
);
837 EFUSE_ForceWriteVendorId( struct net_device
* dev
)
839 u8 tmpdata
[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
841 efuse_PowerSwitch(dev
, TRUE
);
843 efuse_PgPacketWrite(dev
, 1, 0xD, tmpdata
);
845 efuse_PowerSwitch(dev
, FALSE
);
849 /*-----------------------------------------------------------------------------
850 * Function: efuse_ShadowRead1Byte
851 * efuse_ShadowRead2Byte
852 * efuse_ShadowRead4Byte
854 * Overview: Read from efuse init map by one/two/four bytes !!!!!
864 * 11/12/2008 MHC Create Version 0.
866 *---------------------------------------------------------------------------*/
868 efuse_ShadowRead1Byte(struct net_device
* dev
, u16 Offset
, u8
*Value
)
870 struct r8192_priv
*priv
= ieee80211_priv(dev
);
872 *Value
= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
];
876 //---------------Read Two Bytes
878 efuse_ShadowRead2Byte(struct net_device
* dev
, u16 Offset
, u16
*Value
)
880 struct r8192_priv
*priv
= ieee80211_priv(dev
);
882 *Value
= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
];
883 *Value
|= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+1]<<8;
887 //---------------Read Four Bytes
889 efuse_ShadowRead4Byte(struct net_device
* dev
, u16 Offset
, u32
*Value
)
891 struct r8192_priv
*priv
= ieee80211_priv(dev
);
893 *Value
= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
];
894 *Value
|= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+1]<<8;
895 *Value
|= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+2]<<16;
896 *Value
|= priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+3]<<24;
902 /*-----------------------------------------------------------------------------
903 * Function: efuse_ShadowWrite1Byte
904 * efuse_ShadowWrite2Byte
905 * efuse_ShadowWrite4Byte
907 * Overview: Write efuse modify map by one/two/four byte.
917 * 11/12/2008 MHC Create Version 0.
919 *---------------------------------------------------------------------------*/
921 efuse_ShadowWrite1Byte(struct net_device
* dev
, u16 Offset
, u8 Value
)
923 struct r8192_priv
*priv
= ieee80211_priv(dev
);
925 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
] = Value
;
929 //---------------Write Two Bytes
931 efuse_ShadowWrite2Byte(struct net_device
* dev
, u16 Offset
, u16 Value
)
933 struct r8192_priv
*priv
= ieee80211_priv(dev
);
935 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
] = Value
&0x00FF;
936 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+1] = Value
>>8;
940 //---------------Write Four Bytes
942 efuse_ShadowWrite4Byte(struct net_device
* dev
, u16 Offset
, u32 Value
)
944 struct r8192_priv
*priv
= ieee80211_priv(dev
);
946 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
] = (u8
)(Value
&0x000000FF);
947 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+1] = (u8
)((Value
>>8)&0x0000FF);
948 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+2] = (u8
)((Value
>>16)&0x00FF);
949 priv
->EfuseMap
[EFUSE_MODIFY_MAP
][Offset
+3] = (u8
)((Value
>>24)&0xFF);
954 efuse_OneByteRead(struct net_device
* dev
, u16 addr
,u8
*data
)
959 // -----------------e-fuse reg ctrl ---------------------------------
961 write_nic_byte(dev
, EFUSE_CTRL
+1, (u8
)(addr
&0xff));
962 write_nic_byte(dev
, EFUSE_CTRL
+2, ((u8
)((addr
>>8) &0x03) ) |
963 (read_nic_byte(dev
, EFUSE_CTRL
+2)&0xFC ));
965 write_nic_byte(dev
, EFUSE_CTRL
+3, 0x72);//read cmd
967 while(!(0x80 &read_nic_byte(dev
, EFUSE_CTRL
+3))&&(tmpidx
<100))
973 *data
=read_nic_byte(dev
, EFUSE_CTRL
);
984 /* 11/16/2008 MH Write one byte to reald Efuse. */
986 efuse_OneByteWrite(struct net_device
* dev
, u16 addr
, u8 data
)
991 // -----------------e-fuse reg ctrl ---------------------------------
993 write_nic_byte(dev
, EFUSE_CTRL
+1, (u8
)(addr
&0xff));
994 write_nic_byte(dev
, EFUSE_CTRL
+2,
995 read_nic_byte(dev
, EFUSE_CTRL
+2)|(u8
)((addr
>>8)&0x03) );
997 write_nic_byte(dev
, EFUSE_CTRL
, data
);//data
998 write_nic_byte(dev
, EFUSE_CTRL
+3, 0xF2);//write cmd
1000 while((0x80 & read_nic_byte(dev
, EFUSE_CTRL
+3)) && (tmpidx
<100) ){
1016 /*-----------------------------------------------------------------------------
1017 * Function: efuse_ReadAllMap
1019 * Overview: Read All Efuse content
1029 * 11/11/2008 MHC Create Version 0.
1031 *---------------------------------------------------------------------------*/
1033 efuse_ReadAllMap(struct net_device
* dev
, u8
*Efuse
)
1036 // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
1038 efuse_PowerSwitch(dev
, TRUE
);
1039 ReadEFuse(dev
, 0, 128, Efuse
);
1040 efuse_PowerSwitch(dev
, FALSE
);
1043 /*-----------------------------------------------------------------------------
1044 * Function: efuse_WriteAllMap
1046 * Overview: Write All Efuse content
1056 * 11/11/2008 MHC Create Version 0.
1058 *---------------------------------------------------------------------------*/
1061 efuse_WriteAllMap(struct net_device
* dev
,u8
*eeprom
, u32 eeprom_size
)
1063 unsigned char word_en
= 0x00;
1065 unsigned char tmpdata
[8];
1066 unsigned char offset
;
1068 // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
1069 efuse_PowerSwitch(dev
, TRUE
);
1072 for(offset
=0 ; offset
< eeprom_size
/PGPKT_DATA_SIZE
; offset
++)
1074 // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
1075 if (IS_HARDWARE_TYPE_8192SE(dev
))
1078 // 0x18-1f Reserve >0x50 Reserve for tx power
1079 if (offset
== 3/* || offset > 9*/)
1080 continue;//word_en = 0x0F;
1085 memcpy(tmpdata
, (eeprom
+(offset
*PGPKT_DATA_SIZE
)), 8);
1086 efuse_PgPacketWrite(dev
,offset
,word_en
,tmpdata
);
1091 // For warm reboot, we must resume Efuse clock to 500K.
1092 efuse_PowerSwitch(dev
, FALSE
);
1097 /*-----------------------------------------------------------------------------
1098 * Function: efuse_PgPacketRead
1100 * Overview: Receive dedicated Efuse are content. For92s, we support 16
1101 * area now. It will return 8 bytes content for every area.
1111 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1113 *---------------------------------------------------------------------------*/
1115 efuse_PgPacketRead( struct net_device
* dev
, u8 offset
, u8
*data
)
1117 u8 ReadState
= PG_STATE_HEADER
;
1119 bool bContinual
= TRUE
;
1120 bool bDataEmpty
= TRUE
;
1122 u8 efuse_data
,word_cnts
=0;
1124 u8 hoffset
=0,hworden
=0;
1128 if(data
==NULL
) return FALSE
;
1129 if(offset
>15) return FALSE
;
1131 memset(data
, 0xff, sizeof(u8
)*PGPKT_DATA_SIZE
);
1132 memset(tmpdata
, 0xff, sizeof(u8
)*PGPKT_DATA_SIZE
);
1134 while(bContinual
&& (efuse_addr
< EFUSE_MAX_SIZE
) )
1136 //------- Header Read -------------
1137 if(ReadState
& PG_STATE_HEADER
)
1139 if(efuse_OneByteRead(dev
, efuse_addr
,&efuse_data
)&&(efuse_data
!=0xFF)){
1140 hoffset
= (efuse_data
>>4) & 0x0F;
1141 hworden
= efuse_data
& 0x0F;
1142 word_cnts
= efuse_CalculateWordCnts(hworden
);
1145 if(hoffset
==offset
){
1146 for(tmpidx
= 0;tmpidx
< word_cnts
*2 ;tmpidx
++){
1147 if(efuse_OneByteRead(dev
, efuse_addr
+1+tmpidx
,&efuse_data
) ){
1148 tmpdata
[tmpidx
] = efuse_data
;
1149 if(efuse_data
!=0xff){
1154 if(bDataEmpty
==FALSE
){
1155 ReadState
= PG_STATE_DATA
;
1156 }else{//read next header
1157 efuse_addr
= efuse_addr
+ (word_cnts
*2)+1;
1158 ReadState
= PG_STATE_HEADER
;
1161 else{//read next header
1162 efuse_addr
= efuse_addr
+ (word_cnts
*2)+1;
1163 ReadState
= PG_STATE_HEADER
;
1168 bContinual
= FALSE
;
1171 //------- Data section Read -------------
1172 else if(ReadState
& PG_STATE_DATA
)
1174 efuse_WordEnableDataRead(hworden
,tmpdata
,data
);
1175 efuse_addr
= efuse_addr
+ (word_cnts
*2)+1;
1176 ReadState
= PG_STATE_HEADER
;
1181 if( (data
[0]==0xff) &&(data
[1]==0xff) && (data
[2]==0xff) && (data
[3]==0xff) &&
1182 (data
[4]==0xff) &&(data
[5]==0xff) && (data
[6]==0xff) && (data
[7]==0xff))
1189 /*-----------------------------------------------------------------------------
1190 * Function: efuse_PgPacketWrite
1192 * Overview: Send A G package for different section in real efuse area.
1193 * For 92S, One PG package contain 8 bytes content and 4 word
1194 * unit. PG header = 0x[bit7-4=offset][bit3-0word enable]
1204 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1206 *---------------------------------------------------------------------------*/
1207 static u32
efuse_PgPacketWrite(struct net_device
* dev
, u8 offset
, u8 word_en
,u8
*data
)
1209 u8 WriteState
= PG_STATE_HEADER
;
1211 bool bContinual
= TRUE
,bDataEmpty
=TRUE
, bResult
= TRUE
;
1217 u8 tmp_word_cnts
=0,target_word_cnts
=0;
1218 u8 tmp_header
,match_word_en
,tmp_word_en
;
1220 PGPKT_STRUCT target_pkt
;
1221 PGPKT_STRUCT tmp_pkt
;
1223 u8 originaldata
[sizeof(u8
)*8];
1224 u8 tmpindex
= 0,badworden
= 0x0F;
1226 static u32 repeat_times
= 0;
1228 if( efuse_GetCurrentSize(dev
) >= EFUSE_MAX_SIZE
)
1230 printk("efuse_PgPacketWrite error \n");
1234 // Init the 8 bytes content as 0xff
1235 target_pkt
.offset
= offset
;
1236 target_pkt
.word_en
= word_en
;
1238 //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
1239 memset(target_pkt
.data
,0xFF,sizeof(u8
)*8);
1241 efuse_WordEnableDataRead(word_en
,data
,target_pkt
.data
);
1242 target_word_cnts
= efuse_CalculateWordCnts(target_pkt
.word_en
);
1244 printk("EFUSE Power ON\n");
1246 while( bContinual
&& (efuse_addr
< EFUSE_MAX_SIZE
) )
1249 if(WriteState
==PG_STATE_HEADER
)
1253 //************ so *******************
1254 printk("EFUSE PG_STATE_HEADER\n");
1255 if ( efuse_OneByteRead(dev
, efuse_addr
,&efuse_data
) &&
1258 tmp_header
= efuse_data
;
1260 tmp_pkt
.offset
= (tmp_header
>>4) & 0x0F;
1261 tmp_pkt
.word_en
= tmp_header
& 0x0F;
1262 tmp_word_cnts
= efuse_CalculateWordCnts(tmp_pkt
.word_en
);
1264 //************ so-1 *******************
1265 if(tmp_pkt
.offset
!= target_pkt
.offset
)
1267 efuse_addr
= efuse_addr
+ (tmp_word_cnts
*2) +1; //Next pg_packet
1268 #if (EFUSE_ERROE_HANDLE == 1)
1269 WriteState
= PG_STATE_HEADER
;
1274 //************ so-2 *******************
1275 for(tmpindex
=0 ; tmpindex
<(tmp_word_cnts
*2) ; tmpindex
++)
1277 if(efuse_OneByteRead(dev
, (efuse_addr
+1+tmpindex
) ,&efuse_data
)&&(efuse_data
!= 0xFF)){
1281 //************ so-2-1 *******************
1282 if(bDataEmpty
== FALSE
)
1284 efuse_addr
= efuse_addr
+ (tmp_word_cnts
*2) +1; //Next pg_packet
1285 #if (EFUSE_ERROE_HANDLE == 1)
1286 WriteState
=PG_STATE_HEADER
;
1290 {//************ so-2-2 *******************
1291 match_word_en
= 0x0F;
1292 if( !( (target_pkt
.word_en
&BIT0
)|(tmp_pkt
.word_en
&BIT0
) ))
1294 match_word_en
&= (~BIT0
);
1296 if( !( (target_pkt
.word_en
&BIT1
)|(tmp_pkt
.word_en
&BIT1
) ))
1298 match_word_en
&= (~BIT1
);
1300 if( !( (target_pkt
.word_en
&BIT2
)|(tmp_pkt
.word_en
&BIT2
) ))
1302 match_word_en
&= (~BIT2
);
1304 if( !( (target_pkt
.word_en
&BIT3
)|(tmp_pkt
.word_en
&BIT3
) ))
1306 match_word_en
&= (~BIT3
);
1309 //************ so-2-2-A *******************
1310 if((match_word_en
&0x0F)!=0x0F)
1312 badworden
= efuse_WordEnableDataWrite(dev
,efuse_addr
+1, tmp_pkt
.word_en
,target_pkt
.data
);
1314 //************ so-2-2-A-1 *******************
1315 if(0x0F != (badworden
&0x0F))
1317 u8 reorg_offset
= offset
;
1318 u8 reorg_worden
=badworden
;
1319 efuse_PgPacketWrite(dev
,reorg_offset
,reorg_worden
,originaldata
);
1323 if( (target_pkt
.word_en
&BIT0
)^(match_word_en
&BIT0
) )
1325 tmp_word_en
&= (~BIT0
);
1327 if( (target_pkt
.word_en
&BIT1
)^(match_word_en
&BIT1
) )
1329 tmp_word_en
&= (~BIT1
);
1331 if( (target_pkt
.word_en
&BIT2
)^(match_word_en
&BIT2
) )
1333 tmp_word_en
&= (~BIT2
);
1335 if( (target_pkt
.word_en
&BIT3
)^(match_word_en
&BIT3
) )
1337 tmp_word_en
&=(~BIT3
);
1340 //************ so-2-2-A-2 *******************
1341 if((tmp_word_en
&0x0F)!=0x0F){
1342 //reorganize other pg packet
1344 efuse_addr
= efuse_GetCurrentSize(dev
);
1346 target_pkt
.offset
= offset
;
1347 target_pkt
.word_en
= tmp_word_en
;
1352 #if (EFUSE_ERROE_HANDLE == 1)
1353 WriteState
=PG_STATE_HEADER
;
1355 if(repeat_times
>EFUSE_REPEAT_THRESHOLD_
){
1361 else{//************ so-2-2-B *******************
1362 //reorganize other pg packet
1363 efuse_addr
= efuse_addr
+ (2*tmp_word_cnts
) +1;//next pg packet addr
1364 target_pkt
.offset
= offset
;
1365 target_pkt
.word_en
= target_pkt
.word_en
;
1366 #if (EFUSE_ERROE_HANDLE == 1)
1367 WriteState
=PG_STATE_HEADER
;
1372 printk("EFUSE PG_STATE_HEADER-1\n");
1374 else //************ s1: header == oxff *******************
1376 pg_header
= ((target_pkt
.offset
<< 4)&0xf0) |target_pkt
.word_en
;
1378 efuse_OneByteWrite(dev
,efuse_addr
, pg_header
);
1379 efuse_OneByteRead(dev
,efuse_addr
, &tmp_header
);
1381 if(tmp_header
== pg_header
)
1382 { //************ s1-1*******************
1383 WriteState
= PG_STATE_DATA
;
1385 #if (EFUSE_ERROE_HANDLE == 1)
1386 else if(tmp_header
== 0xFF){//************ s1-3: if Write or read func doesn't work *******************
1387 //efuse_addr doesn't change
1388 WriteState
= PG_STATE_HEADER
;
1390 if(repeat_times
>EFUSE_REPEAT_THRESHOLD_
){
1397 {//************ s1-2 : fixed the header procedure *******************
1398 tmp_pkt
.offset
= (tmp_header
>>4) & 0x0F;
1399 tmp_pkt
.word_en
= tmp_header
& 0x0F;
1400 tmp_word_cnts
= efuse_CalculateWordCnts(tmp_pkt
.word_en
);
1402 //************ s1-2-A :cover the exist data *******************
1403 memset(originaldata
,0xff,sizeof(u8
)*8);
1405 if(efuse_PgPacketRead( dev
, tmp_pkt
.offset
,originaldata
))
1406 { //check if data exist
1407 badworden
= efuse_WordEnableDataWrite(dev
,efuse_addr
+1,tmp_pkt
.word_en
,originaldata
);
1408 if(0x0F != (badworden
&0x0F))
1410 u8 reorg_offset
= tmp_pkt
.offset
;
1411 u8 reorg_worden
=badworden
;
1412 efuse_PgPacketWrite(dev
,reorg_offset
,reorg_worden
,originaldata
);
1413 efuse_addr
= efuse_GetCurrentSize(dev
);
1416 efuse_addr
= efuse_addr
+ (tmp_word_cnts
*2) +1; //Next pg_packet
1419 //************ s1-2-B: wrong address*******************
1422 efuse_addr
= efuse_addr
+ (tmp_word_cnts
*2) +1; //Next pg_packet
1425 #if (EFUSE_ERROE_HANDLE == 1)
1426 WriteState
=PG_STATE_HEADER
;
1428 if(repeat_times
>EFUSE_REPEAT_THRESHOLD_
){
1434 printk("EFUSE PG_STATE_HEADER-2\n");
1441 else if(WriteState
==PG_STATE_DATA
)
1442 { //************ s1-1 *******************
1443 printk("EFUSE PG_STATE_DATA\n");
1445 badworden
= efuse_WordEnableDataWrite(dev
,efuse_addr
+1,target_pkt
.word_en
,target_pkt
.data
);
1446 if((badworden
&0x0F)==0x0F)
1447 { //************ s1-1-A *******************
1451 {//reorganize other pg packet //************ s1-1-B *******************
1452 efuse_addr
= efuse_addr
+ (2*target_word_cnts
) +1;//next pg packet addr
1454 target_pkt
.offset
= offset
;
1455 target_pkt
.word_en
= badworden
;
1456 target_word_cnts
= efuse_CalculateWordCnts(target_pkt
.word_en
);
1457 #if (EFUSE_ERROE_HANDLE == 1)
1458 WriteState
=PG_STATE_HEADER
;
1460 if(repeat_times
>EFUSE_REPEAT_THRESHOLD_
){
1465 printk("EFUSE PG_STATE_HEADER-3\n");
1470 if(efuse_addr
>= (EFUSE_MAX_SIZE
-EFUSE_OOB_PROTECT_BYTES
))
1472 RT_TRACE(COMP_EPROM
, "efuse_PgPacketWrite(): efuse_addr(%x) Out of size!!\n", efuse_addr
);
1477 /*-----------------------------------------------------------------------------
1478 * Function: efuse_WordEnableDataRead
1480 * Overview: Read allowed word in current efuse section data.
1490 * 11/16/2008 MHC Create Version 0.
1491 * 11/21/2008 MHC Fix Write bug when we only enable late word.
1493 *---------------------------------------------------------------------------*/
1495 efuse_WordEnableDataRead( u8 word_en
,u8
*sourdata
,u8
*targetdata
)
1498 if (!(word_en
&BIT0
))
1500 targetdata
[0] = sourdata
[0];//sourdata[tmpindex++];
1501 targetdata
[1] = sourdata
[1];//sourdata[tmpindex++];
1503 if (!(word_en
&BIT1
))
1505 targetdata
[2] = sourdata
[2];//sourdata[tmpindex++];
1506 targetdata
[3] = sourdata
[3];//sourdata[tmpindex++];
1508 if (!(word_en
&BIT2
))
1510 targetdata
[4] = sourdata
[4];//sourdata[tmpindex++];
1511 targetdata
[5] = sourdata
[5];//sourdata[tmpindex++];
1513 if (!(word_en
&BIT3
))
1515 targetdata
[6] = sourdata
[6];//sourdata[tmpindex++];
1516 targetdata
[7] = sourdata
[7];//sourdata[tmpindex++];
1520 /*-----------------------------------------------------------------------------
1521 * Function: efuse_WordEnableDataWrite
1523 * Overview: Write necessary word unit into current efuse section!
1533 * 11/16/2008 MHC Reorganize Efuse operate flow!!.
1535 *---------------------------------------------------------------------------*/
1537 efuse_WordEnableDataWrite( struct net_device
* dev
, u16 efuse_addr
, u8 word_en
, u8
*data
)
1540 u16 start_addr
= efuse_addr
;
1541 u8 badworden
= 0x0F;
1544 memset(tmpdata
,0xff,PGPKT_DATA_SIZE
);
1548 tmpaddr
= start_addr
;
1549 efuse_OneByteWrite(dev
,start_addr
++, data
[0]);
1550 efuse_OneByteWrite(dev
,start_addr
++, data
[1]);
1552 efuse_OneByteRead(dev
,tmpaddr
, &tmpdata
[0]);
1553 efuse_OneByteRead(dev
,tmpaddr
+1, &tmpdata
[1]);
1554 if((data
[0]!=tmpdata
[0])||(data
[1]!=tmpdata
[1])){
1555 badworden
&= (~BIT0
);
1560 tmpaddr
= start_addr
;
1561 efuse_OneByteWrite(dev
,start_addr
++, data
[2]);
1562 efuse_OneByteWrite(dev
,start_addr
++, data
[3]);
1564 efuse_OneByteRead(dev
,tmpaddr
, &tmpdata
[2]);
1565 efuse_OneByteRead(dev
,tmpaddr
+1, &tmpdata
[3]);
1566 if((data
[2]!=tmpdata
[2])||(data
[3]!=tmpdata
[3])){
1567 badworden
&=( ~BIT1
);
1572 tmpaddr
= start_addr
;
1573 efuse_OneByteWrite(dev
,start_addr
++, data
[4]);
1574 efuse_OneByteWrite(dev
,start_addr
++, data
[5]);
1576 efuse_OneByteRead(dev
,tmpaddr
, &tmpdata
[4]);
1577 efuse_OneByteRead(dev
,tmpaddr
+1, &tmpdata
[5]);
1578 if((data
[4]!=tmpdata
[4])||(data
[5]!=tmpdata
[5])){
1579 badworden
&=( ~BIT2
);
1584 tmpaddr
= start_addr
;
1585 efuse_OneByteWrite(dev
,start_addr
++, data
[6]);
1586 efuse_OneByteWrite(dev
,start_addr
++, data
[7]);
1588 efuse_OneByteRead(dev
,tmpaddr
, &tmpdata
[6]);
1589 efuse_OneByteRead(dev
,tmpaddr
+1, &tmpdata
[7]);
1590 if((data
[6]!=tmpdata
[6])||(data
[7]!=tmpdata
[7])){
1591 badworden
&=( ~BIT3
);
1597 /*-----------------------------------------------------------------------------
1598 * Function: efuse_PowerSwitch
1600 * Overview: When we want to enable write operation, we should change to
1601 * pwr on state. When we stop write, we should switch to 500k mode
1602 * and disable LDO 2.5V.
1612 * 11/17/2008 MHC Create Version 0.
1614 *---------------------------------------------------------------------------*/
1616 efuse_PowerSwitch(struct net_device
* dev
, u8 PwrState
)
1619 if (PwrState
== TRUE
)
1621 // Enable LDO 2.5V for write action
1622 tempval
= read_nic_byte(dev
, EFUSE_TEST
+3);
1623 write_nic_byte(dev
, EFUSE_TEST
+3, (tempval
| 0x80));
1625 // Change Efuse Clock for write action to 40MHZ
1626 write_nic_byte(dev
, EFUSE_CLK
, 0x03);
1630 // Enable LDO 2.5V for write action
1631 tempval
= read_nic_byte(dev
, EFUSE_TEST
+3);
1632 write_nic_byte(dev
, EFUSE_TEST
+3, (tempval
& 0x7F));
1634 // Change Efuse Clock for write action to 500K
1635 write_nic_byte(dev
, EFUSE_CLK
, 0x02);
1640 /*-----------------------------------------------------------------------------
1641 * Function: efuse_GetCurrentSize
1643 * Overview: Get current efuse size!!!
1653 * 11/16/2008 MHC Create Version 0.
1655 *---------------------------------------------------------------------------*/
1657 efuse_GetCurrentSize(struct net_device
* dev
)
1659 bool bContinual
= TRUE
;
1662 u8 hoffset
=0,hworden
=0;
1663 u8 efuse_data
,word_cnts
=0;
1665 while ( bContinual
&&
1666 efuse_OneByteRead(dev
, efuse_addr
,&efuse_data
) &&
1667 (efuse_addr
< EFUSE_MAX_SIZE
) )
1669 if(efuse_data
!=0xFF)
1671 hoffset
= (efuse_data
>>4) & 0x0F;
1672 hworden
= efuse_data
& 0x0F;
1673 word_cnts
= efuse_CalculateWordCnts(hworden
);
1675 efuse_addr
= efuse_addr
+ (word_cnts
*2)+1;
1679 bContinual
= FALSE
;
1687 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
1689 efuse_CalculateWordCnts(u8 word_en
)
1692 if(!(word_en
& BIT0
)) word_cnts
++; // 0 : write enable
1693 if(!(word_en
& BIT1
)) word_cnts
++;
1694 if(!(word_en
& BIT2
)) word_cnts
++;
1695 if(!(word_en
& BIT3
)) word_cnts
++;
1699 /*-----------------------------------------------------------------------------
1700 * Function: EFUSE_ProgramMap
1702 * Overview: Read EFUSE map file and execute PG.
1712 * 11/10/2008 MHC Create Version 0.
1714 *---------------------------------------------------------------------------*/
1716 extern bool // 0=Shadow 1=Real Efuse
1717 EFUSE_ProgramMap(struct net_device
* dev
, char* pFileName
,u8 TableType
)
1719 struct r8192_priv
*priv
= ieee80211_priv(dev
);
1720 s4Byte nLinesRead
, ithLine
;
1721 RT_STATUS rtStatus
= RT_STATUS_SUCCESS
;
1723 u32 u4bRegValue
, u4RegMask
;
1727 u8 eeprom
[HWSET_MAX_SIZE_92S
];
1729 rtStatus
= PlatformReadFile(
1732 (u8
*)(priv
->BufOfLines
),
1733 MAX_LINES_HWCONFIG_TXT
,
1734 MAX_BYTES_LINE_HWCONFIG_TXT
,
1738 if(rtStatus
== RT_STATUS_SUCCESS
)
1740 memcp(pHalData
->BufOfLines3
, pHalData
->BufOfLines
,
1741 nLinesRead
*MAX_BYTES_LINE_HWCONFIG_TXT
);
1742 pHalData
->nLinesRead3
= nLinesRead
;
1745 if(rtStatus
== RT_STATUS_SUCCESS
)
1747 printk("szEepromFile(): read %s ok\n", pFileName
);
1748 for(ithLine
= 0; ithLine
< nLinesRead
; ithLine
++)
1750 szLine
= pHalData
->BufOfLines
[ithLine
];
1751 printk("Line-%d String =%s\n", ithLine
, szLine
);
1753 if(!IsCommentString(szLine
))
1755 // EEPROM map one line has 8 words content.
1756 for (i
= 0; i
< 8; i
++)
1760 efuse_ParsingMap(szLine
, &u4bRegValue
, &u4bMove
);
1762 // Get next hex value as EEPROM value.
1764 eeprom
[index
++] = (u8
)(u4bRegValue
&0xff);
1765 eeprom
[index
++] = (u8
)((u4bRegValue
>>8)&0xff);
1767 printk("Addr-%d = %x\n", (ithLine
*8+i
), u4bRegValue
);
1776 printk("szEepromFile(): Fail read%s\n", pFileName
);
1777 return RT_STATUS_FAILURE
;
1780 // Use map file to update real Efuse or shadow modify table.
1783 efuse_WriteAllMap(dev
, eeprom
, HWSET_MAX_SIZE_92S
);
1787 // Modify shadow table.
1788 for (i
= 0; i
< HWSET_MAX_SIZE_92S
; i
++)
1789 EFUSE_ShadowWrite(dev
, 1, i
, (u32
)eeprom
[i
]);
1797 /*-----------------------------------------------------------------------------
1798 * Function: efuse_ParsingMap
1810 * 11/08/2008 MHC Create Version 0.
1812 *---------------------------------------------------------------------------*/
1815 efuse_ParsingMap(char* szStr
,u32
* pu4bVal
,u32
* pu4bMove
)
1817 char* szScan
= szStr
;
1819 // Check input parameter.
1820 if(szStr
== NULL
|| pu4bVal
== NULL
|| pu4bMove
== NULL
)
1825 // Initialize output.
1829 // Skip leading space.
1830 while( *szScan
!= '\0' &&
1831 (*szScan
== ' ' || *szScan
== '\t') )
1837 // Check if szScan is now pointer to a character for hex digit,
1838 // if not, it means this is not a valid hex number.
1839 if (!isxdigit(*szScan
))
1842 // Parse each digit.
1845 *pu4bVal
= (*pu4bVal
<< 4) + hex_to_bin(*szScan
);
1849 } while (isxdigit(*szScan
));
1856 int efuse_one_byte_rw(struct net_device
* dev
, u8 bRead
, u16 addr
, u8
*data
)
1862 // -----------------e-fuse reg ctrl ---------------------------------
1864 write_nic_byte(dev
, EFUSE_CTRL
+1, (u8
)(addr
&0xff)); //address
1865 tmpv8
= ((u8
)((addr
>>8) &0x03) ) | (read_nic_byte(dev
, EFUSE_CTRL
+2)&0xFC );
1866 write_nic_byte(dev
, EFUSE_CTRL
+2, tmpv8
);
1870 write_nic_byte(dev
, EFUSE_CTRL
+3, 0x72);//read cmd
1872 while(!(0x80 & read_nic_byte(dev
, EFUSE_CTRL
+3)) && (tmpidx
<100) ){
1876 *data
=read_nic_byte(dev
, EFUSE_CTRL
);
1887 write_nic_byte(dev
, EFUSE_CTRL
, *data
);//data
1889 write_nic_byte(dev
, EFUSE_CTRL
+3, 0xF2);//write cmd
1891 while((0x80 & read_nic_byte(dev
, EFUSE_CTRL
+3)) && (tmpidx
<100) ){
1896 *data
=read_nic_byte(dev
, EFUSE_CTRL
);
1909 void efuse_access(struct net_device
* dev
, u8 bRead
,u16 start_addr
, u8 cnts
, u8
*data
)
1911 u8 efuse_clk_ori
,efuse_clk_new
;//,tmp8;
1914 if(start_addr
>0x200) return;
1915 // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
1916 efuse_clk_ori
= read_nic_byte(dev
,SYS_FUNC_EN
+1);
1917 efuse_clk_new
= efuse_clk_ori
|0x20;
1919 if(efuse_clk_new
!= efuse_clk_ori
){
1920 write_nic_byte(dev
, SYS_FUNC_EN
+1, efuse_clk_new
);
1922 #ifdef _POWERON_DELAY_
1925 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1926 write_nic_byte(dev
, EFUSE_TEST
+3, (read_nic_byte(dev
, EFUSE_TEST
+3)|0x80));
1927 write_nic_byte(dev
, EFUSE_CLK_CTRL
, (read_nic_byte(dev
, EFUSE_CLK_CTRL
)|0x03));
1929 #ifdef _PRE_EXECUTE_READ_CMD_
1931 unsigned char tmpdata
;
1932 efuse_OneByteRead(dev
, 0,&tmpdata
);
1936 //-----------------e-fuse one byte read / write ------------------------------
1937 for(i
=0;i
<cnts
;i
++){
1938 efuse_one_byte_rw(dev
,bRead
, start_addr
+i
, data
+i
);
1941 write_nic_byte(dev
, EFUSE_TEST
+3, read_nic_byte(dev
, EFUSE_TEST
+3)&0x7f);
1942 write_nic_byte(dev
, EFUSE_CLK_CTRL
, read_nic_byte(dev
, EFUSE_CLK_CTRL
)&0xfd);
1944 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
1945 if(efuse_clk_new
!= efuse_clk_ori
) write_nic_byte(dev
, 0x10250003, efuse_clk_ori
);
1950 static void efuse_reg_ctrl(struct net_device
* dev
, u8 bPowerOn
)
1953 // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
1954 write_nic_byte(dev
, SYS_FUNC_EN
+1, read_nic_byte(dev
,SYS_FUNC_EN
+1)|0x20);
1955 #ifdef _POWERON_DELAY_
1958 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1959 write_nic_byte(dev
, EFUSE_TEST
+4, (read_nic_byte(dev
, EFUSE_TEST
+4)|0x80));
1960 write_nic_byte(dev
, EFUSE_CLK_CTRL
, (read_nic_byte(dev
, EFUSE_CLK_CTRL
)|0x03));
1961 #ifdef _PRE_EXECUTE_READ_CMD_
1963 unsigned char tmpdata
;
1964 efuse_OneByteRead(dev
, 0,&tmpdata
);
1970 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1971 write_nic_byte(dev
, EFUSE_TEST
+4, read_nic_byte(dev
, EFUSE_TEST
+4)&0x7f);
1972 write_nic_byte(dev
, EFUSE_CLK_CTRL
, read_nic_byte(dev
, EFUSE_CLK_CTRL
)&0xfd);
1973 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
1981 void efuse_read_data(struct net_device
* dev
,u8 efuse_read_item
,u8
*data
,u32 data_size
)
1983 u8 offset
, word_start
,byte_start
,byte_cnts
;
1984 u8 efusedata
[EFUSE_MAC_LEN
];
1992 if(efuse_read_item
> (sizeof(RTL8712_SDIO_EFUSE_TABLE
)/sizeof(EFUSE_MAP
))){
1996 offset
= RTL8712_SDIO_EFUSE_TABLE
[efuse_read_item
].offset
;
1997 word_start
= RTL8712_SDIO_EFUSE_TABLE
[efuse_read_item
].word_start
;
1998 byte_start
= RTL8712_SDIO_EFUSE_TABLE
[efuse_read_item
].byte_start
;
1999 byte_cnts
= RTL8712_SDIO_EFUSE_TABLE
[efuse_read_item
].byte_cnts
;
2001 if(data_size
!=byte_cnts
){
2005 pg_pkt_cnts
= (byte_cnts
/PGPKT_DATA_SIZE
) +1;
2007 if(pg_pkt_cnts
> 1){
2008 tmpdata
= efusedata
;
2012 memset(tmpdata
,0xff,pg_pkt_cnts
*PGPKT_DATA_SIZE
);
2014 for(tmpidx
=0;tmpidx
<pg_pkt_cnts
;tmpidx
++)
2016 memset(pg_data
,0xff,PGPKT_DATA_SIZE
);
2017 if(TRUE
== efuse_PgPacketRead(dev
,offset
+tmpidx
,pg_data
))
2019 memcpy(tmpdata
+(PGPKT_DATA_SIZE
*tmpidx
),pg_data
,PGPKT_DATA_SIZE
);
2022 memcpy(data
,(tmpdata
+ (2*word_start
)+byte_start
),data_size
);
2027 memset(pg_data
,0xff,PGPKT_DATA_SIZE
);
2028 if(TRUE
==efuse_PgPacketRead(dev
,offset
,pg_data
)){
2029 memcpy(data
,pg_data
+ (2*word_start
)+byte_start
,data_size
);
2035 //per interface doesn't alike
2036 void efuse_write_data(struct net_device
* dev
,u8 efuse_write_item
,u8
*data
,u32 data_size
,u32 bWordUnit
)
2038 u8 offset
, word_start
,byte_start
,byte_cnts
;
2039 u8 word_en
= 0x0f,word_cnts
;
2042 u8 tmpidx
,tmpbitmask
;
2043 u8 pg_data
[8],tmpbytes
=0;
2045 if(efuse_write_item
> (sizeof(RTL8712_SDIO_EFUSE_TABLE
)/sizeof(EFUSE_MAP
))){
2049 offset
= RTL8712_SDIO_EFUSE_TABLE
[efuse_write_item
].offset
;
2050 word_start
= RTL8712_SDIO_EFUSE_TABLE
[efuse_write_item
].word_start
;
2051 byte_start
= RTL8712_SDIO_EFUSE_TABLE
[efuse_write_item
].byte_start
;
2052 byte_cnts
= RTL8712_SDIO_EFUSE_TABLE
[efuse_write_item
].byte_cnts
;
2054 if(data_size
> byte_cnts
){
2057 pg_pkt_cnts
= (byte_cnts
/PGPKT_DATA_SIZE
) +1;
2058 word_cnts
= byte_cnts
/2 ;
2063 if((byte_start
==1)||((byte_cnts
%2)==1)){//situation A
2065 if((efuse_write_item
==EFUSE_F0CIS
)||(efuse_write_item
==EFUSE_F1CIS
)){
2066 memset(pg_data
,0xff,PGPKT_DATA_SIZE
);
2067 efuse_PgPacketRead(dev
,offset
,pg_data
);
2069 if(efuse_write_item
==EFUSE_F0CIS
){
2071 memcpy(pg_data
+word_start
*2+byte_start
,data
,sizeof(u8
)*2);
2072 efuse_PgPacketWrite(dev
,offset
,word_en
,pg_data
+(word_start
*2));
2075 efuse_PgPacketWrite(dev
,(offset
+1),word_en
,data
+2);
2078 efuse_PgPacketRead(dev
,offset
+2,pg_data
);
2079 memcpy(pg_data
,data
+2+8,sizeof(u8
)*7);
2081 efuse_PgPacketWrite(dev
,(offset
+2),word_en
,pg_data
);
2083 else if(efuse_write_item
==EFUSE_F1CIS
){
2085 efuse_PgPacketRead(dev
,offset
,pg_data
);
2086 pg_data
[7] = data
[0];
2087 efuse_PgPacketWrite(dev
,offset
,word_en
,pg_data
+(word_start
*2));
2090 for(tmpidx
= 0 ;tmpidx
<(word_cnts
/4);tmpidx
++){
2091 efuse_PgPacketWrite(dev
,(offset
+1+tmpidx
),word_en
,data
+1+(tmpidx
*PGPKT_DATA_SIZE
));
2097 memset(pg_data
,0xff,PGPKT_DATA_SIZE
);
2098 if((efuse_write_item
==EFUSE_SDIO_SETTING
)||(efuse_write_item
==EFUSE_CCCR
)){
2102 else if(efuse_write_item
== EFUSE_SDIO_MODE
){
2106 else if(efuse_write_item
== EFUSE_OCR
){
2110 else if((efuse_write_item
== EFUSE_EEPROM_VER
)||(efuse_write_item
==EFUSE_CHAN_PLAN
)){
2114 if(bWordUnit
==TRUE
){
2115 memcpy(pg_data
+word_start
*2 ,data
,sizeof(u8
)*tmpbytes
);
2118 efuse_PgPacketRead(dev
,offset
,pg_data
);
2119 memcpy(pg_data
+(2*word_start
)+byte_start
,data
,sizeof(u8
)*byte_cnts
);
2122 efuse_PgPacketWrite(dev
,offset
,word_en
,pg_data
+(word_start
*2));
2127 else if(pg_pkt_cnts
>1){//situation B
2130 for(tmpidx
= 0 ;tmpidx
<(word_cnts
/4);tmpidx
++)
2132 efuse_PgPacketWrite(dev
,(offset
+tmpidx
),word_en
,data
+(tmpidx
*PGPKT_DATA_SIZE
));
2135 for(tmpidx
= 0; tmpidx
<(word_cnts
%4) ; tmpidx
++)
2138 word_en
&= (~(EFUSE_BIT(tmpbitmask
)));
2141 efuse_PgPacketWrite(dev
,offset
+(word_cnts
/4),word_en
,data
+((word_cnts
/4)*PGPKT_DATA_SIZE
));
2149 for(tmpidx
= 0; tmpidx
<word_cnts
; tmpidx
++)
2151 tmpbitmask
= word_start
+ tmpidx
;
2152 word_en
&= (~(EFUSE_BIT(tmpbitmask
)));
2154 efuse_PgPacketWrite(dev
,offset
,word_en
,data
);
2159 void efuset_test_func_read(struct net_device
* dev
)
2164 u8 txpowertable
[28];
2166 memset(chipid
,0,sizeof(u8
)*2);
2167 efuse_read_data(dev
,EFUSE_CHIP_ID
,chipid
,sizeof(chipid
));
2169 memset(ocr
,0,sizeof(u8
)*3);
2170 efuse_read_data(dev
,EFUSE_CCCR
,ocr
,sizeof(ocr
));
2172 memset(macaddr
,0,sizeof(u8
)*6);
2173 efuse_read_data(dev
,EFUSE_MAC_ADDR
,macaddr
,sizeof(macaddr
));
2175 memset(txpowertable
,0,sizeof(u8
)*28);
2176 efuse_read_data(dev
,EFUSE_TXPW_TAB
,txpowertable
,sizeof(txpowertable
));
2179 void efuset_test_func_write(struct net_device
* dev
)
2181 u32 bWordUnit
= TRUE
;
2182 u8 CCCR
=0x02,SDIO_SETTING
= 0xFF;
2185 u8 macaddr
[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
2186 efuse_write_data(dev
,EFUSE_MAC_ADDR
,macaddr
,sizeof(macaddr
),bWordUnit
);
2189 efuse_write_data(dev
,EFUSE_CCCR
,&CCCR
,sizeof(u8
),bWordUnit
);
2192 efuse_write_data(dev
,EFUSE_SDIO_SETTING
,&SDIO_SETTING
,sizeof(u8
),bWordUnit
);
2195 tmpdata
[0] =SDIO_SETTING
;
2197 efuse_write_data(dev
,EFUSE_SDIO_SETTING
,tmpdata
,sizeof(tmpdata
),bWordUnit
);