Merge tag 'nfs-for-3.14-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / rtl8821ae / efuse.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  Realtek Corporation.
4  *
5  * Tmis program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * Tmis program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * tmis program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  * Tme full GNU General Public License is included in this distribution in the
19  * file called LICENSE.
20  *
21  * Contact Information:
22  * wlanfae <wlanfae@realtek.com>
23  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24  * Hsinchu 300, Taiwan.
25  *
26  * Larry Finger <Larry.Finger@lwfinger.net>
27  *
28  *****************************************************************************/
29 #include "wifi.h"
30 #include "efuse.h"
31 #include "btcoexist/halbt_precomp.h"
32 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
33 #include <linux/export.h>
34 #endif
35
36 static const u8 MAX_PGPKT_SIZE = 9;
37 static const u8 PGPKT_DATA_SIZE = 8;
38 static const int EFUSE_MAX_SIZE = 512;
39
40 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
41         {0, 0, 0, 2},
42         {0, 1, 0, 2},
43         {0, 2, 0, 2},
44         {1, 0, 0, 1},
45         {1, 0, 1, 1},
46         {1, 1, 0, 1},
47         {1, 1, 1, 3},
48         {1, 3, 0, 17},
49         {3, 3, 1, 48},
50         {10, 0, 0, 6},
51         {10, 3, 0, 1},
52         {10, 3, 1, 1},
53         {11, 0, 0, 28}
54 };
55
56 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
57                                     u8 * value);
58 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
59                                     u16 * value);
60 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
61                                     u32 * value);
62 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
63                                      u8 value);
64 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
65                                      u16 value);
66 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
67                                      u32 value);
68 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
69                                 u8 data);
70 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse);
71 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
72                                 u8 *data);
73 static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
74                                  u8 word_en, u8 * data);
75 static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
76                                         u8 * targetdata);
77 static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
78                                        u16 efuse_addr, u8 word_en, u8 * data);
79 static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
80                                         u8 pwrstate);
81 static u16 efuse_get_current_size(struct ieee80211_hw *hw);
82 static u8 efuse_calculate_word_cnts(u8 word_en);
83
84 void efuse_initialize(struct ieee80211_hw *hw)
85 {
86         struct rtl_priv *rtlpriv = rtl_priv(hw);
87         u8 bytetemp;
88         u8 temp;
89
90         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
91         temp = bytetemp | 0x20;
92         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
93
94         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
95         temp = bytetemp & 0xFE;
96         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
97
98         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
99         temp = bytetemp | 0x80;
100         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
101
102         rtl_write_byte(rtlpriv, 0x2F8, 0x3);
103
104         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
105
106 }
107
108 u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
109 {
110         struct rtl_priv *rtlpriv = rtl_priv(hw);
111         u8 data;
112         u8 bytetemp;
113         u8 temp;
114         u32 k = 0;
115         const u32 efuse_real_content_len =
116                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
117
118         if (address < efuse_real_content_len) {
119                 temp = address & 0xFF;
120                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
121                                temp);
122                 bytetemp = rtl_read_byte(rtlpriv,
123                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
124                 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
125                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
126                                temp);
127
128                 bytetemp = rtl_read_byte(rtlpriv,
129                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
130                 temp = bytetemp & 0x7F;
131                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
132                                temp);
133
134                 bytetemp = rtl_read_byte(rtlpriv,
135                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
136                 while (!(bytetemp & 0x80)) {
137                         bytetemp = rtl_read_byte(rtlpriv,
138                                                  rtlpriv->cfg->
139                                                  maps[EFUSE_CTRL] + 3);
140                         k++;
141                         if (k == 1000) {
142                                 k = 0;
143                                 break;
144                         }
145                 }
146                 data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
147                 return data;
148         } else
149                 return 0xFF;
150
151 }
152 //EXPORT_SYMBOL(efuse_read_1byte);
153
154 void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
155 {
156         struct rtl_priv *rtlpriv = rtl_priv(hw);
157         u8 bytetemp;
158         u8 temp;
159         u32 k = 0;
160         const u32 efuse_real_content_len =
161                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
162
163         RT_TRACE(COMP_EFUSE, DBG_LOUD,
164                  ("Addr=%x Data =%x\n", address, value));
165
166         if (address < efuse_real_content_len) {
167                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
168
169                 temp = address & 0xFF;
170                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
171                                temp);
172                 bytetemp = rtl_read_byte(rtlpriv,
173                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
174
175                 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
176                 rtl_write_byte(rtlpriv,
177                                rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
178
179                 bytetemp = rtl_read_byte(rtlpriv,
180                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
181                 temp = bytetemp | 0x80;
182                 rtl_write_byte(rtlpriv,
183                                rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
184
185                 bytetemp = rtl_read_byte(rtlpriv,
186                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
187
188                 while (bytetemp & 0x80) {
189                         bytetemp = rtl_read_byte(rtlpriv,
190                                                  rtlpriv->cfg->
191                                                  maps[EFUSE_CTRL] + 3);
192                         k++;
193                         if (k == 100) {
194                                 k = 0;
195                                 break;
196                         }
197                 }
198         }
199
200 }
201
202 void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
203 {
204         struct rtl_priv *rtlpriv = rtl_priv(hw);
205         u32 value32;
206         u8 readbyte;
207         u16 retry;
208
209         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
210                        (_offset & 0xff));
211         readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
212         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
213                        ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
214
215         readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
216         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
217                        (readbyte & 0x7f));
218
219         retry = 0;
220         value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
221         while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
222                 value32 = rtl_read_dword(rtlpriv,
223                                          rtlpriv->cfg->maps[EFUSE_CTRL]);
224                 retry++;
225         }
226
227         udelay(50);
228         value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
229
230         *pbuf = (u8) (value32 & 0xff);
231 }
232
233 void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
234 {
235         struct rtl_priv *rtlpriv = rtl_priv(hw);
236         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
237         u8 efuse_tbl[rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]];
238         u8 rtemp8[1];
239         u16 efuse_addr = 0;
240         u8 offset, wren;
241         u8 u1temp = 0;
242         u16 i;
243         u16 j;
244         const u16 efuse_max_section =
245                 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
246         const u32 efuse_real_content_len =
247                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
248         u16 efuse_word[efuse_max_section][EFUSE_MAX_WORD_UNIT];
249         u16 efuse_utilized = 0;
250         u8 efuse_usage;
251
252         if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
253                 RT_TRACE(COMP_EFUSE, DBG_LOUD,
254                          ("read_efuse(): Invalid offset(%#x) with read "
255                           "bytes(%#x)!!\n", _offset, _size_byte));
256                 return;
257         }
258
259         for (i = 0; i < efuse_max_section; i++)
260                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
261                         efuse_word[i][j] = 0xFFFF;
262
263         read_efuse_byte(hw, efuse_addr, rtemp8);
264         if (*rtemp8 != 0xFF) {
265                 efuse_utilized++;
266                 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
267                         ("Addr=%d\n", efuse_addr));
268                 efuse_addr++;
269         }
270
271         while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_real_content_len)) {
272                 /*  Check PG header for section num.  */
273                 if((*rtemp8 & 0x1F ) == 0x0F) {/* extended header */
274                         u1temp =( (*rtemp8 & 0xE0) >> 5);
275                         read_efuse_byte(hw, efuse_addr, rtemp8);
276
277                         if((*rtemp8 & 0x0F) == 0x0F) {
278                                 efuse_addr++;
279                                 read_efuse_byte(hw, efuse_addr, rtemp8);
280
281                                 if (*rtemp8 != 0xFF &&
282                                     (efuse_addr < efuse_real_content_len)) {
283                                         efuse_addr++;
284                                 }
285                                 continue;
286                         } else {
287                                 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
288                                 wren = (*rtemp8 & 0x0F);
289                                 efuse_addr++;
290                         }
291                 } else {
292                         offset = ((*rtemp8 >> 4) & 0x0f);
293                         wren = (*rtemp8 & 0x0f);
294                 }
295
296                 if (offset < efuse_max_section) {
297                         RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
298                                 ("offset-%d Worden=%x\n", offset, wren));
299
300                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
301                                 if (!(wren & 0x01)) {
302                                         RTPRINT(rtlpriv, FEEPROM,
303                                                 EFUSE_READ_ALL, ("Addr=%d\n",
304                                                                  efuse_addr));
305
306                                         read_efuse_byte(hw, efuse_addr, rtemp8);
307                                         efuse_addr++;
308                                         efuse_utilized++;
309                                         efuse_word[offset][i] = (*rtemp8 &
310                                                                  0xff);
311
312                                         if (efuse_addr >=
313                                             efuse_real_content_len)
314                                                 break;
315
316                                         RTPRINT(rtlpriv, FEEPROM,
317                                                 EFUSE_READ_ALL, ("Addr=%d\n",
318                                                                  efuse_addr));
319
320                                         read_efuse_byte(hw, efuse_addr, rtemp8);
321                                         efuse_addr++;
322                                         efuse_utilized++;
323                                         efuse_word[offset][i] |=
324                                             (((u16) * rtemp8 << 8) & 0xff00);
325
326                                         if (efuse_addr >= efuse_real_content_len)
327                                                 break;
328                                 }
329
330                                 wren >>= 1;
331                         }
332                 }
333
334                 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
335                         ("Addr=%d\n", efuse_addr));
336                 read_efuse_byte(hw, efuse_addr, rtemp8);
337                 if (*rtemp8 != 0xFF && (efuse_addr < efuse_real_content_len)) {
338                         efuse_utilized++;
339                         efuse_addr++;
340                 }
341         }
342
343         for (i = 0; i < efuse_max_section; i++) {
344                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
345                         efuse_tbl[(i * 8) + (j * 2)] =
346                             (efuse_word[i][j] & 0xff);
347                         efuse_tbl[(i * 8) + ((j * 2) + 1)] =
348                             ((efuse_word[i][j] >> 8) & 0xff);
349                 }
350         }
351
352         for (i = 0; i < _size_byte; i++)
353                 pbuf[i] = efuse_tbl[_offset + i];
354
355         rtlefuse->efuse_usedbytes = efuse_utilized;
356         efuse_usage = (u8) ((efuse_utilized * 100) / efuse_real_content_len);
357         rtlefuse->efuse_usedpercentage = efuse_usage;
358         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
359                                       (u8 *) & efuse_utilized);
360         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
361                                       (u8 *) & efuse_usage);
362 }
363
364 bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
365 {
366         struct rtl_priv *rtlpriv = rtl_priv(hw);
367         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
368         u8 section_idx, i, Base;
369         u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
370         bool bwordchanged, bresult = true;
371
372         for (section_idx = 0; section_idx < 16; section_idx++) {
373                 Base = section_idx * 8;
374                 bwordchanged = false;
375
376                 for (i = 0; i < 8; i = i + 2) {
377                         if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
378                              rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i]) ||
379                             (rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i + 1] !=
380                              rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
381                                                                    1])) {
382                                 words_need++;
383                                 bwordchanged = true;
384                         }
385                 }
386
387                 if (bwordchanged == true)
388                         hdr_num++;
389         }
390
391         totalbytes = hdr_num + words_need * 2;
392         efuse_used = rtlefuse->efuse_usedbytes;
393
394         if ((totalbytes + efuse_used) >= (EFUSE_MAX_SIZE -
395                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
396                 bresult = false;
397
398         RT_TRACE(COMP_EFUSE, DBG_LOUD,
399                  ("efuse_shadow_update_chk(): totalbytes(%#x), "
400                   "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
401                   totalbytes, hdr_num, words_need, efuse_used));
402
403         return bresult;
404 }
405
406 void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
407                        u16 offset, u32 *value)
408 {
409         if (type == 1)
410                 efuse_shadow_read_1byte(hw, offset, (u8 *) value);
411         else if (type == 2)
412                 efuse_shadow_read_2byte(hw, offset, (u16 *) value);
413         else if (type == 4)
414                 efuse_shadow_read_4byte(hw, offset, (u32 *) value);
415
416 }
417
418 void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
419                                 u32 value)
420 {
421         if (type == 1)
422                 efuse_shadow_write_1byte(hw, offset, (u8) value);
423         else if (type == 2)
424                 efuse_shadow_write_2byte(hw, offset, (u16) value);
425         else if (type == 4)
426                 efuse_shadow_write_4byte(hw, offset, (u32) value);
427
428 }
429
430 bool efuse_shadow_update(struct ieee80211_hw *hw)
431 {
432         struct rtl_priv *rtlpriv = rtl_priv(hw);
433         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
434         u16 i, offset, base;
435         u8 word_en = 0x0F;
436         u8 first_pg = false;
437
438         RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
439
440         if (!efuse_shadow_update_chk(hw)) {
441                 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
442                 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
443                        &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
444                        rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
445
446                 RT_TRACE(COMP_EFUSE, DBG_LOUD,
447                          ("efuse out of capacity!!\n"));
448                 return false;
449         }
450         efuse_power_switch(hw, true, true);
451
452         for (offset = 0; offset < 16; offset++) {
453
454                 word_en = 0x0F;
455                 base = offset * 8;
456
457                 for (i = 0; i < 8; i++) {
458                         if (first_pg == true) {
459
460                                 word_en &= ~(BIT(i / 2));
461
462                                 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
463                                     rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
464                         } else {
465
466                                 if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
467                                     rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
468                                         word_en &= ~(BIT(i / 2));
469
470                                         rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
471                                             rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
472                                 }
473                         }
474                 }
475
476                 if (word_en != 0x0F) {
477                         u8 tmpdata[8];
478                         memcpy(tmpdata, (&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base]), 8);
479                         RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
480                                       ("U-efuse\n"), tmpdata, 8);
481
482                         if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
483                                                    tmpdata)) {
484                                 RT_TRACE(COMP_ERR, DBG_WARNING,
485                                          ("PG section(%#x) fail!!\n", offset));
486                                 break;
487                         }
488                 }
489
490         }
491
492         efuse_power_switch(hw, true, false);
493         efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
494
495         memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
496                &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
497                rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
498
499         RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n"));
500         return true;
501 }
502
503 void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
504 {
505         struct rtl_priv *rtlpriv = rtl_priv(hw);
506         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
507
508         if (rtlefuse->autoload_failflag == true) {
509                 memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
510                         0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
511         } else {
512                 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
513         }
514
515         memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
516                         &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
517                         rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
518
519 }
520 //EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
521
522 void efuse_force_write_vendor_Id(struct ieee80211_hw *hw)
523 {
524         u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
525
526         efuse_power_switch(hw, true, true);
527
528         efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
529
530         efuse_power_switch(hw, true, false);
531
532 }
533
534 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
535 {
536 }
537
538 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
539                                     u16 offset, u8 *value)
540 {
541         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
542         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
543 }
544
545 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
546                                     u16 offset, u16 *value)
547 {
548         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
549
550         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
551         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
552
553 }
554
555 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
556                                     u16 offset, u32 *value)
557 {
558         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
559
560         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
561         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
562         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
563         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
564 }
565
566 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
567                                      u16 offset, u8 value)
568 {
569         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
570
571         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
572 }
573
574 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
575                                      u16 offset, u16 value)
576 {
577         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
578
579         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
580         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
581
582 }
583
584 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
585                                      u16 offset, u32 value)
586 {
587         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
588
589         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
590             (u8) (value & 0x000000FF);
591         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
592             (u8) ((value >> 8) & 0x0000FF);
593         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
594             (u8) ((value >> 16) & 0x00FF);
595         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
596             (u8) ((value >> 24) & 0xFF);
597
598 }
599
600 int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
601 {
602         struct rtl_priv *rtlpriv = rtl_priv(hw);
603         u8 tmpidx = 0;
604         int bresult;
605
606         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
607                        (u8) (addr & 0xff));
608         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
609                        ((u8) ((addr >> 8) & 0x03)) |
610                        (rtl_read_byte(rtlpriv,
611                                       rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
612                         0xFC));
613
614         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
615
616         while (!(0x80 & rtl_read_byte(rtlpriv,
617                                       rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
618                && (tmpidx < 100)) {
619                 tmpidx++;
620         }
621
622         if (tmpidx < 100) {
623                 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
624                 bresult = true;
625         } else {
626                 *data = 0xff;
627                 bresult = false;
628         }
629         return bresult;
630 }
631 //EXPORT_SYMBOL(efuse_one_byte_read);
632
633 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
634 {
635         struct rtl_priv *rtlpriv = rtl_priv(hw);
636         u8 tmpidx = 0;
637         bool bresult;
638
639         RT_TRACE(COMP_EFUSE, DBG_LOUD,
640                  ("Addr = %x Data=%x\n", addr, data));
641
642         rtl_write_byte(rtlpriv,
643                        rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
644         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
645                        (rtl_read_byte(rtlpriv,
646                          rtlpriv->cfg->maps[EFUSE_CTRL] +
647                          2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
648
649         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
650         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
651
652         while ((0x80 & rtl_read_byte(rtlpriv,
653                                      rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
654                && (tmpidx < 100)) {
655                 tmpidx++;
656         }
657
658         if (tmpidx < 100)
659                 bresult = true;
660         else
661                 bresult = false;
662
663         return bresult;
664 }
665
666 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
667 {
668         struct rtl_priv *rtlpriv = rtl_priv(hw);
669         efuse_power_switch(hw, false, true);
670         read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
671         efuse_power_switch(hw, false, false);
672 }
673
674 static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
675                                 u8 efuse_data, u8 offset, u8 *tmpdata,
676                                 u8 *readstate)
677 {
678         bool bdataempty = true;
679         u8 hoffset;
680         u8 tmpidx;
681         u8 hworden;
682         u8 word_cnts;
683
684         hoffset = (efuse_data >> 4) & 0x0F;
685         hworden = efuse_data & 0x0F;
686         word_cnts = efuse_calculate_word_cnts(hworden);
687
688         if (hoffset == offset) {
689                 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
690                         if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
691                                                 &efuse_data)) {
692                                 tmpdata[tmpidx] = efuse_data;
693                                 if (efuse_data != 0xff)
694                                         bdataempty = true;
695                         }
696                 }
697
698                 if (bdataempty == true) {
699                         *readstate = PG_STATE_DATA;
700                 } else {
701                         *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
702                         *readstate = PG_STATE_HEADER;
703                 }
704
705         } else {
706                 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
707                 *readstate = PG_STATE_HEADER;
708         }
709 }
710
711 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
712 {
713         u8 readstate = PG_STATE_HEADER;
714
715         bool bcontinual = true;
716
717         u8 efuse_data, word_cnts = 0;
718         u16 efuse_addr = 0;
719         u8 hworden = 0;
720         u8 tmpdata[8];
721
722         if (data == NULL)
723                 return false;
724         if (offset > 15)
725                 return false;
726
727         memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
728         memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
729
730         while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
731                 if (readstate & PG_STATE_HEADER) {
732                         if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
733                             && (efuse_data != 0xFF))
734                                 efuse_read_data_case1(hw, &efuse_addr, efuse_data, offset,
735                                                         tmpdata, &readstate);
736                         else
737                                 bcontinual = false;
738                 } else if (readstate & PG_STATE_DATA) {
739                         efuse_word_enable_data_read(hworden, tmpdata, data);
740                         efuse_addr = efuse_addr + (word_cnts * 2) + 1;
741                         readstate = PG_STATE_HEADER;
742                 }
743
744         }
745
746         if ((data[0] == 0xff) && (data[1] == 0xff) &&
747             (data[2] == 0xff) && (data[3] == 0xff) &&
748             (data[4] == 0xff) && (data[5] == 0xff) &&
749             (data[6] == 0xff) && (data[7] == 0xff))
750                 return false;
751         else
752                 return true;
753
754 }
755
756 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
757                                 u8 efuse_data, u8 offset, int *bcontinual,
758                                 u8 *write_state, struct pgpkt_struct *target_pkt,
759                                 int *repeat_times, int *bresult, u8 word_en)
760 {
761         struct rtl_priv *rtlpriv = rtl_priv(hw);
762         struct pgpkt_struct tmp_pkt;
763         int bdataempty = true;
764         u8 originaldata[8 * sizeof(u8)];
765         u8 badworden = 0x0F;
766         u8 match_word_en, tmp_word_en;
767         u8 tmpindex;
768         u8 tmp_header = efuse_data;
769         u8 tmp_word_cnts;
770
771         tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
772         tmp_pkt.word_en = tmp_header & 0x0F;
773         tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
774
775         if (tmp_pkt.offset != target_pkt->offset) {
776                 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
777                 *write_state = PG_STATE_HEADER;
778         } else {
779                 for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
780                         if (efuse_one_byte_read(hw,
781                                                 (*efuse_addr + 1 + tmpindex),
782                                                 &efuse_data) && (efuse_data != 0xFF))
783                                 bdataempty = false;
784                 }
785
786                 if (bdataempty == false) {
787                         *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
788                         *write_state = PG_STATE_HEADER;
789                 } else {
790                         match_word_en = 0x0F;
791                         if (!((target_pkt->word_en & BIT(0)) |
792                             (tmp_pkt.word_en & BIT(0))))
793                                 match_word_en &= (~BIT(0));
794
795                         if (!((target_pkt->word_en & BIT(1)) |
796                             (tmp_pkt.word_en & BIT(1))))
797                                 match_word_en &= (~BIT(1));
798
799                         if (!((target_pkt->word_en & BIT(2)) |
800                             (tmp_pkt.word_en & BIT(2))))
801                                 match_word_en &= (~BIT(2));
802
803                         if (!((target_pkt->word_en & BIT(3)) |
804                             (tmp_pkt.word_en & BIT(3))))
805                                 match_word_en &= (~BIT(3));
806
807                         if ((match_word_en & 0x0F) != 0x0F) {
808                                 badworden = efuse_word_enable_data_write(hw,
809                                                         *efuse_addr + 1,
810                                                         tmp_pkt.word_en,
811                                                         target_pkt->data);
812
813                                 if (0x0F != (badworden & 0x0F)) {
814                                         u8 reorg_offset = offset;
815                                         u8 reorg_worden = badworden;
816                                         efuse_pg_packet_write(hw, reorg_offset,
817                                                               reorg_worden,
818                                                               originaldata);
819                                 }
820
821                                 tmp_word_en = 0x0F;
822                                 if ((target_pkt->word_en & BIT(0)) ^
823                                     (match_word_en & BIT(0)))
824                                         tmp_word_en &= (~BIT(0));
825
826                                 if ((target_pkt->word_en & BIT(1)) ^
827                                     (match_word_en & BIT(1)))
828                                         tmp_word_en &= (~BIT(1));
829
830                                 if ((target_pkt->word_en & BIT(2)) ^
831                                     (match_word_en & BIT(2)))
832                                         tmp_word_en &= (~BIT(2));
833
834                                 if ((target_pkt->word_en & BIT(3)) ^
835                                     (match_word_en & BIT(3)))
836                                         tmp_word_en &= (~BIT(3));
837
838                                 if ((tmp_word_en & 0x0F) != 0x0F) {
839                                         *efuse_addr = efuse_get_current_size(hw);
840                                         target_pkt->offset = offset;
841                                         target_pkt->word_en = tmp_word_en;
842                                 } else {
843                                         *bcontinual = false;
844                                 }
845                                 *write_state = PG_STATE_HEADER;
846                                 *repeat_times += 1;
847                                 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
848                                         *bcontinual = false;
849                                         *bresult = false;
850                                 }
851                         } else {
852                                 *efuse_addr += (2 * tmp_word_cnts) + 1;
853                                 target_pkt->offset = offset;
854                                 target_pkt->word_en = word_en;
855                                 *write_state = PG_STATE_HEADER;
856                         }
857                 }
858         }
859         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
860 }
861
862 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
863                                    int *bcontinual, u8 *write_state,
864                                    struct pgpkt_struct target_pkt,
865                                    int *repeat_times, int *bresult)
866 {
867         struct rtl_priv *rtlpriv = rtl_priv(hw);
868         struct pgpkt_struct tmp_pkt;
869         u8 pg_header;
870         u8 tmp_header;
871         u8 originaldata[8 * sizeof(u8)];
872         u8 tmp_word_cnts;
873         u8 badworden = 0x0F;
874
875         pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
876         efuse_one_byte_write(hw, *efuse_addr, pg_header);
877         efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
878
879         if (tmp_header == pg_header) {
880                 *write_state = PG_STATE_DATA;
881         } else if (tmp_header == 0xFF) {
882                 *write_state = PG_STATE_HEADER;
883                 *repeat_times += 1;
884                 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
885                         *bcontinual = false;
886                         *bresult = false;
887                 }
888         } else {
889                 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
890                 tmp_pkt.word_en = tmp_header & 0x0F;
891
892                 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
893
894                 memset(originaldata, 0xff,  8 * sizeof(u8));
895
896                 if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
897                         badworden = efuse_word_enable_data_write(hw,
898                                                                 *efuse_addr + 1,
899                                                                 tmp_pkt.word_en,
900                                                                 originaldata);
901
902                         if (0x0F != (badworden & 0x0F)) {
903                                 u8 reorg_offset = tmp_pkt.offset;
904                                 u8 reorg_worden = badworden;
905                                 efuse_pg_packet_write(hw, reorg_offset,
906                                                       reorg_worden,
907                                                       originaldata);
908                                 *efuse_addr = efuse_get_current_size(hw);
909                         } else {
910                                 *efuse_addr = *efuse_addr +
911                                               (tmp_word_cnts * 2) + 1;
912                         }
913                 } else {
914                         *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
915                 }
916
917                 *write_state = PG_STATE_HEADER;
918                 *repeat_times += 1;
919                 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
920                         *bcontinual = false;
921                         *bresult = false;
922                 }
923
924                 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
925                         ("efuse PG_STATE_HEADER-2\n"));
926         }
927 }
928
929 static int efuse_pg_packet_write(struct ieee80211_hw *hw,
930                                  u8 offset, u8 word_en, u8 *data)
931 {
932         struct rtl_priv *rtlpriv = rtl_priv(hw);
933         struct pgpkt_struct target_pkt;
934         u8 write_state = PG_STATE_HEADER;
935         int bcontinual = true, bdataempty = true, bresult = true;
936         u16 efuse_addr = 0;
937         u8 efuse_data;
938         u8 target_word_cnts = 0;
939         u8 badworden = 0x0F;
940         static int repeat_times = 0;
941
942         if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE -
943                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
944                 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
945                         ("efuse_pg_packet_write error \n"));
946                 return false;
947         }
948
949         target_pkt.offset = offset;
950         target_pkt.word_en = word_en;
951
952         memset(target_pkt.data, 0xFF,  8 * sizeof(u8));
953
954         efuse_word_enable_data_read(word_en, data, target_pkt.data);
955         target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
956
957         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
958
959         while (bcontinual && (efuse_addr < (EFUSE_MAX_SIZE -
960                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
961
962                 if (write_state == PG_STATE_HEADER) {
963                         bdataempty = true;
964                         badworden = 0x0F;
965                         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
966                                 ("efuse PG_STATE_HEADER\n"));
967
968                         if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
969                             (efuse_data != 0xFF))
970                                 efuse_write_data_case1(hw, &efuse_addr,
971                                                        efuse_data, offset,
972                                                        &bcontinual,
973                                                        &write_state,
974                                                        &target_pkt,
975                                                        &repeat_times, &bresult,
976                                                        word_en);
977                         else
978                                 efuse_write_data_case2(hw, &efuse_addr,
979                                                        &bcontinual,
980                                                        &write_state,
981                                                        target_pkt,
982                                                        &repeat_times,
983                                                        &bresult);
984
985                 } else if (write_state == PG_STATE_DATA) {
986                         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
987                                 ("efuse PG_STATE_DATA\n"));
988                         badworden = 0x0f;
989                         badworden =
990                             efuse_word_enable_data_write(hw, efuse_addr + 1,
991                                                          target_pkt.word_en,
992                                                          target_pkt.data);
993
994                         if ((badworden & 0x0F) == 0x0F) {
995                                 bcontinual = false;
996                         } else {
997                                 efuse_addr =
998                                     efuse_addr + (2 * target_word_cnts) + 1;
999
1000                                 target_pkt.offset = offset;
1001                                 target_pkt.word_en = badworden;
1002                                 target_word_cnts =
1003                                     efuse_calculate_word_cnts(target_pkt.
1004                                                               word_en);
1005                                 write_state = PG_STATE_HEADER;
1006                                 repeat_times++;
1007                                 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
1008                                         bcontinual = false;
1009                                         bresult = false;
1010                                 }
1011                                 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
1012                                         ("efuse PG_STATE_HEADER-3\n"));
1013                         }
1014                 }
1015         }
1016
1017         if (efuse_addr >= (EFUSE_MAX_SIZE -
1018                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
1019                 RT_TRACE(COMP_EFUSE, DBG_LOUD,
1020                          ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
1021         }
1022
1023         return true;
1024 }
1025
1026 static void efuse_word_enable_data_read(u8 word_en, u8 * sourdata,
1027                                         u8 *targetdata)
1028 {
1029         if (!(word_en & BIT(0))) {
1030                 targetdata[0] = sourdata[0];
1031                 targetdata[1] = sourdata[1];
1032         }
1033
1034         if (!(word_en & BIT(1))) {
1035                 targetdata[2] = sourdata[2];
1036                 targetdata[3] = sourdata[3];
1037         }
1038
1039         if (!(word_en & BIT(2))) {
1040                 targetdata[4] = sourdata[4];
1041                 targetdata[5] = sourdata[5];
1042         }
1043
1044         if (!(word_en & BIT(3))) {
1045                 targetdata[6] = sourdata[6];
1046                 targetdata[7] = sourdata[7];
1047         }
1048 }
1049
1050 static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
1051                                        u16 efuse_addr, u8 word_en, u8 *data)
1052 {
1053         struct rtl_priv *rtlpriv = rtl_priv(hw);
1054         u16 tmpaddr;
1055         u16 start_addr = efuse_addr;
1056         u8 badworden = 0x0F;
1057         u8 tmpdata[8];
1058
1059         memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
1060         RT_TRACE(COMP_EFUSE, DBG_LOUD,
1061                  ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
1062
1063         if (!(word_en & BIT(0))) {
1064                 tmpaddr = start_addr;
1065                 efuse_one_byte_write(hw, start_addr++, data[0]);
1066                 efuse_one_byte_write(hw, start_addr++, data[1]);
1067
1068                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
1069                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
1070                 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1071                         badworden &= (~BIT(0));
1072         }
1073
1074         if (!(word_en & BIT(1))) {
1075                 tmpaddr = start_addr;
1076                 efuse_one_byte_write(hw, start_addr++, data[2]);
1077                 efuse_one_byte_write(hw, start_addr++, data[3]);
1078
1079                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
1080                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
1081                 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1082                         badworden &= (~BIT(1));
1083         }
1084
1085         if (!(word_en & BIT(2))) {
1086                 tmpaddr = start_addr;
1087                 efuse_one_byte_write(hw, start_addr++, data[4]);
1088                 efuse_one_byte_write(hw, start_addr++, data[5]);
1089
1090                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
1091                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
1092                 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1093                         badworden &= (~BIT(2));
1094         }
1095
1096         if (!(word_en & BIT(3))) {
1097                 tmpaddr = start_addr;
1098                 efuse_one_byte_write(hw, start_addr++, data[6]);
1099                 efuse_one_byte_write(hw, start_addr++, data[7]);
1100
1101                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
1102                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
1103                 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1104                         badworden &= (~BIT(3));
1105         }
1106
1107         return badworden;
1108 }
1109
1110 static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
1111 {
1112         struct rtl_priv *rtlpriv = rtl_priv(hw);
1113         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1114         u8 tempval;
1115         u16 tmpV16;
1116
1117         if(rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
1118         {
1119                 if (pwrstate == true)
1120                 {
1121                         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
1122
1123                         // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid
1124                         tmpV16 = rtl_read_word(rtlpriv,
1125                                                rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1126
1127                         printk("SYS_ISO_CTRL=%04x.\n",tmpV16);
1128                         if( ! (tmpV16 & PWC_EV12V ) ){
1129                                 tmpV16 |= PWC_EV12V ;
1130                                  //PlatformEFIOWrite2Byte(pAdapter,REG_SYS_ISO_CTRL,tmpV16);
1131                         }
1132                         // Reset: 0x0000h[28], default valid
1133                         tmpV16 = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[SYS_FUNC_EN]);
1134                         printk("SYS_FUNC_EN=%04x.\n",tmpV16);
1135                         if( !(tmpV16 & FEN_ELDR) ){
1136                                 tmpV16 |= FEN_ELDR ;
1137                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
1138                         }
1139
1140                         // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1141                         tmpV16 = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[SYS_CLK] );
1142                         printk("SYS_CLK=%04x.\n",tmpV16);
1143                         if( (!(tmpV16 & LOADER_CLK_EN) )  ||(!(tmpV16 & ANA8M) ) )
1144                         {
1145                                 tmpV16 |= (LOADER_CLK_EN |ANA8M ) ;
1146                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_CLK], tmpV16);
1147                         }
1148
1149                         if(bwrite == true)
1150                         {
1151                                 // Enable LDO 2.5V before read/write action
1152                                 tempval = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3);
1153                                 printk("EFUSE_TEST=%04x.\n",tmpV16);
1154                                 tempval &= ~(BIT(3) | BIT(4) |BIT(5) | BIT(6));
1155                                 tempval |= (VOLTAGE_V25 << 3);
1156                                 tempval |= BIT(7);
1157                                 rtl_write_byte(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3, tempval);
1158                         }
1159                 }
1160                 else
1161                 {
1162                         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0x00);
1163                         if(bwrite == true){
1164                                 // Disable LDO 2.5V after read/write action
1165                                 tempval = rtl_read_word(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3);
1166                                 rtl_write_byte(rtlpriv,  rtlpriv->cfg->maps[EFUSE_TEST] + 3, (tempval & 0x7F));
1167                         }
1168                 }
1169         }
1170         else
1171         {
1172                 if (pwrstate == true && (rtlhal->hw_type !=
1173                         HARDWARE_TYPE_RTL8192SE)) {
1174
1175                         if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1176                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS],
1177                                                 0x69);
1178
1179                         tmpV16 = rtl_read_word(rtlpriv,
1180                                                rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1181                         if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
1182                                 tmpV16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
1183                                 rtl_write_word(rtlpriv,
1184                                                rtlpriv->cfg->maps[SYS_ISO_CTRL],
1185                                                tmpV16);
1186                         }
1187
1188                         tmpV16 = rtl_read_word(rtlpriv,
1189                                                rtlpriv->cfg->maps[SYS_FUNC_EN]);
1190                         if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
1191                                 tmpV16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
1192                                 rtl_write_word(rtlpriv,
1193                                                rtlpriv->cfg->maps[SYS_FUNC_EN], tmpV16);
1194                         }
1195
1196                         tmpV16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
1197                         if ((!(tmpV16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
1198                             (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
1199                                 tmpV16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
1200                                            rtlpriv->cfg->maps[EFUSE_ANA8M]);
1201                                 rtl_write_word(rtlpriv,
1202                                                rtlpriv->cfg->maps[SYS_CLK], tmpV16);
1203                         }
1204                 }
1205
1206                 if (pwrstate == true) {
1207                         if (bwrite == true) {
1208                                 tempval = rtl_read_byte(rtlpriv,
1209                                                         rtlpriv->cfg->maps[EFUSE_TEST] +
1210                                                         3);
1211
1212                                 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
1213                                         tempval &= 0x0F;
1214                                         tempval |= (VOLTAGE_V25 << 4);
1215                                 }
1216
1217                                 rtl_write_byte(rtlpriv,
1218                                                rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1219                                                (tempval | 0x80));
1220                         }
1221
1222                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1223                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1224                                                         0x03);
1225                         }
1226
1227                 } else {
1228                         if(rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE)
1229                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
1230
1231                         if (bwrite == true) {
1232                                 tempval = rtl_read_byte(rtlpriv,
1233                                                         rtlpriv->cfg->maps[EFUSE_TEST] +
1234                                                         3);
1235                                 rtl_write_byte(rtlpriv,
1236                                                rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1237                                                (tempval & 0x7F));
1238                         }
1239
1240                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1241                                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1242                                                         0x02);
1243                         }
1244
1245                 }
1246         }
1247
1248 }
1249
1250 static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1251 {
1252         int bcontinual = true;
1253         u16 efuse_addr = 0;
1254         u8 hoffset, hworden;
1255         u8 efuse_data, word_cnts;
1256
1257         while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
1258                && (efuse_addr < EFUSE_MAX_SIZE)) {
1259                 if (efuse_data != 0xFF) {
1260                         hoffset = (efuse_data >> 4) & 0x0F;
1261                         hworden = efuse_data & 0x0F;
1262                         word_cnts = efuse_calculate_word_cnts(hworden);
1263                         efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1264                 } else {
1265                         bcontinual = false;
1266                 }
1267         }
1268
1269         return efuse_addr;
1270 }
1271
1272 static u8 efuse_calculate_word_cnts(u8 word_en)
1273 {
1274         u8 word_cnts = 0;
1275         if (!(word_en & BIT(0)))
1276                 word_cnts++;
1277         if (!(word_en & BIT(1)))
1278                 word_cnts++;
1279         if (!(word_en & BIT(2)))
1280                 word_cnts++;
1281         if (!(word_en & BIT(3)))
1282                 word_cnts++;
1283         return word_cnts;
1284 }
1285