]> Pileus Git - ~andy/linux/blob - drivers/staging/rtl8192su/r8192S_Efuse.c
Merge branches 'softirq-for-linus', 'x86-debug-for-linus', 'x86-numa-for-linus',...
[~andy/linux] / drivers / staging / rtl8192su / r8192S_Efuse.c
1 /******************************************************************************
2  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3  *
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.
9  *
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
13  * more details.
14  *
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
18  *
19  * The full GNU General Public License is included in this distribution in the
20  * file called LICENSE.
21  *
22  * Contact Information:
23  * wlanfae <wlanfae@realtek.com>
24 ******************************************************************************/
25 #include "r8192U.h"
26 #include "r8192S_hw.h"
27 #include "r8192S_phy.h"
28 #include "r8192S_phyreg.h"
29 #include "r8192S_Efuse.h"
30
31 #include <linux/types.h>
32 #include <linux/ctype.h>
33
34 #define         _POWERON_DELAY_
35 #define         _PRE_EXECUTE_READ_CMD_
36
37 #define         EFUSE_REPEAT_THRESHOLD_         3
38 #define         EFUSE_ERROE_HANDLE              1
39
40 typedef struct _EFUSE_MAP_A{
41         u8 offset;              //0~15
42         u8 word_start;  //0~3
43         u8 byte_start;  //0 or 1
44         u8 byte_cnts;
45
46 }EFUSE_MAP, *PEFUSE_MAP;
47
48 typedef struct PG_PKT_STRUCT_A{
49         u8 offset;
50         u8 word_en;
51         u8 data[8];
52 }PGPKT_STRUCT,*PPGPKT_STRUCT;
53
54 typedef enum _EFUSE_DATA_ITEM{
55         EFUSE_CHIP_ID=0,
56         EFUSE_LDO_SETTING,
57         EFUSE_CLK_SETTING,
58         EFUSE_SDIO_SETTING,
59         EFUSE_CCCR,
60         EFUSE_SDIO_MODE,
61         EFUSE_OCR,
62         EFUSE_F0CIS,
63         EFUSE_F1CIS,
64         EFUSE_MAC_ADDR,
65         EFUSE_EEPROM_VER,
66         EFUSE_CHAN_PLAN,
67         EFUSE_TXPW_TAB
68 } EFUSE_DATA_ITEM;
69
70 struct efuse_priv
71 {
72         u8              id[2];
73         u8              ldo_setting[2];
74         u8              clk_setting[2];
75         u8              cccr;
76         u8              sdio_mode;
77         u8              ocr[3];
78         u8              cis0[17];
79         u8              cis1[48];
80         u8              mac_addr[6];
81         u8              eeprom_verno;
82         u8              channel_plan;
83         u8              tx_power_b[14];
84         u8              tx_power_g[14];
85 };
86
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;
90
91 const u8 EFUSE_OOB_PROTECT_BYTES = 14;
92
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
108 };
109
110 //
111 // From WMAC Efuse one byte R/W
112 //
113 extern  void
114 EFUSE_Initialize(struct net_device* dev);
115 extern  u8
116 EFUSE_Read1Byte(struct net_device* dev, u16 Address);
117 extern  void
118 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value);
119
120 //
121 // Efuse Shadow Area operation
122 //
123 static  void
124 efuse_ShadowRead1Byte(struct net_device* dev,u16 Offset,u8 *Value);
125 static  void
126 efuse_ShadowRead2Byte(struct net_device* dev,   u16 Offset,u16 *Value   );
127 static  void
128 efuse_ShadowRead4Byte(struct net_device* dev,   u16 Offset,u32 *Value   );
129 static  void
130 efuse_ShadowWrite1Byte(struct net_device* dev,  u16 Offset, u8 Value);
131 static  void
132 efuse_ShadowWrite2Byte(struct net_device* dev,  u16 Offset,u16 Value);
133 static  void
134 efuse_ShadowWrite4Byte(struct net_device* dev,  u16 Offset,u32 Value);
135
136 //
137 // Real Efuse operation
138 //
139 static  u8
140 efuse_OneByteRead(struct net_device* dev,u16 addr,u8 *data);
141 static  u8
142 efuse_OneByteWrite(struct net_device* dev,u16 addr, u8 data);
143
144 //
145 // HW setting map file operation
146 //
147 static  void
148 efuse_ReadAllMap(struct net_device* dev,u8 *Efuse);
149 #ifdef TO_DO_LIST
150 static  void
151 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom,u32 eeprom_size);
152 static  bool
153 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove);
154 #endif
155 //
156 // Reald Efuse R/W or other operation API.
157 //
158 static  u8
159 efuse_PgPacketRead(     struct net_device* dev,u8       offset,u8 *data);
160 static  u32
161 efuse_PgPacketWrite(struct net_device* dev,u8 offset,u8 word_en,u8      *data);
162 static  void
163 efuse_WordEnableDataRead(       u8 word_en,u8 *sourdata,u8 *targetdata);
164 static  u8
165 efuse_WordEnableDataWrite(      struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data);
166 static  void
167 efuse_PowerSwitch(struct net_device* dev,u8 PwrState);
168 static  u16
169 efuse_GetCurrentSize(struct net_device* dev);
170 static u8
171 efuse_CalculateWordCnts(u8 word_en);
172 //
173 // API for power on power off!!!
174 //
175 #ifdef TO_DO_LIST
176 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
177 #endif
178
179
180
181 /*-----------------------------------------------------------------------------
182  * Function:    EFUSE_Initialize
183  *
184  * Overview:    Copy from WMAC fot EFUSE testing setting init.
185  *
186  * Input:       NONE
187  *
188  * Output:      NONE
189  *
190  * Return:      NONE
191  *
192  * Revised History:
193  * When                 Who             Remark
194  * 09/23/2008   MHC             Copy from WMAC.
195  *
196  *---------------------------------------------------------------------------*/
197 extern  void
198 EFUSE_Initialize(struct net_device* dev)
199 {
200         u8      Bytetemp = {0x00};
201         u8      temp = {0x00};
202
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);
207
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);
212
213
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);
218
219         //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
220         write_nic_byte(dev, 0x2F8, 0x3);
221
222         //Set E-fuse program time & read time : 0x30[30:24]=1110010b
223         write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
224
225 }
226
227 /*-----------------------------------------------------------------------------
228  * Function:    EFUSE_Read1Byte
229  *
230  * Overview:    Copy from WMAC fot EFUSE read 1 byte.
231  *
232  * Input:       NONE
233  *
234  * Output:      NONE
235  *
236  * Return:      NONE
237  *
238  * Revised History:
239  * When                 Who             Remark
240  * 09/23/2008   MHC             Copy from WMAC.
241  *
242  *---------------------------------------------------------------------------*/
243 extern  u8
244 EFUSE_Read1Byte(struct net_device* dev, u16     Address)
245 {
246         u8      data;
247         u8      Bytetemp = {0x00};
248         u8      temp = {0x00};
249         u32     k=0;
250
251         if (Address < EFUSE_MAC_LEN)    //E-fuse 512Byte
252         {
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);
260
261                 //Write 0x30[31]=0
262                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
263                 temp = Bytetemp & 0x7F;
264                 write_nic_byte(dev, EFUSE_CTRL+3, temp);
265
266                 //Wait Write-ready (0x30[31]=1)
267                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
268                 while(!(Bytetemp & 0x80))
269                 {
270                         Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
271                         k++;
272                         if(k==1000)
273                         {
274                                 k=0;
275                                 break;
276                         }
277                 }
278                 data=read_nic_byte(dev, EFUSE_CTRL);
279                 return data;
280         }
281         else
282                 return 0xFF;
283
284 }
285
286
287 /*-----------------------------------------------------------------------------
288  * Function:    EFUSE_Write1Byte
289  *
290  * Overview:    Copy from WMAC fot EFUSE write 1 byte.
291  *
292  * Input:       NONE
293  *
294  * Output:      NONE
295  *
296  * Return:      NONE
297  *
298  * Revised History:
299  * When                 Who             Remark
300  * 09/23/2008   MHC             Copy from WMAC.
301  *
302  *---------------------------------------------------------------------------*/
303 extern  void
304 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
305 {
306         u8      Bytetemp = {0x00};
307         u8      temp = {0x00};
308         u32     k=0;
309
310         if( Address < EFUSE_MAC_LEN)    //E-fuse 512Byte
311         {
312                 write_nic_byte(dev, EFUSE_CTRL, Value);
313
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);
318
319                 //Write E-fuse Register address bit8~9
320                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
321                 write_nic_byte(dev, EFUSE_CTRL+2, temp);
322
323                 //Write 0x30[31]=1
324                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
325                 temp = Bytetemp | 0x80;
326                 write_nic_byte(dev, EFUSE_CTRL+3, temp);
327
328                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
329                 while(Bytetemp & 0x80)
330                 {
331                         Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
332                         k++;
333                         if(k==100)
334                         {
335                                 k=0;
336                                 break;
337                         }
338                 }
339         }
340
341 }
342
343 #ifdef EFUSE_FOR_92SU
344 //
345 //      Description:
346 //              1. Process CR93C46 Data polling cycle.
347 //              2. Refered from SD1 Richard.
348 //
349 //      Assumption:
350 //              1. Boot from E-Fuse and successfully auto-load.
351 //              2. PASSIVE_LEVEL (USB interface)
352 //
353 //      Created by Roger, 2008.10.21.
354 //
355 void do_93c46(struct net_device* dev,  u8 addorvalue)
356 {
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
361         u8  count;
362
363         for(count=0 ; count<8 ; count++)
364         {
365                 if((addorvalue&0x80)!=0)
366                 {
367                         write_nic_byte(dev, EPROM_CMD, csdi[0]);
368                         write_nic_byte(dev, EPROM_CMD, csskdi[0]);
369                 }
370                 else
371                 {
372                         write_nic_byte(dev, EPROM_CMD, cs[0]);
373                         write_nic_byte(dev, EPROM_CMD, cssk[0]);
374                 }
375                 addorvalue = addorvalue << 1;
376         }
377 }
378
379
380 //
381 //      Description:
382 //              Process CR93C46 Data read polling cycle.
383 //              Refered from SD1 Richard.
384 //
385 //      Assumption:
386 //              1. Boot from E-Fuse and successfully auto-load.
387 //              2. PASSIVE_LEVEL (USB interface)
388 //
389 //      Created by Roger, 2008.10.21.
390 //
391 u16 Read93C46(struct net_device*        dev,    u16     Reg     )
392 {
393
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};
400         u8      address;
401
402         u16     storedataF[1] = {0x0};   //93c46 data packet for 16bits
403         u8      t,data[1],storedata[1];
404
405
406         address = (u8)Reg;
407
408         *EepromSEL= read_nic_byte(dev, EPROM_CMD);
409
410         if((*EepromSEL & 0x10) == 0x10) // select 93c46
411         {
412                 address = address | 0x80;
413
414                 write_nic_byte(dev, EPROM_CMD, csdi[0]);
415                 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
416                 do_93c46(dev, address);
417         }
418
419
420         for(t=0 ; t<16 ; t++)      //if read 93c46 , t=16
421         {
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);
425
426                 if(*data & 0x8d) //original code
427                 {
428                         *data = *data & 0x01;
429                         *storedata = *data;
430                 }
431                 else
432                 {
433                         *data = *data & 0x01 ;
434                         *storedata = *data;
435                 }
436                 *storedataF = (*storedataF << 1 ) + *storedata;
437         }
438         write_nic_byte(dev, EPROM_CMD, cs[0]);
439         write_nic_byte(dev, EPROM_CMD, clear[0]);
440
441         return *storedataF;
442 }
443
444
445 //
446 //      Description:
447 //              Execute E-Fuse read byte operation.
448 //              Refered from SD1 Richard.
449 //
450 //      Assumption:
451 //              1. Boot from E-Fuse and successfully auto-load.
452 //              2. PASSIVE_LEVEL (USB interface)
453 //
454 //      Created by Roger, 2008.10.21.
455 //
456 void
457 ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
458 {
459         u32  value32;
460         u8      readbyte;
461         u16     retry;
462
463         //Write Address
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));
467
468         //Write bit 32 0
469         readbyte = read_nic_byte(dev, EFUSE_CTRL+3);
470         write_nic_byte(dev, EFUSE_CTRL+3, (readbyte & 0x7f));
471
472         //Check bit 32 read-ready
473         retry = 0;
474         value32 = read_nic_dword(dev, EFUSE_CTRL);
475         while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
476         {
477                 value32 = read_nic_dword(dev, EFUSE_CTRL);
478                 retry++;
479         }
480         *pbuf = (u8)(value32 & 0xff);
481 }
482
483
484 #define         EFUSE_READ_SWITCH               1
485 //
486 //      Description:
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.
490 //
491 //      Assumption:
492 //              1. Boot from E-Fuse and successfully auto-load.
493 //              2. PASSIVE_LEVEL (USB interface)
494 //
495 //      Created by Roger, 2008.10.21.
496 //
497 void
498 ReadEFuse(struct net_device* dev, u16    _offset, u16 _size_byte, u8 *pbuf)
499 {
500
501         struct r8192_priv *priv = ieee80211_priv(dev);
502         u8      efuseTbl[EFUSE_MAP_LEN];
503         u8      rtemp8[1];
504         u16     eFuse_Addr = 0;
505         u8      offset, wren;
506         u16     i, j;
507         u16     eFuseWord[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
508         u16     efuse_utilized = 0;
509         u16     efuse_usage = 0;
510
511         if((_offset + _size_byte)>EFUSE_MAP_LEN)
512         {
513                 printk("ReadEFuse(): Invalid offset with read bytes!!\n");
514                 return;
515         }
516
517         for(i = 0; i < EFUSE_MAX_SECTION; i++)
518                 for(j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
519                         eFuseWord[i][j]=0xFFFF;
520
521 #if (EFUSE_READ_SWITCH == 1)
522         ReadEFuseByte(dev, eFuse_Addr, rtemp8);
523 #else
524         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);
525 #endif
526         if(*rtemp8 != 0xFF){
527                 efuse_utilized++;
528                 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
529                 eFuse_Addr++;
530         }
531
532         while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN))
533         {
534                 offset = ((*rtemp8 >> 4) & 0x0f);
535                 if(offset < EFUSE_MAX_SECTION)
536                 {
537                         wren = (*rtemp8 & 0x0f);
538                         RT_TRACE(COMP_EPROM, "Offset-%d Worden=%x\n", offset, wren);
539
540                         for(i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
541                         {
542                                 if(!(wren & 0x01))
543                                 {
544                                         RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
545 #if (EFUSE_READ_SWITCH == 1)
546                                         ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
547 #else
548                                         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
549 #endif
550                                         efuse_utilized++;
551                                         eFuseWord[offset][i] = (*rtemp8 & 0xff);
552                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
553                                                 break;
554
555                                         RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
556 #if (EFUSE_READ_SWITCH == 1)
557                                         ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
558 #else
559                                         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
560 #endif
561                                         efuse_utilized++;
562                                         eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
563                                         if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
564                                                 break;
565                                 }
566                                 wren >>= 1;
567                         }
568                 }
569
570                 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
571 #if (EFUSE_READ_SWITCH == 1)
572                 ReadEFuseByte(dev, eFuse_Addr, rtemp8);
573 #else
574                 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
575 #endif
576                 if(*rtemp8 != 0xFF && (eFuse_Addr < 512))
577                 {
578                         efuse_utilized++;
579                         eFuse_Addr++;
580                 }
581         }
582
583         for(i=0; i<EFUSE_MAX_SECTION; i++)
584         {
585                 for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
586                 {
587                         efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
588                         efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
589                 }
590         }
591         for(i=0; i<_size_byte; i++)
592                 pbuf[i] = efuseTbl[_offset+i];
593
594         efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN);
595         priv->EfuseUsedBytes = efuse_utilized;
596         priv->EfuseUsedPercentage = (u8)efuse_usage;
597 }
598 #endif
599
600 extern  bool
601 EFUSE_ShadowUpdateChk(struct net_device* dev)
602 {
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;
607
608         for (SectionIdx = 0; SectionIdx < 16; SectionIdx++)
609         {
610                 Base = SectionIdx * 8;
611                 bWordChanged = false;
612
613                 for (i = 0; i < 8; i=i+2)
614                 {
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]))
619                         {
620                                 WordsNeed++;
621                                 bWordChanged = true;
622                         }
623                 }
624
625                 if( bWordChanged==true )
626                         HdrNum++;
627         }
628
629         TotalBytes = HdrNum + WordsNeed*2;
630         EfuseUsed = priv->EfuseUsedBytes;
631
632         if( (TotalBytes + EfuseUsed) >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
633                 bResult = true;
634
635         RT_TRACE(COMP_EPROM, "EFUSE_ShadowUpdateChk(): TotalBytes(%x), HdrNum(%x), WordsNeed(%x), EfuseUsed(%d)\n",
636                 TotalBytes, HdrNum, WordsNeed, EfuseUsed);
637
638         return bResult;
639 }
640
641 /*-----------------------------------------------------------------------------
642  * Function:    EFUSE_ShadowRead
643  *
644  * Overview:    Read from efuse init map !!!!!
645  *
646  * Input:       NONE
647  *
648  * Output:      NONE
649  *
650  * Return:      NONE
651  *
652  * Revised History:
653  * When                 Who             Remark
654  * 11/12/2008   MHC             Create Version 0.
655  *
656  *---------------------------------------------------------------------------*/
657 extern void
658 EFUSE_ShadowRead(       struct net_device*      dev,    u8 Type, u16 Offset, u32 *Value)
659 {
660         if (Type == 1)
661                 efuse_ShadowRead1Byte(dev, Offset, (u8 *)Value);
662         else if (Type == 2)
663                 efuse_ShadowRead2Byte(dev, Offset, (u16 *)Value);
664         else if (Type == 4)
665                 efuse_ShadowRead4Byte(dev, Offset, (u32 *)Value);
666
667 }
668
669 /*-----------------------------------------------------------------------------
670  * Function:    EFUSE_ShadowWrite
671  *
672  * Overview:    Write efuse modify map for later update operation to use!!!!!
673  *
674  * Input:       NONE
675  *
676  * Output:      NONE
677  *
678  * Return:      NONE
679  *
680  * Revised History:
681  * When                 Who             Remark
682  * 11/12/2008   MHC             Create Version 0.
683  *
684  *---------------------------------------------------------------------------*/
685 extern  void
686 EFUSE_ShadowWrite(      struct net_device*      dev,    u8 Type, u16 Offset,u32 Value)
687 {
688         if (Offset >= 0x18 && Offset <= 0x1F)
689                 return;
690
691         if (Type == 1)
692                 efuse_ShadowWrite1Byte(dev, Offset, (u8)Value);
693         else if (Type == 2)
694                 efuse_ShadowWrite2Byte(dev, Offset, (u16)Value);
695         else if (Type == 4)
696                 efuse_ShadowWrite4Byte(dev, Offset, (u32)Value);
697
698 }
699
700 /*-----------------------------------------------------------------------------
701  * Function:    EFUSE_ShadowUpdate
702  *
703  * Overview:    Compare init and modify map to update Efuse!!!!!
704  *
705  * Input:       NONE
706  *
707  * Output:      NONE
708  *
709  * Return:      NONE
710  *
711  * Revised History:
712  * When                 Who             Remark
713  * 11/12/2008   MHC             Create Version 0.
714  *
715  *---------------------------------------------------------------------------*/
716 extern bool
717 EFUSE_ShadowUpdate(struct net_device* dev)
718 {
719         struct r8192_priv *priv = ieee80211_priv(dev);
720         u16                     i, offset, base = 0;
721         u8                      word_en = 0x0F;
722         bool                    first_pg = false;
723
724         RT_TRACE(COMP_EPROM, "--->EFUSE_ShadowUpdate()\n");
725
726         if(!EFUSE_ShadowUpdateChk(dev))
727         {
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);
731
732                 RT_TRACE(COMP_EPROM, "<---EFUSE_ShadowUpdate(): Efuse out of capacity!!\n");
733                 return false;
734         }
735         efuse_PowerSwitch(dev, TRUE);
736
737         //
738         // Efuse support 16 write are with PG header packet!!!!
739         //
740         for (offset = 0; offset < 16; offset++)
741         {
742                 // Offset 0x18-1F are reserved now!!!
743                 word_en = 0x0F;
744                 base = offset * 8;
745
746                 //
747                 // Decide Word Enable Bit for the Efuse section
748                 // One section contain 4 words = 8 bytes!!!!!
749                 //
750                 for (i = 0; i < 8; i++)
751                 {
752                         if (first_pg == TRUE)
753                         {
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];
760                         }else
761                         {
762                         if (    priv->EfuseMap[EFUSE_INIT_MAP][base+i] !=
763                                 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
764                         {
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);
769
770                                 // Update init table!!!
771                                 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
772                                 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
773                                 }
774                         }
775                 }
776
777                 //
778                 // Call Efuse real write section !!!!
779                 //
780                 if (word_en != 0x0F)
781                 {
782                         u8      tmpdata[8];
783
784                         memcpy((void *)tmpdata, (void *)&(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
785                         RT_TRACE(COMP_INIT, "U-EFUSE\n");
786
787                         if(!efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata))
788                         {
789                                 RT_TRACE(COMP_EPROM,"EFUSE_ShadowUpdate(): PG section(%x) fail!!\n", offset);
790                                 break;
791                         }
792                 }
793
794         }
795         // For warm reboot, we must resume Efuse clock to 500K.
796
797         efuse_PowerSwitch(dev, FALSE);
798
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);
802
803         return true;
804 }
805
806 /*-----------------------------------------------------------------------------
807  * Function:    EFUSE_ShadowMapUpdate
808  *
809  * Overview:    Transfer current EFUSE content to shadow init and modify map.
810  *
811  * Input:       NONE
812  *
813  * Output:      NONE
814  *
815  * Return:      NONE
816  *
817  * Revised History:
818  * When                 Who             Remark
819  * 11/13/2008   MHC             Create Version 0.
820  *
821  *---------------------------------------------------------------------------*/
822 extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
823 {
824         struct r8192_priv *priv = ieee80211_priv(dev);
825
826         if (priv->AutoloadFailFlag == true){
827                 memset(&(priv->EfuseMap[EFUSE_INIT_MAP][0]), 0xff, 128);
828         }else{
829                 efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
830         }
831         memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
832                 (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
833
834 }
835
836 extern  void
837 EFUSE_ForceWriteVendorId( struct net_device* dev)
838 {
839         u8 tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
840
841         efuse_PowerSwitch(dev, TRUE);
842
843         efuse_PgPacketWrite(dev, 1, 0xD, tmpdata);
844
845         efuse_PowerSwitch(dev, FALSE);
846
847 }
848
849 /*-----------------------------------------------------------------------------
850  * Function:    efuse_ShadowRead1Byte
851  *                      efuse_ShadowRead2Byte
852  *                      efuse_ShadowRead4Byte
853  *
854  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
855  *
856  * Input:       NONE
857  *
858  * Output:      NONE
859  *
860  * Return:      NONE
861  *
862  * Revised History:
863  * When                 Who             Remark
864  * 11/12/2008   MHC             Create Version 0.
865  *
866  *---------------------------------------------------------------------------*/
867 static  void
868 efuse_ShadowRead1Byte(struct net_device*        dev,    u16 Offset,     u8 *Value)
869 {
870         struct r8192_priv *priv = ieee80211_priv(dev);
871
872         *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
873
874 }
875
876 //---------------Read Two Bytes
877 static  void
878 efuse_ShadowRead2Byte(struct net_device*        dev,    u16 Offset,     u16 *Value)
879 {
880         struct r8192_priv *priv = ieee80211_priv(dev);
881
882         *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
883         *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
884
885 }
886
887 //---------------Read Four Bytes
888 static  void
889 efuse_ShadowRead4Byte(struct net_device*        dev,    u16 Offset,     u32 *Value)
890 {
891         struct r8192_priv *priv = ieee80211_priv(dev);
892
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;
897
898 }
899
900
901
902 /*-----------------------------------------------------------------------------
903  * Function:    efuse_ShadowWrite1Byte
904  *                      efuse_ShadowWrite2Byte
905  *                      efuse_ShadowWrite4Byte
906  *
907  * Overview:    Write efuse modify map by one/two/four byte.
908  *
909  * Input:       NONE
910  *
911  * Output:      NONE
912  *
913  * Return:      NONE
914  *
915  * Revised History:
916  * When                 Who             Remark
917  * 11/12/2008   MHC             Create Version 0.
918  *
919  *---------------------------------------------------------------------------*/
920 static  void
921 efuse_ShadowWrite1Byte(struct net_device*       dev,    u16 Offset,     u8 Value)
922 {
923         struct r8192_priv *priv = ieee80211_priv(dev);
924
925         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
926
927 }
928
929 //---------------Write Two Bytes
930 static  void
931 efuse_ShadowWrite2Byte(struct net_device*       dev,    u16 Offset,     u16 Value)
932 {
933         struct r8192_priv *priv = ieee80211_priv(dev);
934
935         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
936         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
937
938 }
939
940 //---------------Write Four Bytes
941 static  void
942 efuse_ShadowWrite4Byte(struct net_device*       dev,    u16 Offset,     u32 Value)
943 {
944         struct r8192_priv *priv = ieee80211_priv(dev);
945
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);
950
951 }
952
953 static  u8
954 efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
955 {
956         u8 tmpidx = 0;
957         u8 bResult;
958
959         // -----------------e-fuse reg ctrl ---------------------------------
960         //address
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 ));
964
965         write_nic_byte(dev, EFUSE_CTRL+3,  0x72);//read cmd
966
967         while(!(0x80 &read_nic_byte(dev, EFUSE_CTRL+3))&&(tmpidx<100))
968         {
969                 tmpidx++;
970         }
971         if(tmpidx<100)
972         {
973                 *data=read_nic_byte(dev, EFUSE_CTRL);
974                 bResult = TRUE;
975         }
976         else
977         {
978                 *data = 0xff;
979                 bResult = FALSE;
980         }
981         return bResult;
982 }
983
984 /*  11/16/2008 MH Write one byte to reald Efuse. */
985 static  u8
986 efuse_OneByteWrite(struct net_device* dev,  u16 addr, u8 data)
987 {
988         u8 tmpidx = 0;
989         u8 bResult;
990
991         // -----------------e-fuse reg ctrl ---------------------------------
992         //address
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) );
996
997         write_nic_byte(dev, EFUSE_CTRL, data);//data
998         write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
999
1000         while((0x80 &  read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1001                 tmpidx++;
1002         }
1003
1004         if(tmpidx<100)
1005         {
1006                 bResult = TRUE;
1007         }
1008         else
1009         {
1010                 bResult = FALSE;
1011         }
1012
1013         return bResult;
1014 }
1015
1016 /*-----------------------------------------------------------------------------
1017  * Function:    efuse_ReadAllMap
1018  *
1019  * Overview:    Read All Efuse content
1020  *
1021  * Input:       NONE
1022  *
1023  * Output:      NONE
1024  *
1025  * Return:      NONE
1026  *
1027  * Revised History:
1028  * When                 Who             Remark
1029  * 11/11/2008   MHC             Create Version 0.
1030  *
1031  *---------------------------------------------------------------------------*/
1032 static  void
1033 efuse_ReadAllMap(struct net_device*     dev, u8 *Efuse)
1034 {
1035         //
1036         // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
1037         //
1038         efuse_PowerSwitch(dev, TRUE);
1039         ReadEFuse(dev, 0, 128, Efuse);
1040         efuse_PowerSwitch(dev, FALSE);
1041 }
1042
1043 /*-----------------------------------------------------------------------------
1044  * Function:    efuse_WriteAllMap
1045  *
1046  * Overview:    Write All Efuse content
1047  *
1048  * Input:       NONE
1049  *
1050  * Output:      NONE
1051  *
1052  * Return:      NONE
1053  *
1054  * Revised History:
1055  * When                 Who             Remark
1056  * 11/11/2008   MHC             Create Version 0.
1057  *
1058  *---------------------------------------------------------------------------*/
1059 #ifdef TO_DO_LIST
1060 static  void
1061 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
1062 {
1063         unsigned char word_en = 0x00;
1064
1065         unsigned char tmpdata[8];
1066         unsigned char offset;
1067
1068         // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
1069         efuse_PowerSwitch(dev, TRUE);
1070
1071         //sdio contents
1072         for(offset=0 ; offset< eeprom_size/PGPKT_DATA_SIZE ; offset++)
1073         {
1074                 // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
1075                 if (IS_HARDWARE_TYPE_8192SE(dev))
1076                 {
1077                         // Refer to
1078                         // 0x18-1f Reserve >0x50 Reserve for tx power
1079                         if (offset == 3/* || offset > 9*/)
1080                                 continue;//word_en = 0x0F;
1081                         else
1082                                 word_en = 0x00;
1083                 }
1084
1085                 memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
1086                 efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
1087
1088
1089         }
1090
1091         // For warm reboot, we must resume Efuse clock to 500K.
1092         efuse_PowerSwitch(dev, FALSE);
1093
1094 }
1095 #endif
1096
1097 /*-----------------------------------------------------------------------------
1098  * Function:    efuse_PgPacketRead
1099  *
1100  * Overview:    Receive dedicated Efuse are content. For92s, we support 16
1101  *                              area now. It will return 8 bytes content for every area.
1102  *
1103  * Input:       NONE
1104  *
1105  * Output:      NONE
1106  *
1107  * Return:      NONE
1108  *
1109  * Revised History:
1110  * When                 Who             Remark
1111  * 11/16/2008   MHC             Reorganize code Arch and assign as local API.
1112  *
1113  *---------------------------------------------------------------------------*/
1114 static  u8
1115 efuse_PgPacketRead(     struct net_device*      dev,    u8 offset, u8   *data)
1116 {
1117         u8 ReadState = PG_STATE_HEADER;
1118
1119         bool bContinual = TRUE;
1120         bool  bDataEmpty = TRUE ;
1121
1122         u8 efuse_data,word_cnts=0;
1123         u16 efuse_addr = 0;
1124         u8 hoffset=0,hworden=0;
1125         u8 tmpidx=0;
1126         u8 tmpdata[8];
1127
1128         if(data==NULL)  return FALSE;
1129         if(offset>15)           return FALSE;
1130
1131         memset(data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1132         memset(tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1133
1134         while(bContinual && (efuse_addr  < EFUSE_MAX_SIZE) )
1135         {
1136                 //-------  Header Read -------------
1137                 if(ReadState & PG_STATE_HEADER)
1138                 {
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);
1143                                 bDataEmpty = TRUE ;
1144
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){
1150                                                                 bDataEmpty = FALSE;
1151                                                         }
1152                                                 }
1153                                         }
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;
1159                                         }
1160                                 }
1161                                 else{//read next header
1162                                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1163                                         ReadState = PG_STATE_HEADER;
1164                                 }
1165
1166                         }
1167                         else{
1168                                 bContinual = FALSE ;
1169                         }
1170                 }
1171                 //-------  Data section Read -------------
1172                 else if(ReadState & PG_STATE_DATA)
1173                 {
1174                         efuse_WordEnableDataRead(hworden,tmpdata,data);
1175                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1176                         ReadState = PG_STATE_HEADER;
1177                 }
1178
1179         }
1180
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))
1183                 return FALSE;
1184         else
1185                 return TRUE;
1186
1187 }
1188
1189 /*-----------------------------------------------------------------------------
1190  * Function:    efuse_PgPacketWrite
1191  *
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]
1195  *
1196  * Input:       NONE
1197  *
1198  * Output:      NONE
1199  *
1200  * Return:      NONE
1201  *
1202  * Revised History:
1203  * When                 Who             Remark
1204  * 11/16/2008   MHC             Reorganize code Arch and assign as local API.
1205  *
1206  *---------------------------------------------------------------------------*/
1207 static u32 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
1208 {
1209         u8 WriteState = PG_STATE_HEADER;
1210
1211         bool bContinual = TRUE,bDataEmpty=TRUE, bResult = TRUE;
1212         u16 efuse_addr = 0;
1213         u8 efuse_data;
1214
1215         u8 pg_header = 0;
1216
1217         u8 tmp_word_cnts=0,target_word_cnts=0;
1218         u8 tmp_header,match_word_en,tmp_word_en;
1219
1220         PGPKT_STRUCT target_pkt;
1221         PGPKT_STRUCT tmp_pkt;
1222
1223         u8 originaldata[sizeof(u8)*8];
1224         u8 tmpindex = 0,badworden = 0x0F;
1225
1226         static u32 repeat_times = 0;
1227
1228         if( efuse_GetCurrentSize(dev) >= EFUSE_MAX_SIZE)
1229         {
1230                 printk("efuse_PgPacketWrite error \n");
1231                 return FALSE;
1232         }
1233
1234         // Init the 8 bytes content as 0xff
1235         target_pkt.offset = offset;
1236         target_pkt.word_en= word_en;
1237
1238         //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
1239         memset(target_pkt.data,0xFF,sizeof(u8)*8);
1240
1241         efuse_WordEnableDataRead(word_en,data,target_pkt.data);
1242         target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
1243
1244         printk("EFUSE Power ON\n");
1245
1246         while( bContinual && (efuse_addr  < EFUSE_MAX_SIZE) )
1247         {
1248
1249                 if(WriteState==PG_STATE_HEADER)
1250                 {
1251                         bDataEmpty=TRUE;
1252                         badworden = 0x0F;
1253                         //************  so *******************
1254                         printk("EFUSE PG_STATE_HEADER\n");
1255                         if (    efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
1256                                 (efuse_data!=0xFF))
1257                         {
1258                                 tmp_header  =  efuse_data;
1259
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);
1263
1264                                 //************  so-1 *******************
1265                                 if(tmp_pkt.offset  != target_pkt.offset)
1266                                 {
1267                                         efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1268                                         #if (EFUSE_ERROE_HANDLE == 1)
1269                                         WriteState = PG_STATE_HEADER;
1270                                         #endif
1271                                 }
1272                                 else
1273                                 {
1274                                         //************  so-2 *******************
1275                                         for(tmpindex=0 ; tmpindex<(tmp_word_cnts*2) ; tmpindex++)
1276                                         {
1277                                                 if(efuse_OneByteRead(dev, (efuse_addr+1+tmpindex) ,&efuse_data)&&(efuse_data != 0xFF)){
1278                                                         bDataEmpty = FALSE;
1279                                                 }
1280                                         }
1281                                         //************  so-2-1 *******************
1282                                         if(bDataEmpty == FALSE)
1283                                         {
1284                                                 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1285                                                 #if (EFUSE_ERROE_HANDLE == 1)
1286                                                 WriteState=PG_STATE_HEADER;
1287                                                 #endif
1288                                         }
1289                                         else
1290                                         {//************  so-2-2 *******************
1291                                                 match_word_en = 0x0F;
1292                                                 if(   !( (target_pkt.word_en&BIT0)|(tmp_pkt.word_en&BIT0)  ))
1293                                                 {
1294                                                          match_word_en &= (~BIT0);
1295                                                 }
1296                                                 if(   !( (target_pkt.word_en&BIT1)|(tmp_pkt.word_en&BIT1)  ))
1297                                                 {
1298                                                          match_word_en &= (~BIT1);
1299                                                 }
1300                                                 if(   !( (target_pkt.word_en&BIT2)|(tmp_pkt.word_en&BIT2)  ))
1301                                                 {
1302                                                          match_word_en &= (~BIT2);
1303                                                 }
1304                                                 if(   !( (target_pkt.word_en&BIT3)|(tmp_pkt.word_en&BIT3)  ))
1305                                                 {
1306                                                          match_word_en &= (~BIT3);
1307                                                 }
1308
1309                                                 //************  so-2-2-A *******************
1310                                                 if((match_word_en&0x0F)!=0x0F)
1311                                                 {
1312                                                         badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1, tmp_pkt.word_en ,target_pkt.data);
1313
1314                                                         //************  so-2-2-A-1 *******************
1315                                                         if(0x0F != (badworden&0x0F))
1316                                                         {
1317                                                                 u8 reorg_offset = offset;
1318                                                                 u8 reorg_worden=badworden;
1319                                                                 efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1320                                                         }
1321
1322                                                         tmp_word_en = 0x0F;
1323                                                         if(  (target_pkt.word_en&BIT0)^(match_word_en&BIT0)  )
1324                                                         {
1325                                                                 tmp_word_en &= (~BIT0);
1326                                                         }
1327                                                         if(   (target_pkt.word_en&BIT1)^(match_word_en&BIT1) )
1328                                                         {
1329                                                                 tmp_word_en &=  (~BIT1);
1330                                                         }
1331                                                         if(   (target_pkt.word_en&BIT2)^(match_word_en&BIT2) )
1332                                                         {
1333                                                                 tmp_word_en &= (~BIT2);
1334                                                         }
1335                                                         if(   (target_pkt.word_en&BIT3)^(match_word_en&BIT3) )
1336                                                         {
1337                                                                 tmp_word_en &=(~BIT3);
1338                                                         }
1339
1340                                                         //************  so-2-2-A-2 *******************
1341                                                         if((tmp_word_en&0x0F)!=0x0F){
1342                                                                 //reorganize other pg packet
1343
1344                                                         efuse_addr = efuse_GetCurrentSize(dev);
1345
1346                                                         target_pkt.offset = offset;
1347                                                                 target_pkt.word_en= tmp_word_en;
1348
1349                                                 }else{
1350                                                                 bContinual = FALSE;
1351                                                         }
1352                                                         #if (EFUSE_ERROE_HANDLE == 1)
1353                                                         WriteState=PG_STATE_HEADER;
1354                                                         repeat_times++;
1355                                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1356                                                                 bContinual = FALSE;
1357                                                                 bResult = FALSE;
1358                                                         }
1359                                                         #endif
1360                                                 }
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;
1368                                                         #endif
1369                                                 }
1370                                         }
1371                                 }
1372                                 printk("EFUSE PG_STATE_HEADER-1\n");
1373                         }
1374                         else            //************  s1: header == oxff  *******************
1375                         {
1376                                 pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en;
1377
1378                                 efuse_OneByteWrite(dev,efuse_addr, pg_header);
1379                                 efuse_OneByteRead(dev,efuse_addr, &tmp_header);
1380
1381                                 if(tmp_header == pg_header)
1382                                 { //************  s1-1*******************
1383                                         WriteState = PG_STATE_DATA;
1384                                 }
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;
1389                                         repeat_times++;
1390                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1391                                                 bContinual = FALSE;
1392                                                 bResult = FALSE;
1393                                         }
1394                                 }
1395                                 #endif
1396                                 else
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);
1401
1402                                         //************  s1-2-A :cover the exist data *******************
1403                                         memset(originaldata,0xff,sizeof(u8)*8);
1404
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))
1409                                                 {
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);
1414                                                 }
1415                                                 else{
1416                                                         efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1417                                                 }
1418                                         }
1419                                          //************  s1-2-B: wrong address*******************
1420                                         else
1421                                         {
1422                                                 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1423                                         }
1424
1425                                         #if (EFUSE_ERROE_HANDLE == 1)
1426                                         WriteState=PG_STATE_HEADER;
1427                                         repeat_times++;
1428                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1429                                                 bContinual = FALSE;
1430                                                 bResult = FALSE;
1431                                         }
1432                                         #endif
1433
1434                                         printk("EFUSE PG_STATE_HEADER-2\n");
1435                                 }
1436
1437                         }
1438
1439                 }
1440                 //write data state
1441                 else if(WriteState==PG_STATE_DATA)
1442                 {       //************  s1-1  *******************
1443                         printk("EFUSE PG_STATE_DATA\n");
1444                         badworden = 0x0f;
1445                         badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,target_pkt.word_en,target_pkt.data);
1446                         if((badworden&0x0F)==0x0F)
1447                         { //************  s1-1-A *******************
1448                                 bContinual = FALSE;
1449                         }
1450                         else
1451                         {//reorganize other pg packet //************  s1-1-B *******************
1452                                 efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
1453
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;
1459                                 repeat_times++;
1460                                 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1461                                         bContinual = FALSE;
1462                                         bResult = FALSE;
1463                                 }
1464                                 #endif
1465                                 printk("EFUSE PG_STATE_HEADER-3\n");
1466                         }
1467                 }
1468         }
1469
1470         if(efuse_addr  >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
1471         {
1472                 RT_TRACE(COMP_EPROM, "efuse_PgPacketWrite(): efuse_addr(%x) Out of size!!\n", efuse_addr);
1473         }
1474         return TRUE;
1475 }
1476
1477 /*-----------------------------------------------------------------------------
1478  * Function:    efuse_WordEnableDataRead
1479  *
1480  * Overview:    Read allowed word in current efuse section data.
1481  *
1482  * Input:       NONE
1483  *
1484  * Output:      NONE
1485  *
1486  * Return:      NONE
1487  *
1488  * Revised History:
1489  * When                 Who             Remark
1490  * 11/16/2008   MHC             Create Version 0.
1491  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
1492  *
1493  *---------------------------------------------------------------------------*/
1494 static  void
1495 efuse_WordEnableDataRead(       u8 word_en,u8 *sourdata,u8 *targetdata)
1496 {
1497
1498         if (!(word_en&BIT0))
1499         {
1500                 targetdata[0] = sourdata[0];//sourdata[tmpindex++];
1501                 targetdata[1] = sourdata[1];//sourdata[tmpindex++];
1502         }
1503         if (!(word_en&BIT1))
1504         {
1505                 targetdata[2] = sourdata[2];//sourdata[tmpindex++];
1506                 targetdata[3] = sourdata[3];//sourdata[tmpindex++];
1507         }
1508         if (!(word_en&BIT2))
1509         {
1510                 targetdata[4] = sourdata[4];//sourdata[tmpindex++];
1511                 targetdata[5] = sourdata[5];//sourdata[tmpindex++];
1512         }
1513         if (!(word_en&BIT3))
1514         {
1515                 targetdata[6] = sourdata[6];//sourdata[tmpindex++];
1516                 targetdata[7] = sourdata[7];//sourdata[tmpindex++];
1517         }
1518 }
1519
1520 /*-----------------------------------------------------------------------------
1521  * Function:    efuse_WordEnableDataWrite
1522  *
1523  * Overview:    Write necessary word unit into current efuse section!
1524  *
1525  * Input:       NONE
1526  *
1527  * Output:      NONE
1528  *
1529  * Return:      NONE
1530  *
1531  * Revised History:
1532  * When                 Who             Remark
1533  * 11/16/2008   MHC             Reorganize Efuse operate flow!!.
1534  *
1535  *---------------------------------------------------------------------------*/
1536 static  u8
1537 efuse_WordEnableDataWrite(      struct net_device*      dev,    u16 efuse_addr, u8 word_en, u8 *data)
1538 {
1539         u16 tmpaddr = 0;
1540         u16 start_addr = efuse_addr;
1541         u8 badworden = 0x0F;
1542         u8 tmpdata[8];
1543
1544         memset(tmpdata,0xff,PGPKT_DATA_SIZE);
1545
1546         if(!(word_en&BIT0))
1547         {
1548                 tmpaddr = start_addr;
1549                 efuse_OneByteWrite(dev,start_addr++, data[0]);
1550                 efuse_OneByteWrite(dev,start_addr++, data[1]);
1551
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);
1556                 }
1557         }
1558         if(!(word_en&BIT1))
1559         {
1560                 tmpaddr = start_addr;
1561                 efuse_OneByteWrite(dev,start_addr++, data[2]);
1562                 efuse_OneByteWrite(dev,start_addr++, data[3]);
1563
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);
1568                 }
1569         }
1570         if(!(word_en&BIT2))
1571         {
1572                 tmpaddr = start_addr;
1573                 efuse_OneByteWrite(dev,start_addr++, data[4]);
1574                 efuse_OneByteWrite(dev,start_addr++, data[5]);
1575
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);
1580                 }
1581         }
1582         if(!(word_en&BIT3))
1583         {
1584                 tmpaddr = start_addr;
1585                 efuse_OneByteWrite(dev,start_addr++, data[6]);
1586                 efuse_OneByteWrite(dev,start_addr++, data[7]);
1587
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);
1592                 }
1593         }
1594         return badworden;
1595 }
1596
1597 /*-----------------------------------------------------------------------------
1598  * Function:    efuse_PowerSwitch
1599  *
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.
1603  *
1604  * Input:       NONE
1605  *
1606  * Output:      NONE
1607  *
1608  * Return:      NONE
1609  *
1610  * Revised History:
1611  * When                 Who             Remark
1612  * 11/17/2008   MHC             Create Version 0.
1613  *
1614  *---------------------------------------------------------------------------*/
1615 static  void
1616 efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
1617 {
1618         u8      tempval;
1619         if (PwrState == TRUE)
1620         {
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));
1624
1625                 // Change Efuse Clock for write action to 40MHZ
1626                 write_nic_byte(dev, EFUSE_CLK, 0x03);
1627         }
1628         else
1629         {
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));
1633
1634                 // Change Efuse Clock for write action to 500K
1635                 write_nic_byte(dev, EFUSE_CLK, 0x02);
1636         }
1637
1638 }
1639
1640 /*-----------------------------------------------------------------------------
1641  * Function:    efuse_GetCurrentSize
1642  *
1643  * Overview:    Get current efuse size!!!
1644  *
1645  * Input:       NONE
1646  *
1647  * Output:      NONE
1648  *
1649  * Return:      NONE
1650  *
1651  * Revised History:
1652  * When                 Who             Remark
1653  * 11/16/2008   MHC             Create Version 0.
1654  *
1655  *---------------------------------------------------------------------------*/
1656 static  u16
1657 efuse_GetCurrentSize(struct net_device* dev)
1658 {
1659         bool bContinual = TRUE;
1660
1661         u16 efuse_addr = 0;
1662         u8 hoffset=0,hworden=0;
1663         u8 efuse_data,word_cnts=0;
1664
1665         while ( bContinual &&
1666                         efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
1667                         (efuse_addr  < EFUSE_MAX_SIZE) )
1668         {
1669                 if(efuse_data!=0xFF)
1670                 {
1671                         hoffset = (efuse_data>>4) & 0x0F;
1672                         hworden =  efuse_data & 0x0F;
1673                         word_cnts = efuse_CalculateWordCnts(hworden);
1674                         //read next header
1675                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1676                 }
1677                 else
1678                 {
1679                         bContinual = FALSE ;
1680                 }
1681         }
1682
1683         return efuse_addr;
1684
1685 }
1686
1687 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
1688 static u8
1689 efuse_CalculateWordCnts(u8      word_en)
1690 {
1691         u8 word_cnts = 0;
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++;
1696         return word_cnts;
1697 }
1698
1699 /*-----------------------------------------------------------------------------
1700  * Function:    EFUSE_ProgramMap
1701  *
1702  * Overview:    Read EFUSE map file and execute PG.
1703  *
1704  * Input:       NONE
1705  *
1706  * Output:      NONE
1707  *
1708  * Return:      NONE
1709  *
1710  * Revised History:
1711  * When                 Who             Remark
1712  * 11/10/2008   MHC             Create Version 0.
1713  *
1714  *---------------------------------------------------------------------------*/
1715  #ifdef TO_DO_LIST
1716 extern  bool    // 0=Shadow 1=Real Efuse
1717 EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8     TableType)
1718 {
1719         struct r8192_priv       *priv = ieee80211_priv(dev);
1720         s4Byte                  nLinesRead, ithLine;
1721         RT_STATUS               rtStatus = RT_STATUS_SUCCESS;
1722         char*                   szLine;
1723         u32                     u4bRegValue, u4RegMask;
1724         u32                     u4bMove;
1725         u16                     index = 0;
1726         u16                     i;
1727         u8                      eeprom[HWSET_MAX_SIZE_92S];
1728
1729         rtStatus = PlatformReadFile(
1730                                         dev,
1731                                         pFileName,
1732                                         (u8*)(priv->BufOfLines),
1733                                         MAX_LINES_HWCONFIG_TXT,
1734                                         MAX_BYTES_LINE_HWCONFIG_TXT,
1735                                         &nLinesRead
1736                                         );
1737
1738         if(rtStatus == RT_STATUS_SUCCESS)
1739         {
1740                 memcp(pHalData->BufOfLines3, pHalData->BufOfLines,
1741                         nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT);
1742                 pHalData->nLinesRead3 = nLinesRead;
1743         }
1744
1745         if(rtStatus == RT_STATUS_SUCCESS)
1746         {
1747                 printk("szEepromFile(): read %s ok\n", pFileName);
1748                 for(ithLine = 0; ithLine < nLinesRead; ithLine++)
1749                 {
1750                         szLine = pHalData->BufOfLines[ithLine];
1751                         printk("Line-%d String =%s\n", ithLine, szLine);
1752
1753                         if(!IsCommentString(szLine))
1754                         {
1755                                 // EEPROM map one line has 8 words content.
1756                                 for (i = 0; i < 8; i++)
1757                                 {
1758                                         u32     j;
1759
1760                                         efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
1761
1762                                         // Get next hex value as EEPROM value.
1763                                         szLine += u4bMove;
1764                                         eeprom[index++] = (u8)(u4bRegValue&0xff);
1765                                         eeprom[index++] = (u8)((u4bRegValue>>8)&0xff);
1766
1767                                         printk("Addr-%d = %x\n", (ithLine*8+i), u4bRegValue);
1768                                 }
1769                         }
1770
1771                 }
1772
1773         }
1774         else
1775         {
1776                 printk("szEepromFile(): Fail read%s\n", pFileName);
1777                 return  RT_STATUS_FAILURE;
1778         }
1779
1780         // Use map file to update real Efuse or shadow modify table.
1781         if (TableType == 1)
1782         {
1783                 efuse_WriteAllMap(dev, eeprom, HWSET_MAX_SIZE_92S);
1784         }
1785         else
1786         {
1787                 // Modify shadow table.
1788                 for (i = 0; i < HWSET_MAX_SIZE_92S; i++)
1789                         EFUSE_ShadowWrite(dev, 1, i, (u32)eeprom[i]);
1790         }
1791
1792         return  rtStatus;
1793 }
1794
1795 #endif
1796
1797 /*-----------------------------------------------------------------------------
1798  * Function:    efuse_ParsingMap
1799  *
1800  * Overview:
1801  *
1802  * Input:       NONE
1803  *
1804  * Output:      NONE
1805  *
1806  * Return:      NONE
1807  *
1808  * Revised History:
1809  * When                 Who             Remark
1810  * 11/08/2008   MHC             Create Version 0.
1811  *
1812  *---------------------------------------------------------------------------*/
1813 #ifdef TO_DO_LIST
1814 static  bool
1815 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
1816 {
1817         char*           szScan = szStr;
1818
1819         // Check input parameter.
1820         if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
1821         {
1822                 return FALSE;
1823         }
1824
1825         // Initialize output.
1826         *pu4bMove = 0;
1827         *pu4bVal = 0;
1828
1829         // Skip leading space.
1830         while(  *szScan != '\0' &&
1831                         (*szScan == ' ' || *szScan == '\t') )
1832         {
1833                 szScan++;
1834                 (*pu4bMove)++;
1835         }
1836
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))
1840                 return FALSE;
1841
1842         // Parse each digit.
1843         do
1844         {
1845                 *pu4bVal = (*pu4bVal << 4) + hex_to_bin(*szScan);
1846
1847                 szScan++;
1848                 (*pu4bMove)++;
1849         } while (isxdigit(*szScan));
1850
1851         return TRUE;
1852
1853 }
1854 #endif
1855
1856 int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
1857 {
1858         u32 bResult;
1859         u8 tmpidx = 0;
1860         u8 tmpv8=0;
1861
1862         // -----------------e-fuse reg ctrl ---------------------------------
1863
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);
1867
1868         if(TRUE==bRead){
1869
1870                 write_nic_byte(dev, EFUSE_CTRL+3,  0x72);//read cmd
1871
1872                 while(!(0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1873                         tmpidx++;
1874                 }
1875                 if(tmpidx<100){
1876                         *data=read_nic_byte(dev, EFUSE_CTRL);
1877                         bResult = TRUE;
1878                 }
1879                 else
1880                 {
1881                         *data = 0;
1882                         bResult = FALSE;
1883                 }
1884
1885         }
1886         else{
1887                 write_nic_byte(dev, EFUSE_CTRL, *data);//data
1888
1889                 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
1890
1891                 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1892                         tmpidx++;
1893                 }
1894                 if(tmpidx<100)
1895                 {
1896                         *data=read_nic_byte(dev, EFUSE_CTRL);
1897                         bResult = TRUE;
1898                 }
1899                 else
1900                 {
1901                         *data = 0;
1902                         bResult = FALSE;
1903                 }
1904
1905         }
1906         return bResult;
1907 }
1908
1909 void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
1910 {
1911         u8      efuse_clk_ori,efuse_clk_new;//,tmp8;
1912         u32 i = 0;
1913
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;
1918
1919         if(efuse_clk_new!= efuse_clk_ori){
1920                 write_nic_byte(dev, SYS_FUNC_EN+1, efuse_clk_new);
1921         }
1922 #ifdef _POWERON_DELAY_
1923         mdelay(10);
1924 #endif
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));
1928
1929 #ifdef _PRE_EXECUTE_READ_CMD_
1930         {
1931                 unsigned char tmpdata;
1932                 efuse_OneByteRead(dev, 0,&tmpdata);
1933         }
1934 #endif
1935
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);
1939
1940         }
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);
1943
1944         // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
1945         if(efuse_clk_new != efuse_clk_ori)      write_nic_byte(dev, 0x10250003, efuse_clk_ori);
1946
1947 }
1948
1949 #ifdef TO_DO_LIST
1950 static  void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
1951 {
1952         if(TRUE==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_
1956                 mdelay(10);
1957 #endif
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_
1962                 {
1963                         unsigned char tmpdata;
1964                         efuse_OneByteRead(dev, 0,&tmpdata);
1965                 }
1966
1967 #endif
1968         }
1969         else{
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 ---------------------------------
1974
1975         }
1976
1977
1978 }
1979 #endif
1980
1981 void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
1982 {
1983         u8 offset, word_start,byte_start,byte_cnts;
1984         u8      efusedata[EFUSE_MAC_LEN];
1985         u8 *tmpdata = NULL;
1986
1987         u8 pg_pkt_cnts ;
1988
1989         u8 tmpidx;
1990         u8 pg_data[8];
1991
1992         if(efuse_read_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
1993                 return ;
1994         }
1995
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;
2000
2001         if(data_size!=byte_cnts){
2002                 return;
2003         }
2004
2005         pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2006
2007         if(pg_pkt_cnts > 1){
2008                 tmpdata = efusedata;
2009
2010                 if(tmpdata!=NULL)
2011                 {
2012                         memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
2013
2014                         for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
2015                         {
2016                                 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2017                                 if(TRUE== efuse_PgPacketRead(dev,offset+tmpidx,pg_data))
2018                                 {
2019                                         memcpy(tmpdata+(PGPKT_DATA_SIZE*tmpidx),pg_data,PGPKT_DATA_SIZE);
2020                                 }
2021                         }
2022                         memcpy(data,(tmpdata+ (2*word_start)+byte_start ),data_size);
2023                 }
2024         }
2025         else
2026         {
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);
2030                 }
2031         }
2032
2033 }
2034
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)
2037 {
2038         u8 offset, word_start,byte_start,byte_cnts;
2039         u8 word_en = 0x0f,word_cnts;
2040         u8 pg_pkt_cnts ;
2041
2042         u8 tmpidx,tmpbitmask;
2043         u8 pg_data[8],tmpbytes=0;
2044
2045         if(efuse_write_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2046                 return ;
2047         }
2048
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;
2053
2054         if(data_size >  byte_cnts){
2055                 return;
2056         }
2057         pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2058         word_cnts = byte_cnts /2 ;
2059
2060         if(byte_cnts %2){
2061                 word_cnts+=1;
2062         }
2063         if((byte_start==1)||((byte_cnts%2)==1)){//situation A
2064
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);
2068
2069                         if(efuse_write_item==EFUSE_F0CIS){
2070                                 word_en = 0x07;
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));
2073
2074                                 word_en = 0x00;
2075                                 efuse_PgPacketWrite(dev,(offset+1),word_en,data+2);
2076
2077                                 word_en = 0x00;
2078                                 efuse_PgPacketRead(dev,offset+2,pg_data);
2079                                 memcpy(pg_data,data+2+8,sizeof(u8)*7);
2080
2081                                 efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
2082                         }
2083                         else if(efuse_write_item==EFUSE_F1CIS){
2084                                 word_en = 0x07;
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));
2088
2089                                 word_en = 0x00;
2090                                 for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++){
2091                                         efuse_PgPacketWrite(dev,(offset+1+tmpidx),word_en,data+1+(tmpidx*PGPKT_DATA_SIZE));
2092                                 }
2093                         }
2094
2095                 }
2096                 else{
2097                         memset(pg_data,0xff,PGPKT_DATA_SIZE);
2098                         if((efuse_write_item==EFUSE_SDIO_SETTING)||(efuse_write_item==EFUSE_CCCR)){
2099                                 word_en = 0x0e ;
2100                                 tmpbytes = 2;
2101                         }
2102                         else if(efuse_write_item == EFUSE_SDIO_MODE){
2103                                 word_en = 0x0d ;
2104                                 tmpbytes = 2;
2105                         }
2106                         else if(efuse_write_item == EFUSE_OCR){
2107                                 word_en = 0x09 ;
2108                                 tmpbytes = 4;
2109                         }
2110                         else if((efuse_write_item == EFUSE_EEPROM_VER)||(efuse_write_item==EFUSE_CHAN_PLAN)){
2111                                 word_en = 0x07 ;
2112                                 tmpbytes = 2;
2113                         }
2114                         if(bWordUnit==TRUE){
2115                                 memcpy(pg_data+word_start*2 ,data,sizeof(u8)*tmpbytes);
2116                         }
2117                         else{
2118                                 efuse_PgPacketRead(dev,offset,pg_data);
2119                                 memcpy(pg_data+(2*word_start)+byte_start,data,sizeof(u8)*byte_cnts);
2120                         }
2121
2122                         efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2123
2124                 }
2125
2126         }
2127         else if(pg_pkt_cnts>1){//situation B
2128                 if(word_start==0){
2129                         word_en = 0x00;
2130                         for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++)
2131                         {
2132                                 efuse_PgPacketWrite(dev,(offset+tmpidx),word_en,data+(tmpidx*PGPKT_DATA_SIZE));
2133                         }
2134                         word_en = 0x0f;
2135                         for(tmpidx= 0; tmpidx<(word_cnts%4) ; tmpidx++)
2136                         {
2137                                 tmpbitmask =tmpidx;
2138                                 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2139                                 //BIT0
2140                         }
2141                         efuse_PgPacketWrite(dev,offset+(word_cnts/4),word_en,data+((word_cnts/4)*PGPKT_DATA_SIZE));
2142                 }else
2143                 {
2144
2145                 }
2146         }
2147         else{//situation C
2148                 word_en = 0x0f;
2149                 for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
2150                 {
2151                         tmpbitmask = word_start + tmpidx ;
2152                         word_en &= (~(EFUSE_BIT(tmpbitmask)));
2153                 }
2154                 efuse_PgPacketWrite(dev,offset,word_en,data);
2155         }
2156
2157 }
2158
2159 void efuset_test_func_read(struct net_device* dev)
2160 {
2161         u8 chipid[2];
2162         u8 ocr[3];
2163         u8 macaddr[6];
2164         u8 txpowertable[28];
2165
2166         memset(chipid,0,sizeof(u8)*2);
2167         efuse_read_data(dev,EFUSE_CHIP_ID,chipid,sizeof(chipid));
2168
2169         memset(ocr,0,sizeof(u8)*3);
2170         efuse_read_data(dev,EFUSE_CCCR,ocr,sizeof(ocr));
2171
2172         memset(macaddr,0,sizeof(u8)*6);
2173         efuse_read_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr));
2174
2175         memset(txpowertable,0,sizeof(u8)*28);
2176         efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
2177 }
2178
2179 void efuset_test_func_write(struct net_device* dev)
2180 {
2181         u32 bWordUnit = TRUE;
2182         u8 CCCR=0x02,SDIO_SETTING = 0xFF;
2183         u8 tmpdata[2];
2184
2185         u8 macaddr[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
2186         efuse_write_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr),bWordUnit);
2187
2188         bWordUnit = FALSE;
2189         efuse_write_data(dev,EFUSE_CCCR,&CCCR,sizeof(u8),bWordUnit);
2190
2191         bWordUnit = FALSE;
2192         efuse_write_data(dev,EFUSE_SDIO_SETTING,&SDIO_SETTING,sizeof(u8),bWordUnit);
2193
2194         bWordUnit = TRUE;
2195         tmpdata[0] =SDIO_SETTING ;
2196         tmpdata[1] =CCCR ;
2197         efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);
2198
2199 }