Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / wireless / realtek / rtlwifi / efuse.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2012  Realtek Corporation.*/
3
4 #include "wifi.h"
5 #include "efuse.h"
6 #include "pci.h"
7 #include <linux/export.h>
8
9 static const u8 MAX_PGPKT_SIZE = 9;
10 static const u8 PGPKT_DATA_SIZE = 8;
11 static const int EFUSE_MAX_SIZE = 512;
12
13 #define START_ADDRESS           0x1000
14 #define REG_MCUFWDL             0x0080
15
16 static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = {
17         {0, 0, 0, 2},
18         {0, 1, 0, 2},
19         {0, 2, 0, 2},
20         {1, 0, 0, 1},
21         {1, 0, 1, 1},
22         {1, 1, 0, 1},
23         {1, 1, 1, 3},
24         {1, 3, 0, 17},
25         {3, 3, 1, 48},
26         {10, 0, 0, 6},
27         {10, 3, 0, 1},
28         {10, 3, 1, 1},
29         {11, 0, 0, 28}
30 };
31
32 static const struct rtl_efuse_ops efuse_ops = {
33         .efuse_onebyte_read = efuse_one_byte_read,
34         .efuse_logical_map_read = efuse_shadow_read,
35 };
36
37 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
38                                     u8 *value);
39 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
40                                     u16 *value);
41 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw, u16 offset,
42                                     u32 *value);
43 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw, u16 offset,
44                                      u8 value);
45 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw, u16 offset,
46                                      u16 value);
47 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw, u16 offset,
48                                      u32 value);
49 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr,
50                                 u8 data);
51 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse);
52 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset,
53                                 u8 *data);
54 static int efuse_pg_packet_write(struct ieee80211_hw *hw, u8 offset,
55                                  u8 word_en, u8 *data);
56 static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
57                                         u8 *targetdata);
58 static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
59                                   u16 efuse_addr, u8 word_en, u8 *data);
60 static u16 efuse_get_current_size(struct ieee80211_hw *hw);
61 static u8 efuse_calculate_word_cnts(u8 word_en);
62
63 void efuse_initialize(struct ieee80211_hw *hw)
64 {
65         struct rtl_priv *rtlpriv = rtl_priv(hw);
66         u8 bytetemp;
67         u8 temp;
68
69         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1);
70         temp = bytetemp | 0x20;
71         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_FUNC_EN] + 1, temp);
72
73         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1);
74         temp = bytetemp & 0xFE;
75         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[SYS_ISO_CTRL] + 1, temp);
76
77         bytetemp = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3);
78         temp = bytetemp | 0x80;
79         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST] + 3, temp);
80
81         rtl_write_byte(rtlpriv, 0x2F8, 0x3);
82
83         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
84
85 }
86
87 u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address)
88 {
89         struct rtl_priv *rtlpriv = rtl_priv(hw);
90         u8 data;
91         u8 bytetemp;
92         u8 temp;
93         u32 k = 0;
94         const u32 efuse_len =
95                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
96
97         if (address < efuse_len) {
98                 temp = address & 0xFF;
99                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
100                                temp);
101                 bytetemp = rtl_read_byte(rtlpriv,
102                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
103                 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
104                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
105                                temp);
106
107                 bytetemp = rtl_read_byte(rtlpriv,
108                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
109                 temp = bytetemp & 0x7F;
110                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
111                                temp);
112
113                 bytetemp = rtl_read_byte(rtlpriv,
114                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
115                 while (!(bytetemp & 0x80)) {
116                         bytetemp = rtl_read_byte(rtlpriv,
117                                                  rtlpriv->cfg->
118                                                  maps[EFUSE_CTRL] + 3);
119                         k++;
120                         if (k == 1000)
121                                 break;
122                 }
123                 data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
124                 return data;
125         } else
126                 return 0xFF;
127
128 }
129 EXPORT_SYMBOL(efuse_read_1byte);
130
131 void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
132 {
133         struct rtl_priv *rtlpriv = rtl_priv(hw);
134         u8 bytetemp;
135         u8 temp;
136         u32 k = 0;
137         const u32 efuse_len =
138                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
139
140         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n",
141                  address, value);
142
143         if (address < efuse_len) {
144                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
145
146                 temp = address & 0xFF;
147                 rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
148                                temp);
149                 bytetemp = rtl_read_byte(rtlpriv,
150                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
151
152                 temp = ((address >> 8) & 0x03) | (bytetemp & 0xFC);
153                 rtl_write_byte(rtlpriv,
154                                rtlpriv->cfg->maps[EFUSE_CTRL] + 2, temp);
155
156                 bytetemp = rtl_read_byte(rtlpriv,
157                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
158                 temp = bytetemp | 0x80;
159                 rtl_write_byte(rtlpriv,
160                                rtlpriv->cfg->maps[EFUSE_CTRL] + 3, temp);
161
162                 bytetemp = rtl_read_byte(rtlpriv,
163                                          rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
164
165                 while (bytetemp & 0x80) {
166                         bytetemp = rtl_read_byte(rtlpriv,
167                                                  rtlpriv->cfg->
168                                                  maps[EFUSE_CTRL] + 3);
169                         k++;
170                         if (k == 100) {
171                                 k = 0;
172                                 break;
173                         }
174                 }
175         }
176
177 }
178
179 void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
180 {
181         struct rtl_priv *rtlpriv = rtl_priv(hw);
182         u32 value32;
183         u8 readbyte;
184         u16 retry;
185
186         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
187                        (_offset & 0xff));
188         readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2);
189         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
190                        ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
191
192         readbyte = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3);
193         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3,
194                        (readbyte & 0x7f));
195
196         retry = 0;
197         value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
198         while (!(((value32 >> 24) & 0xff) & 0x80) && (retry < 10000)) {
199                 value32 = rtl_read_dword(rtlpriv,
200                                          rtlpriv->cfg->maps[EFUSE_CTRL]);
201                 retry++;
202         }
203
204         udelay(50);
205         value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
206
207         *pbuf = (u8) (value32 & 0xff);
208 }
209 EXPORT_SYMBOL_GPL(read_efuse_byte);
210
211 void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
212 {
213         struct rtl_priv *rtlpriv = rtl_priv(hw);
214         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
215         u8 *efuse_tbl;
216         u8 rtemp8[1];
217         u16 efuse_addr = 0;
218         u8 offset, wren;
219         u8 u1temp = 0;
220         u16 i;
221         u16 j;
222         const u16 efuse_max_section =
223                 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
224         const u32 efuse_len =
225                 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
226         u16 **efuse_word;
227         u16 efuse_utilized = 0;
228         u8 efuse_usage;
229
230         if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
231                 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
232                          "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n",
233                          _offset, _size_byte);
234                 return;
235         }
236
237         /* allocate memory for efuse_tbl and efuse_word */
238         efuse_tbl = kzalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE],
239                             GFP_ATOMIC);
240         if (!efuse_tbl)
241                 return;
242         efuse_word = kcalloc(EFUSE_MAX_WORD_UNIT, sizeof(u16 *), GFP_ATOMIC);
243         if (!efuse_word)
244                 goto out;
245         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
246                 efuse_word[i] = kcalloc(efuse_max_section, sizeof(u16),
247                                         GFP_ATOMIC);
248                 if (!efuse_word[i])
249                         goto done;
250         }
251
252         for (i = 0; i < efuse_max_section; i++)
253                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
254                         efuse_word[j][i] = 0xFFFF;
255
256         read_efuse_byte(hw, efuse_addr, rtemp8);
257         if (*rtemp8 != 0xFF) {
258                 efuse_utilized++;
259                 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
260                         "Addr=%d\n", efuse_addr);
261                 efuse_addr++;
262         }
263
264         while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
265                 /*  Check PG header for section num.  */
266                 if ((*rtemp8 & 0x1F) == 0x0F) {/* extended header */
267                         u1temp = ((*rtemp8 & 0xE0) >> 5);
268                         read_efuse_byte(hw, efuse_addr, rtemp8);
269
270                         if ((*rtemp8 & 0x0F) == 0x0F) {
271                                 efuse_addr++;
272                                 read_efuse_byte(hw, efuse_addr, rtemp8);
273
274                                 if (*rtemp8 != 0xFF &&
275                                     (efuse_addr < efuse_len)) {
276                                         efuse_addr++;
277                                 }
278                                 continue;
279                         } else {
280                                 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
281                                 wren = (*rtemp8 & 0x0F);
282                                 efuse_addr++;
283                         }
284                 } else {
285                         offset = ((*rtemp8 >> 4) & 0x0f);
286                         wren = (*rtemp8 & 0x0f);
287                 }
288
289                 if (offset < efuse_max_section) {
290                         RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
291                                 "offset-%d Worden=%x\n", offset, wren);
292
293                         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
294                                 if (!(wren & 0x01)) {
295                                         RTPRINT(rtlpriv, FEEPROM,
296                                                 EFUSE_READ_ALL,
297                                                 "Addr=%d\n", efuse_addr);
298
299                                         read_efuse_byte(hw, efuse_addr, rtemp8);
300                                         efuse_addr++;
301                                         efuse_utilized++;
302                                         efuse_word[i][offset] =
303                                                          (*rtemp8 & 0xff);
304
305                                         if (efuse_addr >= efuse_len)
306                                                 break;
307
308                                         RTPRINT(rtlpriv, FEEPROM,
309                                                 EFUSE_READ_ALL,
310                                                 "Addr=%d\n", efuse_addr);
311
312                                         read_efuse_byte(hw, efuse_addr, rtemp8);
313                                         efuse_addr++;
314                                         efuse_utilized++;
315                                         efuse_word[i][offset] |=
316                                             (((u16)*rtemp8 << 8) & 0xff00);
317
318                                         if (efuse_addr >= efuse_len)
319                                                 break;
320                                 }
321
322                                 wren >>= 1;
323                         }
324                 }
325
326                 RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
327                         "Addr=%d\n", efuse_addr);
328                 read_efuse_byte(hw, efuse_addr, rtemp8);
329                 if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
330                         efuse_utilized++;
331                         efuse_addr++;
332                 }
333         }
334
335         for (i = 0; i < efuse_max_section; i++) {
336                 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
337                         efuse_tbl[(i * 8) + (j * 2)] =
338                             (efuse_word[j][i] & 0xff);
339                         efuse_tbl[(i * 8) + ((j * 2) + 1)] =
340                             ((efuse_word[j][i] >> 8) & 0xff);
341                 }
342         }
343
344         for (i = 0; i < _size_byte; i++)
345                 pbuf[i] = efuse_tbl[_offset + i];
346
347         rtlefuse->efuse_usedbytes = efuse_utilized;
348         efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len);
349         rtlefuse->efuse_usedpercentage = efuse_usage;
350         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
351                                       (u8 *)&efuse_utilized);
352         rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
353                                       &efuse_usage);
354 done:
355         for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
356                 kfree(efuse_word[i]);
357         kfree(efuse_word);
358 out:
359         kfree(efuse_tbl);
360 }
361
362 bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
363 {
364         struct rtl_priv *rtlpriv = rtl_priv(hw);
365         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
366         u8 section_idx, i, base;
367         u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
368         bool wordchanged, result = true;
369
370         for (section_idx = 0; section_idx < 16; section_idx++) {
371                 base = section_idx * 8;
372                 wordchanged = false;
373
374                 for (i = 0; i < 8; i = i + 2) {
375                         if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
376                             rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i] ||
377                             rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i + 1] !=
378                             rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i +
379                                                                    1]) {
380                                 words_need++;
381                                 wordchanged = true;
382                         }
383                 }
384
385                 if (wordchanged)
386                         hdr_num++;
387         }
388
389         totalbytes = hdr_num + words_need * 2;
390         efuse_used = rtlefuse->efuse_usedbytes;
391
392         if ((totalbytes + efuse_used) >=
393             (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))
394                 result = false;
395
396         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
397                  "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
398                  totalbytes, hdr_num, words_need, efuse_used);
399
400         return result;
401 }
402
403 void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
404                        u16 offset, u32 *value)
405 {
406         if (type == 1)
407                 efuse_shadow_read_1byte(hw, offset, (u8 *)value);
408         else if (type == 2)
409                 efuse_shadow_read_2byte(hw, offset, (u16 *)value);
410         else if (type == 4)
411                 efuse_shadow_read_4byte(hw, offset, value);
412
413 }
414 EXPORT_SYMBOL(efuse_shadow_read);
415
416 void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset,
417                                 u32 value)
418 {
419         if (type == 1)
420                 efuse_shadow_write_1byte(hw, offset, (u8) value);
421         else if (type == 2)
422                 efuse_shadow_write_2byte(hw, offset, (u16) value);
423         else if (type == 4)
424                 efuse_shadow_write_4byte(hw, offset, value);
425
426 }
427
428 bool efuse_shadow_update(struct ieee80211_hw *hw)
429 {
430         struct rtl_priv *rtlpriv = rtl_priv(hw);
431         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
432         u16 i, offset, base;
433         u8 word_en = 0x0F;
434         u8 first_pg = false;
435
436         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
437
438         if (!efuse_shadow_update_chk(hw)) {
439                 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
440                 memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
441                        &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
442                        rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
443
444                 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
445                          "efuse out of capacity!!\n");
446                 return false;
447         }
448         efuse_power_switch(hw, true, true);
449
450         for (offset = 0; offset < 16; offset++) {
451
452                 word_en = 0x0F;
453                 base = offset * 8;
454
455                 for (i = 0; i < 8; i++) {
456                         if (first_pg) {
457                                 word_en &= ~(BIT(i / 2));
458
459                                 rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
460                                     rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
461                         } else {
462
463                                 if (rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] !=
464                                     rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i]) {
465                                         word_en &= ~(BIT(i / 2));
466
467                                         rtlefuse->efuse_map[EFUSE_INIT_MAP][base + i] =
468                                             rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base + i];
469                                 }
470                         }
471                 }
472
473                 if (word_en != 0x0F) {
474                         u8 tmpdata[8];
475
476                         memcpy(tmpdata,
477                                &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base],
478                                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(rtlpriv, COMP_ERR, DBG_WARNING,
485                                          "PG section(%#x) fail!!\n", offset);
486                                 break;
487                         }
488                 }
489         }
490
491         efuse_power_switch(hw, true, false);
492         efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
493
494         memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
495                &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
496                rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
497
498         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n");
499         return true;
500 }
501
502 void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw)
503 {
504         struct rtl_priv *rtlpriv = rtl_priv(hw);
505         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
506
507         if (rtlefuse->autoload_failflag)
508                 memset((&rtlefuse->efuse_map[EFUSE_INIT_MAP][0]),
509                        0xFF, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
510         else
511                 efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
512
513         memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
514                         &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
515                         rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
516
517 }
518 EXPORT_SYMBOL(rtl_efuse_shadow_map_update);
519
520 void efuse_force_write_vendor_id(struct ieee80211_hw *hw)
521 {
522         u8 tmpdata[8] = { 0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF };
523
524         efuse_power_switch(hw, true, true);
525
526         efuse_pg_packet_write(hw, 1, 0xD, tmpdata);
527
528         efuse_power_switch(hw, true, false);
529
530 }
531
532 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
533 {
534 }
535
536 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw,
537                                     u16 offset, u8 *value)
538 {
539         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
540         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
541 }
542
543 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw,
544                                     u16 offset, u16 *value)
545 {
546         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
547
548         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
549         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
550
551 }
552
553 static void efuse_shadow_read_4byte(struct ieee80211_hw *hw,
554                                     u16 offset, u32 *value)
555 {
556         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
557
558         *value = rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset];
559         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] << 8;
560         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] << 16;
561         *value |= rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] << 24;
562 }
563
564 static void efuse_shadow_write_1byte(struct ieee80211_hw *hw,
565                                      u16 offset, u8 value)
566 {
567         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
568
569         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value;
570 }
571
572 static void efuse_shadow_write_2byte(struct ieee80211_hw *hw,
573                                      u16 offset, u16 value)
574 {
575         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
576
577         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] = value & 0x00FF;
578         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] = value >> 8;
579
580 }
581
582 static void efuse_shadow_write_4byte(struct ieee80211_hw *hw,
583                                      u16 offset, u32 value)
584 {
585         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
586
587         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset] =
588             (u8) (value & 0x000000FF);
589         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 1] =
590             (u8) ((value >> 8) & 0x0000FF);
591         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 2] =
592             (u8) ((value >> 16) & 0x00FF);
593         rtlefuse->efuse_map[EFUSE_MODIFY_MAP][offset + 3] =
594             (u8) ((value >> 24) & 0xFF);
595
596 }
597
598 int efuse_one_byte_read(struct ieee80211_hw *hw, u16 addr, u8 *data)
599 {
600         struct rtl_priv *rtlpriv = rtl_priv(hw);
601         u8 tmpidx = 0;
602         int result;
603
604         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
605                        (u8) (addr & 0xff));
606         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
607                        ((u8) ((addr >> 8) & 0x03)) |
608                        (rtl_read_byte(rtlpriv,
609                                       rtlpriv->cfg->maps[EFUSE_CTRL] + 2) &
610                         0xFC));
611
612         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0x72);
613
614         while (!(0x80 & rtl_read_byte(rtlpriv,
615                                       rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
616                && (tmpidx < 100)) {
617                 tmpidx++;
618         }
619
620         if (tmpidx < 100) {
621                 *data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
622                 result = true;
623         } else {
624                 *data = 0xff;
625                 result = false;
626         }
627         return result;
628 }
629 EXPORT_SYMBOL(efuse_one_byte_read);
630
631 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
632 {
633         struct rtl_priv *rtlpriv = rtl_priv(hw);
634         u8 tmpidx = 0;
635
636         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
637                  "Addr = %x Data=%x\n", addr, data);
638
639         rtl_write_byte(rtlpriv,
640                        rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
641         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 2,
642                        (rtl_read_byte(rtlpriv,
643                          rtlpriv->cfg->maps[EFUSE_CTRL] +
644                          2) & 0xFC) | (u8) ((addr >> 8) & 0x03));
645
646         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], data);
647         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 3, 0xF2);
648
649         while ((0x80 & rtl_read_byte(rtlpriv,
650                                      rtlpriv->cfg->maps[EFUSE_CTRL] + 3))
651                && (tmpidx < 100)) {
652                 tmpidx++;
653         }
654
655         if (tmpidx < 100)
656                 return true;
657         return false;
658 }
659
660 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 *efuse)
661 {
662         struct rtl_priv *rtlpriv = rtl_priv(hw);
663
664         efuse_power_switch(hw, false, true);
665         read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
666         efuse_power_switch(hw, false, false);
667 }
668
669 static void efuse_read_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
670                                 u8 efuse_data, u8 offset, u8 *tmpdata,
671                                 u8 *readstate)
672 {
673         bool dataempty = true;
674         u8 hoffset;
675         u8 tmpidx;
676         u8 hworden;
677         u8 word_cnts;
678
679         hoffset = (efuse_data >> 4) & 0x0F;
680         hworden = efuse_data & 0x0F;
681         word_cnts = efuse_calculate_word_cnts(hworden);
682
683         if (hoffset == offset) {
684                 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
685                         if (efuse_one_byte_read(hw, *efuse_addr + 1 + tmpidx,
686                                                 &efuse_data)) {
687                                 tmpdata[tmpidx] = efuse_data;
688                                 if (efuse_data != 0xff)
689                                         dataempty = false;
690                         }
691                 }
692
693                 if (!dataempty) {
694                         *readstate = PG_STATE_DATA;
695                 } else {
696                         *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
697                         *readstate = PG_STATE_HEADER;
698                 }
699
700         } else {
701                 *efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
702                 *readstate = PG_STATE_HEADER;
703         }
704 }
705
706 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
707 {
708         u8 readstate = PG_STATE_HEADER;
709
710         bool continual = true;
711
712         u8 efuse_data, word_cnts = 0;
713         u16 efuse_addr = 0;
714         u8 tmpdata[8];
715
716         if (data == NULL)
717                 return false;
718         if (offset > 15)
719                 return false;
720
721         memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
722         memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
723
724         while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
725                 if (readstate & PG_STATE_HEADER) {
726                         if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
727                             && (efuse_data != 0xFF))
728                                 efuse_read_data_case1(hw, &efuse_addr,
729                                                       efuse_data, offset,
730                                                       tmpdata, &readstate);
731                         else
732                                 continual = false;
733                 } else if (readstate & PG_STATE_DATA) {
734                         efuse_word_enable_data_read(0, tmpdata, data);
735                         efuse_addr = efuse_addr + (word_cnts * 2) + 1;
736                         readstate = PG_STATE_HEADER;
737                 }
738
739         }
740
741         if ((data[0] == 0xff) && (data[1] == 0xff) &&
742             (data[2] == 0xff) && (data[3] == 0xff) &&
743             (data[4] == 0xff) && (data[5] == 0xff) &&
744             (data[6] == 0xff) && (data[7] == 0xff))
745                 return false;
746         else
747                 return true;
748
749 }
750
751 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
752                                    u8 efuse_data, u8 offset,
753                                    int *continual, u8 *write_state,
754                                    struct pgpkt_struct *target_pkt,
755                                    int *repeat_times, int *result, u8 word_en)
756 {
757         struct rtl_priv *rtlpriv = rtl_priv(hw);
758         struct pgpkt_struct tmp_pkt;
759         int dataempty = true;
760         u8 originaldata[8 * sizeof(u8)];
761         u8 badworden = 0x0F;
762         u8 match_word_en, tmp_word_en;
763         u8 tmpindex;
764         u8 tmp_header = efuse_data;
765         u8 tmp_word_cnts;
766
767         tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
768         tmp_pkt.word_en = tmp_header & 0x0F;
769         tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
770
771         if (tmp_pkt.offset != target_pkt->offset) {
772                 *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
773                 *write_state = PG_STATE_HEADER;
774         } else {
775                 for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) {
776                         if (efuse_one_byte_read(hw,
777                                                 (*efuse_addr + 1 + tmpindex),
778                                                 &efuse_data) &&
779                             (efuse_data != 0xFF))
780                                 dataempty = false;
781                 }
782
783                 if (!dataempty) {
784                         *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
785                         *write_state = PG_STATE_HEADER;
786                 } else {
787                         match_word_en = 0x0F;
788                         if (!((target_pkt->word_en & BIT(0)) |
789                             (tmp_pkt.word_en & BIT(0))))
790                                 match_word_en &= (~BIT(0));
791
792                         if (!((target_pkt->word_en & BIT(1)) |
793                             (tmp_pkt.word_en & BIT(1))))
794                                 match_word_en &= (~BIT(1));
795
796                         if (!((target_pkt->word_en & BIT(2)) |
797                             (tmp_pkt.word_en & BIT(2))))
798                                 match_word_en &= (~BIT(2));
799
800                         if (!((target_pkt->word_en & BIT(3)) |
801                             (tmp_pkt.word_en & BIT(3))))
802                                 match_word_en &= (~BIT(3));
803
804                         if ((match_word_en & 0x0F) != 0x0F) {
805                                 badworden =
806                                   enable_efuse_data_write(hw,
807                                                           *efuse_addr + 1,
808                                                           tmp_pkt.word_en,
809                                                           target_pkt->data);
810
811                                 if (0x0F != (badworden & 0x0F)) {
812                                         u8 reorg_offset = offset;
813                                         u8 reorg_worden = badworden;
814
815                                         efuse_pg_packet_write(hw, reorg_offset,
816                                                               reorg_worden,
817                                                               originaldata);
818                                 }
819
820                                 tmp_word_en = 0x0F;
821                                 if ((target_pkt->word_en & BIT(0)) ^
822                                     (match_word_en & BIT(0)))
823                                         tmp_word_en &= (~BIT(0));
824
825                                 if ((target_pkt->word_en & BIT(1)) ^
826                                     (match_word_en & BIT(1)))
827                                         tmp_word_en &= (~BIT(1));
828
829                                 if ((target_pkt->word_en & BIT(2)) ^
830                                     (match_word_en & BIT(2)))
831                                         tmp_word_en &= (~BIT(2));
832
833                                 if ((target_pkt->word_en & BIT(3)) ^
834                                     (match_word_en & BIT(3)))
835                                         tmp_word_en &= (~BIT(3));
836
837                                 if ((tmp_word_en & 0x0F) != 0x0F) {
838                                         *efuse_addr = efuse_get_current_size(hw);
839                                         target_pkt->offset = offset;
840                                         target_pkt->word_en = tmp_word_en;
841                                 } else {
842                                         *continual = false;
843                                 }
844                                 *write_state = PG_STATE_HEADER;
845                                 *repeat_times += 1;
846                                 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
847                                         *continual = false;
848                                         *result = false;
849                                 }
850                         } else {
851                                 *efuse_addr += (2 * tmp_word_cnts) + 1;
852                                 target_pkt->offset = offset;
853                                 target_pkt->word_en = word_en;
854                                 *write_state = PG_STATE_HEADER;
855                         }
856                 }
857         }
858         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n");
859 }
860
861 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
862                                    int *continual, u8 *write_state,
863                                    struct pgpkt_struct target_pkt,
864                                    int *repeat_times, int *result)
865 {
866         struct rtl_priv *rtlpriv = rtl_priv(hw);
867         struct pgpkt_struct tmp_pkt;
868         u8 pg_header;
869         u8 tmp_header;
870         u8 originaldata[8 * sizeof(u8)];
871         u8 tmp_word_cnts;
872         u8 badworden = 0x0F;
873
874         pg_header = ((target_pkt.offset << 4) & 0xf0) | target_pkt.word_en;
875         efuse_one_byte_write(hw, *efuse_addr, pg_header);
876         efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
877
878         if (tmp_header == pg_header) {
879                 *write_state = PG_STATE_DATA;
880         } else if (tmp_header == 0xFF) {
881                 *write_state = PG_STATE_HEADER;
882                 *repeat_times += 1;
883                 if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
884                         *continual = false;
885                         *result = false;
886                 }
887         } else {
888                 tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
889                 tmp_pkt.word_en = tmp_header & 0x0F;
890
891                 tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en);
892
893                 memset(originaldata, 0xff,  8 * sizeof(u8));
894
895                 if (efuse_pg_packet_read(hw, tmp_pkt.offset, originaldata)) {
896                         badworden = enable_efuse_data_write(hw,
897                                                             *efuse_addr + 1,
898                                                             tmp_pkt.word_en,
899                                                             originaldata);
900
901                         if (0x0F != (badworden & 0x0F)) {
902                                 u8 reorg_offset = tmp_pkt.offset;
903                                 u8 reorg_worden = badworden;
904
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                         *continual = false;
921                         *result = 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 continual = true, dataempty = true, result = 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;
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 (continual && (efuse_addr < (EFUSE_MAX_SIZE -
960                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN]))) {
961                 if (write_state == PG_STATE_HEADER) {
962                         dataempty = true;
963                         badworden = 0x0F;
964                         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
965                                 "efuse PG_STATE_HEADER\n");
966
967                         if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
968                             (efuse_data != 0xFF))
969                                 efuse_write_data_case1(hw, &efuse_addr,
970                                                        efuse_data, offset,
971                                                        &continual,
972                                                        &write_state,
973                                                        &target_pkt,
974                                                        &repeat_times, &result,
975                                                        word_en);
976                         else
977                                 efuse_write_data_case2(hw, &efuse_addr,
978                                                        &continual,
979                                                        &write_state,
980                                                        target_pkt,
981                                                        &repeat_times,
982                                                        &result);
983
984                 } else if (write_state == PG_STATE_DATA) {
985                         RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
986                                 "efuse PG_STATE_DATA\n");
987                         badworden =
988                             enable_efuse_data_write(hw, efuse_addr + 1,
989                                                     target_pkt.word_en,
990                                                     target_pkt.data);
991
992                         if ((badworden & 0x0F) == 0x0F) {
993                                 continual = false;
994                         } else {
995                                 efuse_addr =
996                                     efuse_addr + (2 * target_word_cnts) + 1;
997
998                                 target_pkt.offset = offset;
999                                 target_pkt.word_en = badworden;
1000                                 target_word_cnts =
1001                                     efuse_calculate_word_cnts(target_pkt.
1002                                                               word_en);
1003                                 write_state = PG_STATE_HEADER;
1004                                 repeat_times++;
1005                                 if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
1006                                         continual = false;
1007                                         result = false;
1008                                 }
1009                                 RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
1010                                         "efuse PG_STATE_HEADER-3\n");
1011                         }
1012                 }
1013         }
1014
1015         if (efuse_addr >= (EFUSE_MAX_SIZE -
1016                 rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) {
1017                 RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
1018                          "efuse_addr(%#x) Out of size!!\n", efuse_addr);
1019         }
1020
1021         return true;
1022 }
1023
1024 static void efuse_word_enable_data_read(u8 word_en, u8 *sourdata,
1025                                         u8 *targetdata)
1026 {
1027         if (!(word_en & BIT(0))) {
1028                 targetdata[0] = sourdata[0];
1029                 targetdata[1] = sourdata[1];
1030         }
1031
1032         if (!(word_en & BIT(1))) {
1033                 targetdata[2] = sourdata[2];
1034                 targetdata[3] = sourdata[3];
1035         }
1036
1037         if (!(word_en & BIT(2))) {
1038                 targetdata[4] = sourdata[4];
1039                 targetdata[5] = sourdata[5];
1040         }
1041
1042         if (!(word_en & BIT(3))) {
1043                 targetdata[6] = sourdata[6];
1044                 targetdata[7] = sourdata[7];
1045         }
1046 }
1047
1048 static u8 enable_efuse_data_write(struct ieee80211_hw *hw,
1049                                   u16 efuse_addr, u8 word_en, u8 *data)
1050 {
1051         struct rtl_priv *rtlpriv = rtl_priv(hw);
1052         u16 tmpaddr;
1053         u16 start_addr = efuse_addr;
1054         u8 badworden = 0x0F;
1055         u8 tmpdata[8];
1056
1057         memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
1058         RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
1059                  "word_en = %x efuse_addr=%x\n", word_en, efuse_addr);
1060
1061         if (!(word_en & BIT(0))) {
1062                 tmpaddr = start_addr;
1063                 efuse_one_byte_write(hw, start_addr++, data[0]);
1064                 efuse_one_byte_write(hw, start_addr++, data[1]);
1065
1066                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[0]);
1067                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[1]);
1068                 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1069                         badworden &= (~BIT(0));
1070         }
1071
1072         if (!(word_en & BIT(1))) {
1073                 tmpaddr = start_addr;
1074                 efuse_one_byte_write(hw, start_addr++, data[2]);
1075                 efuse_one_byte_write(hw, start_addr++, data[3]);
1076
1077                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[2]);
1078                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[3]);
1079                 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1080                         badworden &= (~BIT(1));
1081         }
1082
1083         if (!(word_en & BIT(2))) {
1084                 tmpaddr = start_addr;
1085                 efuse_one_byte_write(hw, start_addr++, data[4]);
1086                 efuse_one_byte_write(hw, start_addr++, data[5]);
1087
1088                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[4]);
1089                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[5]);
1090                 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1091                         badworden &= (~BIT(2));
1092         }
1093
1094         if (!(word_en & BIT(3))) {
1095                 tmpaddr = start_addr;
1096                 efuse_one_byte_write(hw, start_addr++, data[6]);
1097                 efuse_one_byte_write(hw, start_addr++, data[7]);
1098
1099                 efuse_one_byte_read(hw, tmpaddr, &tmpdata[6]);
1100                 efuse_one_byte_read(hw, tmpaddr + 1, &tmpdata[7]);
1101                 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1102                         badworden &= (~BIT(3));
1103         }
1104
1105         return badworden;
1106 }
1107
1108 void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
1109 {
1110         struct rtl_priv *rtlpriv = rtl_priv(hw);
1111         struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1112         u8 tempval;
1113         u16 tmpv16;
1114
1115         if (pwrstate && (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)) {
1116                 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
1117                     rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE) {
1118                         rtl_write_byte(rtlpriv,
1119                                        rtlpriv->cfg->maps[EFUSE_ACCESS], 0x69);
1120                 } else {
1121                         tmpv16 =
1122                           rtl_read_word(rtlpriv,
1123                                         rtlpriv->cfg->maps[SYS_ISO_CTRL]);
1124                         if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
1125                                 tmpv16 |= rtlpriv->cfg->maps[EFUSE_PWC_EV12V];
1126                                 rtl_write_word(rtlpriv,
1127                                                rtlpriv->cfg->maps[SYS_ISO_CTRL],
1128                                                tmpv16);
1129                         }
1130                 }
1131                 tmpv16 = rtl_read_word(rtlpriv,
1132                                        rtlpriv->cfg->maps[SYS_FUNC_EN]);
1133                 if (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_FEN_ELDR])) {
1134                         tmpv16 |= rtlpriv->cfg->maps[EFUSE_FEN_ELDR];
1135                         rtl_write_word(rtlpriv,
1136                                        rtlpriv->cfg->maps[SYS_FUNC_EN], tmpv16);
1137                 }
1138
1139                 tmpv16 = rtl_read_word(rtlpriv, rtlpriv->cfg->maps[SYS_CLK]);
1140                 if ((!(tmpv16 & rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN])) ||
1141                     (!(tmpv16 & rtlpriv->cfg->maps[EFUSE_ANA8M]))) {
1142                         tmpv16 |= (rtlpriv->cfg->maps[EFUSE_LOADER_CLK_EN] |
1143                                    rtlpriv->cfg->maps[EFUSE_ANA8M]);
1144                         rtl_write_word(rtlpriv,
1145                                        rtlpriv->cfg->maps[SYS_CLK], tmpv16);
1146                 }
1147         }
1148
1149         if (pwrstate) {
1150                 if (write) {
1151                         tempval = rtl_read_byte(rtlpriv,
1152                                                 rtlpriv->cfg->maps[EFUSE_TEST] +
1153                                                 3);
1154
1155                         if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1156                                 tempval &= ~(BIT(3) | BIT(4) | BIT(5) | BIT(6));
1157                                 tempval |= (VOLTAGE_V25 << 3);
1158                         } else if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
1159                                 tempval &= 0x0F;
1160                                 tempval |= (VOLTAGE_V25 << 4);
1161                         }
1162
1163                         rtl_write_byte(rtlpriv,
1164                                        rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1165                                        (tempval | 0x80));
1166                 }
1167
1168                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1169                         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1170                                        0x03);
1171                 }
1172         } else {
1173                 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192CE &&
1174                     rtlhal->hw_type != HARDWARE_TYPE_RTL8192DE)
1175                         rtl_write_byte(rtlpriv,
1176                                        rtlpriv->cfg->maps[EFUSE_ACCESS], 0);
1177
1178                 if (write) {
1179                         tempval = rtl_read_byte(rtlpriv,
1180                                                 rtlpriv->cfg->maps[EFUSE_TEST] +
1181                                                 3);
1182                         rtl_write_byte(rtlpriv,
1183                                        rtlpriv->cfg->maps[EFUSE_TEST] + 3,
1184                                        (tempval & 0x7F));
1185                 }
1186
1187                 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
1188                         rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
1189                                        0x02);
1190                 }
1191         }
1192 }
1193 EXPORT_SYMBOL(efuse_power_switch);
1194
1195 static u16 efuse_get_current_size(struct ieee80211_hw *hw)
1196 {
1197         int continual = true;
1198         u16 efuse_addr = 0;
1199         u8 hoffset, hworden;
1200         u8 efuse_data, word_cnts;
1201
1202         while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
1203                (efuse_addr < EFUSE_MAX_SIZE)) {
1204                 if (efuse_data != 0xFF) {
1205                         hoffset = (efuse_data >> 4) & 0x0F;
1206                         hworden = efuse_data & 0x0F;
1207                         word_cnts = efuse_calculate_word_cnts(hworden);
1208                         efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1209                 } else {
1210                         continual = false;
1211                 }
1212         }
1213
1214         return efuse_addr;
1215 }
1216
1217 static u8 efuse_calculate_word_cnts(u8 word_en)
1218 {
1219         u8 word_cnts = 0;
1220
1221         if (!(word_en & BIT(0)))
1222                 word_cnts++;
1223         if (!(word_en & BIT(1)))
1224                 word_cnts++;
1225         if (!(word_en & BIT(2)))
1226                 word_cnts++;
1227         if (!(word_en & BIT(3)))
1228                 word_cnts++;
1229         return word_cnts;
1230 }
1231
1232 int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
1233                    int max_size, u8 *hwinfo, int *params)
1234 {
1235         struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1236         struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1237         struct device *dev = &rtlpcipriv->dev.pdev->dev;
1238         u16 eeprom_id;
1239         u16 i, usvalue;
1240
1241         switch (rtlefuse->epromtype) {
1242         case EEPROM_BOOT_EFUSE:
1243                 rtl_efuse_shadow_map_update(hw);
1244                 break;
1245
1246         case EEPROM_93C46:
1247                 pr_err("RTL8XXX did not boot from eeprom, check it !!\n");
1248                 return 1;
1249
1250         default:
1251                 dev_warn(dev, "no efuse data\n");
1252                 return 1;
1253         }
1254
1255         memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], max_size);
1256
1257         RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
1258                       hwinfo, max_size);
1259
1260         eeprom_id = *((u16 *)&hwinfo[0]);
1261         if (eeprom_id != params[0]) {
1262                 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1263                          "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1264                 rtlefuse->autoload_failflag = true;
1265         } else {
1266                 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1267                 rtlefuse->autoload_failflag = false;
1268         }
1269
1270         if (rtlefuse->autoload_failflag)
1271                 return 1;
1272
1273         rtlefuse->eeprom_vid = *(u16 *)&hwinfo[params[1]];
1274         rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]];
1275         rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]];
1276         rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]];
1277         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1278                  "EEPROMId = 0x%4x\n", eeprom_id);
1279         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1280                  "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1281         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1282                  "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1283         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1284                  "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1285         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1286                  "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1287
1288         for (i = 0; i < 6; i += 2) {
1289                 usvalue = *(u16 *)&hwinfo[params[5] + i];
1290                 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
1291         }
1292         RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
1293
1294         rtlefuse->eeprom_channelplan = *&hwinfo[params[6]];
1295         rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]];
1296         rtlefuse->txpwr_fromeprom = true;
1297         rtlefuse->eeprom_oemid = *&hwinfo[params[8]];
1298
1299         RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1300                  "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1301
1302         /* set channel plan to world wide 13 */
1303         rtlefuse->channel_plan = params[9];
1304
1305         return 0;
1306 }
1307 EXPORT_SYMBOL_GPL(rtl_get_hwinfo);
1308
1309 void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
1310 {
1311         struct rtl_priv *rtlpriv = rtl_priv(hw);
1312         u8 *pu4byteptr = (u8 *)buffer;
1313         u32 i;
1314
1315         for (i = 0; i < size; i++)
1316                 rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
1317 }
1318 EXPORT_SYMBOL_GPL(rtl_fw_block_write);
1319
1320 void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
1321                        u32 size)
1322 {
1323         struct rtl_priv *rtlpriv = rtl_priv(hw);
1324         u8 value8;
1325         u8 u8page = (u8)(page & 0x07);
1326
1327         value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
1328
1329         rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
1330         rtl_fw_block_write(hw, buffer, size);
1331 }
1332 EXPORT_SYMBOL_GPL(rtl_fw_page_write);
1333
1334 void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
1335 {
1336         u32 fwlen = *pfwlen;
1337         u8 remain = (u8)(fwlen % 4);
1338
1339         remain = (remain == 0) ? 0 : (4 - remain);
1340
1341         while (remain > 0) {
1342                 pfwbuf[fwlen] = 0;
1343                 fwlen++;
1344                 remain--;
1345         }
1346
1347         *pfwlen = fwlen;
1348 }
1349 EXPORT_SYMBOL_GPL(rtl_fill_dummy);
1350
1351 void rtl_efuse_ops_init(struct ieee80211_hw *hw)
1352 {
1353         struct rtl_priv *rtlpriv = rtl_priv(hw);
1354
1355         rtlpriv->efuse.efuse_ops = &efuse_ops;
1356 }
1357 EXPORT_SYMBOL_GPL(rtl_efuse_ops_init);