ALSA: asihpi: incorrect range check
[safe/jmp/linux-2.6] / drivers / staging / rtl8192su / r8192S_Efuse.c
1 /******************************************************************************
2  *
3  *     (c) Copyright  2008, RealTEK Technologies Inc. All Rights Reserved.
4  *
5  * Module:      Efuse.c ( Source C File)
6  *
7  * Note:                Copy from WMAC for the first version!!!!
8  *
9  *
10  * Function:
11  *
12  * Export:
13  *
14  * Abbrev:
15  *
16  * History:
17  * Data                 Who             Remark
18  *
19  * 09/23/2008   MHC             Porting Efuse R/W API from WMAC.
20  * 11/10/2008   MHC             1. Porting from 8712 EFUSE.
21  *                                              2. Add description and reorganize code arch.
22  * 11/16/2008   MHC             1. Reorganize code architecture.
23  *                                              2. Rename for some API and change extern or static type.
24  *
25 ******************************************************************************/
26 #include "r8192U.h"
27 #include "r8192S_hw.h"
28 #include "r8192S_phy.h"
29 #include "r8192S_phyreg.h"
30 #include "r8192S_Efuse.h"
31
32 #include <linux/types.h>
33
34 //typedef  int  INT32;
35 //
36 // In the future, we will always support EFUSE!!
37 //
38 /*---------------------------Define Local Constant---------------------------*/
39 #define         _POWERON_DELAY_
40 #define         _PRE_EXECUTE_READ_CMD_
41
42 #define         EFUSE_REPEAT_THRESHOLD_         3
43 #define         EFUSE_ERROE_HANDLE              1
44
45
46 // From 8712!!!!!
47 typedef struct _EFUSE_MAP_A{
48         u8 offset;              //0~15
49         u8 word_start;  //0~3
50         u8 byte_start;  //0 or 1
51         u8 byte_cnts;
52
53 }EFUSE_MAP, *PEFUSE_MAP;
54
55 typedef struct PG_PKT_STRUCT_A{
56         u8 offset;
57         u8 word_en;
58         u8 data[8];
59 }PGPKT_STRUCT,*PPGPKT_STRUCT;
60
61 typedef enum _EFUSE_DATA_ITEM{
62         EFUSE_CHIP_ID=0,
63         EFUSE_LDO_SETTING,
64         EFUSE_CLK_SETTING,
65         EFUSE_SDIO_SETTING,
66         EFUSE_CCCR,
67         EFUSE_SDIO_MODE,
68         EFUSE_OCR,
69         EFUSE_F0CIS,
70         EFUSE_F1CIS,
71         EFUSE_MAC_ADDR,
72         EFUSE_EEPROM_VER,
73         EFUSE_CHAN_PLAN,
74         EFUSE_TXPW_TAB
75 } EFUSE_DATA_ITEM;
76
77 struct efuse_priv
78 {
79         u8              id[2];
80         u8              ldo_setting[2];
81         u8              clk_setting[2];
82         u8              cccr;
83         u8              sdio_mode;
84         u8              ocr[3];
85         u8              cis0[17];
86         u8              cis1[48];
87         u8              mac_addr[6];
88         u8              eeprom_verno;
89         u8              channel_plan;
90         u8              tx_power_b[14];
91         u8              tx_power_g[14];
92 };
93
94 /*---------------------------Define Local Constant---------------------------*/
95
96
97 /*------------------------Define global variable-----------------------------*/
98 const u8 MAX_PGPKT_SIZE = 9; //header+ 2* 4 words (BYTES)
99 const u8 PGPKT_DATA_SIZE = 8; //BYTES sizeof(u8)*8
100 const u32 EFUSE_MAX_SIZE = 512;
101
102
103 const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE[]={
104                                 //offset        word_s  byte_start      byte_cnts
105 /*ID*/                  {0              ,0              ,0                      ,2      }, // 00~01h
106 /*LDO Setting*/ {0              ,1              ,0                      ,2      }, // 02~03h
107 /*CLK Setting*/ {0              ,2              ,0                      ,2      }, // 04~05h
108 /*SDIO Setting*/        {1              ,0              ,0                      ,1      }, // 08h
109 /*CCCR*/                {1              ,0              ,1                      ,1      }, // 09h
110 /*SDIO MODE*/   {1              ,1              ,0                      ,1      }, // 0Ah
111 /*OCR*/                 {1              ,1              ,1                      ,3      }, // 0B~0Dh
112 /*CCIS*/                        {1              ,3              ,0                      ,17     }, // 0E~1Eh  2...1
113 /*F1CIS*/               {3              ,3              ,1                      ,48     }, // 1F~4Eh  6...0
114 /*MAC Addr*/            {10             ,0              ,0                      ,6      }, // 50~55h
115 /*EEPROM ver*/  {10             ,3              ,0                      ,1      }, // 56h
116 /*Channel plan*/        {10             ,3              ,1                      ,1      }, // 57h
117 /*TxPwIndex */  {11             ,0              ,0                      ,28     }  // 58~73h  3...4
118 };
119
120 /*------------------------Define global variable-----------------------------*/
121
122
123 /*------------------------Define local variable------------------------------*/
124
125 /*------------------------Define local variable------------------------------*/
126
127
128 /*--------------------Define function prototype-----------------------*/
129 //
130 // From WMAC Efuse one byte R/W
131 //
132 extern  void
133 EFUSE_Initialize(struct net_device* dev);
134 extern  u8
135 EFUSE_Read1Byte(struct net_device* dev, u16 Address);
136 extern  void
137 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value);
138
139 //
140 // Efuse Shadow Area operation
141 //
142 static  void
143 efuse_ShadowRead1Byte(struct net_device* dev,u16 Offset,u8 *Value);
144 static  void
145 efuse_ShadowRead2Byte(struct net_device* dev,   u16 Offset,u16 *Value   );
146 static  void
147 efuse_ShadowRead4Byte(struct net_device* dev,   u16 Offset,u32 *Value   );
148 static  void
149 efuse_ShadowWrite1Byte(struct net_device* dev,  u16 Offset, u8 Value);
150 static  void
151 efuse_ShadowWrite2Byte(struct net_device* dev,  u16 Offset,u16 Value);
152 static  void
153 efuse_ShadowWrite4Byte(struct net_device* dev,  u16 Offset,u32 Value);
154
155 //
156 // Real Efuse operation
157 //
158 static  u8
159 efuse_OneByteRead(struct net_device* dev,u16 addr,u8 *data);
160 static  u8
161 efuse_OneByteWrite(struct net_device* dev,u16 addr, u8 data);
162
163 //
164 // HW setting map file operation
165 //
166 static  void
167 efuse_ReadAllMap(struct net_device* dev,u8 *Efuse);
168 #ifdef TO_DO_LIST
169 static  void
170 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom,u32 eeprom_size);
171 static  bool
172 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove);
173 #endif
174 //
175 // Reald Efuse R/W or other operation API.
176 //
177 static  u8
178 efuse_PgPacketRead(     struct net_device* dev,u8       offset,u8 *data);
179 static  u8
180 efuse_PgPacketWrite(struct net_device* dev,u8 offset,u8 word_en,u8      *data);
181 static  void
182 efuse_WordEnableDataRead(       u8 word_en,u8 *sourdata,u8 *targetdata);
183 static  u8
184 efuse_WordEnableDataWrite(      struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data);
185 static  void
186 efuse_PowerSwitch(struct net_device* dev,u8 PwrState);
187 static  u16
188 efuse_GetCurrentSize(struct net_device* dev);
189 static u8
190 efuse_CalculateWordCnts(u8 word_en);
191 //
192 // API for power on power off!!!
193 //
194 #ifdef TO_DO_LIST
195 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
196 #endif
197 /*--------------------Define function prototype-----------------------*/
198
199
200
201 /*-----------------------------------------------------------------------------
202  * Function:    EFUSE_Initialize
203  *
204  * Overview:    Copy from WMAC fot EFUSE testing setting init.
205  *
206  * Input:       NONE
207  *
208  * Output:      NONE
209  *
210  * Return:      NONE
211  *
212  * Revised History:
213  * When                 Who             Remark
214  * 09/23/2008   MHC             Copy from WMAC.
215  *
216  *---------------------------------------------------------------------------*/
217 extern  void
218 EFUSE_Initialize(struct net_device* dev)
219 {
220         u8      Bytetemp = {0x00};
221         u8      temp = {0x00};
222
223         //Enable Digital Core Vdd : 0x2[13]=1
224         Bytetemp = read_nic_byte(dev, SYS_FUNC_EN+1);
225         temp = Bytetemp | 0x20;
226         write_nic_byte(dev, SYS_FUNC_EN+1, temp);
227
228         //EE loader to retention path1: attach 0x0[8]=0
229         Bytetemp = read_nic_byte(dev, SYS_ISO_CTRL+1);
230         temp = Bytetemp & 0xFE;
231         write_nic_byte(dev, SYS_ISO_CTRL+1, temp);
232
233
234         //Enable E-fuse use 2.5V LDO : 0x37[7]=1
235         Bytetemp = read_nic_byte(dev, EFUSE_TEST+3);
236         temp = Bytetemp | 0x80;
237         write_nic_byte(dev, EFUSE_TEST+3, temp);
238
239         //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
240         write_nic_byte(dev, 0x2F8, 0x3);
241
242         //Set E-fuse program time & read time : 0x30[30:24]=1110010b
243         write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
244
245 }       /* EFUSE_Initialize */
246
247
248 /*-----------------------------------------------------------------------------
249  * Function:    EFUSE_Read1Byte
250  *
251  * Overview:    Copy from WMAC fot EFUSE read 1 byte.
252  *
253  * Input:       NONE
254  *
255  * Output:      NONE
256  *
257  * Return:      NONE
258  *
259  * Revised History:
260  * When                 Who             Remark
261  * 09/23/2008   MHC             Copy from WMAC.
262  *
263  *---------------------------------------------------------------------------*/
264 extern  u8
265 EFUSE_Read1Byte(struct net_device* dev, u16     Address)
266 {
267         u8      data;
268         u8      Bytetemp = {0x00};
269         u8      temp = {0x00};
270         u32     k=0;
271
272         if (Address < EFUSE_MAC_LEN)    //E-fuse 512Byte
273         {
274                 //Write E-fuse Register address bit0~7
275                 temp = Address & 0xFF;
276                 write_nic_byte(dev, EFUSE_CTRL+1, temp);
277                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
278                 //Write E-fuse Register address bit8~9
279                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
280                 write_nic_byte(dev, EFUSE_CTRL+2, temp);
281
282                 //Write 0x30[31]=0
283                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
284                 temp = Bytetemp & 0x7F;
285                 write_nic_byte(dev, EFUSE_CTRL+3, temp);
286
287                 //Wait Write-ready (0x30[31]=1)
288                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
289                 while(!(Bytetemp & 0x80))
290                 {
291                         Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
292                         k++;
293                         if(k==1000)
294                         {
295                                 k=0;
296                                 break;
297                         }
298                 }
299                 data=read_nic_byte(dev, EFUSE_CTRL);
300                 return data;
301         }
302         else
303                 return 0xFF;
304
305 }       /* EFUSE_Read1Byte */
306
307
308 /*-----------------------------------------------------------------------------
309  * Function:    EFUSE_Write1Byte
310  *
311  * Overview:    Copy from WMAC fot EFUSE write 1 byte.
312  *
313  * Input:       NONE
314  *
315  * Output:      NONE
316  *
317  * Return:      NONE
318  *
319  * Revised History:
320  * When                 Who             Remark
321  * 09/23/2008   MHC             Copy from WMAC.
322  *
323  *---------------------------------------------------------------------------*/
324 extern  void
325 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
326 {
327         //u8    data;
328         u8      Bytetemp = {0x00};
329         u8      temp = {0x00};
330         u32     k=0;
331
332         //RT_TRACE(COMP_EFUSE, "Addr=%x Data =%x\n", Address, Value);
333
334         if( Address < EFUSE_MAC_LEN)    //E-fuse 512Byte
335         {
336                 write_nic_byte(dev, EFUSE_CTRL, Value);
337
338                 //Write E-fuse Register address bit0~7
339                 temp = Address & 0xFF;
340                 write_nic_byte(dev, EFUSE_CTRL+1, temp);
341                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
342
343                 //Write E-fuse Register address bit8~9
344                 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
345                 write_nic_byte(dev, EFUSE_CTRL+2, temp);
346
347                 //Write 0x30[31]=1
348                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
349                 temp = Bytetemp | 0x80;
350                 write_nic_byte(dev, EFUSE_CTRL+3, temp);
351
352                 //Wait Write-ready (0x30[31]=0)
353                 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
354                 while(Bytetemp & 0x80)
355                 {
356                         Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
357                         k++;
358                         if(k==100)
359                         {
360                                 k=0;
361                                 break;
362                         }
363                 }
364         }
365
366 }       /* EFUSE_Write1Byte */
367
368
369 #ifdef EFUSE_FOR_92SU
370 //
371 //      Description:
372 //              1. Process CR93C46 Data polling cycle.
373 //              2. Refered from SD1 Richard.
374 //
375 //      Assumption:
376 //              1. Boot from E-Fuse and successfully auto-load.
377 //              2. PASSIVE_LEVEL (USB interface)
378 //
379 //      Created by Roger, 2008.10.21.
380 //
381 void do_93c46(struct net_device* dev,  u8 addorvalue)
382 {
383         //u8  clear[1] = {0x0};      // cs=0 , sk=0 , di=0 , do=0
384         u8  cs[1] = {0x88};        // cs=1 , sk=0 , di=0 , do=0
385         u8  cssk[1] = {0x8c};      // cs=1 , sk=1 , di=0 , do=0
386         u8  csdi[1] = {0x8a};      // cs=1 , sk=0 , di=1 , do=0
387         u8  csskdi[1] = {0x8e};    // cs=1 , sk=1 , di=1 , do=0
388         //u8  di[1] = {0x82};        // cs=0 , sk=0 , di=1 , do=0
389         u8  count;
390
391         for(count=0 ; count<8 ; count++)
392         {
393                 if((addorvalue&0x80)!=0)
394                 {
395                         write_nic_byte(dev, EPROM_CMD, csdi[0]);
396                         write_nic_byte(dev, EPROM_CMD, csskdi[0]);
397                 }
398                 else
399                 {
400                         write_nic_byte(dev, EPROM_CMD, cs[0]);
401                         write_nic_byte(dev, EPROM_CMD, cssk[0]);
402                 }
403                 addorvalue = addorvalue << 1;
404         }
405 }
406
407
408 //
409 //      Description:
410 //              Process CR93C46 Data read polling cycle.
411 //              Refered from SD1 Richard.
412 //
413 //      Assumption:
414 //              1. Boot from E-Fuse and successfully auto-load.
415 //              2. PASSIVE_LEVEL (USB interface)
416 //
417 //      Created by Roger, 2008.10.21.
418 //
419 u16 Read93C46(struct net_device*        dev,    u16     Reg     )
420 {
421
422         u8      clear[1] = {0x0};      // cs=0 , sk=0 , di=0 , do=0
423         u8      cs[1] = {0x88};        // cs=1 , sk=0 , di=0 , do=0
424         u8      cssk[1] = {0x8c};      // cs=1 , sk=1 , di=0 , do=0
425         u8      csdi[1] = {0x8a};      // cs=1 , sk=0 , di=1 , do=0
426         u8      csskdi[1] = {0x8e};    // cs=1 , sk=1 , di=1 , do=0
427         //u8    di[1] = {0x82};        // cs=0 , sk=0 , di=1 , do=0
428         u8      EepromSEL[1]={0x00};
429         u8      address;
430
431         u16     storedataF[1] = {0x0};   //93c46 data packet for 16bits
432         u8      t,data[1],storedata[1];
433
434
435         address = (u8)Reg;
436
437         // Suggested by SD1 Alex, 2008.10.20. Revised by Roger.
438         *EepromSEL= read_nic_byte(dev, EPROM_CMD);
439
440         if((*EepromSEL & 0x10) == 0x10) // select 93c46
441         {
442                 address = address | 0x80;
443
444                 write_nic_byte(dev, EPROM_CMD, csdi[0]);
445                 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
446                 do_93c46(dev, address);
447         }
448
449
450         for(t=0 ; t<16 ; t++)      //if read 93c46 , t=16
451         {
452                 write_nic_byte(dev, EPROM_CMD, cs[0]);
453                 write_nic_byte(dev, EPROM_CMD, cssk[0]);
454                 *data= read_nic_byte(dev, EPROM_CMD);
455
456                 if(*data & 0x8d) //original code
457                 {
458                         *data = *data & 0x01;
459                         *storedata = *data;
460                 }
461                 else
462                 {
463                         *data = *data & 0x01 ;
464                         *storedata = *data;
465                 }
466                 *storedataF = (*storedataF << 1 ) + *storedata;
467         }
468         write_nic_byte(dev, EPROM_CMD, cs[0]);
469         write_nic_byte(dev, EPROM_CMD, clear[0]);
470
471         return *storedataF;
472 }
473
474
475 //
476 //      Description:
477 //              Execute E-Fuse read byte operation.
478 //              Refered from SD1 Richard.
479 //
480 //      Assumption:
481 //              1. Boot from E-Fuse and successfully auto-load.
482 //              2. PASSIVE_LEVEL (USB interface)
483 //
484 //      Created by Roger, 2008.10.21.
485 //
486 void
487 ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
488 {
489
490         //u16   indexk=0;
491         u32  value32;
492         u8      readbyte;
493         u16     retry;
494
495
496         //Write Address
497         write_nic_byte(dev, EFUSE_CTRL+1, (_offset & 0xff));
498         readbyte = read_nic_byte(dev, EFUSE_CTRL+2);
499         write_nic_byte(dev, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
500
501         //Write bit 32 0
502         readbyte = read_nic_byte(dev, EFUSE_CTRL+3);
503         write_nic_byte(dev, EFUSE_CTRL+3, (readbyte & 0x7f));
504
505         //Check bit 32 read-ready
506         retry = 0;
507         value32 = read_nic_dword(dev, EFUSE_CTRL);
508         //while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10))
509         while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
510         {
511                 value32 = read_nic_dword(dev, EFUSE_CTRL);
512                 retry++;
513         }
514         *pbuf = (u8)(value32 & 0xff);
515 }
516
517
518 #define         EFUSE_READ_SWITCH               1
519 //
520 //      Description:
521 //              1. Execute E-Fuse read byte operation according as map offset and
522 //                  save to E-Fuse table.
523 //              2. Refered from SD1 Richard.
524 //
525 //      Assumption:
526 //              1. Boot from E-Fuse and successfully auto-load.
527 //              2. PASSIVE_LEVEL (USB interface)
528 //
529 //      Created by Roger, 2008.10.21.
530 //
531 void
532 ReadEFuse(struct net_device* dev, u16    _offset, u16 _size_byte, u8 *pbuf)
533 {
534
535         u8      efuseTbl[128];
536         u8      rtemp8[1];
537         u16     eFuse_Addr = 0;
538         u8      offset, wren;
539         u16     i, j;
540         u16     eFuseWord[16][4];// = {0xFF};//FIXLZM
541
542         for(i=0; i<16; i++)
543                 for(j=0; j<4; j++)
544                         eFuseWord[i][j]=0xFF;
545
546         // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
547         if((_offset + _size_byte)>128)
548         {// total E-Fuse table is 128bytes
549                 //RT_TRACE(COMP_EFUSE, "ReadEFuse(): Invalid offset(%#x) with read bytes(%#x)!!\n",_offset, _size_byte);
550                 printk("ReadEFuse(): Invalid offset with read bytes!!\n");
551                 return;
552         }
553
554         // Refresh efuse init map as all oxFF.
555         for (i = 0; i < 128; i++)
556                 efuseTbl[i] = 0xFF;
557
558 #if (EFUSE_READ_SWITCH == 1)
559         ReadEFuseByte(dev, eFuse_Addr, rtemp8);
560 #else
561         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);
562 #endif
563         if(*rtemp8 != 0xFF)             eFuse_Addr++;
564         while((*rtemp8 != 0xFF) && (eFuse_Addr < 512)){
565                 offset = ((*rtemp8 >> 4) & 0x0f);
566                 if(offset <= 0x0F){
567                         wren = (*rtemp8 & 0x0f);
568                         for(i=0; i<4; i++){
569                                 if(!(wren & 0x01)){
570 #if (EFUSE_READ_SWITCH == 1)
571                                         ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
572 #else
573                                         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
574 #endif
575                                         eFuseWord[offset][i] = (*rtemp8 & 0xff);
576                                         if(eFuse_Addr >= 512) break;
577 #if (EFUSE_READ_SWITCH == 1)
578                                         ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
579 #else
580                                         rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
581 #endif
582                                         eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
583                                         if(eFuse_Addr >= 512) break;
584                                 }
585                                 wren >>= 1;
586                         }
587                 }
588 #if (EFUSE_READ_SWITCH == 1)
589                 ReadEFuseByte(dev, eFuse_Addr, rtemp8);
590 #else
591                 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);   eFuse_Addr++;
592 #endif
593                 if(*rtemp8 != 0xFF && (eFuse_Addr < 512))       eFuse_Addr++;
594         }
595
596         for(i=0; i<16; i++){
597                 for(j=0; j<4; j++){
598                         efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
599                         efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
600                 }
601         }
602         for(i=0; i<_size_byte; i++)
603                 pbuf[i] = efuseTbl[_offset+i];
604 }
605 #endif  // #if (EFUSE_FOR_92SU == 1)
606
607
608 /*-----------------------------------------------------------------------------
609  * Function:    EFUSE_ShadowRead
610  *
611  * Overview:    Read from efuse init map !!!!!
612  *
613  * Input:       NONE
614  *
615  * Output:      NONE
616  *
617  * Return:      NONE
618  *
619  * Revised History:
620  * When                 Who             Remark
621  * 11/12/2008   MHC             Create Version 0.
622  *
623  *---------------------------------------------------------------------------*/
624 extern void
625 EFUSE_ShadowRead(       struct net_device*      dev,    u8 Type, u16 Offset, u32 *Value)
626 {
627         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
628
629         if (Type == 1)
630                 efuse_ShadowRead1Byte(dev, Offset, (u8 *)Value);
631         else if (Type == 2)
632                 efuse_ShadowRead2Byte(dev, Offset, (u16 *)Value);
633         else if (Type == 4)
634                 efuse_ShadowRead4Byte(dev, Offset, (u32 *)Value);
635
636 }       // EFUSE_ShadowRead
637
638
639 /*-----------------------------------------------------------------------------
640  * Function:    EFUSE_ShadowWrite
641  *
642  * Overview:    Write efuse modify map for later update operation to use!!!!!
643  *
644  * Input:       NONE
645  *
646  * Output:      NONE
647  *
648  * Return:      NONE
649  *
650  * Revised History:
651  * When                 Who             Remark
652  * 11/12/2008   MHC             Create Version 0.
653  *
654  *---------------------------------------------------------------------------*/
655 extern  void
656 EFUSE_ShadowWrite(      struct net_device*      dev,    u8 Type, u16 Offset,u32 Value)
657 {
658         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
659
660         if (Offset >= 0x18 && Offset <= 0x1F)
661                 return;
662
663         if (Type == 1)
664                 efuse_ShadowWrite1Byte(dev, Offset, (u8)Value);
665         else if (Type == 2)
666                 efuse_ShadowWrite2Byte(dev, Offset, (u16)Value);
667         else if (Type == 4)
668                 efuse_ShadowWrite4Byte(dev, Offset, (u32)Value);
669
670 }       // EFUSE_ShadowWrite
671
672
673 /*-----------------------------------------------------------------------------
674  * Function:    EFUSE_ShadowUpdate
675  *
676  * Overview:    Compare init and modify map to update Efuse!!!!!
677  *
678  * Input:       NONE
679  *
680  * Output:      NONE
681  *
682  * Return:      NONE
683  *
684  * Revised History:
685  * When                 Who             Remark
686  * 11/12/2008   MHC             Create Version 0.
687  *
688  *---------------------------------------------------------------------------*/
689 extern  void
690 EFUSE_ShadowUpdate(struct net_device* dev)
691 {
692         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
693         struct r8192_priv *priv = ieee80211_priv(dev);
694         u16                     i, offset, base = 0;
695         u8                      word_en = 0x0F;
696         bool first_pg = false;
697         // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
698         efuse_PowerSwitch(dev, TRUE);
699
700         //
701         // Efuse support 16 write are with PG header packet!!!!
702         //
703         for (offset = 0; offset < 16; offset++)
704         {
705                 // Offset 0x18-1F are reserved now!!!
706                 word_en = 0x0F;
707                 base = offset * 8;
708
709                 //
710                 // Decide Word Enable Bit for the Efuse section
711                 // One section contain 4 words = 8 bytes!!!!!
712                 //
713                 for (i = 0; i < 8; i++)
714                 {
715                         if (offset == 0 && priv->EfuseMap[EFUSE_INIT_MAP][base+i] == 0xFF)
716                         {
717                                 first_pg = TRUE;
718                         }
719
720                         // 2008/12/11 MH HW autoload fail workaround for A/BCUT.
721
722                         if (first_pg == TRUE)
723                         {
724                                 word_en &= ~(1<<(i/2));
725                                 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
726                                 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
727                         }else
728                         {
729                         if (    priv->EfuseMap[EFUSE_INIT_MAP][base+i] !=
730                                 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
731                         {
732                                 word_en &= ~(EFUSE_BIT(i/2));
733                                 //RT_TRACE(COMP_EFUSE,  "Offset=%d Addr%x %x ==> %x Word_En=%02x\n",
734                                 //offset, base+i, priv->EfuseMap[0][base+i], priv->EfuseMap[1][base+i],word_en);
735
736                                 // Update init table!!!
737                                 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
738                                 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
739                                 }
740                         }
741                 }
742
743                 //
744                 // Call Efuse real write section !!!!
745                 //
746                 if (word_en != 0x0F)
747                 {
748                         u8      tmpdata[8];
749
750                         //FIXLZM
751                         memcpy(tmpdata, &(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
752                         //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("U-EFUSE\n"), tmpdata, 8);
753                         efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata);
754                 }
755
756         }
757         // 2008/12/01 MH For Efuse HW load bug workarounf method!!!!
758         // We will force write 0x10EC into address 10&11 after all Efuse content.
759         //
760
761
762         // For warm reboot, we must resume Efuse clock to 500K.
763         efuse_PowerSwitch(dev, FALSE);
764         // 2008/12/01 MH We update shadow content again!!!!
765         EFUSE_ShadowMapUpdate(dev);
766
767 }       // EFUSE_ShadowUpdate
768
769
770 /*-----------------------------------------------------------------------------
771  * Function:    EFUSE_ShadowMapUpdate
772  *
773  * Overview:    Transfer current EFUSE content to shadow init and modify map.
774  *
775  * Input:       NONE
776  *
777  * Output:      NONE
778  *
779  * Return:      NONE
780  *
781  * Revised History:
782  * When                 Who             Remark
783  * 11/13/2008   MHC             Create Version 0.
784  *
785  *---------------------------------------------------------------------------*/
786 extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
787 {
788         struct r8192_priv *priv = ieee80211_priv(dev);
789
790         if (priv->AutoloadFailFlag == true){
791                 memset(&(priv->EfuseMap[EFUSE_INIT_MAP][0]), 0xff, 128);
792         }else{
793                 efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
794         }
795         //PlatformMoveMemory(&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
796                 //&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);//FIXLZM
797         memcpy(&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
798                 &priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
799
800 }       // EFUSE_ShadowMapUpdate
801
802 extern  void
803 EFUSE_ForceWriteVendorId( struct net_device* dev)
804 {
805         u8 tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
806
807         efuse_PowerSwitch(dev, TRUE);
808
809         efuse_PgPacketWrite(dev, 1, 0xD, tmpdata);
810
811         efuse_PowerSwitch(dev, FALSE);
812
813 }       // EFUSE_ForceWriteVendorId
814
815 /*-----------------------------------------------------------------------------
816  * Function:    efuse_ShadowRead1Byte
817  *                      efuse_ShadowRead2Byte
818  *                      efuse_ShadowRead4Byte
819  *
820  * Overview:    Read from efuse init map by one/two/four bytes !!!!!
821  *
822  * Input:       NONE
823  *
824  * Output:      NONE
825  *
826  * Return:      NONE
827  *
828  * Revised History:
829  * When                 Who             Remark
830  * 11/12/2008   MHC             Create Version 0.
831  *
832  *---------------------------------------------------------------------------*/
833 static  void
834 efuse_ShadowRead1Byte(struct net_device*        dev,    u16 Offset,     u8 *Value)
835 {
836         struct r8192_priv *priv = ieee80211_priv(dev);
837
838         *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
839
840 }       // EFUSE_ShadowRead1Byte
841
842 //---------------Read Two Bytes
843 static  void
844 efuse_ShadowRead2Byte(struct net_device*        dev,    u16 Offset,     u16 *Value)
845 {
846         struct r8192_priv *priv = ieee80211_priv(dev);
847
848         *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
849         *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
850
851 }       // EFUSE_ShadowRead2Byte
852
853 //---------------Read Four Bytes
854 static  void
855 efuse_ShadowRead4Byte(struct net_device*        dev,    u16 Offset,     u32 *Value)
856 {
857         struct r8192_priv *priv = ieee80211_priv(dev);
858
859         *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
860         *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
861         *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2]<<16;
862         *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3]<<24;
863
864 }       // efuse_ShadowRead4Byte
865
866
867
868 /*-----------------------------------------------------------------------------
869  * Function:    efuse_ShadowWrite1Byte
870  *                      efuse_ShadowWrite2Byte
871  *                      efuse_ShadowWrite4Byte
872  *
873  * Overview:    Write efuse modify map by one/two/four byte.
874  *
875  * Input:       NONE
876  *
877  * Output:      NONE
878  *
879  * Return:      NONE
880  *
881  * Revised History:
882  * When                 Who             Remark
883  * 11/12/2008   MHC             Create Version 0.
884  *
885  *---------------------------------------------------------------------------*/
886 static  void
887 efuse_ShadowWrite1Byte(struct net_device*       dev,    u16 Offset,     u8 Value)
888 {
889         struct r8192_priv *priv = ieee80211_priv(dev);
890
891         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
892
893 }       // efuse_ShadowWrite1Byte
894
895 //---------------Write Two Bytes
896 static  void
897 efuse_ShadowWrite2Byte(struct net_device*       dev,    u16 Offset,     u16 Value)
898 {
899         struct r8192_priv *priv = ieee80211_priv(dev);
900
901         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
902         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
903
904 }       // efuse_ShadowWrite1Byte
905
906 //---------------Write Four Bytes
907 static  void
908 efuse_ShadowWrite4Byte(struct net_device*       dev,    u16 Offset,     u32 Value)
909 {
910         struct r8192_priv *priv = ieee80211_priv(dev);
911
912         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = (u8)(Value&0x000000FF);
913         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = (u8)((Value>>8)&0x0000FF);
914         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2] = (u8)((Value>>16)&0x00FF);
915         priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3] = (u8)((Value>>24)&0xFF);
916
917 }       // efuse_ShadowWrite1Byte
918
919
920 /*  11/16/2008 MH Read one byte from real Efuse. */
921 static  u8
922 efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
923 {
924         u8 tmpidx = 0;
925         u8 bResult;
926
927         // -----------------e-fuse reg ctrl ---------------------------------
928         //address
929         write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
930         write_nic_byte(dev, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
931         (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC ));
932
933         write_nic_byte(dev, EFUSE_CTRL+3,  0x72);//read cmd
934
935         while(!(0x80 &read_nic_byte(dev, EFUSE_CTRL+3))&&(tmpidx<100))
936         {
937                 tmpidx++;
938         }
939         if(tmpidx<100)
940         {
941                 *data=read_nic_byte(dev, EFUSE_CTRL);
942                 bResult = TRUE;
943         }
944         else
945         {
946                 *data = 0xff;
947                 bResult = FALSE;
948         }
949         return bResult;
950 }       // efuse_OneByteRead
951
952 /*  11/16/2008 MH Write one byte to reald Efuse. */
953 static  u8
954 efuse_OneByteWrite(struct net_device* dev,  u16 addr, u8 data)
955 {
956         u8 tmpidx = 0;
957         u8 bResult;
958
959         //RT_TRACE(COMP_EFUSE, "Addr = %x Data=%x\n", addr, data);
960
961         //return        0;
962
963         // -----------------e-fuse reg ctrl ---------------------------------
964         //address
965         write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
966         write_nic_byte(dev, EFUSE_CTRL+2,
967         read_nic_byte(dev, EFUSE_CTRL+2)|(u8)((addr>>8)&0x03) );
968
969         write_nic_byte(dev, EFUSE_CTRL, data);//data
970         write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
971
972         while((0x80 &  read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
973                 tmpidx++;
974         }
975
976         if(tmpidx<100)
977         {
978                 bResult = TRUE;
979         }
980         else
981         {
982                 bResult = FALSE;
983         }
984
985         return bResult;
986 }       // efuse_OneByteWrite
987
988
989 /*-----------------------------------------------------------------------------
990  * Function:    efuse_ReadAllMap
991  *
992  * Overview:    Read All Efuse content
993  *
994  * Input:       NONE
995  *
996  * Output:      NONE
997  *
998  * Return:      NONE
999  *
1000  * Revised History:
1001  * When                 Who             Remark
1002  * 11/11/2008   MHC             Create Version 0.
1003  *
1004  *---------------------------------------------------------------------------*/
1005 static  void
1006 efuse_ReadAllMap(struct net_device*     dev, u8 *Efuse)
1007 {
1008         //u8    pg_data[8];
1009         //u8    offset = 0;
1010         //u8    tmpidx;
1011         //static        u8      index = 0;
1012
1013         //
1014         // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
1015         //
1016         efuse_PowerSwitch(dev, TRUE);
1017         ReadEFuse(dev, 0, 128, Efuse);
1018         efuse_PowerSwitch(dev, FALSE);
1019 }       // efuse_ReadAllMap
1020
1021
1022 /*-----------------------------------------------------------------------------
1023  * Function:    efuse_WriteAllMap
1024  *
1025  * Overview:    Write All Efuse content
1026  *
1027  * Input:       NONE
1028  *
1029  * Output:      NONE
1030  *
1031  * Return:      NONE
1032  *
1033  * Revised History:
1034  * When                 Who             Remark
1035  * 11/11/2008   MHC             Create Version 0.
1036  *
1037  *---------------------------------------------------------------------------*/
1038 #ifdef TO_DO_LIST
1039 static  void
1040 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
1041 {
1042         unsigned char word_en = 0x00;
1043
1044         unsigned char tmpdata[8];
1045         unsigned char offset;
1046
1047         // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
1048         efuse_PowerSwitch(dev, TRUE);
1049
1050         //sdio contents
1051         for(offset=0 ; offset< eeprom_size/PGPKT_DATA_SIZE ; offset++)
1052         {
1053                 // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
1054                 if (IS_HARDWARE_TYPE_8192SE(dev))
1055                 {
1056                         // Refer to
1057                         // 0x18-1f Reserve >0x50 Reserve for tx power
1058                         if (offset == 3/* || offset > 9*/)
1059                                 continue;//word_en = 0x0F;
1060                         //else if (offset == 9) // 0x4c-4f Reserve
1061                                 //word_en = 0x0C;
1062                         else
1063                                 word_en = 0x00;
1064                 }
1065                 //RT_TRACE(COMP_EFUSE, ("Addr=%d size=%d Word_En=%02x\n", offset, eeprom_size, word_en));
1066
1067                 //memcpy(tmpdata,eeprom+(offset*PGPKT_DATA_SIZE),8);
1068                 memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
1069
1070                 //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("EFUSE\t"), tmpdata, 8);
1071
1072                 efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
1073
1074
1075         }
1076
1077         // For warm reboot, we must resume Efuse clock to 500K.
1078         efuse_PowerSwitch(dev, FALSE);
1079
1080 }       // efuse_WriteAllMap
1081 #endif
1082
1083 /*-----------------------------------------------------------------------------
1084  * Function:    efuse_PgPacketRead
1085  *
1086  * Overview:    Receive dedicated Efuse are content. For92s, we support 16
1087  *                              area now. It will return 8 bytes content for every area.
1088  *
1089  * Input:       NONE
1090  *
1091  * Output:      NONE
1092  *
1093  * Return:      NONE
1094  *
1095  * Revised History:
1096  * When                 Who             Remark
1097  * 11/16/2008   MHC             Reorganize code Arch and assign as local API.
1098  *
1099  *---------------------------------------------------------------------------*/
1100 static  u8
1101 efuse_PgPacketRead(     struct net_device*      dev,    u8 offset, u8   *data)
1102 {
1103         u8 ReadState = PG_STATE_HEADER;
1104
1105         bool bContinual = TRUE;
1106         bool  bDataEmpty = TRUE ;
1107
1108         u8 efuse_data,word_cnts=0;
1109         u16 efuse_addr = 0;
1110         u8 hoffset=0,hworden=0;
1111         u8 tmpidx=0;
1112         u8 tmpdata[8];
1113
1114         if(data==NULL)  return FALSE;
1115         if(offset>15)           return FALSE;
1116
1117         //FIXLZM
1118         //PlatformFillMemory((PVOID)data, sizeof(u8)*PGPKT_DATA_SIZE, 0xff);
1119         //PlatformFillMemory((PVOID)tmpdata, sizeof(u8)*PGPKT_DATA_SIZE, 0xff);
1120         memset(data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1121         memset(tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1122
1123         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-1\n"), data, 8);
1124
1125         //efuse_reg_ctrl(pAdapter,TRUE);//power on
1126         while(bContinual && (efuse_addr  < EFUSE_MAX_SIZE) )
1127         {
1128                 //-------  Header Read -------------
1129                 if(ReadState & PG_STATE_HEADER)
1130                 {
1131                         if(efuse_OneByteRead(dev, efuse_addr ,&efuse_data)&&(efuse_data!=0xFF)){
1132                                 hoffset = (efuse_data>>4) & 0x0F;
1133                                 hworden =  efuse_data & 0x0F;
1134                                 word_cnts = efuse_CalculateWordCnts(hworden);
1135                                 bDataEmpty = TRUE ;
1136
1137                                 if(hoffset==offset){
1138                                         for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++){
1139                                                 if(efuse_OneByteRead(dev, efuse_addr+1+tmpidx ,&efuse_data) ){
1140                                                         tmpdata[tmpidx] = efuse_data;
1141                                                         if(efuse_data!=0xff){
1142                                                                 bDataEmpty = FALSE;
1143                                                         }
1144                                                 }
1145                                         }
1146                                         if(bDataEmpty==FALSE){
1147                                                 ReadState = PG_STATE_DATA;
1148                                         }else{//read next header
1149                                                 efuse_addr = efuse_addr + (word_cnts*2)+1;
1150                                                 ReadState = PG_STATE_HEADER;
1151                                         }
1152                                 }
1153                                 else{//read next header
1154                                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1155                                         ReadState = PG_STATE_HEADER;
1156                                 }
1157
1158                         }
1159                         else{
1160                                 bContinual = FALSE ;
1161                         }
1162                 }
1163                 //-------  Data section Read -------------
1164                 else if(ReadState & PG_STATE_DATA)
1165                 {
1166                         efuse_WordEnableDataRead(hworden,tmpdata,data);
1167                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1168                         ReadState = PG_STATE_HEADER;
1169                 }
1170
1171         }
1172         //efuse_reg_ctrl(pAdapter,FALSE);//power off
1173
1174         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-2\n"), data, 8);
1175
1176         if(     (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff)  && (data[3]==0xff) &&
1177                 (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff)  && (data[7]==0xff))
1178                 return FALSE;
1179         else
1180                 return TRUE;
1181
1182 }       // efuse_PgPacketRead
1183
1184
1185 /*-----------------------------------------------------------------------------
1186  * Function:    efuse_PgPacketWrite
1187  *
1188  * Overview:    Send A G package for different section in real efuse area.
1189  *                              For 92S, One PG package contain 8 bytes content and 4 word
1190  *                              unit. PG header = 0x[bit7-4=offset][bit3-0word enable]
1191  *
1192  * Input:       NONE
1193  *
1194  * Output:      NONE
1195  *
1196  * Return:      NONE
1197  *
1198  * Revised History:
1199  * When                 Who             Remark
1200  * 11/16/2008   MHC             Reorganize code Arch and assign as local API.
1201  *
1202  *---------------------------------------------------------------------------*/
1203 static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
1204 {
1205         u8 WriteState = PG_STATE_HEADER;
1206
1207         bool bContinual = TRUE,bDataEmpty=TRUE, bResult = TRUE;
1208         u16 efuse_addr = 0;
1209         u8 efuse_data;
1210
1211         u8 pg_header = 0;
1212
1213         //u16 tmp_addr=0;
1214         u8 tmp_word_cnts=0,target_word_cnts=0;
1215         u8 tmp_header,match_word_en,tmp_word_en;
1216
1217         //u8    efuse_clk_ori,efuse_clk_new;
1218
1219         PGPKT_STRUCT target_pkt;
1220         PGPKT_STRUCT tmp_pkt;
1221
1222         u8 originaldata[sizeof(u8)*8];
1223         u8 tmpindex = 0,badworden = 0x0F;
1224
1225         static u32 repeat_times = 0;
1226
1227         if( efuse_GetCurrentSize(dev) >= EFUSE_MAX_SIZE)
1228         {
1229                 printk("efuse_PgPacketWrite error \n");
1230                 return FALSE;
1231         }
1232
1233         // Init the 8 bytes content as 0xff
1234         target_pkt.offset = offset;
1235         target_pkt.word_en= word_en;
1236
1237         //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
1238         memset(target_pkt.data,0xFF,sizeof(u8)*8);
1239
1240         efuse_WordEnableDataRead(word_en,data,target_pkt.data);
1241         target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
1242
1243         //efuse_reg_ctrl(pAdapter,TRUE);//power on
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                                                         //############################
1316                                                         if(0x0F != (badworden&0x0F))
1317                                                         {
1318                                                                 u8 reorg_offset = offset;
1319                                                                 u8 reorg_worden=badworden;
1320                                                                 efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1321                                                         }
1322                                                         //############################
1323
1324                                                         tmp_word_en = 0x0F;
1325                                                         if(  (target_pkt.word_en&BIT0)^(match_word_en&BIT0)  )
1326                                                         {
1327                                                                 tmp_word_en &= (~BIT0);
1328                                                         }
1329                                                         if(   (target_pkt.word_en&BIT1)^(match_word_en&BIT1) )
1330                                                         {
1331                                                                 tmp_word_en &=  (~BIT1);
1332                                                         }
1333                                                         if(   (target_pkt.word_en&BIT2)^(match_word_en&BIT2) )
1334                                                         {
1335                                                                 tmp_word_en &= (~BIT2);
1336                                                         }
1337                                                         if(   (target_pkt.word_en&BIT3)^(match_word_en&BIT3) )
1338                                                         {
1339                                                                 tmp_word_en &=(~BIT3);
1340                                                         }
1341
1342                                                         //************  so-2-2-A-2 *******************
1343                                                         if((tmp_word_en&0x0F)!=0x0F){
1344                                                                 //reorganize other pg packet
1345                                                                 //efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
1346                                                                 efuse_addr = efuse_GetCurrentSize(dev);
1347                                                                 //===========================
1348                                                                 target_pkt.offset = offset;
1349                                                                 target_pkt.word_en= tmp_word_en;
1350                                                                 //===========================
1351                                                         }else{
1352                                                                 bContinual = FALSE;
1353                                                         }
1354                                                         #if (EFUSE_ERROE_HANDLE == 1)
1355                                                         WriteState=PG_STATE_HEADER;
1356                                                         repeat_times++;
1357                                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1358                                                                 bContinual = FALSE;
1359                                                                 bResult = FALSE;
1360                                                         }
1361                                                         #endif
1362                                                 }
1363                                                 else{//************  so-2-2-B *******************
1364                                                         //reorganize other pg packet
1365                                                         efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
1366                                                         //===========================
1367                                                         target_pkt.offset = offset;
1368                                                         target_pkt.word_en= target_pkt.word_en;
1369                                                         //===========================
1370                                                         #if (EFUSE_ERROE_HANDLE == 1)
1371                                                         WriteState=PG_STATE_HEADER;
1372                                                         #endif
1373                                                 }
1374                                         }
1375                                 }
1376                                 printk("EFUSE PG_STATE_HEADER-1\n");
1377                         }
1378                         else            //************  s1: header == oxff  *******************
1379                         {
1380                                 pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en;
1381
1382                                 efuse_OneByteWrite(dev,efuse_addr, pg_header);
1383                                 efuse_OneByteRead(dev,efuse_addr, &tmp_header);
1384
1385                                 if(tmp_header == pg_header)
1386                                 { //************  s1-1*******************
1387                                         WriteState = PG_STATE_DATA;
1388                                 }
1389                                 #if (EFUSE_ERROE_HANDLE == 1)
1390                                 else if(tmp_header == 0xFF){//************  s1-3: if Write or read func doesn't work *******************
1391                                         //efuse_addr doesn't change
1392                                         WriteState = PG_STATE_HEADER;
1393                                         repeat_times++;
1394                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1395                                                 bContinual = FALSE;
1396                                                 bResult = FALSE;
1397                                         }
1398                                 }
1399                                 #endif
1400                                 else
1401                                 {//************  s1-2 : fixed the header procedure *******************
1402                                         tmp_pkt.offset = (tmp_header>>4) & 0x0F;
1403                                         tmp_pkt.word_en=  tmp_header & 0x0F;
1404                                         tmp_word_cnts =  efuse_CalculateWordCnts(tmp_pkt.word_en);
1405
1406                                         //************  s1-2-A :cover the exist data *******************
1407                                         memset(originaldata,0xff,sizeof(u8)*8);
1408                                         //PlatformFillMemory((PVOID)originaldata, sizeof(u8)*8, 0xff);
1409
1410                                         if(efuse_PgPacketRead( dev, tmp_pkt.offset,originaldata))
1411                                         {       //check if data exist
1412                                                 //efuse_reg_ctrl(pAdapter,TRUE);//power on
1413                                                 badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,tmp_pkt.word_en,originaldata);
1414                                                 //############################
1415                                                 if(0x0F != (badworden&0x0F))
1416                                                 {
1417                                                         u8 reorg_offset = tmp_pkt.offset;
1418                                                         u8 reorg_worden=badworden;
1419                                                         efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1420                                                         efuse_addr = efuse_GetCurrentSize(dev);
1421                                                 }
1422                                                 //############################
1423                                                 else{
1424                                                         efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1425                                                 }
1426                                         }
1427                                          //************  s1-2-B: wrong address*******************
1428                                         else
1429                                         {
1430                                                 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1431                                         }
1432
1433                                         #if (EFUSE_ERROE_HANDLE == 1)
1434                                         WriteState=PG_STATE_HEADER;
1435                                         repeat_times++;
1436                                         if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1437                                                 bContinual = FALSE;
1438                                                 bResult = FALSE;
1439                                         }
1440                                         #endif
1441
1442                                         printk("EFUSE PG_STATE_HEADER-2\n");
1443                                 }
1444
1445                         }
1446
1447                 }
1448                 //write data state
1449                 else if(WriteState==PG_STATE_DATA)
1450                 {       //************  s1-1  *******************
1451                         printk("EFUSE PG_STATE_DATA\n");
1452                         badworden = 0x0f;
1453                         badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,target_pkt.word_en,target_pkt.data);
1454                         if((badworden&0x0F)==0x0F)
1455                         { //************  s1-1-A *******************
1456                                 bContinual = FALSE;
1457                         }
1458                         else
1459                         {//reorganize other pg packet //************  s1-1-B *******************
1460                                 efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
1461
1462                                 //===========================
1463                                 target_pkt.offset = offset;
1464                                 target_pkt.word_en= badworden;
1465                                 target_word_cnts =  efuse_CalculateWordCnts(target_pkt.word_en);
1466                                 //===========================
1467                                 #if (EFUSE_ERROE_HANDLE == 1)
1468                                 WriteState=PG_STATE_HEADER;
1469                                 repeat_times++;
1470                                 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1471                                         bContinual = FALSE;
1472                                         bResult = FALSE;
1473                                 }
1474                                 #endif
1475                                 printk("EFUSE PG_STATE_HEADER-3\n");
1476                         }
1477                 }
1478         }
1479
1480         //efuse_reg_ctrl(pAdapter,FALSE);//power off
1481
1482         return TRUE;
1483 }       // efuse_PgPacketWrite
1484
1485
1486 /*-----------------------------------------------------------------------------
1487  * Function:    efuse_WordEnableDataRead
1488  *
1489  * Overview:    Read allowed word in current efuse section data.
1490  *
1491  * Input:       NONE
1492  *
1493  * Output:      NONE
1494  *
1495  * Return:      NONE
1496  *
1497  * Revised History:
1498  * When                 Who             Remark
1499  * 11/16/2008   MHC             Create Version 0.
1500  * 11/21/2008   MHC             Fix Write bug when we only enable late word.
1501  *
1502  *---------------------------------------------------------------------------*/
1503 static  void
1504 efuse_WordEnableDataRead(       u8 word_en,u8 *sourdata,u8 *targetdata)
1505 {
1506         //u8 tmpindex = 0;
1507
1508         //DbgPrint("efuse_WordEnableDataRead word_en = %x\n", word_en);
1509
1510         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("sourdata\n"), sourdata, 8);
1511         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("targetdata\n"), targetdata, 8);
1512
1513         if (!(word_en&BIT0))
1514         {
1515                 targetdata[0] = sourdata[0];//sourdata[tmpindex++];
1516                 targetdata[1] = sourdata[1];//sourdata[tmpindex++];
1517         }
1518         if (!(word_en&BIT1))
1519         {
1520                 targetdata[2] = sourdata[2];//sourdata[tmpindex++];
1521                 targetdata[3] = sourdata[3];//sourdata[tmpindex++];
1522         }
1523         if (!(word_en&BIT2))
1524         {
1525                 targetdata[4] = sourdata[4];//sourdata[tmpindex++];
1526                 targetdata[5] = sourdata[5];//sourdata[tmpindex++];
1527         }
1528         if (!(word_en&BIT3))
1529         {
1530                 targetdata[6] = sourdata[6];//sourdata[tmpindex++];
1531                 targetdata[7] = sourdata[7];//sourdata[tmpindex++];
1532         }
1533 }       // efuse_WordEnableDataRead
1534
1535
1536 /*-----------------------------------------------------------------------------
1537  * Function:    efuse_WordEnableDataWrite
1538  *
1539  * Overview:    Write necessary word unit into current efuse section!
1540  *
1541  * Input:       NONE
1542  *
1543  * Output:      NONE
1544  *
1545  * Return:      NONE
1546  *
1547  * Revised History:
1548  * When                 Who             Remark
1549  * 11/16/2008   MHC             Reorganize Efuse operate flow!!.
1550  *
1551  *---------------------------------------------------------------------------*/
1552 static  u8
1553 efuse_WordEnableDataWrite(      struct net_device*      dev,    u16 efuse_addr, u8 word_en, u8 *data)
1554 {
1555         u16 tmpaddr = 0;
1556         u16 start_addr = efuse_addr;
1557         u8 badworden = 0x0F;
1558         //u8 NextState;
1559         u8 tmpdata[8];
1560
1561         memset(tmpdata,0xff,PGPKT_DATA_SIZE);
1562         //PlatformFillMemory((PVOID)tmpdata, PGPKT_DATA_SIZE, 0xff);
1563
1564         //RT_TRACE(COMP_EFUSE, "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
1565
1566         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("U-EFUSE\n"), data, 8);
1567
1568         if(!(word_en&BIT0))
1569         {
1570                 tmpaddr = start_addr;
1571                 efuse_OneByteWrite(dev,start_addr++, data[0]);
1572                 efuse_OneByteWrite(dev,start_addr++, data[1]);
1573
1574                 efuse_OneByteRead(dev,tmpaddr, &tmpdata[0]);
1575                 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[1]);
1576                 if((data[0]!=tmpdata[0])||(data[1]!=tmpdata[1])){
1577                         badworden &= (~BIT0);
1578                 }
1579         }
1580         if(!(word_en&BIT1))
1581         {
1582                 tmpaddr = start_addr;
1583                 efuse_OneByteWrite(dev,start_addr++, data[2]);
1584                 efuse_OneByteWrite(dev,start_addr++, data[3]);
1585
1586                 efuse_OneByteRead(dev,tmpaddr    , &tmpdata[2]);
1587                 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[3]);
1588                 if((data[2]!=tmpdata[2])||(data[3]!=tmpdata[3])){
1589                         badworden &=( ~BIT1);
1590                 }
1591         }
1592         if(!(word_en&BIT2))
1593         {
1594                 tmpaddr = start_addr;
1595                 efuse_OneByteWrite(dev,start_addr++, data[4]);
1596                 efuse_OneByteWrite(dev,start_addr++, data[5]);
1597
1598                 efuse_OneByteRead(dev,tmpaddr, &tmpdata[4]);
1599                 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[5]);
1600                 if((data[4]!=tmpdata[4])||(data[5]!=tmpdata[5])){
1601                         badworden &=( ~BIT2);
1602                 }
1603         }
1604         if(!(word_en&BIT3))
1605         {
1606                 tmpaddr = start_addr;
1607                 efuse_OneByteWrite(dev,start_addr++, data[6]);
1608                 efuse_OneByteWrite(dev,start_addr++, data[7]);
1609
1610                 efuse_OneByteRead(dev,tmpaddr, &tmpdata[6]);
1611                 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[7]);
1612                 if((data[6]!=tmpdata[6])||(data[7]!=tmpdata[7])){
1613                         badworden &=( ~BIT3);
1614                 }
1615         }
1616         return badworden;
1617 }       // efuse_WordEnableDataWrite
1618
1619
1620 /*-----------------------------------------------------------------------------
1621  * Function:    efuse_PowerSwitch
1622  *
1623  * Overview:    When we want to enable write operation, we should change to
1624  *                              pwr on state. When we stop write, we should switch to 500k mode
1625  *                              and disable LDO 2.5V.
1626  *
1627  * Input:       NONE
1628  *
1629  * Output:      NONE
1630  *
1631  * Return:      NONE
1632  *
1633  * Revised History:
1634  * When                 Who             Remark
1635  * 11/17/2008   MHC             Create Version 0.
1636  *
1637  *---------------------------------------------------------------------------*/
1638 static  void
1639 efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
1640 {
1641         u8      tempval;
1642         if (PwrState == TRUE)
1643         {
1644                 // Enable LDO 2.5V for write action
1645                 tempval = read_nic_byte(dev, EFUSE_TEST+3);
1646                 write_nic_byte(dev, EFUSE_TEST+3, (tempval | 0x80));
1647
1648                 // Change Efuse Clock for write action to 40MHZ
1649                 write_nic_byte(dev, EFUSE_CLK, 0x03);
1650         }
1651         else
1652         {
1653                 // Enable LDO 2.5V for write action
1654                 tempval = read_nic_byte(dev, EFUSE_TEST+3);
1655                 write_nic_byte(dev, EFUSE_TEST+3, (tempval & 0x7F));
1656
1657                 // Change Efuse Clock for write action to 500K
1658                 write_nic_byte(dev, EFUSE_CLK, 0x02);
1659         }
1660
1661 }       /* efuse_PowerSwitch */
1662
1663
1664 /*-----------------------------------------------------------------------------
1665  * Function:    efuse_GetCurrentSize
1666  *
1667  * Overview:    Get current efuse size!!!
1668  *
1669  * Input:       NONE
1670  *
1671  * Output:      NONE
1672  *
1673  * Return:      NONE
1674  *
1675  * Revised History:
1676  * When                 Who             Remark
1677  * 11/16/2008   MHC             Create Version 0.
1678  *
1679  *---------------------------------------------------------------------------*/
1680 static  u16
1681 efuse_GetCurrentSize(struct net_device* dev)
1682 {
1683         bool bContinual = TRUE;
1684
1685         u16 efuse_addr = 0;
1686         u8 hoffset=0,hworden=0;
1687         u8 efuse_data,word_cnts=0;
1688
1689         //efuse_reg_ctrl(pAdapter,TRUE);//power on
1690
1691         while ( bContinual &&
1692                         efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
1693                         (efuse_addr  < EFUSE_MAX_SIZE) )
1694         {
1695                 if(efuse_data!=0xFF)
1696                 {
1697                         hoffset = (efuse_data>>4) & 0x0F;
1698                         hworden =  efuse_data & 0x0F;
1699                         word_cnts = efuse_CalculateWordCnts(hworden);
1700                         //read next header
1701                         efuse_addr = efuse_addr + (word_cnts*2)+1;
1702                 }
1703                 else
1704                 {
1705                         bContinual = FALSE ;
1706                 }
1707         }
1708
1709         //efuse_reg_ctrl(pAdapter,FALSE);//power off
1710
1711         return efuse_addr;
1712
1713 }       // efuse_GetCurrentSize}
1714
1715
1716 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
1717 static u8
1718 efuse_CalculateWordCnts(u8      word_en)
1719 {
1720         u8 word_cnts = 0;
1721         if(!(word_en & BIT0))   word_cnts++; // 0 : write enable
1722         if(!(word_en & BIT1))   word_cnts++;
1723         if(!(word_en & BIT2))   word_cnts++;
1724         if(!(word_en & BIT3))   word_cnts++;
1725         return word_cnts;
1726 }       // efuse_CalculateWordCnts
1727
1728 /*-----------------------------------------------------------------------------
1729  * Function:    EFUSE_ProgramMap
1730  *
1731  * Overview:    Read EFUSE map file and execute PG.
1732  *
1733  * Input:       NONE
1734  *
1735  * Output:      NONE
1736  *
1737  * Return:      NONE
1738  *
1739  * Revised History:
1740  * When                 Who             Remark
1741  * 11/10/2008   MHC             Create Version 0.
1742  *
1743  *---------------------------------------------------------------------------*/
1744  #ifdef TO_DO_LIST
1745 extern  bool    // 0=Shadow 1=Real Efuse
1746 EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8     TableType)
1747 {
1748         struct r8192_priv       *priv = ieee80211_priv(dev);
1749         s4Byte                  nLinesRead, ithLine;
1750         RT_STATUS               rtStatus = RT_STATUS_SUCCESS;
1751         char*                   szLine;
1752         u32                     u4bRegValue, u4RegMask;
1753         u32                     u4bMove;
1754         u16                     index = 0;
1755         u16                     i;
1756         u8                      eeprom[HWSET_MAX_SIZE_92S];
1757
1758         rtStatus = PlatformReadFile(
1759                                         dev,
1760                                         pFileName,
1761                                         (u8*)(priv->BufOfLines),
1762                                         MAX_LINES_HWCONFIG_TXT,
1763                                         MAX_BYTES_LINE_HWCONFIG_TXT,
1764                                         &nLinesRead
1765                                         );
1766
1767         if(rtStatus == RT_STATUS_SUCCESS)
1768         {
1769                 memcp(pHalData->BufOfLines3, pHalData->BufOfLines,
1770                         nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT);
1771                 pHalData->nLinesRead3 = nLinesRead;
1772         }
1773
1774         if(rtStatus == RT_STATUS_SUCCESS)
1775         {
1776                 printk("szEepromFile(): read %s ok\n", pFileName);
1777                 for(ithLine = 0; ithLine < nLinesRead; ithLine++)
1778                 {
1779                         szLine = pHalData->BufOfLines[ithLine];
1780                         printk("Line-%d String =%s\n", ithLine, szLine);
1781
1782                         if(!IsCommentString(szLine))
1783                         {
1784                                 // EEPROM map one line has 8 words content.
1785                                 for (i = 0; i < 8; i++)
1786                                 {
1787                                         u32     j;
1788
1789                                         //GetHexValueFromString(szLine, &u4bRegValue, &u4bMove);
1790                                         efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
1791
1792                                         // Get next hex value as EEPROM value.
1793                                         szLine += u4bMove;
1794                                         //WriteEEprom(dev, (u16)(ithLine*8+i), (u16)u4bRegValue);
1795                                         eeprom[index++] = (u8)(u4bRegValue&0xff);
1796                                         eeprom[index++] = (u8)((u4bRegValue>>8)&0xff);
1797
1798                                         printk("Addr-%d = %x\n", (ithLine*8+i), u4bRegValue);
1799                                 }
1800                         }
1801
1802                 }
1803
1804         }
1805         else
1806         {
1807                 printk("szEepromFile(): Fail read%s\n", pFileName);
1808                 return  RT_STATUS_FAILURE;
1809         }
1810
1811
1812         //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("EFUSE "), eeprom, HWSET_MAX_SIZE_92S);
1813
1814         // Use map file to update real Efuse or shadow modify table.
1815         if (TableType == 1)
1816         {
1817                 efuse_WriteAllMap(dev, eeprom, HWSET_MAX_SIZE_92S);
1818         }
1819         else
1820         {
1821                 // Modify shadow table.
1822                 for (i = 0; i < HWSET_MAX_SIZE_92S; i++)
1823                         EFUSE_ShadowWrite(dev, 1, i, (u32)eeprom[i]);
1824         }
1825
1826         return  rtStatus;
1827 }       /* EFUSE_ProgramMap */
1828
1829 #endif
1830
1831 //
1832 //      Description:
1833 //              Return TRUE if chTmp is represent for hex digit and
1834 //              FALSE otherwise.
1835 //
1836 //
1837 bool IsHexDigit(        char chTmp)
1838 {
1839         if( (chTmp >= '0' && chTmp <= '9') ||
1840                 (chTmp >= 'a' && chTmp <= 'f') ||
1841                 (chTmp >= 'A' && chTmp <= 'F') )
1842         {
1843                 return TRUE;
1844         }
1845         else
1846         {
1847                 return FALSE;
1848         }
1849 }
1850
1851 //
1852 //      Description:
1853 //              Translate a character to hex digit.
1854 //
1855 u32 MapCharToHexDigit(char chTmp)
1856 {
1857         if(chTmp >= '0' && chTmp <= '9')
1858                 return (chTmp - '0');
1859         else if(chTmp >= 'a' && chTmp <= 'f')
1860                 return (10 + (chTmp - 'a'));
1861         else if(chTmp >= 'A' && chTmp <= 'F')
1862                 return (10 + (chTmp - 'A'));
1863         else
1864                 return 0;
1865 }
1866
1867 /*-----------------------------------------------------------------------------
1868  * Function:    efuse_ParsingMap
1869  *
1870  * Overview:
1871  *
1872  * Input:       NONE
1873  *
1874  * Output:      NONE
1875  *
1876  * Return:      NONE
1877  *
1878  * Revised History:
1879  * When                 Who             Remark
1880  * 11/08/2008   MHC             Create Version 0.
1881  *
1882  *---------------------------------------------------------------------------*/
1883 #ifdef TO_DO_LIST
1884 static  bool
1885 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
1886 {
1887         char*           szScan = szStr;
1888
1889         // Check input parameter.
1890         if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
1891         {
1892                 //RT_TRACE(COMP_EFUSE,
1893                 //"eeprom_ParsingMap(): Invalid IN args! szStr: %p, pu4bVal: %p, pu4bMove: %p\n",
1894                 //szStr, pu4bVal, pu4bMove);
1895                 return FALSE;
1896         }
1897
1898         // Initialize output.
1899         *pu4bMove = 0;
1900         *pu4bVal = 0;
1901
1902         // Skip leading space.
1903         while(  *szScan != '\0' &&
1904                         (*szScan == ' ' || *szScan == '\t') )
1905         {
1906                 szScan++;
1907                 (*pu4bMove)++;
1908         }
1909
1910         // Check if szScan is now pointer to a character for hex digit,
1911         // if not, it means this is not a valid hex number.
1912         if(!IsHexDigit(*szScan))
1913         {
1914                 return FALSE;
1915         }
1916
1917         // Parse each digit.
1918         do
1919         {
1920                 (*pu4bVal) <<= 4;
1921                 *pu4bVal += MapCharToHexDigit(*szScan);
1922
1923                 szScan++;
1924                 (*pu4bMove)++;
1925         } while(IsHexDigit(*szScan));
1926
1927         return TRUE;
1928
1929 }       /* efuse_ParsingMap */
1930 #endif
1931
1932 //
1933 // Useless Section Code Now!!!!!!
1934 //
1935 // Porting from 8712 SDIO
1936 int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
1937 {
1938         u32 bResult;
1939         //u8 efuse_ctlreg,tmpidx = 0;
1940         u8 tmpidx = 0;
1941         u8 tmpv8=0;
1942
1943         // -----------------e-fuse reg ctrl ---------------------------------
1944
1945         write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));             //address
1946         tmpv8 = ((u8)((addr>>8) &0x03) ) | (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC );
1947         write_nic_byte(dev, EFUSE_CTRL+2, tmpv8);
1948
1949         if(TRUE==bRead){
1950
1951                 write_nic_byte(dev, EFUSE_CTRL+3,  0x72);//read cmd
1952
1953                 while(!(0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1954                         tmpidx++;
1955                 }
1956                 if(tmpidx<100){
1957                         *data=read_nic_byte(dev, EFUSE_CTRL);
1958                         bResult = TRUE;
1959                 }
1960                 else
1961                 {
1962                         *data = 0;
1963                         bResult = FALSE;
1964                 }
1965
1966         }
1967         else{
1968                 //return        0;
1969                 write_nic_byte(dev, EFUSE_CTRL, *data);//data
1970
1971                 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
1972
1973                 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1974                         tmpidx++;
1975                 }
1976                 if(tmpidx<100)
1977                 {
1978                         *data=read_nic_byte(dev, EFUSE_CTRL);
1979                         bResult = TRUE;
1980                 }
1981                 else
1982                 {
1983                         *data = 0;
1984                         bResult = FALSE;
1985                 }
1986
1987         }
1988         return bResult;
1989 }
1990 //------------------------------------------------------------------------------
1991 void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
1992 {
1993         u8      efuse_clk_ori,efuse_clk_new;//,tmp8;
1994         u32 i = 0;
1995
1996         if(start_addr>0x200) return;
1997         //RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,
1998         //      ("\n ===> efuse_access [start_addr=0x%x cnts:%d dataarray:0x%08x  Query Efuse].\n",start_addr,cnts,data));
1999         // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
2000         efuse_clk_ori = read_nic_byte(dev,SYS_FUNC_EN+1);
2001         efuse_clk_new = efuse_clk_ori|0x20;
2002
2003         if(efuse_clk_new!= efuse_clk_ori){
2004                 //RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
2005                 write_nic_byte(dev, SYS_FUNC_EN+1, efuse_clk_new);
2006         }
2007 #ifdef _POWERON_DELAY_
2008         mdelay(10);
2009 #endif
2010         // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
2011         write_nic_byte(dev, EFUSE_TEST+3, (read_nic_byte(dev, EFUSE_TEST+3)|0x80));
2012         write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
2013
2014 #ifdef _PRE_EXECUTE_READ_CMD_
2015         {
2016                 unsigned char tmpdata;
2017                 efuse_OneByteRead(dev, 0,&tmpdata);
2018         }
2019 #endif
2020
2021         //-----------------e-fuse one byte read / write ------------------------------
2022         for(i=0;i<cnts;i++){
2023                 efuse_one_byte_rw(dev,bRead, start_addr+i , data+i);
2024                 ////RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("==>efuse_access addr:0x%02x value:0x%02x\n",data+i,*(data+i)));
2025         }
2026         // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
2027         write_nic_byte(dev, EFUSE_TEST+3, read_nic_byte(dev, EFUSE_TEST+3)&0x7f);
2028         write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
2029
2030         // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
2031         if(efuse_clk_new != efuse_clk_ori)      write_nic_byte(dev, 0x10250003, efuse_clk_ori);
2032
2033 }
2034 //------------------------------------------------------------------------------
2035 //------------------------------------------------------------------------------
2036
2037 #ifdef TO_DO_LIST
2038 static  void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
2039 {
2040         if(TRUE==bPowerOn){
2041                 // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
2042                 write_nic_byte(dev, SYS_FUNC_EN+1,  read_nic_byte(dev,SYS_FUNC_EN+1)|0x20);
2043 #ifdef _POWERON_DELAY_
2044                 mdelay(10);
2045 #endif
2046                 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
2047                 write_nic_byte(dev, EFUSE_TEST+4, (read_nic_byte(dev, EFUSE_TEST+4)|0x80));
2048                 write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
2049 #ifdef _PRE_EXECUTE_READ_CMD_
2050                 {
2051                         unsigned char tmpdata;
2052                         efuse_OneByteRead(dev, 0,&tmpdata);
2053                 }
2054
2055 #endif
2056         }
2057         else{
2058                 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
2059                 write_nic_byte(dev, EFUSE_TEST+4, read_nic_byte(dev, EFUSE_TEST+4)&0x7f);
2060                 write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
2061                 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
2062
2063                 //write_nic_byte(pAdapter, SYS_FUNC_EN+1,  read_nic_byte(pAdapter,SYS_FUNC_EN+1)&0xDF);
2064         }
2065
2066
2067 }
2068 #endif
2069 //------------------------------------------------------------------------------
2070
2071 //------------------------------------------------------------------------------
2072 void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
2073 {
2074         u8 offset, word_start,byte_start,byte_cnts;
2075         u8      efusedata[EFUSE_MAC_LEN];
2076         u8 *tmpdata = NULL;
2077
2078         u8 pg_pkt_cnts ;
2079
2080         u8 tmpidx;
2081         u8 pg_data[8];
2082         //u8    temp_value[8] = {0xff};
2083
2084         if(efuse_read_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2085                 //error msg
2086                 return ;
2087         }
2088
2089         offset          = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].offset ;
2090         word_start      = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].word_start;
2091         byte_start      = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_start;
2092         byte_cnts       = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_cnts;
2093
2094         if(data_size!=byte_cnts){
2095                 //error msg
2096                 return;
2097         }
2098
2099         pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2100
2101         if(pg_pkt_cnts > 1){
2102                 //tmpdata = _malloc(pg_pkt_cnts*PGPKT_DATA_SIZE);
2103                 tmpdata = efusedata;
2104
2105                 if(tmpdata!=NULL)
2106                 {
2107                         memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
2108                         //PlatformFillMemory((PVOID)pg_data, pg_pkt_cnts*PGPKT_DATA_SIZE, 0xff);
2109
2110                         for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
2111                         {
2112                                 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2113                                 //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
2114                                 if(TRUE== efuse_PgPacketRead(dev,offset+tmpidx,pg_data))
2115                                 {
2116                                         memcpy(tmpdata+(PGPKT_DATA_SIZE*tmpidx),pg_data,PGPKT_DATA_SIZE);
2117                                         //PlatformMoveMemory((PVOID)(tmpdata+(PGPKT_DATA_SIZE*tmpidx)), (PVOID)pg_data, PGPKT_DATA_SIZE);
2118                                 }
2119                         }
2120                         memcpy(data,(tmpdata+ (2*word_start)+byte_start ),data_size);
2121                         //PlatformMoveMemory((PVOID)data, (PVOID)(tmpdata+ (2*word_start)+byte_start ), data_size);
2122                         //_mfree(tmpdata, pg_pkt_cnts*PGPKT_DATA_SIZE);
2123                 }
2124         }
2125         else
2126         {
2127                 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2128                 //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
2129                 if(TRUE==efuse_PgPacketRead(dev,offset,pg_data)){
2130                         memcpy(data,pg_data+ (2*word_start)+byte_start ,data_size);
2131                         //PlatformMoveMemory((PVOID)data, (PVOID)(pg_data+ (2*word_start)+byte_start), data_size);
2132                 }
2133         }
2134
2135 }
2136 //------------------------------------------------------------------------------
2137 //per interface doesn't alike
2138 void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 data_size,u32 bWordUnit)
2139 {
2140         u8 offset, word_start,byte_start,byte_cnts;
2141         u8 word_en = 0x0f,word_cnts;
2142         u8 pg_pkt_cnts ;
2143
2144         u8 tmpidx,tmpbitmask;
2145         u8 pg_data[8],tmpbytes=0;
2146
2147         if(efuse_write_item>  (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2148                 //error msg
2149                 return ;
2150         }
2151
2152         offset          = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].offset ;
2153         word_start      = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].word_start;
2154         byte_start      = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_start;
2155         byte_cnts       = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_cnts;
2156
2157         if(data_size >  byte_cnts){
2158                 //error msg
2159                 return;
2160         }
2161         pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2162         word_cnts = byte_cnts /2 ;
2163
2164         if(byte_cnts %2){
2165                 word_cnts+=1;
2166         }
2167         if((byte_start==1)||((byte_cnts%2)==1)){//situation A
2168
2169                 if((efuse_write_item==EFUSE_F0CIS)||(efuse_write_item==EFUSE_F1CIS)){
2170                         memset(pg_data,0xff,PGPKT_DATA_SIZE);
2171                         //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
2172                         efuse_PgPacketRead(dev,offset,pg_data);
2173
2174                         if(efuse_write_item==EFUSE_F0CIS){
2175                                 word_en = 0x07;
2176                                 memcpy(pg_data+word_start*2+byte_start,data,sizeof(u8)*2);
2177                                 //PlatformMoveMemory((PVOID)(pg_data+word_start*2+byte_start), (PVOID)data, sizeof(u8)*2);
2178                                 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2179
2180                                 word_en = 0x00;
2181                                 efuse_PgPacketWrite(dev,(offset+1),word_en,data+2);
2182
2183                                 word_en = 0x00;
2184                                 efuse_PgPacketRead(dev,offset+2,pg_data);
2185                                 memcpy(pg_data,data+2+8,sizeof(u8)*7);
2186                                 //PlatformMoveMemory((PVOID)(pg_data), (PVOID)(data+2+8), sizeof(u8)*7);
2187
2188                                 efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
2189                         }
2190                         else if(efuse_write_item==EFUSE_F1CIS){
2191                                 word_en = 0x07;
2192                                 efuse_PgPacketRead(dev,offset,pg_data);
2193                                 pg_data[7] = data[0];
2194                                 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2195
2196                                 word_en = 0x00;
2197                                 for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++){
2198                                         efuse_PgPacketWrite(dev,(offset+1+tmpidx),word_en,data+1+(tmpidx*PGPKT_DATA_SIZE));
2199                                 }
2200                         }
2201
2202                 }
2203                 else{
2204                         memset(pg_data,0xff,PGPKT_DATA_SIZE);
2205                         //PlatformFillMemory((PVOID)pg_data, PGPKT_DATA_SIZE, 0xff);
2206                         if((efuse_write_item==EFUSE_SDIO_SETTING)||(efuse_write_item==EFUSE_CCCR)){
2207                                 word_en = 0x0e ;
2208                                 tmpbytes = 2;
2209                         }
2210                         else if(efuse_write_item == EFUSE_SDIO_MODE){
2211                                 word_en = 0x0d ;
2212                                 tmpbytes = 2;
2213                         }
2214                         else if(efuse_write_item == EFUSE_OCR){
2215                                 word_en = 0x09 ;
2216                                 tmpbytes = 4;
2217                         }
2218                         else if((efuse_write_item == EFUSE_EEPROM_VER)||(efuse_write_item==EFUSE_CHAN_PLAN)){
2219                                 word_en = 0x07 ;
2220                                 tmpbytes = 2;
2221                         }
2222                         if(bWordUnit==TRUE){
2223                                 memcpy(pg_data+word_start*2 ,data,sizeof(u8)*tmpbytes);
2224                                 //PlatformMoveMemory((PVOID)(pg_data+word_start*2), (PVOID)(data), sizeof(u8)*tmpbytes);
2225                         }
2226                         else{
2227                                 efuse_PgPacketRead(dev,offset,pg_data);
2228                                 memcpy(pg_data+(2*word_start)+byte_start,data,sizeof(u8)*byte_cnts);
2229                                 //PlatformMoveMemory((PVOID)(pg_data+(2*word_start)+byte_start), (PVOID)(data), sizeof(u8)*byte_cnts);
2230                         }
2231
2232                         efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2233
2234                 }
2235
2236         }
2237         //========================================================================
2238         else if(pg_pkt_cnts>1){//situation B
2239                 if(word_start==0){
2240                         word_en = 0x00;
2241                         for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++)
2242                         {
2243                                 efuse_PgPacketWrite(dev,(offset+tmpidx),word_en,data+(tmpidx*PGPKT_DATA_SIZE));
2244                         }
2245                         word_en = 0x0f;
2246                         for(tmpidx= 0; tmpidx<(word_cnts%4) ; tmpidx++)
2247                         {
2248                                 tmpbitmask =tmpidx;
2249                                 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2250                                 //BIT0
2251                         }
2252                         efuse_PgPacketWrite(dev,offset+(word_cnts/4),word_en,data+((word_cnts/4)*PGPKT_DATA_SIZE));
2253                 }else
2254                 {
2255
2256                 }
2257         }
2258         //========================================================================
2259         else{//situation C
2260                 word_en = 0x0f;
2261                 for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
2262                 {
2263                         tmpbitmask = word_start + tmpidx ;
2264                         word_en &= (~(EFUSE_BIT(tmpbitmask)));
2265                 }
2266                 efuse_PgPacketWrite(dev,offset,word_en,data);
2267         }
2268
2269 }
2270 //------------------------------------------------------------------------------
2271
2272 void efuset_test_func_read(struct net_device* dev)
2273 {
2274         u8 chipid[2];
2275         u8 ocr[3];
2276         u8 macaddr[6];
2277         u8 txpowertable[28];
2278
2279         memset(chipid,0,sizeof(u8)*2);
2280         efuse_read_data(dev,EFUSE_CHIP_ID,chipid,sizeof(chipid));
2281
2282         memset(ocr,0,sizeof(u8)*3);
2283         efuse_read_data(dev,EFUSE_CCCR,ocr,sizeof(ocr));
2284
2285         memset(macaddr,0,sizeof(u8)*6);
2286         efuse_read_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr));
2287
2288         memset(txpowertable,0,sizeof(u8)*28);
2289         efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
2290 }
2291 //------------------------------------------------------------------------------
2292
2293 void efuset_test_func_write(struct net_device* dev)
2294 {
2295         u32 bWordUnit = TRUE;
2296         u8 CCCR=0x02,SDIO_SETTING = 0xFF;
2297         u8 tmpdata[2];
2298
2299         u8 macaddr[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
2300         efuse_write_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr),bWordUnit);
2301
2302         bWordUnit = FALSE;
2303         efuse_write_data(dev,EFUSE_CCCR,&CCCR,sizeof(u8),bWordUnit);
2304
2305         bWordUnit = FALSE;
2306         efuse_write_data(dev,EFUSE_SDIO_SETTING,&SDIO_SETTING,sizeof(u8),bWordUnit);
2307
2308         bWordUnit = TRUE;
2309         tmpdata[0] =SDIO_SETTING ;
2310         tmpdata[1] =CCCR ;
2311         efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);
2312
2313 }
2314 //------------------------------------------------------------------------------
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325 /* End of Efuse.c */
2326
2327
2328
2329