GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / rtl8192su / r8192S_Efuse.c
blobbbefd0f30348020936b0397d81bb9cf09af7f3cd
1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 * Based on the r8180 driver, which is:
5 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 * The full GNU General Public License is included in this distribution in the
20 * file called LICENSE.
22 * Contact Information:
23 * wlanfae <wlanfae@realtek.com>
24 ******************************************************************************/
25 #include "r8192U.h"
26 #include "r8192S_hw.h"
27 #include "r8192S_phy.h"
28 #include "r8192S_phyreg.h"
29 #include "r8192S_Efuse.h"
31 #include <linux/types.h>
32 #include <linux/ctype.h>
34 #define _POWERON_DELAY_
35 #define _PRE_EXECUTE_READ_CMD_
37 #define EFUSE_REPEAT_THRESHOLD_ 3
38 #define EFUSE_ERROE_HANDLE 1
40 typedef struct _EFUSE_MAP_A{
41 u8 offset; //0~15
42 u8 word_start; //0~3
43 u8 byte_start; //0 or 1
44 u8 byte_cnts;
46 }EFUSE_MAP, *PEFUSE_MAP;
48 typedef struct PG_PKT_STRUCT_A{
49 u8 offset;
50 u8 word_en;
51 u8 data[8];
52 }PGPKT_STRUCT,*PPGPKT_STRUCT;
54 typedef enum _EFUSE_DATA_ITEM{
55 EFUSE_CHIP_ID=0,
56 EFUSE_LDO_SETTING,
57 EFUSE_CLK_SETTING,
58 EFUSE_SDIO_SETTING,
59 EFUSE_CCCR,
60 EFUSE_SDIO_MODE,
61 EFUSE_OCR,
62 EFUSE_F0CIS,
63 EFUSE_F1CIS,
64 EFUSE_MAC_ADDR,
65 EFUSE_EEPROM_VER,
66 EFUSE_CHAN_PLAN,
67 EFUSE_TXPW_TAB
68 } EFUSE_DATA_ITEM;
70 struct efuse_priv
72 u8 id[2];
73 u8 ldo_setting[2];
74 u8 clk_setting[2];
75 u8 cccr;
76 u8 sdio_mode;
77 u8 ocr[3];
78 u8 cis0[17];
79 u8 cis1[48];
80 u8 mac_addr[6];
81 u8 eeprom_verno;
82 u8 channel_plan;
83 u8 tx_power_b[14];
84 u8 tx_power_g[14];
87 const u8 MAX_PGPKT_SIZE = 9; //header+ 2* 4 words (BYTES)
88 const u8 PGPKT_DATA_SIZE = 8; //BYTES sizeof(u8)*8
89 const u32 EFUSE_MAX_SIZE = 512;
91 const u8 EFUSE_OOB_PROTECT_BYTES = 14;
93 const EFUSE_MAP RTL8712_SDIO_EFUSE_TABLE[]={
94 //offset word_s byte_start byte_cnts
95 /*ID*/ {0 ,0 ,0 ,2 }, // 00~01h
96 /*LDO Setting*/ {0 ,1 ,0 ,2 }, // 02~03h
97 /*CLK Setting*/ {0 ,2 ,0 ,2 }, // 04~05h
98 /*SDIO Setting*/ {1 ,0 ,0 ,1 }, // 08h
99 /*CCCR*/ {1 ,0 ,1 ,1 }, // 09h
100 /*SDIO MODE*/ {1 ,1 ,0 ,1 }, // 0Ah
101 /*OCR*/ {1 ,1 ,1 ,3 }, // 0B~0Dh
102 /*CCIS*/ {1 ,3 ,0 ,17 }, // 0E~1Eh 2...1
103 /*F1CIS*/ {3 ,3 ,1 ,48 }, // 1F~4Eh 6...0
104 /*MAC Addr*/ {10 ,0 ,0 ,6 }, // 50~55h
105 /*EEPROM ver*/ {10 ,3 ,0 ,1 }, // 56h
106 /*Channel plan*/ {10 ,3 ,1 ,1 }, // 57h
107 /*TxPwIndex */ {11 ,0 ,0 ,28 } // 58~73h 3...4
111 // From WMAC Efuse one byte R/W
113 extern void
114 EFUSE_Initialize(struct net_device* dev);
115 extern u8
116 EFUSE_Read1Byte(struct net_device* dev, u16 Address);
117 extern void
118 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value);
121 // Efuse Shadow Area operation
123 static void
124 efuse_ShadowRead1Byte(struct net_device* dev,u16 Offset,u8 *Value);
125 static void
126 efuse_ShadowRead2Byte(struct net_device* dev, u16 Offset,u16 *Value );
127 static void
128 efuse_ShadowRead4Byte(struct net_device* dev, u16 Offset,u32 *Value );
129 static void
130 efuse_ShadowWrite1Byte(struct net_device* dev, u16 Offset, u8 Value);
131 static void
132 efuse_ShadowWrite2Byte(struct net_device* dev, u16 Offset,u16 Value);
133 static void
134 efuse_ShadowWrite4Byte(struct net_device* dev, u16 Offset,u32 Value);
137 // Real Efuse operation
139 static u8
140 efuse_OneByteRead(struct net_device* dev,u16 addr,u8 *data);
141 static u8
142 efuse_OneByteWrite(struct net_device* dev,u16 addr, u8 data);
145 // HW setting map file operation
147 static void
148 efuse_ReadAllMap(struct net_device* dev,u8 *Efuse);
149 #ifdef TO_DO_LIST
150 static void
151 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom,u32 eeprom_size);
152 static bool
153 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove);
154 #endif
156 // Reald Efuse R/W or other operation API.
158 static u8
159 efuse_PgPacketRead( struct net_device* dev,u8 offset,u8 *data);
160 static u32
161 efuse_PgPacketWrite(struct net_device* dev,u8 offset,u8 word_en,u8 *data);
162 static void
163 efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata);
164 static u8
165 efuse_WordEnableDataWrite( struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data);
166 static void
167 efuse_PowerSwitch(struct net_device* dev,u8 PwrState);
168 static u16
169 efuse_GetCurrentSize(struct net_device* dev);
170 static u8
171 efuse_CalculateWordCnts(u8 word_en);
173 // API for power on power off!!!
175 #ifdef TO_DO_LIST
176 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn);
177 #endif
181 /*-----------------------------------------------------------------------------
182 * Function: EFUSE_Initialize
184 * Overview: Copy from WMAC fot EFUSE testing setting init.
186 * Input: NONE
188 * Output: NONE
190 * Return: NONE
192 * Revised History:
193 * When Who Remark
194 * 09/23/2008 MHC Copy from WMAC.
196 *---------------------------------------------------------------------------*/
197 extern void
198 EFUSE_Initialize(struct net_device* dev)
200 u8 Bytetemp = {0x00};
201 u8 temp = {0x00};
203 //Enable Digital Core Vdd : 0x2[13]=1
204 Bytetemp = read_nic_byte(dev, SYS_FUNC_EN+1);
205 temp = Bytetemp | 0x20;
206 write_nic_byte(dev, SYS_FUNC_EN+1, temp);
208 //EE loader to retention path1: attach 0x0[8]=0
209 Bytetemp = read_nic_byte(dev, SYS_ISO_CTRL+1);
210 temp = Bytetemp & 0xFE;
211 write_nic_byte(dev, SYS_ISO_CTRL+1, temp);
214 //Enable E-fuse use 2.5V LDO : 0x37[7]=1
215 Bytetemp = read_nic_byte(dev, EFUSE_TEST+3);
216 temp = Bytetemp | 0x80;
217 write_nic_byte(dev, EFUSE_TEST+3, temp);
219 //E-fuse clk switch from 500k to 40M : 0x2F8[1:0]=11b
220 write_nic_byte(dev, 0x2F8, 0x3);
222 //Set E-fuse program time & read time : 0x30[30:24]=1110010b
223 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);
227 /*-----------------------------------------------------------------------------
228 * Function: EFUSE_Read1Byte
230 * Overview: Copy from WMAC fot EFUSE read 1 byte.
232 * Input: NONE
234 * Output: NONE
236 * Return: NONE
238 * Revised History:
239 * When Who Remark
240 * 09/23/2008 MHC Copy from WMAC.
242 *---------------------------------------------------------------------------*/
243 extern u8
244 EFUSE_Read1Byte(struct net_device* dev, u16 Address)
246 u8 data;
247 u8 Bytetemp = {0x00};
248 u8 temp = {0x00};
249 u32 k=0;
251 if (Address < EFUSE_MAC_LEN) //E-fuse 512Byte
253 //Write E-fuse Register address bit0~7
254 temp = Address & 0xFF;
255 write_nic_byte(dev, EFUSE_CTRL+1, temp);
256 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
257 //Write E-fuse Register address bit8~9
258 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
259 write_nic_byte(dev, EFUSE_CTRL+2, temp);
261 //Write 0x30[31]=0
262 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
263 temp = Bytetemp & 0x7F;
264 write_nic_byte(dev, EFUSE_CTRL+3, temp);
266 //Wait Write-ready (0x30[31]=1)
267 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
268 while(!(Bytetemp & 0x80))
270 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
271 k++;
272 if(k==1000)
274 k=0;
275 break;
278 data=read_nic_byte(dev, EFUSE_CTRL);
279 return data;
281 else
282 return 0xFF;
287 /*-----------------------------------------------------------------------------
288 * Function: EFUSE_Write1Byte
290 * Overview: Copy from WMAC fot EFUSE write 1 byte.
292 * Input: NONE
294 * Output: NONE
296 * Return: NONE
298 * Revised History:
299 * When Who Remark
300 * 09/23/2008 MHC Copy from WMAC.
302 *---------------------------------------------------------------------------*/
303 extern void
304 EFUSE_Write1Byte(struct net_device* dev, u16 Address,u8 Value)
306 u8 Bytetemp = {0x00};
307 u8 temp = {0x00};
308 u32 k=0;
310 if( Address < EFUSE_MAC_LEN) //E-fuse 512Byte
312 write_nic_byte(dev, EFUSE_CTRL, Value);
314 //Write E-fuse Register address bit0~7
315 temp = Address & 0xFF;
316 write_nic_byte(dev, EFUSE_CTRL+1, temp);
317 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+2);
319 //Write E-fuse Register address bit8~9
320 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
321 write_nic_byte(dev, EFUSE_CTRL+2, temp);
323 //Write 0x30[31]=1
324 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
325 temp = Bytetemp | 0x80;
326 write_nic_byte(dev, EFUSE_CTRL+3, temp);
328 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
329 while(Bytetemp & 0x80)
331 Bytetemp = read_nic_byte(dev, EFUSE_CTRL+3);
332 k++;
333 if(k==100)
335 k=0;
336 break;
343 #ifdef EFUSE_FOR_92SU
345 // Description:
346 // 1. Process CR93C46 Data polling cycle.
347 // 2. Refered from SD1 Richard.
349 // Assumption:
350 // 1. Boot from E-Fuse and successfully auto-load.
351 // 2. PASSIVE_LEVEL (USB interface)
353 // Created by Roger, 2008.10.21.
355 void do_93c46(struct net_device* dev, u8 addorvalue)
357 u8 cs[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
358 u8 cssk[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
359 u8 csdi[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
360 u8 csskdi[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
361 u8 count;
363 for(count=0 ; count<8 ; count++)
365 if((addorvalue&0x80)!=0)
367 write_nic_byte(dev, EPROM_CMD, csdi[0]);
368 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
370 else
372 write_nic_byte(dev, EPROM_CMD, cs[0]);
373 write_nic_byte(dev, EPROM_CMD, cssk[0]);
375 addorvalue = addorvalue << 1;
381 // Description:
382 // Process CR93C46 Data read polling cycle.
383 // Refered from SD1 Richard.
385 // Assumption:
386 // 1. Boot from E-Fuse and successfully auto-load.
387 // 2. PASSIVE_LEVEL (USB interface)
389 // Created by Roger, 2008.10.21.
391 u16 Read93C46(struct net_device* dev, u16 Reg )
394 u8 clear[1] = {0x0}; // cs=0 , sk=0 , di=0 , do=0
395 u8 cs[1] = {0x88}; // cs=1 , sk=0 , di=0 , do=0
396 u8 cssk[1] = {0x8c}; // cs=1 , sk=1 , di=0 , do=0
397 u8 csdi[1] = {0x8a}; // cs=1 , sk=0 , di=1 , do=0
398 u8 csskdi[1] = {0x8e}; // cs=1 , sk=1 , di=1 , do=0
399 u8 EepromSEL[1]={0x00};
400 u8 address;
402 u16 storedataF[1] = {0x0}; //93c46 data packet for 16bits
403 u8 t,data[1],storedata[1];
406 address = (u8)Reg;
408 *EepromSEL= read_nic_byte(dev, EPROM_CMD);
410 if((*EepromSEL & 0x10) == 0x10) // select 93c46
412 address = address | 0x80;
414 write_nic_byte(dev, EPROM_CMD, csdi[0]);
415 write_nic_byte(dev, EPROM_CMD, csskdi[0]);
416 do_93c46(dev, address);
420 for(t=0 ; t<16 ; t++) //if read 93c46 , t=16
422 write_nic_byte(dev, EPROM_CMD, cs[0]);
423 write_nic_byte(dev, EPROM_CMD, cssk[0]);
424 *data= read_nic_byte(dev, EPROM_CMD);
426 if(*data & 0x8d) //original code
428 *data = *data & 0x01;
429 *storedata = *data;
431 else
433 *data = *data & 0x01 ;
434 *storedata = *data;
436 *storedataF = (*storedataF << 1 ) + *storedata;
438 write_nic_byte(dev, EPROM_CMD, cs[0]);
439 write_nic_byte(dev, EPROM_CMD, clear[0]);
441 return *storedataF;
446 // Description:
447 // Execute E-Fuse read byte operation.
448 // Refered from SD1 Richard.
450 // Assumption:
451 // 1. Boot from E-Fuse and successfully auto-load.
452 // 2. PASSIVE_LEVEL (USB interface)
454 // Created by Roger, 2008.10.21.
456 void
457 ReadEFuseByte(struct net_device* dev,u16 _offset, u8 *pbuf)
459 u32 value32;
460 u8 readbyte;
461 u16 retry;
463 //Write Address
464 write_nic_byte(dev, EFUSE_CTRL+1, (_offset & 0xff));
465 readbyte = read_nic_byte(dev, EFUSE_CTRL+2);
466 write_nic_byte(dev, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
468 //Write bit 32 0
469 readbyte = read_nic_byte(dev, EFUSE_CTRL+3);
470 write_nic_byte(dev, EFUSE_CTRL+3, (readbyte & 0x7f));
472 //Check bit 32 read-ready
473 retry = 0;
474 value32 = read_nic_dword(dev, EFUSE_CTRL);
475 while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000))
477 value32 = read_nic_dword(dev, EFUSE_CTRL);
478 retry++;
480 *pbuf = (u8)(value32 & 0xff);
484 #define EFUSE_READ_SWITCH 1
486 // Description:
487 // 1. Execute E-Fuse read byte operation according as map offset and
488 // save to E-Fuse table.
489 // 2. Refered from SD1 Richard.
491 // Assumption:
492 // 1. Boot from E-Fuse and successfully auto-load.
493 // 2. PASSIVE_LEVEL (USB interface)
495 // Created by Roger, 2008.10.21.
497 void
498 ReadEFuse(struct net_device* dev, u16 _offset, u16 _size_byte, u8 *pbuf)
501 struct r8192_priv *priv = ieee80211_priv(dev);
502 u8 efuseTbl[EFUSE_MAP_LEN];
503 u8 rtemp8[1];
504 u16 eFuse_Addr = 0;
505 u8 offset, wren;
506 u16 i, j;
507 u16 eFuseWord[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
508 u16 efuse_utilized = 0;
509 u16 efuse_usage = 0;
511 if((_offset + _size_byte)>EFUSE_MAP_LEN)
513 printk("ReadEFuse(): Invalid offset with read bytes!!\n");
514 return;
517 for(i = 0; i < EFUSE_MAX_SECTION; i++)
518 for(j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
519 eFuseWord[i][j]=0xFFFF;
521 #if (EFUSE_READ_SWITCH == 1)
522 ReadEFuseByte(dev, eFuse_Addr, rtemp8);
523 #else
524 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr);
525 #endif
526 if(*rtemp8 != 0xFF){
527 efuse_utilized++;
528 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
529 eFuse_Addr++;
532 while((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN))
534 offset = ((*rtemp8 >> 4) & 0x0f);
535 if(offset < EFUSE_MAX_SECTION)
537 wren = (*rtemp8 & 0x0f);
538 RT_TRACE(COMP_EPROM, "Offset-%d Worden=%x\n", offset, wren);
540 for(i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
542 if(!(wren & 0x01))
544 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
545 #if (EFUSE_READ_SWITCH == 1)
546 ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
547 #else
548 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
549 #endif
550 efuse_utilized++;
551 eFuseWord[offset][i] = (*rtemp8 & 0xff);
552 if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
553 break;
555 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
556 #if (EFUSE_READ_SWITCH == 1)
557 ReadEFuseByte(dev, eFuse_Addr, rtemp8); eFuse_Addr++;
558 #else
559 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
560 #endif
561 efuse_utilized++;
562 eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
563 if(eFuse_Addr >= EFUSE_REAL_CONTENT_LEN)
564 break;
566 wren >>= 1;
570 RT_TRACE(COMP_EPROM, "Addr=%d\n", eFuse_Addr);
571 #if (EFUSE_READ_SWITCH == 1)
572 ReadEFuseByte(dev, eFuse_Addr, rtemp8);
573 #else
574 rtemp8[0] = EFUSE_Read1Byte(dev, eFuse_Addr); eFuse_Addr++;
575 #endif
576 if(*rtemp8 != 0xFF && (eFuse_Addr < 512))
578 efuse_utilized++;
579 eFuse_Addr++;
583 for(i=0; i<EFUSE_MAX_SECTION; i++)
585 for(j=0; j<EFUSE_MAX_WORD_UNIT; j++)
587 efuseTbl[(i*8)+(j*2)]=(eFuseWord[i][j] & 0xff);
588 efuseTbl[(i*8)+((j*2)+1)]=((eFuseWord[i][j] >> 8) & 0xff);
591 for(i=0; i<_size_byte; i++)
592 pbuf[i] = efuseTbl[_offset+i];
594 efuse_usage = (u8)((efuse_utilized*100)/EFUSE_REAL_CONTENT_LEN);
595 priv->EfuseUsedBytes = efuse_utilized;
596 priv->EfuseUsedPercentage = (u8)efuse_usage;
598 #endif
600 extern bool
601 EFUSE_ShadowUpdateChk(struct net_device* dev)
603 struct r8192_priv *priv = ieee80211_priv(dev);
604 u8 SectionIdx, i, Base;
605 u16 WordsNeed = 0, HdrNum = 0, TotalBytes = 0, EfuseUsed = 0;
606 bool bWordChanged, bResult = true;
608 for (SectionIdx = 0; SectionIdx < 16; SectionIdx++)
610 Base = SectionIdx * 8;
611 bWordChanged = false;
613 for (i = 0; i < 8; i=i+2)
615 if((priv->EfuseMap[EFUSE_INIT_MAP][Base+i] !=
616 priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i]) ||
617 (priv->EfuseMap[EFUSE_INIT_MAP][Base+i+1] !=
618 priv->EfuseMap[EFUSE_MODIFY_MAP][Base+i+1]))
620 WordsNeed++;
621 bWordChanged = true;
625 if( bWordChanged==true )
626 HdrNum++;
629 TotalBytes = HdrNum + WordsNeed*2;
630 EfuseUsed = priv->EfuseUsedBytes;
632 if( (TotalBytes + EfuseUsed) >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
633 bResult = true;
635 RT_TRACE(COMP_EPROM, "EFUSE_ShadowUpdateChk(): TotalBytes(%x), HdrNum(%x), WordsNeed(%x), EfuseUsed(%d)\n",
636 TotalBytes, HdrNum, WordsNeed, EfuseUsed);
638 return bResult;
641 /*-----------------------------------------------------------------------------
642 * Function: EFUSE_ShadowRead
644 * Overview: Read from efuse init map !!!!!
646 * Input: NONE
648 * Output: NONE
650 * Return: NONE
652 * Revised History:
653 * When Who Remark
654 * 11/12/2008 MHC Create Version 0.
656 *---------------------------------------------------------------------------*/
657 extern void
658 EFUSE_ShadowRead( struct net_device* dev, u8 Type, u16 Offset, u32 *Value)
660 if (Type == 1)
661 efuse_ShadowRead1Byte(dev, Offset, (u8 *)Value);
662 else if (Type == 2)
663 efuse_ShadowRead2Byte(dev, Offset, (u16 *)Value);
664 else if (Type == 4)
665 efuse_ShadowRead4Byte(dev, Offset, (u32 *)Value);
669 /*-----------------------------------------------------------------------------
670 * Function: EFUSE_ShadowWrite
672 * Overview: Write efuse modify map for later update operation to use!!!!!
674 * Input: NONE
676 * Output: NONE
678 * Return: NONE
680 * Revised History:
681 * When Who Remark
682 * 11/12/2008 MHC Create Version 0.
684 *---------------------------------------------------------------------------*/
685 extern void
686 EFUSE_ShadowWrite( struct net_device* dev, u8 Type, u16 Offset,u32 Value)
688 if (Offset >= 0x18 && Offset <= 0x1F)
689 return;
691 if (Type == 1)
692 efuse_ShadowWrite1Byte(dev, Offset, (u8)Value);
693 else if (Type == 2)
694 efuse_ShadowWrite2Byte(dev, Offset, (u16)Value);
695 else if (Type == 4)
696 efuse_ShadowWrite4Byte(dev, Offset, (u32)Value);
700 /*-----------------------------------------------------------------------------
701 * Function: EFUSE_ShadowUpdate
703 * Overview: Compare init and modify map to update Efuse!!!!!
705 * Input: NONE
707 * Output: NONE
709 * Return: NONE
711 * Revised History:
712 * When Who Remark
713 * 11/12/2008 MHC Create Version 0.
715 *---------------------------------------------------------------------------*/
716 extern bool
717 EFUSE_ShadowUpdate(struct net_device* dev)
719 struct r8192_priv *priv = ieee80211_priv(dev);
720 u16 i, offset, base = 0;
721 u8 word_en = 0x0F;
722 bool first_pg = false;
724 RT_TRACE(COMP_EPROM, "--->EFUSE_ShadowUpdate()\n");
726 if(!EFUSE_ShadowUpdateChk(dev))
728 efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
729 memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
730 (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
732 RT_TRACE(COMP_EPROM, "<---EFUSE_ShadowUpdate(): Efuse out of capacity!!\n");
733 return false;
735 efuse_PowerSwitch(dev, TRUE);
738 // Efuse support 16 write are with PG header packet!!!!
740 for (offset = 0; offset < 16; offset++)
742 // Offset 0x18-1F are reserved now!!!
743 word_en = 0x0F;
744 base = offset * 8;
747 // Decide Word Enable Bit for the Efuse section
748 // One section contain 4 words = 8 bytes!!!!!
750 for (i = 0; i < 8; i++)
752 if (first_pg == TRUE)
754 word_en &= ~(1<<(i/2));
755 RT_TRACE(COMP_EPROM,"Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
756 offset, base+i, priv->EfuseMap[EFUSE_INIT_MAP][base+i],
757 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i],word_en);
758 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
759 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
760 }else
762 if ( priv->EfuseMap[EFUSE_INIT_MAP][base+i] !=
763 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i])
765 word_en &= ~(EFUSE_BIT(i/2));
766 RT_TRACE(COMP_EPROM, "Section(%x) Addr[%x] %x update to %x, Word_En=%02x\n",
767 offset, base+i, priv->EfuseMap[0][base+i],
768 priv->EfuseMap[1][base+i],word_en);
770 // Update init table!!!
771 priv->EfuseMap[EFUSE_INIT_MAP][base+i] =
772 priv->EfuseMap[EFUSE_MODIFY_MAP][base+i];
778 // Call Efuse real write section !!!!
780 if (word_en != 0x0F)
782 u8 tmpdata[8];
784 memcpy((void *)tmpdata, (void *)&(priv->EfuseMap[EFUSE_MODIFY_MAP][base]), 8);
785 RT_TRACE(COMP_INIT, "U-EFUSE\n");
787 if(!efuse_PgPacketWrite(dev,(u8)offset,word_en,tmpdata))
789 RT_TRACE(COMP_EPROM,"EFUSE_ShadowUpdate(): PG section(%x) fail!!\n", offset);
790 break;
795 // For warm reboot, we must resume Efuse clock to 500K.
797 efuse_PowerSwitch(dev, FALSE);
799 efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
800 memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
801 (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
803 return true;
806 /*-----------------------------------------------------------------------------
807 * Function: EFUSE_ShadowMapUpdate
809 * Overview: Transfer current EFUSE content to shadow init and modify map.
811 * Input: NONE
813 * Output: NONE
815 * Return: NONE
817 * Revised History:
818 * When Who Remark
819 * 11/13/2008 MHC Create Version 0.
821 *---------------------------------------------------------------------------*/
822 extern void EFUSE_ShadowMapUpdate(struct net_device* dev)
824 struct r8192_priv *priv = ieee80211_priv(dev);
826 if (priv->AutoloadFailFlag == true){
827 memset(&(priv->EfuseMap[EFUSE_INIT_MAP][0]), 0xff, 128);
828 }else{
829 efuse_ReadAllMap(dev, &priv->EfuseMap[EFUSE_INIT_MAP][0]);
831 memcpy((void *)&priv->EfuseMap[EFUSE_MODIFY_MAP][0],
832 (void *)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
836 extern void
837 EFUSE_ForceWriteVendorId( struct net_device* dev)
839 u8 tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
841 efuse_PowerSwitch(dev, TRUE);
843 efuse_PgPacketWrite(dev, 1, 0xD, tmpdata);
845 efuse_PowerSwitch(dev, FALSE);
849 /*-----------------------------------------------------------------------------
850 * Function: efuse_ShadowRead1Byte
851 * efuse_ShadowRead2Byte
852 * efuse_ShadowRead4Byte
854 * Overview: Read from efuse init map by one/two/four bytes !!!!!
856 * Input: NONE
858 * Output: NONE
860 * Return: NONE
862 * Revised History:
863 * When Who Remark
864 * 11/12/2008 MHC Create Version 0.
866 *---------------------------------------------------------------------------*/
867 static void
868 efuse_ShadowRead1Byte(struct net_device* dev, u16 Offset, u8 *Value)
870 struct r8192_priv *priv = ieee80211_priv(dev);
872 *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
876 //---------------Read Two Bytes
877 static void
878 efuse_ShadowRead2Byte(struct net_device* dev, u16 Offset, u16 *Value)
880 struct r8192_priv *priv = ieee80211_priv(dev);
882 *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
883 *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
887 //---------------Read Four Bytes
888 static void
889 efuse_ShadowRead4Byte(struct net_device* dev, u16 Offset, u32 *Value)
891 struct r8192_priv *priv = ieee80211_priv(dev);
893 *Value = priv->EfuseMap[EFUSE_MODIFY_MAP][Offset];
894 *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1]<<8;
895 *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2]<<16;
896 *Value |= priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3]<<24;
902 /*-----------------------------------------------------------------------------
903 * Function: efuse_ShadowWrite1Byte
904 * efuse_ShadowWrite2Byte
905 * efuse_ShadowWrite4Byte
907 * Overview: Write efuse modify map by one/two/four byte.
909 * Input: NONE
911 * Output: NONE
913 * Return: NONE
915 * Revised History:
916 * When Who Remark
917 * 11/12/2008 MHC Create Version 0.
919 *---------------------------------------------------------------------------*/
920 static void
921 efuse_ShadowWrite1Byte(struct net_device* dev, u16 Offset, u8 Value)
923 struct r8192_priv *priv = ieee80211_priv(dev);
925 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value;
929 //---------------Write Two Bytes
930 static void
931 efuse_ShadowWrite2Byte(struct net_device* dev, u16 Offset, u16 Value)
933 struct r8192_priv *priv = ieee80211_priv(dev);
935 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = Value&0x00FF;
936 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = Value>>8;
940 //---------------Write Four Bytes
941 static void
942 efuse_ShadowWrite4Byte(struct net_device* dev, u16 Offset, u32 Value)
944 struct r8192_priv *priv = ieee80211_priv(dev);
946 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset] = (u8)(Value&0x000000FF);
947 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+1] = (u8)((Value>>8)&0x0000FF);
948 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+2] = (u8)((Value>>16)&0x00FF);
949 priv->EfuseMap[EFUSE_MODIFY_MAP][Offset+3] = (u8)((Value>>24)&0xFF);
953 static u8
954 efuse_OneByteRead(struct net_device* dev, u16 addr,u8 *data)
956 u8 tmpidx = 0;
957 u8 bResult;
959 // -----------------e-fuse reg ctrl ---------------------------------
960 //address
961 write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
962 write_nic_byte(dev, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
963 (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC ));
965 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
967 while(!(0x80 &read_nic_byte(dev, EFUSE_CTRL+3))&&(tmpidx<100))
969 tmpidx++;
971 if(tmpidx<100)
973 *data=read_nic_byte(dev, EFUSE_CTRL);
974 bResult = TRUE;
976 else
978 *data = 0xff;
979 bResult = FALSE;
981 return bResult;
984 /* 11/16/2008 MH Write one byte to reald Efuse. */
985 static u8
986 efuse_OneByteWrite(struct net_device* dev, u16 addr, u8 data)
988 u8 tmpidx = 0;
989 u8 bResult;
991 // -----------------e-fuse reg ctrl ---------------------------------
992 //address
993 write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff));
994 write_nic_byte(dev, EFUSE_CTRL+2,
995 read_nic_byte(dev, EFUSE_CTRL+2)|(u8)((addr>>8)&0x03) );
997 write_nic_byte(dev, EFUSE_CTRL, data);//data
998 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
1000 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1001 tmpidx++;
1004 if(tmpidx<100)
1006 bResult = TRUE;
1008 else
1010 bResult = FALSE;
1013 return bResult;
1016 /*-----------------------------------------------------------------------------
1017 * Function: efuse_ReadAllMap
1019 * Overview: Read All Efuse content
1021 * Input: NONE
1023 * Output: NONE
1025 * Return: NONE
1027 * Revised History:
1028 * When Who Remark
1029 * 11/11/2008 MHC Create Version 0.
1031 *---------------------------------------------------------------------------*/
1032 static void
1033 efuse_ReadAllMap(struct net_device* dev, u8 *Efuse)
1036 // We must enable clock and LDO 2.5V otherwise, read all map will be fail!!!!
1038 efuse_PowerSwitch(dev, TRUE);
1039 ReadEFuse(dev, 0, 128, Efuse);
1040 efuse_PowerSwitch(dev, FALSE);
1043 /*-----------------------------------------------------------------------------
1044 * Function: efuse_WriteAllMap
1046 * Overview: Write All Efuse content
1048 * Input: NONE
1050 * Output: NONE
1052 * Return: NONE
1054 * Revised History:
1055 * When Who Remark
1056 * 11/11/2008 MHC Create Version 0.
1058 *---------------------------------------------------------------------------*/
1059 #ifdef TO_DO_LIST
1060 static void
1061 efuse_WriteAllMap(struct net_device* dev,u8 *eeprom, u32 eeprom_size)
1063 unsigned char word_en = 0x00;
1065 unsigned char tmpdata[8];
1066 unsigned char offset;
1068 // For Efuse write action, we must enable LDO2.5V and 40MHZ clk.
1069 efuse_PowerSwitch(dev, TRUE);
1071 //sdio contents
1072 for(offset=0 ; offset< eeprom_size/PGPKT_DATA_SIZE ; offset++)
1074 // 92S will only reserv 0x18-1F 8 bytes now. The 3rd efuse write area!
1075 if (IS_HARDWARE_TYPE_8192SE(dev))
1077 // Refer to
1078 // 0x18-1f Reserve >0x50 Reserve for tx power
1079 if (offset == 3/* || offset > 9*/)
1080 continue;//word_en = 0x0F;
1081 else
1082 word_en = 0x00;
1085 memcpy(tmpdata, (eeprom+(offset*PGPKT_DATA_SIZE)), 8);
1086 efuse_PgPacketWrite(dev,offset,word_en,tmpdata);
1091 // For warm reboot, we must resume Efuse clock to 500K.
1092 efuse_PowerSwitch(dev, FALSE);
1095 #endif
1097 /*-----------------------------------------------------------------------------
1098 * Function: efuse_PgPacketRead
1100 * Overview: Receive dedicated Efuse are content. For92s, we support 16
1101 * area now. It will return 8 bytes content for every area.
1103 * Input: NONE
1105 * Output: NONE
1107 * Return: NONE
1109 * Revised History:
1110 * When Who Remark
1111 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1113 *---------------------------------------------------------------------------*/
1114 static u8
1115 efuse_PgPacketRead( struct net_device* dev, u8 offset, u8 *data)
1117 u8 ReadState = PG_STATE_HEADER;
1119 bool bContinual = TRUE;
1120 bool bDataEmpty = TRUE ;
1122 u8 efuse_data,word_cnts=0;
1123 u16 efuse_addr = 0;
1124 u8 hoffset=0,hworden=0;
1125 u8 tmpidx=0;
1126 u8 tmpdata[8];
1128 if(data==NULL) return FALSE;
1129 if(offset>15) return FALSE;
1131 memset(data, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1132 memset(tmpdata, 0xff, sizeof(u8)*PGPKT_DATA_SIZE);
1134 while(bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
1136 //------- Header Read -------------
1137 if(ReadState & PG_STATE_HEADER)
1139 if(efuse_OneByteRead(dev, efuse_addr ,&efuse_data)&&(efuse_data!=0xFF)){
1140 hoffset = (efuse_data>>4) & 0x0F;
1141 hworden = efuse_data & 0x0F;
1142 word_cnts = efuse_CalculateWordCnts(hworden);
1143 bDataEmpty = TRUE ;
1145 if(hoffset==offset){
1146 for(tmpidx = 0;tmpidx< word_cnts*2 ;tmpidx++){
1147 if(efuse_OneByteRead(dev, efuse_addr+1+tmpidx ,&efuse_data) ){
1148 tmpdata[tmpidx] = efuse_data;
1149 if(efuse_data!=0xff){
1150 bDataEmpty = FALSE;
1154 if(bDataEmpty==FALSE){
1155 ReadState = PG_STATE_DATA;
1156 }else{//read next header
1157 efuse_addr = efuse_addr + (word_cnts*2)+1;
1158 ReadState = PG_STATE_HEADER;
1161 else{//read next header
1162 efuse_addr = efuse_addr + (word_cnts*2)+1;
1163 ReadState = PG_STATE_HEADER;
1167 else{
1168 bContinual = FALSE ;
1171 //------- Data section Read -------------
1172 else if(ReadState & PG_STATE_DATA)
1174 efuse_WordEnableDataRead(hworden,tmpdata,data);
1175 efuse_addr = efuse_addr + (word_cnts*2)+1;
1176 ReadState = PG_STATE_HEADER;
1181 if( (data[0]==0xff) &&(data[1]==0xff) && (data[2]==0xff) && (data[3]==0xff) &&
1182 (data[4]==0xff) &&(data[5]==0xff) && (data[6]==0xff) && (data[7]==0xff))
1183 return FALSE;
1184 else
1185 return TRUE;
1189 /*-----------------------------------------------------------------------------
1190 * Function: efuse_PgPacketWrite
1192 * Overview: Send A G package for different section in real efuse area.
1193 * For 92S, One PG package contain 8 bytes content and 4 word
1194 * unit. PG header = 0x[bit7-4=offset][bit3-0word enable]
1196 * Input: NONE
1198 * Output: NONE
1200 * Return: NONE
1202 * Revised History:
1203 * When Who Remark
1204 * 11/16/2008 MHC Reorganize code Arch and assign as local API.
1206 *---------------------------------------------------------------------------*/
1207 static u32 efuse_PgPacketWrite(struct net_device* dev, u8 offset, u8 word_en,u8 *data)
1209 u8 WriteState = PG_STATE_HEADER;
1211 bool bContinual = TRUE,bDataEmpty=TRUE, bResult = TRUE;
1212 u16 efuse_addr = 0;
1213 u8 efuse_data;
1215 u8 pg_header = 0;
1217 u8 tmp_word_cnts=0,target_word_cnts=0;
1218 u8 tmp_header,match_word_en,tmp_word_en;
1220 PGPKT_STRUCT target_pkt;
1221 PGPKT_STRUCT tmp_pkt;
1223 u8 originaldata[sizeof(u8)*8];
1224 u8 tmpindex = 0,badworden = 0x0F;
1226 static u32 repeat_times = 0;
1228 if( efuse_GetCurrentSize(dev) >= EFUSE_MAX_SIZE)
1230 printk("efuse_PgPacketWrite error \n");
1231 return FALSE;
1234 // Init the 8 bytes content as 0xff
1235 target_pkt.offset = offset;
1236 target_pkt.word_en= word_en;
1238 //PlatformFillMemory((PVOID)target_pkt.data, sizeof(u8)*8, 0xFF);
1239 memset(target_pkt.data,0xFF,sizeof(u8)*8);
1241 efuse_WordEnableDataRead(word_en,data,target_pkt.data);
1242 target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
1244 printk("EFUSE Power ON\n");
1246 while( bContinual && (efuse_addr < EFUSE_MAX_SIZE) )
1249 if(WriteState==PG_STATE_HEADER)
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 if(0x0F != (badworden&0x0F))
1317 u8 reorg_offset = offset;
1318 u8 reorg_worden=badworden;
1319 efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1322 tmp_word_en = 0x0F;
1323 if( (target_pkt.word_en&BIT0)^(match_word_en&BIT0) )
1325 tmp_word_en &= (~BIT0);
1327 if( (target_pkt.word_en&BIT1)^(match_word_en&BIT1) )
1329 tmp_word_en &= (~BIT1);
1331 if( (target_pkt.word_en&BIT2)^(match_word_en&BIT2) )
1333 tmp_word_en &= (~BIT2);
1335 if( (target_pkt.word_en&BIT3)^(match_word_en&BIT3) )
1337 tmp_word_en &=(~BIT3);
1340 //************ so-2-2-A-2 *******************
1341 if((tmp_word_en&0x0F)!=0x0F){
1342 //reorganize other pg packet
1344 efuse_addr = efuse_GetCurrentSize(dev);
1346 target_pkt.offset = offset;
1347 target_pkt.word_en= tmp_word_en;
1349 }else{
1350 bContinual = FALSE;
1352 #if (EFUSE_ERROE_HANDLE == 1)
1353 WriteState=PG_STATE_HEADER;
1354 repeat_times++;
1355 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1356 bContinual = FALSE;
1357 bResult = FALSE;
1359 #endif
1361 else{//************ so-2-2-B *******************
1362 //reorganize other pg packet
1363 efuse_addr = efuse_addr + (2*tmp_word_cnts) +1;//next pg packet addr
1364 target_pkt.offset = offset;
1365 target_pkt.word_en= target_pkt.word_en;
1366 #if (EFUSE_ERROE_HANDLE == 1)
1367 WriteState=PG_STATE_HEADER;
1368 #endif
1372 printk("EFUSE PG_STATE_HEADER-1\n");
1374 else //************ s1: header == oxff *******************
1376 pg_header = ((target_pkt.offset << 4)&0xf0) |target_pkt.word_en;
1378 efuse_OneByteWrite(dev,efuse_addr, pg_header);
1379 efuse_OneByteRead(dev,efuse_addr, &tmp_header);
1381 if(tmp_header == pg_header)
1382 { //************ s1-1*******************
1383 WriteState = PG_STATE_DATA;
1385 #if (EFUSE_ERROE_HANDLE == 1)
1386 else if(tmp_header == 0xFF){//************ s1-3: if Write or read func doesn't work *******************
1387 //efuse_addr doesn't change
1388 WriteState = PG_STATE_HEADER;
1389 repeat_times++;
1390 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1391 bContinual = FALSE;
1392 bResult = FALSE;
1395 #endif
1396 else
1397 {//************ s1-2 : fixed the header procedure *******************
1398 tmp_pkt.offset = (tmp_header>>4) & 0x0F;
1399 tmp_pkt.word_en= tmp_header & 0x0F;
1400 tmp_word_cnts = efuse_CalculateWordCnts(tmp_pkt.word_en);
1402 //************ s1-2-A :cover the exist data *******************
1403 memset(originaldata,0xff,sizeof(u8)*8);
1405 if(efuse_PgPacketRead( dev, tmp_pkt.offset,originaldata))
1406 { //check if data exist
1407 badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,tmp_pkt.word_en,originaldata);
1408 if(0x0F != (badworden&0x0F))
1410 u8 reorg_offset = tmp_pkt.offset;
1411 u8 reorg_worden=badworden;
1412 efuse_PgPacketWrite(dev,reorg_offset,reorg_worden,originaldata);
1413 efuse_addr = efuse_GetCurrentSize(dev);
1415 else{
1416 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1419 //************ s1-2-B: wrong address*******************
1420 else
1422 efuse_addr = efuse_addr + (tmp_word_cnts*2) +1; //Next pg_packet
1425 #if (EFUSE_ERROE_HANDLE == 1)
1426 WriteState=PG_STATE_HEADER;
1427 repeat_times++;
1428 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1429 bContinual = FALSE;
1430 bResult = FALSE;
1432 #endif
1434 printk("EFUSE PG_STATE_HEADER-2\n");
1440 //write data state
1441 else if(WriteState==PG_STATE_DATA)
1442 { //************ s1-1 *******************
1443 printk("EFUSE PG_STATE_DATA\n");
1444 badworden = 0x0f;
1445 badworden = efuse_WordEnableDataWrite(dev,efuse_addr+1,target_pkt.word_en,target_pkt.data);
1446 if((badworden&0x0F)==0x0F)
1447 { //************ s1-1-A *******************
1448 bContinual = FALSE;
1450 else
1451 {//reorganize other pg packet //************ s1-1-B *******************
1452 efuse_addr = efuse_addr + (2*target_word_cnts) +1;//next pg packet addr
1454 target_pkt.offset = offset;
1455 target_pkt.word_en= badworden;
1456 target_word_cnts = efuse_CalculateWordCnts(target_pkt.word_en);
1457 #if (EFUSE_ERROE_HANDLE == 1)
1458 WriteState=PG_STATE_HEADER;
1459 repeat_times++;
1460 if(repeat_times>EFUSE_REPEAT_THRESHOLD_){
1461 bContinual = FALSE;
1462 bResult = FALSE;
1464 #endif
1465 printk("EFUSE PG_STATE_HEADER-3\n");
1470 if(efuse_addr >= (EFUSE_MAX_SIZE-EFUSE_OOB_PROTECT_BYTES))
1472 RT_TRACE(COMP_EPROM, "efuse_PgPacketWrite(): efuse_addr(%x) Out of size!!\n", efuse_addr);
1474 return TRUE;
1477 /*-----------------------------------------------------------------------------
1478 * Function: efuse_WordEnableDataRead
1480 * Overview: Read allowed word in current efuse section data.
1482 * Input: NONE
1484 * Output: NONE
1486 * Return: NONE
1488 * Revised History:
1489 * When Who Remark
1490 * 11/16/2008 MHC Create Version 0.
1491 * 11/21/2008 MHC Fix Write bug when we only enable late word.
1493 *---------------------------------------------------------------------------*/
1494 static void
1495 efuse_WordEnableDataRead( u8 word_en,u8 *sourdata,u8 *targetdata)
1498 if (!(word_en&BIT0))
1500 targetdata[0] = sourdata[0];//sourdata[tmpindex++];
1501 targetdata[1] = sourdata[1];//sourdata[tmpindex++];
1503 if (!(word_en&BIT1))
1505 targetdata[2] = sourdata[2];//sourdata[tmpindex++];
1506 targetdata[3] = sourdata[3];//sourdata[tmpindex++];
1508 if (!(word_en&BIT2))
1510 targetdata[4] = sourdata[4];//sourdata[tmpindex++];
1511 targetdata[5] = sourdata[5];//sourdata[tmpindex++];
1513 if (!(word_en&BIT3))
1515 targetdata[6] = sourdata[6];//sourdata[tmpindex++];
1516 targetdata[7] = sourdata[7];//sourdata[tmpindex++];
1520 /*-----------------------------------------------------------------------------
1521 * Function: efuse_WordEnableDataWrite
1523 * Overview: Write necessary word unit into current efuse section!
1525 * Input: NONE
1527 * Output: NONE
1529 * Return: NONE
1531 * Revised History:
1532 * When Who Remark
1533 * 11/16/2008 MHC Reorganize Efuse operate flow!!.
1535 *---------------------------------------------------------------------------*/
1536 static u8
1537 efuse_WordEnableDataWrite( struct net_device* dev, u16 efuse_addr, u8 word_en, u8 *data)
1539 u16 tmpaddr = 0;
1540 u16 start_addr = efuse_addr;
1541 u8 badworden = 0x0F;
1542 u8 tmpdata[8];
1544 memset(tmpdata,0xff,PGPKT_DATA_SIZE);
1546 if(!(word_en&BIT0))
1548 tmpaddr = start_addr;
1549 efuse_OneByteWrite(dev,start_addr++, data[0]);
1550 efuse_OneByteWrite(dev,start_addr++, data[1]);
1552 efuse_OneByteRead(dev,tmpaddr, &tmpdata[0]);
1553 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[1]);
1554 if((data[0]!=tmpdata[0])||(data[1]!=tmpdata[1])){
1555 badworden &= (~BIT0);
1558 if(!(word_en&BIT1))
1560 tmpaddr = start_addr;
1561 efuse_OneByteWrite(dev,start_addr++, data[2]);
1562 efuse_OneByteWrite(dev,start_addr++, data[3]);
1564 efuse_OneByteRead(dev,tmpaddr , &tmpdata[2]);
1565 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[3]);
1566 if((data[2]!=tmpdata[2])||(data[3]!=tmpdata[3])){
1567 badworden &=( ~BIT1);
1570 if(!(word_en&BIT2))
1572 tmpaddr = start_addr;
1573 efuse_OneByteWrite(dev,start_addr++, data[4]);
1574 efuse_OneByteWrite(dev,start_addr++, data[5]);
1576 efuse_OneByteRead(dev,tmpaddr, &tmpdata[4]);
1577 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[5]);
1578 if((data[4]!=tmpdata[4])||(data[5]!=tmpdata[5])){
1579 badworden &=( ~BIT2);
1582 if(!(word_en&BIT3))
1584 tmpaddr = start_addr;
1585 efuse_OneByteWrite(dev,start_addr++, data[6]);
1586 efuse_OneByteWrite(dev,start_addr++, data[7]);
1588 efuse_OneByteRead(dev,tmpaddr, &tmpdata[6]);
1589 efuse_OneByteRead(dev,tmpaddr+1, &tmpdata[7]);
1590 if((data[6]!=tmpdata[6])||(data[7]!=tmpdata[7])){
1591 badworden &=( ~BIT3);
1594 return badworden;
1597 /*-----------------------------------------------------------------------------
1598 * Function: efuse_PowerSwitch
1600 * Overview: When we want to enable write operation, we should change to
1601 * pwr on state. When we stop write, we should switch to 500k mode
1602 * and disable LDO 2.5V.
1604 * Input: NONE
1606 * Output: NONE
1608 * Return: NONE
1610 * Revised History:
1611 * When Who Remark
1612 * 11/17/2008 MHC Create Version 0.
1614 *---------------------------------------------------------------------------*/
1615 static void
1616 efuse_PowerSwitch(struct net_device* dev, u8 PwrState)
1618 u8 tempval;
1619 if (PwrState == TRUE)
1621 // Enable LDO 2.5V for write action
1622 tempval = read_nic_byte(dev, EFUSE_TEST+3);
1623 write_nic_byte(dev, EFUSE_TEST+3, (tempval | 0x80));
1625 // Change Efuse Clock for write action to 40MHZ
1626 write_nic_byte(dev, EFUSE_CLK, 0x03);
1628 else
1630 // Enable LDO 2.5V for write action
1631 tempval = read_nic_byte(dev, EFUSE_TEST+3);
1632 write_nic_byte(dev, EFUSE_TEST+3, (tempval & 0x7F));
1634 // Change Efuse Clock for write action to 500K
1635 write_nic_byte(dev, EFUSE_CLK, 0x02);
1640 /*-----------------------------------------------------------------------------
1641 * Function: efuse_GetCurrentSize
1643 * Overview: Get current efuse size!!!
1645 * Input: NONE
1647 * Output: NONE
1649 * Return: NONE
1651 * Revised History:
1652 * When Who Remark
1653 * 11/16/2008 MHC Create Version 0.
1655 *---------------------------------------------------------------------------*/
1656 static u16
1657 efuse_GetCurrentSize(struct net_device* dev)
1659 bool bContinual = TRUE;
1661 u16 efuse_addr = 0;
1662 u8 hoffset=0,hworden=0;
1663 u8 efuse_data,word_cnts=0;
1665 while ( bContinual &&
1666 efuse_OneByteRead(dev, efuse_addr ,&efuse_data) &&
1667 (efuse_addr < EFUSE_MAX_SIZE) )
1669 if(efuse_data!=0xFF)
1671 hoffset = (efuse_data>>4) & 0x0F;
1672 hworden = efuse_data & 0x0F;
1673 word_cnts = efuse_CalculateWordCnts(hworden);
1674 //read next header
1675 efuse_addr = efuse_addr + (word_cnts*2)+1;
1677 else
1679 bContinual = FALSE ;
1683 return efuse_addr;
1687 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
1688 static u8
1689 efuse_CalculateWordCnts(u8 word_en)
1691 u8 word_cnts = 0;
1692 if(!(word_en & BIT0)) word_cnts++; // 0 : write enable
1693 if(!(word_en & BIT1)) word_cnts++;
1694 if(!(word_en & BIT2)) word_cnts++;
1695 if(!(word_en & BIT3)) word_cnts++;
1696 return word_cnts;
1699 /*-----------------------------------------------------------------------------
1700 * Function: EFUSE_ProgramMap
1702 * Overview: Read EFUSE map file and execute PG.
1704 * Input: NONE
1706 * Output: NONE
1708 * Return: NONE
1710 * Revised History:
1711 * When Who Remark
1712 * 11/10/2008 MHC Create Version 0.
1714 *---------------------------------------------------------------------------*/
1715 #ifdef TO_DO_LIST
1716 extern bool // 0=Shadow 1=Real Efuse
1717 EFUSE_ProgramMap(struct net_device* dev, char* pFileName,u8 TableType)
1719 struct r8192_priv *priv = ieee80211_priv(dev);
1720 s4Byte nLinesRead, ithLine;
1721 RT_STATUS rtStatus = RT_STATUS_SUCCESS;
1722 char* szLine;
1723 u32 u4bRegValue, u4RegMask;
1724 u32 u4bMove;
1725 u16 index = 0;
1726 u16 i;
1727 u8 eeprom[HWSET_MAX_SIZE_92S];
1729 rtStatus = PlatformReadFile(
1730 dev,
1731 pFileName,
1732 (u8*)(priv->BufOfLines),
1733 MAX_LINES_HWCONFIG_TXT,
1734 MAX_BYTES_LINE_HWCONFIG_TXT,
1735 &nLinesRead
1738 if(rtStatus == RT_STATUS_SUCCESS)
1740 memcp(pHalData->BufOfLines3, pHalData->BufOfLines,
1741 nLinesRead*MAX_BYTES_LINE_HWCONFIG_TXT);
1742 pHalData->nLinesRead3 = nLinesRead;
1745 if(rtStatus == RT_STATUS_SUCCESS)
1747 printk("szEepromFile(): read %s ok\n", pFileName);
1748 for(ithLine = 0; ithLine < nLinesRead; ithLine++)
1750 szLine = pHalData->BufOfLines[ithLine];
1751 printk("Line-%d String =%s\n", ithLine, szLine);
1753 if(!IsCommentString(szLine))
1755 // EEPROM map one line has 8 words content.
1756 for (i = 0; i < 8; i++)
1758 u32 j;
1760 efuse_ParsingMap(szLine, &u4bRegValue, &u4bMove);
1762 // Get next hex value as EEPROM value.
1763 szLine += u4bMove;
1764 eeprom[index++] = (u8)(u4bRegValue&0xff);
1765 eeprom[index++] = (u8)((u4bRegValue>>8)&0xff);
1767 printk("Addr-%d = %x\n", (ithLine*8+i), u4bRegValue);
1774 else
1776 printk("szEepromFile(): Fail read%s\n", pFileName);
1777 return RT_STATUS_FAILURE;
1780 // Use map file to update real Efuse or shadow modify table.
1781 if (TableType == 1)
1783 efuse_WriteAllMap(dev, eeprom, HWSET_MAX_SIZE_92S);
1785 else
1787 // Modify shadow table.
1788 for (i = 0; i < HWSET_MAX_SIZE_92S; i++)
1789 EFUSE_ShadowWrite(dev, 1, i, (u32)eeprom[i]);
1792 return rtStatus;
1795 #endif
1797 /*-----------------------------------------------------------------------------
1798 * Function: efuse_ParsingMap
1800 * Overview:
1802 * Input: NONE
1804 * Output: NONE
1806 * Return: NONE
1808 * Revised History:
1809 * When Who Remark
1810 * 11/08/2008 MHC Create Version 0.
1812 *---------------------------------------------------------------------------*/
1813 #ifdef TO_DO_LIST
1814 static bool
1815 efuse_ParsingMap(char* szStr,u32* pu4bVal,u32* pu4bMove)
1817 char* szScan = szStr;
1819 // Check input parameter.
1820 if(szStr == NULL || pu4bVal == NULL || pu4bMove == NULL)
1822 return FALSE;
1825 // Initialize output.
1826 *pu4bMove = 0;
1827 *pu4bVal = 0;
1829 // Skip leading space.
1830 while( *szScan != '\0' &&
1831 (*szScan == ' ' || *szScan == '\t') )
1833 szScan++;
1834 (*pu4bMove)++;
1837 // Check if szScan is now pointer to a character for hex digit,
1838 // if not, it means this is not a valid hex number.
1839 if (!isxdigit(*szScan))
1840 return FALSE;
1842 // Parse each digit.
1845 *pu4bVal = (*pu4bVal << 4) + hex_to_bin(*szScan);
1847 szScan++;
1848 (*pu4bMove)++;
1849 } while (isxdigit(*szScan));
1851 return TRUE;
1854 #endif
1856 int efuse_one_byte_rw(struct net_device* dev, u8 bRead, u16 addr, u8 *data)
1858 u32 bResult;
1859 u8 tmpidx = 0;
1860 u8 tmpv8=0;
1862 // -----------------e-fuse reg ctrl ---------------------------------
1864 write_nic_byte(dev, EFUSE_CTRL+1, (u8)(addr&0xff)); //address
1865 tmpv8 = ((u8)((addr>>8) &0x03) ) | (read_nic_byte(dev, EFUSE_CTRL+2)&0xFC );
1866 write_nic_byte(dev, EFUSE_CTRL+2, tmpv8);
1868 if(TRUE==bRead){
1870 write_nic_byte(dev, EFUSE_CTRL+3, 0x72);//read cmd
1872 while(!(0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1873 tmpidx++;
1875 if(tmpidx<100){
1876 *data=read_nic_byte(dev, EFUSE_CTRL);
1877 bResult = TRUE;
1879 else
1881 *data = 0;
1882 bResult = FALSE;
1886 else{
1887 write_nic_byte(dev, EFUSE_CTRL, *data);//data
1889 write_nic_byte(dev, EFUSE_CTRL+3, 0xF2);//write cmd
1891 while((0x80 & read_nic_byte(dev, EFUSE_CTRL+3)) && (tmpidx<100) ){
1892 tmpidx++;
1894 if(tmpidx<100)
1896 *data=read_nic_byte(dev, EFUSE_CTRL);
1897 bResult = TRUE;
1899 else
1901 *data = 0;
1902 bResult = FALSE;
1906 return bResult;
1909 void efuse_access(struct net_device* dev, u8 bRead,u16 start_addr, u8 cnts, u8 *data)
1911 u8 efuse_clk_ori,efuse_clk_new;//,tmp8;
1912 u32 i = 0;
1914 if(start_addr>0x200) return;
1915 // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
1916 efuse_clk_ori = read_nic_byte(dev,SYS_FUNC_EN+1);
1917 efuse_clk_new = efuse_clk_ori|0x20;
1919 if(efuse_clk_new!= efuse_clk_ori){
1920 write_nic_byte(dev, SYS_FUNC_EN+1, efuse_clk_new);
1922 #ifdef _POWERON_DELAY_
1923 mdelay(10);
1924 #endif
1925 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1926 write_nic_byte(dev, EFUSE_TEST+3, (read_nic_byte(dev, EFUSE_TEST+3)|0x80));
1927 write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
1929 #ifdef _PRE_EXECUTE_READ_CMD_
1931 unsigned char tmpdata;
1932 efuse_OneByteRead(dev, 0,&tmpdata);
1934 #endif
1936 //-----------------e-fuse one byte read / write ------------------------------
1937 for(i=0;i<cnts;i++){
1938 efuse_one_byte_rw(dev,bRead, start_addr+i , data+i);
1941 write_nic_byte(dev, EFUSE_TEST+3, read_nic_byte(dev, EFUSE_TEST+3)&0x7f);
1942 write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
1944 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
1945 if(efuse_clk_new != efuse_clk_ori) write_nic_byte(dev, 0x10250003, efuse_clk_ori);
1949 #ifdef TO_DO_LIST
1950 static void efuse_reg_ctrl(struct net_device* dev, u8 bPowerOn)
1952 if(TRUE==bPowerOn){
1953 // -----------------SYS_FUNC_EN Digital Core Vdd enable ---------------------------------
1954 write_nic_byte(dev, SYS_FUNC_EN+1, read_nic_byte(dev,SYS_FUNC_EN+1)|0x20);
1955 #ifdef _POWERON_DELAY_
1956 mdelay(10);
1957 #endif
1958 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1959 write_nic_byte(dev, EFUSE_TEST+4, (read_nic_byte(dev, EFUSE_TEST+4)|0x80));
1960 write_nic_byte(dev, EFUSE_CLK_CTRL, (read_nic_byte(dev, EFUSE_CLK_CTRL)|0x03));
1961 #ifdef _PRE_EXECUTE_READ_CMD_
1963 unsigned char tmpdata;
1964 efuse_OneByteRead(dev, 0,&tmpdata);
1967 #endif
1969 else{
1970 // -----------------e-fuse pwr & clk reg ctrl ---------------------------------
1971 write_nic_byte(dev, EFUSE_TEST+4, read_nic_byte(dev, EFUSE_TEST+4)&0x7f);
1972 write_nic_byte(dev, EFUSE_CLK_CTRL, read_nic_byte(dev, EFUSE_CLK_CTRL)&0xfd);
1973 // -----------------SYS_FUNC_EN Digital Core Vdd disable ---------------------------------
1979 #endif
1981 void efuse_read_data(struct net_device* dev,u8 efuse_read_item,u8 *data,u32 data_size)
1983 u8 offset, word_start,byte_start,byte_cnts;
1984 u8 efusedata[EFUSE_MAC_LEN];
1985 u8 *tmpdata = NULL;
1987 u8 pg_pkt_cnts ;
1989 u8 tmpidx;
1990 u8 pg_data[8];
1992 if(efuse_read_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
1993 return ;
1996 offset = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].offset ;
1997 word_start = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].word_start;
1998 byte_start = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_start;
1999 byte_cnts = RTL8712_SDIO_EFUSE_TABLE[efuse_read_item].byte_cnts;
2001 if(data_size!=byte_cnts){
2002 return;
2005 pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2007 if(pg_pkt_cnts > 1){
2008 tmpdata = efusedata;
2010 if(tmpdata!=NULL)
2012 memset(tmpdata,0xff,pg_pkt_cnts*PGPKT_DATA_SIZE);
2014 for(tmpidx=0;tmpidx<pg_pkt_cnts;tmpidx++)
2016 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2017 if(TRUE== efuse_PgPacketRead(dev,offset+tmpidx,pg_data))
2019 memcpy(tmpdata+(PGPKT_DATA_SIZE*tmpidx),pg_data,PGPKT_DATA_SIZE);
2022 memcpy(data,(tmpdata+ (2*word_start)+byte_start ),data_size);
2025 else
2027 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2028 if(TRUE==efuse_PgPacketRead(dev,offset,pg_data)){
2029 memcpy(data,pg_data+ (2*word_start)+byte_start ,data_size);
2035 //per interface doesn't alike
2036 void efuse_write_data(struct net_device* dev,u8 efuse_write_item,u8 *data,u32 data_size,u32 bWordUnit)
2038 u8 offset, word_start,byte_start,byte_cnts;
2039 u8 word_en = 0x0f,word_cnts;
2040 u8 pg_pkt_cnts ;
2042 u8 tmpidx,tmpbitmask;
2043 u8 pg_data[8],tmpbytes=0;
2045 if(efuse_write_item> (sizeof(RTL8712_SDIO_EFUSE_TABLE)/sizeof(EFUSE_MAP))){
2046 return ;
2049 offset = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].offset ;
2050 word_start = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].word_start;
2051 byte_start = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_start;
2052 byte_cnts = RTL8712_SDIO_EFUSE_TABLE[efuse_write_item].byte_cnts;
2054 if(data_size > byte_cnts){
2055 return;
2057 pg_pkt_cnts = (byte_cnts /PGPKT_DATA_SIZE) +1;
2058 word_cnts = byte_cnts /2 ;
2060 if(byte_cnts %2){
2061 word_cnts+=1;
2063 if((byte_start==1)||((byte_cnts%2)==1)){//situation A
2065 if((efuse_write_item==EFUSE_F0CIS)||(efuse_write_item==EFUSE_F1CIS)){
2066 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2067 efuse_PgPacketRead(dev,offset,pg_data);
2069 if(efuse_write_item==EFUSE_F0CIS){
2070 word_en = 0x07;
2071 memcpy(pg_data+word_start*2+byte_start,data,sizeof(u8)*2);
2072 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2074 word_en = 0x00;
2075 efuse_PgPacketWrite(dev,(offset+1),word_en,data+2);
2077 word_en = 0x00;
2078 efuse_PgPacketRead(dev,offset+2,pg_data);
2079 memcpy(pg_data,data+2+8,sizeof(u8)*7);
2081 efuse_PgPacketWrite(dev,(offset+2),word_en,pg_data);
2083 else if(efuse_write_item==EFUSE_F1CIS){
2084 word_en = 0x07;
2085 efuse_PgPacketRead(dev,offset,pg_data);
2086 pg_data[7] = data[0];
2087 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2089 word_en = 0x00;
2090 for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++){
2091 efuse_PgPacketWrite(dev,(offset+1+tmpidx),word_en,data+1+(tmpidx*PGPKT_DATA_SIZE));
2096 else{
2097 memset(pg_data,0xff,PGPKT_DATA_SIZE);
2098 if((efuse_write_item==EFUSE_SDIO_SETTING)||(efuse_write_item==EFUSE_CCCR)){
2099 word_en = 0x0e ;
2100 tmpbytes = 2;
2102 else if(efuse_write_item == EFUSE_SDIO_MODE){
2103 word_en = 0x0d ;
2104 tmpbytes = 2;
2106 else if(efuse_write_item == EFUSE_OCR){
2107 word_en = 0x09 ;
2108 tmpbytes = 4;
2110 else if((efuse_write_item == EFUSE_EEPROM_VER)||(efuse_write_item==EFUSE_CHAN_PLAN)){
2111 word_en = 0x07 ;
2112 tmpbytes = 2;
2114 if(bWordUnit==TRUE){
2115 memcpy(pg_data+word_start*2 ,data,sizeof(u8)*tmpbytes);
2117 else{
2118 efuse_PgPacketRead(dev,offset,pg_data);
2119 memcpy(pg_data+(2*word_start)+byte_start,data,sizeof(u8)*byte_cnts);
2122 efuse_PgPacketWrite(dev,offset,word_en,pg_data+(word_start*2));
2127 else if(pg_pkt_cnts>1){//situation B
2128 if(word_start==0){
2129 word_en = 0x00;
2130 for(tmpidx = 0 ;tmpidx<(word_cnts/4);tmpidx++)
2132 efuse_PgPacketWrite(dev,(offset+tmpidx),word_en,data+(tmpidx*PGPKT_DATA_SIZE));
2134 word_en = 0x0f;
2135 for(tmpidx= 0; tmpidx<(word_cnts%4) ; tmpidx++)
2137 tmpbitmask =tmpidx;
2138 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2139 //BIT0
2141 efuse_PgPacketWrite(dev,offset+(word_cnts/4),word_en,data+((word_cnts/4)*PGPKT_DATA_SIZE));
2142 }else
2147 else{//situation C
2148 word_en = 0x0f;
2149 for(tmpidx= 0; tmpidx<word_cnts ; tmpidx++)
2151 tmpbitmask = word_start + tmpidx ;
2152 word_en &= (~(EFUSE_BIT(tmpbitmask)));
2154 efuse_PgPacketWrite(dev,offset,word_en,data);
2159 void efuset_test_func_read(struct net_device* dev)
2161 u8 chipid[2];
2162 u8 ocr[3];
2163 u8 macaddr[6];
2164 u8 txpowertable[28];
2166 memset(chipid,0,sizeof(u8)*2);
2167 efuse_read_data(dev,EFUSE_CHIP_ID,chipid,sizeof(chipid));
2169 memset(ocr,0,sizeof(u8)*3);
2170 efuse_read_data(dev,EFUSE_CCCR,ocr,sizeof(ocr));
2172 memset(macaddr,0,sizeof(u8)*6);
2173 efuse_read_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr));
2175 memset(txpowertable,0,sizeof(u8)*28);
2176 efuse_read_data(dev,EFUSE_TXPW_TAB,txpowertable,sizeof(txpowertable));
2179 void efuset_test_func_write(struct net_device* dev)
2181 u32 bWordUnit = TRUE;
2182 u8 CCCR=0x02,SDIO_SETTING = 0xFF;
2183 u8 tmpdata[2];
2185 u8 macaddr[6] = {0x00,0xe0,0x4c,0x87,0x12,0x66};
2186 efuse_write_data(dev,EFUSE_MAC_ADDR,macaddr,sizeof(macaddr),bWordUnit);
2188 bWordUnit = FALSE;
2189 efuse_write_data(dev,EFUSE_CCCR,&CCCR,sizeof(u8),bWordUnit);
2191 bWordUnit = FALSE;
2192 efuse_write_data(dev,EFUSE_SDIO_SETTING,&SDIO_SETTING,sizeof(u8),bWordUnit);
2194 bWordUnit = TRUE;
2195 tmpdata[0] =SDIO_SETTING ;
2196 tmpdata[1] =CCCR ;
2197 efuse_write_data(dev,EFUSE_SDIO_SETTING,tmpdata,sizeof(tmpdata),bWordUnit);