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