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