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