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
efuse_initialize(struct ieee80211_hw * hw)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
efuse_read_1byte(struct ieee80211_hw * hw,u16 address)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
efuse_write_1byte(struct ieee80211_hw * hw,u16 address,u8 value)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
read_efuse_byte(struct ieee80211_hw * hw,u16 _offset,u8 * pbuf)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
read_efuse(struct ieee80211_hw * hw,u16 _offset,u16 _size_byte,u8 * pbuf)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
efuse_shadow_update_chk(struct ieee80211_hw * hw)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
efuse_shadow_read(struct ieee80211_hw * hw,u8 type,u16 offset,u32 * value)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
efuse_shadow_write(struct ieee80211_hw * hw,u8 type,u16 offset,u32 value)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
efuse_shadow_update(struct ieee80211_hw * hw)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
rtl_efuse_shadow_map_update(struct ieee80211_hw * hw)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
efuse_force_write_vendor_id(struct ieee80211_hw * hw)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
efuse_re_pg_section(struct ieee80211_hw * hw,u8 section_idx)524 void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx)
525 {
526 }
527
efuse_shadow_read_1byte(struct ieee80211_hw * hw,u16 offset,u8 * value)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
efuse_shadow_read_2byte(struct ieee80211_hw * hw,u16 offset,u16 * value)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
efuse_shadow_read_4byte(struct ieee80211_hw * hw,u16 offset,u32 * value)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
efuse_shadow_write_1byte(struct ieee80211_hw * hw,u16 offset,u8 value)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
efuse_shadow_write_2byte(struct ieee80211_hw * hw,u16 offset,u16 value)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
efuse_shadow_write_4byte(struct ieee80211_hw * hw,u16 offset,u32 value)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
efuse_one_byte_read(struct ieee80211_hw * hw,u16 addr,u8 * data)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
efuse_one_byte_write(struct ieee80211_hw * hw,u16 addr,u8 data)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
efuse_read_all_map(struct ieee80211_hw * hw,u8 * efuse)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
efuse_read_data_case1(struct ieee80211_hw * hw,u16 * efuse_addr,u8 efuse_data,u8 offset,u8 * tmpdata,u8 * readstate)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
efuse_pg_packet_read(struct ieee80211_hw * hw,u8 offset,u8 * data)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
efuse_write_data_case1(struct ieee80211_hw * hw,u16 * efuse_addr,u8 efuse_data,u8 offset,int * continual,u8 * write_state,struct pgpkt_struct * target_pkt,int * repeat_times,int * result,u8 word_en)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
efuse_write_data_case2(struct ieee80211_hw * hw,u16 * efuse_addr,int * continual,u8 * write_state,struct pgpkt_struct target_pkt,int * repeat_times,int * result)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
efuse_pg_packet_write(struct ieee80211_hw * hw,u8 offset,u8 word_en,u8 * data)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
efuse_word_enable_data_read(u8 word_en,u8 * sourdata,u8 * targetdata)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
enable_efuse_data_write(struct ieee80211_hw * hw,u16 efuse_addr,u8 word_en,u8 * data)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
efuse_power_switch(struct ieee80211_hw * hw,u8 write,u8 pwrstate)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
efuse_get_current_size(struct ieee80211_hw * hw)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
efuse_calculate_word_cnts(u8 word_en)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
rtl_get_hwinfo(struct ieee80211_hw * hw,struct rtl_priv * rtlpriv,int max_size,u8 * hwinfo,int * params)1222 int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv,
1223 int max_size, u8 *hwinfo, 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
rtl_fw_block_write(struct ieee80211_hw * hw,const u8 * buffer,u32 size)1299 void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size)
1300 {
1301 struct rtl_priv *rtlpriv = rtl_priv(hw);
1302 u8 *pu4byteptr = (u8 *)buffer;
1303 u32 i;
1304
1305 for (i = 0; i < size; i++)
1306 rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i));
1307 }
1308 EXPORT_SYMBOL_GPL(rtl_fw_block_write);
1309
rtl_fw_page_write(struct ieee80211_hw * hw,u32 page,const u8 * buffer,u32 size)1310 void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer,
1311 u32 size)
1312 {
1313 struct rtl_priv *rtlpriv = rtl_priv(hw);
1314 u8 value8;
1315 u8 u8page = (u8)(page & 0x07);
1316
1317 value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page;
1318
1319 rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8);
1320 rtl_fw_block_write(hw, buffer, size);
1321 }
1322 EXPORT_SYMBOL_GPL(rtl_fw_page_write);
1323
rtl_fill_dummy(u8 * pfwbuf,u32 * pfwlen)1324 void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen)
1325 {
1326 u32 fwlen = *pfwlen;
1327 u8 remain = (u8)(fwlen % 4);
1328
1329 remain = (remain == 0) ? 0 : (4 - remain);
1330
1331 while (remain > 0) {
1332 pfwbuf[fwlen] = 0;
1333 fwlen++;
1334 remain--;
1335 }
1336
1337 *pfwlen = fwlen;
1338 }
1339 EXPORT_SYMBOL_GPL(rtl_fill_dummy);
1340
rtl_efuse_ops_init(struct ieee80211_hw * hw)1341 void rtl_efuse_ops_init(struct ieee80211_hw *hw)
1342 {
1343 struct rtl_priv *rtlpriv = rtl_priv(hw);
1344
1345 rtlpriv->efuse.efuse_ops = &efuse_ops;
1346 }
1347 EXPORT_SYMBOL_GPL(rtl_efuse_ops_init);
1348