First Support on Ginger and OMAP TI
[linux-ginger.git] / drivers / staging / rtl8192su / r8192S_Efuse.c
blobf0ce6562c23bc376519246aa17cf34750c9adca0
1 /******************************************************************************
3 * (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
5 * Module: Efuse.c ( Source C File)
7 * Note: Copy from WMAC for the first version!!!!
10 * Function:
12 * Export:
14 * Abbrev:
16 * History:
17 * Data Who Remark
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.
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"
32 #include <linux/types.h>
34 //typedef int INT32;
36 // In the future, we will always support EFUSE!!
38 /*---------------------------Define Local Constant---------------------------*/
39 #define _POWERON_DELAY_
40 #define _PRE_EXECUTE_READ_CMD_
42 #define EFUSE_REPEAT_THRESHOLD_ 3
43 #define EFUSE_ERROE_HANDLE 1
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;
53 }EFUSE_MAP, *PEFUSE_MAP;
55 typedef struct PG_PKT_STRUCT_A{
56 u8 offset;
57 u8 word_en;
58 u8 data[8];
59 }PGPKT_STRUCT,*PPGPKT_STRUCT;
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;
77 struct efuse_priv
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];
94 /*---------------------------Define Local Constant---------------------------*/
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;
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
120 /*------------------------Define global variable-----------------------------*/
123 /*------------------------Define local variable------------------------------*/
125 /*------------------------Define local variable------------------------------*/
128 /*--------------------Define function prototype-----------------------*/
130 // From WMAC Efuse one byte R/W
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);
140 // Efuse Shadow Area operation
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);
156 // Real Efuse operation
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);
164 // HW setting map file operation
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
175 // Reald Efuse R/W or other operation API.
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);
192 // API for power on power off!!!
194 #ifdef TO_DO_LIST
195 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
196 #endif
197 /*--------------------Define function prototype-----------------------*/
201 /*-----------------------------------------------------------------------------
202 * Function: EFUSE_Initialize
204 * Overview: Copy from WMAC fot EFUSE testing setting init.
206 * Input: NONE
208 * Output: NONE
210 * Return: NONE
212 * Revised History:
213 * When Who Remark
214 * 09/23/2008 MHC Copy from WMAC.
216 *---------------------------------------------------------------------------*/
217 extern void
218 EFUSE_Initialize(struct net_device* dev)
220 u8 Bytetemp = {0x00};
221 u8 temp = {0x00};
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);
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);
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);
239 //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
240 write_nic_byte(dev, 0x2F8, 0x3);
242 //Set E-fuse program time & read time : 0x30[30:24]=1110010b
243 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
245 } /* EFUSE_Initialize */
248 /*-----------------------------------------------------------------------------
249 * Function: EFUSE_Read1Byte
251 * Overview: Copy from WMAC fot EFUSE read 1 byte.
253 * Input: NONE
255 * Output: NONE
257 * Return: NONE
259 * Revised History:
260 * When Who Remark
261 * 09/23/2008 MHC Copy from WMAC.
263 *---------------------------------------------------------------------------*/
264 extern u8
265 EFUSE_Read1Byte(struct net_device* dev, u16 Address)
267 u8 data;
268 u8 Bytetemp = {0x00};
269 u8 temp = {0x00};
270 u32 k=0;
272 if (Address < EFUSE_MAC_LEN) //E-fuse 512Byte
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);
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);
287 //Wait Write-ready (0x30[31]=1)
288 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
289 while(!(Bytetemp & 0x80))
291 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
292 k++;
293 if(k==1000)
295 k=0;
296 break;
299 data=read_nic_byte(dev, EFUSE_CTRL);
300 return data;
302 else
303 return 0xFF;
305 } /* EFUSE_Read1Byte */
308 /*-----------------------------------------------------------------------------
309 * Function: EFUSE_Write1Byte
311 * Overview: Copy from WMAC fot EFUSE write 1 byte.
313 * Input: NONE
315 * Output: NONE
317 * Return: NONE
319 * Revised History:
320 * When Who Remark
321 * 09/23/2008 MHC Copy from WMAC.
323 *---------------------------------------------------------------------------*/
324 extern void
325 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
327 //u8 data;
328 u8 Bytetemp = {0x00};
329 u8 temp = {0x00};
330 u32 k=0;
332 //RT_TRACE(COMP_EFUSE, "Addr=%x Data =%x\n", Address, Value);
334 if( Address < EFUSE_MAC_LEN) //E-fuse 512Byte
336 write_nic_byte(dev, EFUSE_CTRL, Value);
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);
343 //Write E-fuse Register address bit8~9
344 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
345 write_nic_byte(dev, EFUSE_CTRL+2, temp);
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);
352 //Wait Write-ready (0x30[31]=0)
353 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
354 while(Bytetemp & 0x80)
356 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
357 k++;
358 if(k==100)
360 k=0;
361 break;
366 } /* EFUSE_Write1Byte */
369 #ifdef EFUSE_FOR_92SU
371 // Description:
372 // 1. Process CR93C46 Data polling cycle.
373 // 2. Refered from SD1 Richard.
375 // Assumption:
376 // 1. Boot from E-Fuse and successfully auto-load.
377 // 2. PASSIVE_LEVEL (USB interface)
379 // Created by Roger, 2008.10.21.
381 void do_93c46(struct net_device* dev, u8 addorvalue)
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;
391 for(count=0 ; count<8 ; count++)
393 if((addorvalue&0x80)!=0)
395 write_nic_byte(dev, EPROM_CMD, csdi[0]);
396 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
398 else
400 write_nic_byte(dev, EPROM_CMD, cs[0]);
401 write_nic_byte(dev, EPROM_CMD, cssk[0]);
403 addorvalue = addorvalue << 1;
409 // Description:
410 // Process CR93C46 Data read polling cycle.
411 // Refered from SD1 Richard.
413 // Assumption:
414 // 1. Boot from E-Fuse and successfully auto-load.
415 // 2. PASSIVE_LEVEL (USB interface)
417 // Created by Roger, 2008.10.21.
419 u16 Read93C46(struct net_device* dev, u16 Reg )
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;
431 u16 storedataF[1] = {0x0}; //93c46 data packet for 16bits
432 u8 t,data[1],storedata[1];
435 address = (u8)Reg;
437 // Suggested by SD1 Alex, 2008.10.20. Revised by Roger.
438 *EepromSEL= read_nic_byte(dev, EPROM_CMD);
440 if((*EepromSEL & 0x10) == 0x10) // select 93c46
442 address = address | 0x80;
444 write_nic_byte(dev, EPROM_CMD, csdi[0]);
445 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
446 do_93c46(dev, address);
450 for(t=0 ; t<16 ; t++) //if read 93c46 , t=16
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);
456 if(*data & 0x8d) //original code
458 *data = *data & 0x01;
459 *storedata = *data;
461 else
463 *data = *data & 0x01 ;
464 *storedata = *data;
466 *storedataF = (*storedataF << 1 ) + *storedata;
468 write_nic_byte(dev, EPROM_CMD, cs[0]);
469 write_nic_byte(dev, EPROM_CMD, clear[0]);
471 return *storedataF;
476 // Description:
477 // Execute E-Fuse read byte operation.
478 // Refered from SD1 Richard.
480 // Assumption:
481 // 1. Boot from E-Fuse and successfully auto-load.
482 // 2. PASSIVE_LEVEL (USB interface)
484 // Created by Roger, 2008.10.21.
486 void
487 ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
490 //u16 indexk=0;
491 u32 value32;
492 u8 readbyte;
493 u16 retry;
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));
501 //Write bit 32 0
502 readbyte = read_nic_byte(dev, EFUSE_CTRL+3);
503 write_nic_byte(dev, EFUSE_CTRL+3, (readbyte & 0x7f));
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))
511 value32 = read_nic_dword(dev, EFUSE_CTRL);
512 retry++;
514 *pbuf = (u8)(value32 & 0xff);
518 #define EFUSE_READ_SWITCH 1
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.
525 // Assumption:
526 // 1. Boot from E-Fuse and successfully auto-load.
527 // 2. PASSIVE_LEVEL (USB interface)
529 // Created by Roger, 2008.10.21.
531 void
532 ReadEFuse(struct net_device* dev, u16 _offset, u16 _size_byte, u8 *pbuf)
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
542 for(i=0; i<16; i++)
543 for(j=0; j<4; j++)
544 eFuseWord[i][j]=0xFF;
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;
554 // Refresh efuse init map as all oxFF.
555 for (i = 0; i < 128; i++)
556 efuseTbl[i] = 0xFF;
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;
585 wren >>= 1;
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++;
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);
602 for(i=0; i<_size_byte; i++)
603 pbuf[i] = efuseTbl[_offset+i];
605 #endif // #if (EFUSE_FOR_92SU == 1)
608 /*-----------------------------------------------------------------------------
609 * Function: EFUSE_ShadowRead
611 * Overview: Read from efuse init map !!!!!
613 * Input: NONE
615 * Output: NONE
617 * Return: NONE
619 * Revised History:
620 * When Who Remark
621 * 11/12/2008 MHC Create Version 0.
623 *---------------------------------------------------------------------------*/
624 extern void
625 EFUSE_ShadowRead( struct net_device* dev, u8 Type, u16 Offset, u32 *Value)
627 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
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);
636 } // EFUSE_ShadowRead
639 /*-----------------------------------------------------------------------------
640 * Function: EFUSE_ShadowWrite
642 * Overview: Write efuse modify map for later update operation to use!!!!!
644 * Input: NONE
646 * Output: NONE
648 * Return: NONE
650 * Revised History:
651 * When Who Remark
652 * 11/12/2008 MHC Create Version 0.
654 *---------------------------------------------------------------------------*/
655 extern void
656 EFUSE_ShadowWrite( struct net_device* dev, u8 Type, u16 Offset,u32 Value)
658 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
660 if (Offset >= 0x18 && Offset <= 0x1F)
661 return;
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);
670 } // EFUSE_ShadowWrite
673 /*-----------------------------------------------------------------------------
674 * Function: EFUSE_ShadowUpdate
676 * Overview: Compare init and modify map to update Efuse!!!!!
678 * Input: NONE
680 * Output: NONE
682 * Return: NONE
684 * Revised History:
685 * When Who Remark
686 * 11/12/2008 MHC Create Version 0.
688 *---------------------------------------------------------------------------*/
689 extern void
690 EFUSE_ShadowUpdate(struct net_device* dev)
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);
701 // Efuse support 16 write are with PG header packet!!!!
703 for (offset = 0; offset < 16; offset++)
705 // Offset 0x18-1F are reserved now!!!
706 word_en = 0x0F;
707 base = offset * 8;
710 // Decide Word Enable Bit for the Efuse section
711 // One section contain 4 words = 8 bytes!!!!!
713 for (i = 0; i < 8; i++)
715 if (offset == 0 && priv->EfuseMap[EFUSE_INIT_MAP][base+i] == 0xFF)
717 first_pg = TRUE;
720 // 2008/12/11 MH HW autoload fail workaround for A/BCUT.
722 if (first_pg == TRUE)
724 word_en &= ~(1<<(i/2));
725 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
726 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
727 }else
729 if ( priv->EfuseMap[EFUSE_INIT_MAP][base+i] !=
730 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
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);
736 // Update init table!!!
737 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
738 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
744 // Call Efuse real write section !!!!
746 if (word_en != 0x0F)
748 u8 tmpdata[8];
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);
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.
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);
767 } // EFUSE_ShadowUpdate
770 /*-----------------------------------------------------------------------------
771 * Function: EFUSE_ShadowMapUpdate
773 * Overview: Transfer current EFUSE content to shadow init and modify map.
775 * Input: NONE
777 * Output: NONE
779 * Return: NONE
781 * Revised History:
782 * When Who Remark
783 * 11/13/2008 MHC Create Version 0.
785 *---------------------------------------------------------------------------*/
786 extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
788 struct r8192_priv *priv = ieee80211_priv(dev);
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]);
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);
800 } // EFUSE_ShadowMapUpdate
802 extern void
803 EFUSE_ForceWriteVendorId( struct net_device* dev)
805 u8 tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
807 efuse_PowerSwitch(dev, TRUE);
809 efuse_PgPacketWrite(dev, 1, 0xD, tmpdata);
811 efuse_PowerSwitch(dev, FALSE);
813 } // EFUSE_ForceWriteVendorId
815 /*-----------------------------------------------------------------------------
816 * Function: efuse_ShadowRead1Byte
817 * efuse_ShadowRead2Byte
818 * efuse_ShadowRead4Byte
820 * Overview: Read from efuse init map by one/two/four bytes !!!!!
822 * Input: NONE
824 * Output: NONE
826 * Return: NONE
828 * Revised History:
829 * When Who Remark
830 * 11/12/2008 MHC Create Version 0.
832 *---------------------------------------------------------------------------*/
833 static void
834 efuse_ShadowRead1Byte(struct net_device* dev, u16 Offset, u8 *Value)
836 struct r8192_priv *priv = ieee80211_priv(dev);
838 *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
840 } // EFUSE_ShadowRead1Byte
842 //---------------Read Two Bytes
843 static void
844 efuse_ShadowRead2Byte(struct net_device* dev, u16 Offset, u16 *Value)
846 struct r8192_priv *priv = ieee80211_priv(dev);
848 *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
849 *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
851 } // EFUSE_ShadowRead2Byte
853 //---------------Read Four Bytes
854 static void
855 efuse_ShadowRead4Byte(struct net_device* dev, u16 Offset, u32 *Value)
857 struct r8192_priv *priv = ieee80211_priv(dev);
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;
864 } // efuse_ShadowRead4Byte
868 /*-----------------------------------------------------------------------------
869 * Function: efuse_ShadowWrite1Byte
870 * efuse_ShadowWrite2Byte
871 * efuse_ShadowWrite4Byte
873 * Overview: Write efuse modify map by one/two/four byte.
875 * Input: NONE
877 * Output: NONE
879 * Return: NONE
881 * Revised History:
882 * When Who Remark
883 * 11/12/2008 MHC Create Version 0.
885 *---------------------------------------------------------------------------*/
886 static void
887 efuse_ShadowWrite1Byte(struct net_device* dev, u16 Offset, u8 Value)
889 struct r8192_priv *priv = ieee80211_priv(dev);
891 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
893 } // efuse_ShadowWrite1Byte
895 //---------------Write Two Bytes
896 static void
897 efuse_ShadowWrite2Byte(struct net_device* dev, u16 Offset, u16 Value)
899 struct r8192_priv *priv = ieee80211_priv(dev);
901 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
902 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
904 } // efuse_ShadowWrite1Byte
906 //---------------Write Four Bytes
907 static void
908 efuse_ShadowWrite4Byte(struct net_device* dev, u16 Offset, u32 Value)
910 struct r8192_priv *priv = ieee80211_priv(dev);
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);
917 } // efuse_ShadowWrite1Byte
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)
924 u8 tmpidx = 0;
925 u8 bResult;
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 ));
933 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
935 while(!(0x80 &read_nic_byte(dev, EFUSE_CTRL+3))&&(tmpidx<100))
937 tmpidx++;
939 if(tmpidx<100)
941 *data=read_nic_byte(dev, EFUSE_CTRL);
942 bResult = TRUE;
944 else
946 *data = 0xff;
947 bResult = FALSE;
949 return bResult;
950 } // efuse_OneByteRead
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)
956 u8 tmpidx = 0;
957 u8 bResult;
959 //RT_TRACE(COMP_EFUSE, "Addr = %x Data=%x\n", addr, data);
961 //return 0;
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) );
969 write_nic_byte(dev, EFUSE_CTRL, data);//data
970 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
972 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
973 tmpidx++;
976 if(tmpidx<100)
978 bResult = TRUE;
980 else
982 bResult = FALSE;
985 return bResult;
986 } // efuse_OneByteWrite
989 /*-----------------------------------------------------------------------------
990 * Function: efuse_ReadAllMap
992 * Overview: Read All Efuse content
994 * Input: NONE
996 * Output: NONE
998 * Return: NONE
1000 * Revised History:
1001 * When Who Remark
1002 * 11/11/2008 MHC Create Version 0.
1004 *---------------------------------------------------------------------------*/
1005 static void
1006 efuse_ReadAllMap(struct net_device* dev, u8 *Efuse)
1008 //u8 pg_data[8];
1009 //u8 offset = 0;
1010 //u8 tmpidx;
1011 //static u8 index = 0;
1014 // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
1016 efuse_PowerSwitch(dev, TRUE);
1017 ReadEFuse(dev, 0, 128, Efuse);
1018 efuse_PowerSwitch(dev, FALSE);
1019 } // efuse_ReadAllMap
1022 /*-----------------------------------------------------------------------------
1023 * Function: efuse_WriteAllMap
1025 * Overview: Write All Efuse content
1027 * Input: NONE
1029 * Output: NONE
1031 * Return: NONE
1033 * Revised History:
1034 * When Who Remark
1035 * 11/11/2008 MHC Create Version 0.
1037 *---------------------------------------------------------------------------*/
1038 #ifdef TO_DO_LIST
1039 static void
1040 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
1042 unsigned char word_en = 0x00;
1044 unsigned char tmpdata[8];
1045 unsigned char offset;
1047 // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
1048 efuse_PowerSwitch(dev, TRUE);
1050 //sdio contents
1051 for(offset=0 ; offset< eeprom_size/PGPKT_DATA_SIZE ; offset++)
1053 // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
1054 if (IS_HARDWARE_TYPE_8192SE(dev))
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;
1065 //RT_TRACE(COMP_EFUSE, ("Addr=%d size=%d Word_En=%02x\n", offset, eeprom_size, word_en));
1067 //memcpy(tmpdata,eeprom+(offset*PGPKT_DATA_SIZE),8);
1068 memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
1070 //RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("EFUSE\t"), tmpdata, 8);
1072 efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
1077 // For warm reboot, we must resume Efuse clock to 500K.
1078 efuse_PowerSwitch(dev, FALSE);
1080 } // efuse_WriteAllMap
1081 #endif
1083 /*-----------------------------------------------------------------------------
1084 * Function: efuse_PgPacketRead
1086 * Overview: Receive dedicated Efuse are content. For92s, we support 16
1087 * area now. It will return 8 bytes content for every area.
1089 * Input: NONE
1091 * Output: NONE
1093 * Return: NONE
1095 * Revised History:
1096 * When Who Remark
1097 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1099 *---------------------------------------------------------------------------*/
1100 static u8
1101 efuse_PgPacketRead( struct net_device* dev, u8 offset, u8 *data)
1103 u8 ReadState = PG_STATE_HEADER;
1105 bool bContinual = TRUE;
1106 bool bDataEmpty = TRUE ;
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];
1114 if(data==NULL) return FALSE;
1115 if(offset>15) return FALSE;
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);
1123 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-1\n"), data, 8);
1125 //efuse_reg_ctrl(pAdapter,TRUE);//power on
1126 while(bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
1128 //------- Header Read -------------
1129 if(ReadState & PG_STATE_HEADER)
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 ;
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;
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;
1153 else{//read next header
1154 efuse_addr = efuse_addr + (word_cnts*2)+1;
1155 ReadState = PG_STATE_HEADER;
1159 else{
1160 bContinual = FALSE ;
1163 //------- Data section Read -------------
1164 else if(ReadState & PG_STATE_DATA)
1166 efuse_WordEnableDataRead(hworden,tmpdata,data);
1167 efuse_addr = efuse_addr + (word_cnts*2)+1;
1168 ReadState = PG_STATE_HEADER;
1172 //efuse_reg_ctrl(pAdapter,FALSE);//power off
1174 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("efuse_PgPacketRead-2\n"), data, 8);
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;
1182 } // efuse_PgPacketRead
1185 /*-----------------------------------------------------------------------------
1186 * Function: efuse_PgPacketWrite
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]
1192 * Input: NONE
1194 * Output: NONE
1196 * Return: NONE
1198 * Revised History:
1199 * When Who Remark
1200 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1202 *---------------------------------------------------------------------------*/
1203 static u8 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
1205 u8 WriteState = PG_STATE_HEADER;
1207 bool bContinual = TRUE,bDataEmpty=TRUE, bResult = TRUE;
1208 u16 efuse_addr = 0;
1209 u8 efuse_data;
1211 u8 pg_header = 0;
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;
1217 //u8 efuse_clk_ori,efuse_clk_new;
1219 PGPKT_STRUCT target_pkt;
1220 PGPKT_STRUCT tmp_pkt;
1222 u8 originaldata[sizeof(u8)*8];
1223 u8 tmpindex = 0,badworden = 0x0F;
1225 static u32 repeat_times = 0;
1227 if( efuse_GetCurrentSize(dev) >= EFUSE_MAX_SIZE)
1229 printk("efuse_PgPacketWrite error \n");
1230 return FALSE;
1233 // Init the 8 bytes content as 0xff
1234 target_pkt.offset = offset;
1235 target_pkt.word_en= word_en;
1237 //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
1238 memset(target_pkt.data,0xFF,sizeof(u8)*8);
1240 efuse_WordEnableDataRead(word_en,data,target_pkt.data);
1241 target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
1243 //efuse_reg_ctrl(pAdapter,TRUE);//power on
1244 printk("EFUSE Power ON\n");
1246 while( bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
1249 if(WriteState==PG_STATE_HEADER)
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))
1258 tmp_header = efuse_data;
1260 tmp_pkt.offset = (tmp_header>>4) & 0x0F;
1261 tmp_pkt.word_en = tmp_header & 0x0F;
1262 tmp_word_cnts = efuse_CalculateWordCnts(tmp_pkt.word_en);
1264 //************ so-1 *******************
1265 if(tmp_pkt.offset != target_pkt.offset)
1267 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1268 #if (EFUSE_ERROE_HANDLE == 1)
1269 WriteState = PG_STATE_HEADER;
1270 #endif
1272 else
1274 //************ so-2 *******************
1275 for(tmpindex=0 ; tmpindex<(tmp_word_cnts*2) ; tmpindex++)
1277 if(efuse_OneByteRead(dev, (efuse_addr+1+tmpindex) ,&efuse_data)&&(efuse_data != 0xFF)){
1278 bDataEmpty = FALSE;
1281 //************ so-2-1 *******************
1282 if(bDataEmpty == FALSE)
1284 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1285 #if (EFUSE_ERROE_HANDLE == 1)
1286 WriteState=PG_STATE_HEADER;
1287 #endif
1289 else
1290 {//************ so-2-2 *******************
1291 match_word_en = 0x0F;
1292 if( !( (target_pkt.word_en&BIT0)|(tmp_pkt.word_en&BIT0) ))
1294 match_word_en &= (~BIT0);
1296 if( !( (target_pkt.word_en&BIT1)|(tmp_pkt.word_en&BIT1) ))
1298 match_word_en &= (~BIT1);
1300 if( !( (target_pkt.word_en&BIT2)|(tmp_pkt.word_en&BIT2) ))
1302 match_word_en &= (~BIT2);
1304 if( !( (target_pkt.word_en&BIT3)|(tmp_pkt.word_en&BIT3) ))
1306 match_word_en &= (~BIT3);
1309 //************ so-2-2-A *******************
1310 if((match_word_en&0x0F)!=0x0F)
1312 badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1, tmp_pkt.word_en ,target_pkt.data);
1314 //************ so-2-2-A-1 *******************
1315 //############################
1316 if(0x0F != (badworden&0x0F))
1318 u8 reorg_offset = offset;
1319 u8 reorg_worden=badworden;
1320 efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1322 //############################
1324 tmp_word_en = 0x0F;
1325 if( (target_pkt.word_en&BIT0)^(match_word_en&BIT0) )
1327 tmp_word_en &= (~BIT0);
1329 if( (target_pkt.word_en&BIT1)^(match_word_en&BIT1) )
1331 tmp_word_en &= (~BIT1);
1333 if( (target_pkt.word_en&BIT2)^(match_word_en&BIT2) )
1335 tmp_word_en &= (~BIT2);
1337 if( (target_pkt.word_en&BIT3)^(match_word_en&BIT3) )
1339 tmp_word_en &=(~BIT3);
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;
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;
1361 #endif
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
1376 printk("EFUSE PG_STATE_HEADER-1\n");
1378 else //************ s1: header == oxff *******************
1380 pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en;
1382 efuse_OneByteWrite(dev,efuse_addr, pg_header);
1383 efuse_OneByteRead(dev,efuse_addr, &tmp_header);
1385 if(tmp_header == pg_header)
1386 { //************ s1-1*******************
1387 WriteState = PG_STATE_DATA;
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;
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);
1406 //************ s1-2-A :cover the exist data *******************
1407 memset(originaldata,0xff,sizeof(u8)*8);
1408 //PlatformFillMemory((PVOID)originaldata, sizeof(u8)*8, 0xff);
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))
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);
1422 //############################
1423 else{
1424 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1427 //************ s1-2-B: wrong address*******************
1428 else
1430 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
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;
1440 #endif
1442 printk("EFUSE PG_STATE_HEADER-2\n");
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;
1458 else
1459 {//reorganize other pg packet //************ s1-1-B *******************
1460 efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
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;
1474 #endif
1475 printk("EFUSE PG_STATE_HEADER-3\n");
1480 //efuse_reg_ctrl(pAdapter,FALSE);//power off
1482 return TRUE;
1483 } // efuse_PgPacketWrite
1486 /*-----------------------------------------------------------------------------
1487 * Function: efuse_WordEnableDataRead
1489 * Overview: Read allowed word in current efuse section data.
1491 * Input: NONE
1493 * Output: NONE
1495 * Return: NONE
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.
1502 *---------------------------------------------------------------------------*/
1503 static void
1504 efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata)
1506 //u8 tmpindex = 0;
1508 //DbgPrint("efuse_WordEnableDataRead word_en = %x\n", word_en);
1510 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("sourdata\n"), sourdata, 8);
1511 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("targetdata\n"), targetdata, 8);
1513 if (!(word_en&BIT0))
1515 targetdata[0] = sourdata[0];//sourdata[tmpindex++];
1516 targetdata[1] = sourdata[1];//sourdata[tmpindex++];
1518 if (!(word_en&BIT1))
1520 targetdata[2] = sourdata[2];//sourdata[tmpindex++];
1521 targetdata[3] = sourdata[3];//sourdata[tmpindex++];
1523 if (!(word_en&BIT2))
1525 targetdata[4] = sourdata[4];//sourdata[tmpindex++];
1526 targetdata[5] = sourdata[5];//sourdata[tmpindex++];
1528 if (!(word_en&BIT3))
1530 targetdata[6] = sourdata[6];//sourdata[tmpindex++];
1531 targetdata[7] = sourdata[7];//sourdata[tmpindex++];
1533 } // efuse_WordEnableDataRead
1536 /*-----------------------------------------------------------------------------
1537 * Function: efuse_WordEnableDataWrite
1539 * Overview: Write necessary word unit into current efuse section!
1541 * Input: NONE
1543 * Output: NONE
1545 * Return: NONE
1547 * Revised History:
1548 * When Who Remark
1549 * 11/16/2008 MHC Reorganize Efuse operate flow!!.
1551 *---------------------------------------------------------------------------*/
1552 static u8
1553 efuse_WordEnableDataWrite( struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data)
1555 u16 tmpaddr = 0;
1556 u16 start_addr = efuse_addr;
1557 u8 badworden = 0x0F;
1558 //u8 NextState;
1559 u8 tmpdata[8];
1561 memset(tmpdata,0xff,PGPKT_DATA_SIZE);
1562 //PlatformFillMemory((PVOID)tmpdata, PGPKT_DATA_SIZE, 0xff);
1564 //RT_TRACE(COMP_EFUSE, "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
1566 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("U-EFUSE\n"), data, 8);
1568 if(!(word_en&BIT0))
1570 tmpaddr = start_addr;
1571 efuse_OneByteWrite(dev,start_addr++, data[0]);
1572 efuse_OneByteWrite(dev,start_addr++, data[1]);
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);
1580 if(!(word_en&BIT1))
1582 tmpaddr = start_addr;
1583 efuse_OneByteWrite(dev,start_addr++, data[2]);
1584 efuse_OneByteWrite(dev,start_addr++, data[3]);
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);
1592 if(!(word_en&BIT2))
1594 tmpaddr = start_addr;
1595 efuse_OneByteWrite(dev,start_addr++, data[4]);
1596 efuse_OneByteWrite(dev,start_addr++, data[5]);
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);
1604 if(!(word_en&BIT3))
1606 tmpaddr = start_addr;
1607 efuse_OneByteWrite(dev,start_addr++, data[6]);
1608 efuse_OneByteWrite(dev,start_addr++, data[7]);
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);
1616 return badworden;
1617 } // efuse_WordEnableDataWrite
1620 /*-----------------------------------------------------------------------------
1621 * Function: efuse_PowerSwitch
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.
1627 * Input: NONE
1629 * Output: NONE
1631 * Return: NONE
1633 * Revised History:
1634 * When Who Remark
1635 * 11/17/2008 MHC Create Version 0.
1637 *---------------------------------------------------------------------------*/
1638 static void
1639 efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
1641 u8 tempval;
1642 if (PwrState == TRUE)
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));
1648 // Change Efuse Clock for write action to 40MHZ
1649 write_nic_byte(dev, EFUSE_CLK, 0x03);
1651 else
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));
1657 // Change Efuse Clock for write action to 500K
1658 write_nic_byte(dev, EFUSE_CLK, 0x02);
1661 } /* efuse_PowerSwitch */
1664 /*-----------------------------------------------------------------------------
1665 * Function: efuse_GetCurrentSize
1667 * Overview: Get current efuse size!!!
1669 * Input: NONE
1671 * Output: NONE
1673 * Return: NONE
1675 * Revised History:
1676 * When Who Remark
1677 * 11/16/2008 MHC Create Version 0.
1679 *---------------------------------------------------------------------------*/
1680 static u16
1681 efuse_GetCurrentSize(struct net_device* dev)
1683 bool bContinual = TRUE;
1685 u16 efuse_addr = 0;
1686 u8 hoffset=0,hworden=0;
1687 u8 efuse_data,word_cnts=0;
1689 //efuse_reg_ctrl(pAdapter,TRUE);//power on
1691 while ( bContinual &&
1692 efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
1693 (efuse_addr < EFUSE_MAX_SIZE) )
1695 if(efuse_data!=0xFF)
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;
1703 else
1705 bContinual = FALSE ;
1709 //efuse_reg_ctrl(pAdapter,FALSE);//power off
1711 return efuse_addr;
1713 } // efuse_GetCurrentSize}
1716 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
1717 static u8
1718 efuse_CalculateWordCnts(u8 word_en)
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
1728 /*-----------------------------------------------------------------------------
1729 * Function: EFUSE_ProgramMap
1731 * Overview: Read EFUSE map file and execute PG.
1733 * Input: NONE
1735 * Output: NONE
1737 * Return: NONE
1739 * Revised History:
1740 * When Who Remark
1741 * 11/10/2008 MHC Create Version 0.
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)
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];
1758 rtStatus = PlatformReadFile(
1759 dev,
1760 pFileName,
1761 (u8*)(priv->BufOfLines),
1762 MAX_LINES_HWCONFIG_TXT,
1763 MAX_BYTES_LINE_HWCONFIG_TXT,
1764 &nLinesRead
1767 if(rtStatus == RT_STATUS_SUCCESS)
1769 memcp(pHalData->BufOfLines3, pHalData->BufOfLines,
1770 nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT);
1771 pHalData->nLinesRead3 = nLinesRead;
1774 if(rtStatus == RT_STATUS_SUCCESS)
1776 printk("szEepromFile(): read %s ok\n", pFileName);
1777 for(ithLine = 0; ithLine < nLinesRead; ithLine++)
1779 szLine = pHalData->BufOfLines[ithLine];
1780 printk("Line-%d String =%s\n", ithLine, szLine);
1782 if(!IsCommentString(szLine))
1784 // EEPROM map one line has 8 words content.
1785 for (i = 0; i < 8; i++)
1787 u32 j;
1789 //GetHexValueFromString(szLine, &u4bRegValue, &u4bMove);
1790 efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
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);
1798 printk("Addr-%d = %x\n", (ithLine*8+i), u4bRegValue);
1805 else
1807 printk("szEepromFile(): Fail read%s\n", pFileName);
1808 return RT_STATUS_FAILURE;
1812 //RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("EFUSE "), eeprom, HWSET_MAX_SIZE_92S);
1814 // Use map file to update real Efuse or shadow modify table.
1815 if (TableType == 1)
1817 efuse_WriteAllMap(dev, eeprom, HWSET_MAX_SIZE_92S);
1819 else
1821 // Modify shadow table.
1822 for (i = 0; i < HWSET_MAX_SIZE_92S; i++)
1823 EFUSE_ShadowWrite(dev, 1, i, (u32)eeprom[i]);
1826 return rtStatus;
1827 } /* EFUSE_ProgramMap */
1829 #endif
1832 // Description:
1833 // Return TRUE if chTmp is represent for hex digit and
1834 // FALSE otherwise.
1837 bool IsHexDigit( char chTmp)
1839 if( (chTmp >= '0' && chTmp <= '9') ||
1840 (chTmp >= 'a' && chTmp <= 'f') ||
1841 (chTmp >= 'A' && chTmp <= 'F') )
1843 return TRUE;
1845 else
1847 return FALSE;
1852 // Description:
1853 // Translate a character to hex digit.
1855 u32 MapCharToHexDigit(char chTmp)
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;
1867 /*-----------------------------------------------------------------------------
1868 * Function: efuse_ParsingMap
1870 * Overview:
1872 * Input: NONE
1874 * Output: NONE
1876 * Return: NONE
1878 * Revised History:
1879 * When Who Remark
1880 * 11/08/2008 MHC Create Version 0.
1882 *---------------------------------------------------------------------------*/
1883 #ifdef TO_DO_LIST
1884 static bool
1885 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
1887 char* szScan = szStr;
1889 // Check input parameter.
1890 if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
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;
1898 // Initialize output.
1899 *pu4bMove = 0;
1900 *pu4bVal = 0;
1902 // Skip leading space.
1903 while( *szScan != '\0' &&
1904 (*szScan == ' ' || *szScan == '\t') )
1906 szScan++;
1907 (*pu4bMove)++;
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))
1914 return FALSE;
1917 // Parse each digit.
1920 (*pu4bVal) <<= 4;
1921 *pu4bVal += MapCharToHexDigit(*szScan);
1923 szScan++;
1924 (*pu4bMove)++;
1925 } while(IsHexDigit(*szScan));
1927 return TRUE;
1929 } /* efuse_ParsingMap */
1930 #endif
1933 // Useless Section Code Now!!!!!!
1935 // Porting from 8712 SDIO
1936 int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
1938 u32 bResult;
1939 //u8 efuse_ctlreg,tmpidx = 0;
1940 u8 tmpidx = 0;
1941 u8 tmpv8=0;
1943 // -----------------e-fuse reg ctrl ---------------------------------
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);
1949 if(TRUE==bRead){
1951 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
1953 while(!(0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1954 tmpidx++;
1956 if(tmpidx<100){
1957 *data=read_nic_byte(dev, EFUSE_CTRL);
1958 bResult = TRUE;
1960 else
1962 *data = 0;
1963 bResult = FALSE;
1967 else{
1968 //return 0;
1969 write_nic_byte(dev, EFUSE_CTRL, *data);//data
1971 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
1973 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1974 tmpidx++;
1976 if(tmpidx<100)
1978 *data=read_nic_byte(dev, EFUSE_CTRL);
1979 bResult = TRUE;
1981 else
1983 *data = 0;
1984 bResult = FALSE;
1988 return bResult;
1990 //------------------------------------------------------------------------------
1991 void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
1993 u8 efuse_clk_ori,efuse_clk_new;//,tmp8;
1994 u32 i = 0;
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;
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);
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));
2014 #ifdef _PRE_EXECUTE_READ_CMD_
2016 unsigned char tmpdata;
2017 efuse_OneByteRead(dev, 0,&tmpdata);
2019 #endif
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)));
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);
2030 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
2031 if(efuse_clk_new != efuse_clk_ori) write_nic_byte(dev, 0x10250003, efuse_clk_ori);
2034 //------------------------------------------------------------------------------
2035 //------------------------------------------------------------------------------
2037 #ifdef TO_DO_LIST
2038 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
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_
2051 unsigned char tmpdata;
2052 efuse_OneByteRead(dev, 0,&tmpdata);
2055 #endif
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 ---------------------------------
2063 //write_nic_byte(pAdapter, SYS_FUNC_EN+1, read_nic_byte(pAdapter,SYS_FUNC_EN+1)&0xDF);
2068 #endif
2069 //------------------------------------------------------------------------------
2071 //------------------------------------------------------------------------------
2072 void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
2074 u8 offset, word_start,byte_start,byte_cnts;
2075 u8 efusedata[EFUSE_MAC_LEN];
2076 u8 *tmpdata = NULL;
2078 u8 pg_pkt_cnts ;
2080 u8 tmpidx;
2081 u8 pg_data[8];
2082 //u8 temp_value[8] = {0xff};
2084 if(efuse_read_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2085 //error msg
2086 return ;
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;
2094 if(data_size!=byte_cnts){
2095 //error msg
2096 return;
2099 pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2101 if(pg_pkt_cnts > 1){
2102 //tmpdata = _malloc(pg_pkt_cnts*PGPKT_DATA_SIZE);
2103 tmpdata = efusedata;
2105 if(tmpdata!=NULL)
2107 memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
2108 //PlatformFillMemory((PVOID)pg_data, pg_pkt_cnts*PGPKT_DATA_SIZE, 0xff);
2110 for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
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))
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);
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);
2125 else
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);
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)
2140 u8 offset, word_start,byte_start,byte_cnts;
2141 u8 word_en = 0x0f,word_cnts;
2142 u8 pg_pkt_cnts ;
2144 u8 tmpidx,tmpbitmask;
2145 u8 pg_data[8],tmpbytes=0;
2147 if(efuse_write_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2148 //error msg
2149 return ;
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;
2157 if(data_size > byte_cnts){
2158 //error msg
2159 return;
2161 pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2162 word_cnts = byte_cnts /2 ;
2164 if(byte_cnts %2){
2165 word_cnts+=1;
2167 if((byte_start==1)||((byte_cnts%2)==1)){//situation A
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);
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));
2180 word_en = 0x00;
2181 efuse_PgPacketWrite(dev,(offset+1),word_en,data+2);
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);
2188 efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
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));
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));
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;
2210 else if(efuse_write_item == EFUSE_SDIO_MODE){
2211 word_en = 0x0d ;
2212 tmpbytes = 2;
2214 else if(efuse_write_item == EFUSE_OCR){
2215 word_en = 0x09 ;
2216 tmpbytes = 4;
2218 else if((efuse_write_item == EFUSE_EEPROM_VER)||(efuse_write_item==EFUSE_CHAN_PLAN)){
2219 word_en = 0x07 ;
2220 tmpbytes = 2;
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);
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);
2232 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
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++)
2243 efuse_PgPacketWrite(dev,(offset+tmpidx),word_en,data+(tmpidx*PGPKT_DATA_SIZE));
2245 word_en = 0x0f;
2246 for(tmpidx= 0; tmpidx<(word_cnts%4) ; tmpidx++)
2248 tmpbitmask =tmpidx;
2249 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2250 //BIT0
2252 efuse_PgPacketWrite(dev,offset+(word_cnts/4),word_en,data+((word_cnts/4)*PGPKT_DATA_SIZE));
2253 }else
2258 //========================================================================
2259 else{//situation C
2260 word_en = 0x0f;
2261 for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
2263 tmpbitmask = word_start + tmpidx ;
2264 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2266 efuse_PgPacketWrite(dev,offset,word_en,data);
2270 //------------------------------------------------------------------------------
2272 void efuset_test_func_read(struct net_device* dev)
2274 u8 chipid[2];
2275 u8 ocr[3];
2276 u8 macaddr[6];
2277 u8 txpowertable[28];
2279 memset(chipid,0,sizeof(u8)*2);
2280 efuse_read_data(dev,EFUSE_CHIP_ID,chipid,sizeof(chipid));
2282 memset(ocr,0,sizeof(u8)*3);
2283 efuse_read_data(dev,EFUSE_CCCR,ocr,sizeof(ocr));
2285 memset(macaddr,0,sizeof(u8)*6);
2286 efuse_read_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr));
2288 memset(txpowertable,0,sizeof(u8)*28);
2289 efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
2291 //------------------------------------------------------------------------------
2293 void efuset_test_func_write(struct net_device* dev)
2295 u32 bWordUnit = TRUE;
2296 u8 CCCR=0x02,SDIO_SETTING = 0xFF;
2297 u8 tmpdata[2];
2299 u8 macaddr[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
2300 efuse_write_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr),bWordUnit);
2302 bWordUnit = FALSE;
2303 efuse_write_data(dev,EFUSE_CCCR,&CCCR,sizeof(u8),bWordUnit);
2305 bWordUnit = FALSE;
2306 efuse_write_data(dev,EFUSE_SDIO_SETTING,&SDIO_SETTING,sizeof(u8),bWordUnit);
2308 bWordUnit = TRUE;
2309 tmpdata[0] =SDIO_SETTING ;
2310 tmpdata[1] =CCCR ;
2311 efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);
2314 //------------------------------------------------------------------------------
2325 /* End of Efuse.c */