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