1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #define _HAL_INIT_C_
5
6 #include "../include/drv_types.h"
7 #include "../include/rtw_efuse.h"
8 #include "../include/rtl8188e_hal.h"
9 #include "../include/rtw_iol.h"
10 #include "../include/usb_ops.h"
11 #include "../include/rtw_fw.h"
12
iol_mode_enable(struct adapter * padapter,u8 enable)13 static void iol_mode_enable(struct adapter *padapter, u8 enable)
14 {
15 u8 reg_0xf0 = 0;
16 int res;
17
18 if (enable) {
19 /* Enable initial offload */
20 res = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
21 if (res)
22 return;
23
24 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
25
26 if (!padapter->bFWReady)
27 rtw_reset_8051(padapter);
28
29 } else {
30 /* disable initial offload */
31 res = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0);
32 if (res)
33 return;
34
35 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
36 }
37 }
38
iol_execute(struct adapter * padapter,u8 control)39 static s32 iol_execute(struct adapter *padapter, u8 control)
40 {
41 s32 status = _FAIL;
42 u8 reg_0x88 = 0;
43 unsigned long timeout;
44 int res;
45
46 control = control & 0x0f;
47 res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
48 if (res)
49 return _FAIL;
50
51 rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
52
53 timeout = jiffies + msecs_to_jiffies(1000);
54
55 do {
56 res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
57 if (res)
58 continue;
59
60 if (!(reg_0x88 & control))
61 break;
62
63 } while (time_before(jiffies, timeout));
64
65 res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88);
66 if (res)
67 return _FAIL;
68
69 status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
70 if (reg_0x88 & control << 4)
71 status = _FAIL;
72 return status;
73 }
74
iol_InitLLTTable(struct adapter * padapter,u8 txpktbuf_bndy)75 static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
76 {
77 s32 rst = _SUCCESS;
78 iol_mode_enable(padapter, 1);
79 rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
80 rst = iol_execute(padapter, CMD_INIT_LLT);
81 iol_mode_enable(padapter, 0);
82 return rst;
83 }
84
85 static void
efuse_phymap_to_logical(u8 * phymap,u16 _size_byte,u8 * pbuf)86 efuse_phymap_to_logical(u8 *phymap, u16 _size_byte, u8 *pbuf)
87 {
88 u8 *efuseTbl = NULL;
89 u8 rtemp8;
90 u16 eFuse_Addr = 0;
91 u8 offset, wren;
92 u16 i, j;
93 u16 **eFuseWord = NULL;
94 u8 u1temp = 0;
95
96 efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
97 if (!efuseTbl)
98 goto exit;
99
100 eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
101 if (!eFuseWord)
102 goto exit;
103
104 /* 0. Refresh efuse init map as all oxFF. */
105 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
106 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
107 eFuseWord[i][j] = 0xFFFF;
108
109 /* */
110 /* 1. Read the first byte to check if efuse is empty!!! */
111 /* */
112 /* */
113 rtemp8 = *(phymap + eFuse_Addr);
114 if (rtemp8 != 0xFF) {
115 eFuse_Addr++;
116 } else {
117 goto exit;
118 }
119
120 /* */
121 /* 2. Read real efuse content. Filter PG header and every section data. */
122 /* */
123 while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
124 /* Check PG header for section num. */
125 if ((rtemp8 & 0x1F) == 0x0F) { /* extended header */
126 u1temp = ((rtemp8 & 0xE0) >> 5);
127 rtemp8 = *(phymap + eFuse_Addr);
128 if ((rtemp8 & 0x0F) == 0x0F) {
129 eFuse_Addr++;
130 rtemp8 = *(phymap + eFuse_Addr);
131
132 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
133 eFuse_Addr++;
134 continue;
135 } else {
136 offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
137 wren = (rtemp8 & 0x0F);
138 eFuse_Addr++;
139 }
140 } else {
141 offset = ((rtemp8 >> 4) & 0x0f);
142 wren = (rtemp8 & 0x0f);
143 }
144
145 if (offset < EFUSE_MAX_SECTION_88E) {
146 /* Get word enable value from PG header */
147 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
148 /* Check word enable condition in the section */
149 if (!(wren & 0x01)) {
150 rtemp8 = *(phymap + eFuse_Addr);
151 eFuse_Addr++;
152 eFuseWord[offset][i] = (rtemp8 & 0xff);
153 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
154 break;
155 rtemp8 = *(phymap + eFuse_Addr);
156 eFuse_Addr++;
157 eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
158
159 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
160 break;
161 }
162 wren >>= 1;
163 }
164 }
165 /* Read next PG header */
166 rtemp8 = *(phymap + eFuse_Addr);
167
168 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
169 eFuse_Addr++;
170 }
171 }
172
173 /* */
174 /* 3. Collect 16 sections and 4 word unit into Efuse map. */
175 /* */
176 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
177 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
178 efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
179 efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
180 }
181 }
182
183 /* */
184 /* 4. Copy from Efuse map to output pointer memory!!! */
185 /* */
186 memcpy(pbuf, efuseTbl, _size_byte);
187
188 exit:
189 kfree(efuseTbl);
190 kfree(eFuseWord);
191 }
192
193 /* FIXME: add error handling in callers */
efuse_read_phymap_from_txpktbuf(struct adapter * adapter,u8 * content,u16 * size)194 static int efuse_read_phymap_from_txpktbuf(
195 struct adapter *adapter,
196 u8 *content, /* buffer to store efuse physical map */
197 u16 *size /* for efuse content: the max byte to read. will update to byte read */
198 )
199 {
200 unsigned long timeout;
201 __le32 lo32 = 0, hi32 = 0;
202 u16 len = 0, count = 0;
203 int i = 0, res;
204 u16 limit = *size;
205 u8 reg;
206 u8 *pos = content;
207 u32 reg32;
208
209 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
210
211 while (1) {
212 rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, i);
213
214 rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
215 timeout = jiffies + msecs_to_jiffies(1000);
216 do {
217 res = rtw_read8(adapter, REG_TXPKTBUF_DBG, ®);
218 if (res)
219 continue;
220
221 if (reg)
222 break;
223
224 msleep(1);
225 } while (time_before(jiffies, timeout));
226
227 /* data from EEPROM needs to be in LE */
228 res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, ®32);
229 if (res)
230 return res;
231
232 lo32 = cpu_to_le32(reg32);
233
234 res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, ®32);
235 if (res)
236 return res;
237
238 hi32 = cpu_to_le32(reg32);
239
240 if (i == 0) {
241 u16 reg;
242
243 /* Although lenc is only used in a debug statement,
244 * do not remove it as the rtw_read16() call consumes
245 * 2 bytes from the EEPROM source.
246 */
247 res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, ®);
248 if (res)
249 return res;
250
251 len = le32_to_cpu(lo32) & 0x0000ffff;
252
253 limit = (len - 2 < limit) ? len - 2 : limit;
254
255 memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
256 count += (limit >= count + 2) ? 2 : limit - count;
257 pos = content + count;
258 } else {
259 memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
260 count += (limit >= count + 4) ? 4 : limit - count;
261 pos = content + count;
262 }
263
264 if (limit > count && len - 2 > count) {
265 memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
266 count += (limit >= count + 4) ? 4 : limit - count;
267 pos = content + count;
268 }
269
270 if (limit <= count || len - 2 <= count)
271 break;
272 i++;
273 }
274 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
275 *size = count;
276
277 return 0;
278 }
279
iol_read_efuse(struct adapter * padapter,u16 size_byte,u8 * logical_map)280 static s32 iol_read_efuse(struct adapter *padapter, u16 size_byte, u8 *logical_map)
281 {
282 s32 status = _FAIL;
283 u8 physical_map[512];
284 u16 size = 512;
285
286 rtw_write8(padapter, REG_TDECTRL + 1, 0);
287 memset(physical_map, 0xFF, 512);
288 rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
289 status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
290 if (status == _SUCCESS)
291 efuse_read_phymap_from_txpktbuf(padapter, physical_map, &size);
292 efuse_phymap_to_logical(physical_map, size_byte, logical_map);
293 return status;
294 }
295
rtl8188e_iol_efuse_patch(struct adapter * padapter)296 s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
297 {
298 s32 result = _SUCCESS;
299
300 if (rtw_IOL_applied(padapter)) {
301 iol_mode_enable(padapter, 1);
302 result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
303 if (result == _SUCCESS)
304 result = iol_execute(padapter, CMD_EFUSE_PATCH);
305
306 iol_mode_enable(padapter, 0);
307 }
308 return result;
309 }
310
iol_ioconfig(struct adapter * padapter,u8 iocfg_bndy)311 static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
312 {
313 s32 rst = _SUCCESS;
314
315 rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
316 rst = iol_execute(padapter, CMD_IOCONFIG);
317 return rst;
318 }
319
rtl8188e_IOL_exec_cmds_sync(struct adapter * adapter,struct xmit_frame * xmit_frame,u32 max_wating_ms,u32 bndy_cnt)320 int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
321 {
322 struct pkt_attrib *pattrib = &xmit_frame->attrib;
323 u8 i;
324 int ret = _FAIL;
325
326 if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
327 goto exit;
328 if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
329 if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
330 goto exit;
331 }
332
333 dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
334
335 iol_mode_enable(adapter, 1);
336 for (i = 0; i < bndy_cnt; i++) {
337 u8 page_no = 0;
338 page_no = i * 2;
339 ret = iol_ioconfig(adapter, page_no);
340 if (ret != _SUCCESS)
341 break;
342 }
343 iol_mode_enable(adapter, 0);
344 exit:
345 /* restore BCN_HEAD */
346 rtw_write8(adapter, REG_TDECTRL + 1, 0);
347 return ret;
348 }
349
rtl8188e_EfusePowerSwitch(struct adapter * pAdapter,u8 PwrState)350 void rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState)
351 {
352 u16 tmpV16;
353 int res;
354
355 if (PwrState) {
356 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
357
358 /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid */
359 res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16);
360 if (res)
361 return;
362
363 if (!(tmpV16 & PWC_EV12V)) {
364 tmpV16 |= PWC_EV12V;
365 rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
366 }
367 /* Reset: 0x0000h[28], default valid */
368 res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16);
369 if (res)
370 return;
371
372 if (!(tmpV16 & FEN_ELDR)) {
373 tmpV16 |= FEN_ELDR;
374 rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
375 }
376
377 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
378 res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16);
379 if (res)
380 return;
381
382 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
383 tmpV16 |= (LOADER_CLK_EN | ANA8M);
384 rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
385 }
386 } else {
387 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
388 }
389 }
390
Hal_EfuseReadEFuse88E(struct adapter * Adapter,u16 _offset,u16 _size_byte,u8 * pbuf)391 static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
392 u16 _offset,
393 u16 _size_byte,
394 u8 *pbuf)
395 {
396 u8 *efuseTbl = NULL;
397 u8 rtemp8[1];
398 u16 eFuse_Addr = 0;
399 u8 offset, wren;
400 u16 i, j;
401 u16 **eFuseWord = NULL;
402 u16 efuse_utilized = 0;
403 u8 u1temp = 0;
404
405 /* */
406 /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
407 /* */
408 if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) /* total E-Fuse table is 512bytes */
409 goto exit;
410
411 efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
412 if (!efuseTbl)
413 goto exit;
414
415 eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
416 if (!eFuseWord)
417 goto exit;
418
419 /* 0. Refresh efuse init map as all oxFF. */
420 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
421 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
422 eFuseWord[i][j] = 0xFFFF;
423
424 /* */
425 /* 1. Read the first byte to check if efuse is empty!!! */
426 /* */
427 /* */
428 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
429 if (*rtemp8 != 0xFF) {
430 efuse_utilized++;
431 eFuse_Addr++;
432 } else {
433 goto exit;
434 }
435
436 /* */
437 /* 2. Read real efuse content. Filter PG header and every section data. */
438 /* */
439 while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
440 /* Check PG header for section num. */
441 if ((*rtemp8 & 0x1F) == 0x0F) { /* extended header */
442 u1temp = ((*rtemp8 & 0xE0) >> 5);
443
444 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
445
446 if ((*rtemp8 & 0x0F) == 0x0F) {
447 eFuse_Addr++;
448 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
449
450 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
451 eFuse_Addr++;
452 continue;
453 } else {
454 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
455 wren = (*rtemp8 & 0x0F);
456 eFuse_Addr++;
457 }
458 } else {
459 offset = ((*rtemp8 >> 4) & 0x0f);
460 wren = (*rtemp8 & 0x0f);
461 }
462
463 if (offset < EFUSE_MAX_SECTION_88E) {
464 /* Get word enable value from PG header */
465
466 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
467 /* Check word enable condition in the section */
468 if (!(wren & 0x01)) {
469 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
470 eFuse_Addr++;
471 efuse_utilized++;
472 eFuseWord[offset][i] = (*rtemp8 & 0xff);
473 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
474 break;
475 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
476 eFuse_Addr++;
477 efuse_utilized++;
478 eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
479 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
480 break;
481 }
482 wren >>= 1;
483 }
484 }
485
486 /* Read next PG header */
487 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8);
488
489 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
490 efuse_utilized++;
491 eFuse_Addr++;
492 }
493 }
494
495 /* 3. Collect 16 sections and 4 word unit into Efuse map. */
496 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
497 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
498 efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
499 efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
500 }
501 }
502
503 /* 4. Copy from Efuse map to output pointer memory!!! */
504 for (i = 0; i < _size_byte; i++)
505 pbuf[i] = efuseTbl[_offset + i];
506
507 exit:
508 kfree(efuseTbl);
509 kfree(eFuseWord);
510 }
511
rtl8188e_ReadEFuse(struct adapter * Adapter,u16 _size_byte,u8 * pbuf)512 void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf)
513 {
514 int ret = _FAIL;
515 if (rtw_IOL_applied(Adapter)) {
516 rtl8188eu_InitPowerOn(Adapter);
517
518 iol_mode_enable(Adapter, 1);
519 ret = iol_read_efuse(Adapter, _size_byte, pbuf);
520 iol_mode_enable(Adapter, 0);
521
522 if (_SUCCESS == ret)
523 return;
524 }
525
526 Hal_EfuseReadEFuse88E(Adapter, 0, _size_byte, pbuf);
527 }
528
dump_chip_info(struct adapter * adapter,struct HAL_VERSION chip_vers)529 static void dump_chip_info(struct adapter *adapter, struct HAL_VERSION chip_vers)
530 {
531 struct net_device *netdev = adapter->pnetdev;
532 char *cut = NULL;
533 char buf[25];
534
535 switch (chip_vers.CUTVersion) {
536 case A_CUT_VERSION:
537 cut = "A_CUT";
538 break;
539 case B_CUT_VERSION:
540 cut = "B_CUT";
541 break;
542 case C_CUT_VERSION:
543 cut = "C_CUT";
544 break;
545 case D_CUT_VERSION:
546 cut = "D_CUT";
547 break;
548 case E_CUT_VERSION:
549 cut = "E_CUT";
550 break;
551 default:
552 snprintf(buf, sizeof(buf), "UNKNOWN_CUT(%d)", chip_vers.CUTVersion);
553 cut = buf;
554 break;
555 }
556
557 netdev_dbg(netdev, "Chip Version Info: CHIP_8188E_%s_%s_%s_1T1R_RomVer(%d)\n",
558 IS_NORMAL_CHIP(chip_vers) ? "Normal_Chip" : "Test_Chip",
559 IS_CHIP_VENDOR_TSMC(chip_vers) ? "TSMC" : "UMC",
560 cut, 0);
561 }
562
rtl8188e_read_chip_version(struct adapter * padapter)563 void rtl8188e_read_chip_version(struct adapter *padapter)
564 {
565 u32 value32;
566 struct HAL_VERSION ChipVersion;
567 struct hal_data_8188e *pHalData = &padapter->haldata;
568 int res;
569
570 res = rtw_read32(padapter, REG_SYS_CFG, &value32);
571 if (res)
572 return;
573
574 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
575
576 ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
577 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
578
579 dump_chip_info(padapter, ChipVersion);
580
581 pHalData->VersionID = ChipVersion;
582 }
583
rtl8188e_SetHalODMVar(struct adapter * Adapter,void * pValue1,bool bSet)584 void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet)
585 {
586 struct hal_data_8188e *pHalData = &Adapter->haldata;
587 struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
588 struct sta_info *psta = (struct sta_info *)pValue1;
589
590 if (bSet) {
591 podmpriv->pODM_StaInfo[psta->mac_id] = psta;
592 ODM_RAInfo_Init(podmpriv, psta->mac_id);
593 } else {
594 podmpriv->pODM_StaInfo[psta->mac_id] = NULL;
595 }
596 }
597
hal_notch_filter_8188e(struct adapter * adapter,bool enable)598 void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
599 {
600 int res;
601 u8 reg;
602
603 res = rtw_read8(adapter, rOFDM0_RxDSP + 1, ®);
604 if (res)
605 return;
606
607 if (enable)
608 rtw_write8(adapter, rOFDM0_RxDSP + 1, reg | BIT(1));
609 else
610 rtw_write8(adapter, rOFDM0_RxDSP + 1, reg & ~BIT(1));
611 }
612
613 /* */
614 /* */
615 /* LLT R/W/Init function */
616 /* */
617 /* */
_LLTWrite(struct adapter * padapter,u32 address,u32 data)618 static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
619 {
620 s32 count;
621 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
622 u16 LLTReg = REG_LLT_INIT;
623 int res;
624
625 rtw_write32(padapter, LLTReg, value);
626
627 /* polling */
628 for (count = 0; count <= POLLING_LLT_THRESHOLD; count++) {
629 res = rtw_read32(padapter, LLTReg, &value);
630 if (res)
631 continue;
632
633 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
634 break;
635 }
636
637 return count > POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS;
638 }
639
InitLLTTable(struct adapter * padapter,u8 txpktbuf_bndy)640 s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
641 {
642 s32 status = _FAIL;
643 u32 i;
644 u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/* 176, 22k */
645
646 if (rtw_IOL_applied(padapter)) {
647 status = iol_InitLLTTable(padapter, txpktbuf_bndy);
648 } else {
649 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
650 status = _LLTWrite(padapter, i, i + 1);
651 if (_SUCCESS != status)
652 return status;
653 }
654
655 /* end of list */
656 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
657 if (_SUCCESS != status)
658 return status;
659
660 /* Make the other pages as ring buffer */
661 /* This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
662 /* Otherwise used as local loopback buffer. */
663 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
664 status = _LLTWrite(padapter, i, (i + 1));
665 if (_SUCCESS != status)
666 return status;
667 }
668
669 /* Let last entry point to the start entry of ring buffer */
670 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
671 if (_SUCCESS != status) {
672 return status;
673 }
674 }
675
676 return status;
677 }
678
679 void
Hal_EfuseParseIDCode88E(struct adapter * padapter,u8 * hwinfo)680 Hal_EfuseParseIDCode88E(
681 struct adapter *padapter,
682 u8 *hwinfo
683 )
684 {
685 struct eeprom_priv *pEEPROM = &padapter->eeprompriv;
686 struct net_device *netdev = padapter->pnetdev;
687 u16 EEPROMId;
688
689 /* Check 0x8129 again for making sure autoload status!! */
690 EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
691 if (EEPROMId != RTL_EEPROM_ID) {
692 pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
693 pEEPROM->bautoload_fail_flag = true;
694 } else {
695 pEEPROM->bautoload_fail_flag = false;
696 }
697
698 netdev_dbg(netdev, "EEPROM ID = 0x%04x\n", EEPROMId);
699 }
700
Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g * pwrInfo24G,u8 * PROMContent,bool AutoLoadFail)701 static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
702 {
703 u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
704
705 memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
706
707 if (AutoLoadFail) {
708 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
709 /* 2.4G default value */
710 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
711 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
712 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
713 }
714 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
715 if (TxCount == 0) {
716 pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
717 pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
718 } else {
719 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
720 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
721 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
722 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
723 }
724 }
725 }
726 return;
727 }
728
729 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
730 /* 2.4G default value */
731 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
732 pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++];
733 if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
734 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
735 }
736 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
737 pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++];
738 if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
739 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
740 }
741 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
742 if (TxCount == 0) {
743 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
744 if (PROMContent[eeAddr] == 0xFF) {
745 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
746 } else {
747 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
748 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
749 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
750 }
751
752 if (PROMContent[eeAddr] == 0xFF) {
753 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF;
754 } else {
755 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
756 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
757 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
758 }
759 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
760 eeAddr++;
761 } else {
762 if (PROMContent[eeAddr] == 0xFF) {
763 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
764 } else {
765 pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
766 if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
767 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
768 }
769
770 if (PROMContent[eeAddr] == 0xFF) {
771 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
772 } else {
773 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
774 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
775 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
776 }
777 eeAddr++;
778
779 if (PROMContent[eeAddr] == 0xFF) {
780 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
781 } else {
782 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
783 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
784 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
785 }
786
787 if (PROMContent[eeAddr] == 0xFF) {
788 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
789 } else {
790 pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
791 if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3)) /* 4bit sign number to 8 bit sign number */
792 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
793 }
794 eeAddr++;
795 }
796 }
797 }
798 }
799
hal_get_chnl_group_88e(u8 chnl,u8 * group)800 static void hal_get_chnl_group_88e(u8 chnl, u8 *group)
801 {
802 if (chnl < 3) /* Channel 1-2 */
803 *group = 0;
804 else if (chnl < 6) /* Channel 3-5 */
805 *group = 1;
806 else if (chnl < 9) /* Channel 6-8 */
807 *group = 2;
808 else if (chnl < 12) /* Channel 9-11 */
809 *group = 3;
810 else if (chnl < 14) /* Channel 12-13 */
811 *group = 4;
812 else if (chnl == 14) /* Channel 14 */
813 *group = 5;
814 }
815
Hal_ReadPowerSavingMode88E(struct adapter * padapter,u8 * hwinfo,bool AutoLoadFail)816 void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
817 {
818 if (AutoLoadFail)
819 padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
820 else
821 /* hw power down mode selection , 0:rf-off / 1:power down */
822
823 /* decide hw if support remote wakeup function */
824 /* if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */
825 padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false;
826 }
827
Hal_ReadTxPowerInfo88E(struct adapter * padapter,u8 * PROMContent,bool AutoLoadFail)828 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
829 {
830 struct hal_data_8188e *pHalData = &padapter->haldata;
831 struct txpowerinfo24g pwrInfo24G;
832 u8 ch, group;
833 u8 TxCount;
834
835 Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
836
837 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
838 hal_get_chnl_group_88e(ch, &group);
839
840 pHalData->Index24G_CCK_Base[ch] = pwrInfo24G.IndexCCK_Base[0][group];
841 if (ch == 14)
842 pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][4];
843 else
844 pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][group];
845 }
846 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
847 pHalData->OFDM_24G_Diff[TxCount] = pwrInfo24G.OFDM_Diff[0][TxCount];
848 pHalData->BW20_24G_Diff[TxCount] = pwrInfo24G.BW20_Diff[0][TxCount];
849 }
850
851 /* 2010/10/19 MH Add Regulator recognize for CU. */
852 if (!AutoLoadFail) {
853 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7); /* bit0~2 */
854 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
855 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */
856 } else {
857 pHalData->EEPROMRegulatory = 0;
858 }
859 }
860
Hal_EfuseParseXtal_8188E(struct adapter * pAdapter,u8 * hwinfo,bool AutoLoadFail)861 void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
862 {
863 struct hal_data_8188e *pHalData = &pAdapter->haldata;
864
865 if (!AutoLoadFail) {
866 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
867 if (pHalData->CrystalCap == 0xFF)
868 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
869 } else {
870 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
871 }
872 }
873
rtl8188e_EfuseParseChnlPlan(struct adapter * padapter,u8 * hwinfo,bool AutoLoadFail)874 void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
875 {
876 padapter->mlmepriv.ChannelPlan =
877 hal_com_get_channel_plan(padapter,
878 hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
879 padapter->registrypriv.channel_plan,
880 RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
881 }
882
Hal_ReadAntennaDiversity88E(struct adapter * pAdapter,u8 * PROMContent,bool AutoLoadFail)883 void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
884 {
885 struct hal_data_8188e *pHalData = &pAdapter->haldata;
886 struct registry_priv *registry_par = &pAdapter->registrypriv;
887
888 if (!AutoLoadFail) {
889 /* Antenna Diversity setting. */
890 if (registry_par->antdiv_cfg == 2) { /* 2:By EFUSE */
891 pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
892 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
893 pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
894 } else {
895 pHalData->AntDivCfg = registry_par->antdiv_cfg; /* 0:OFF , 1:ON, 2:By EFUSE */
896 }
897
898 if (registry_par->antdiv_type == 0) {
899 /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
900 pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
901 if (pHalData->TRxAntDivType == 0xFF)
902 pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /* For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
903 } else {
904 pHalData->TRxAntDivType = registry_par->antdiv_type;
905 }
906
907 if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
908 pHalData->AntDivCfg = 1; /* 0xC1[3] is ignored. */
909 } else {
910 pHalData->AntDivCfg = 0;
911 }
912 }
913
Hal_ReadThermalMeter_88E(struct adapter * Adapter,u8 * PROMContent,bool AutoloadFail)914 void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
915 {
916 struct hal_data_8188e *pHalData = &Adapter->haldata;
917
918 /* ThermalMeter from EEPROM */
919 if (!AutoloadFail)
920 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
921 else
922 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
923
924 if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail)
925 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
926 }
927