1
2
3
4#define _HAL_INIT_C_
5
6#include "../include/linux/firmware.h"
7#include "../include/drv_types.h"
8#include "../include/rtw_efuse.h"
9#include "../include/rtl8188e_hal.h"
10#include "../include/rtw_iol.h"
11#include "../include/usb_ops.h"
12
13static void iol_mode_enable(struct adapter *padapter, u8 enable)
14{
15 u8 reg_0xf0 = 0;
16
17 if (enable) {
18
19 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
20 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN);
21
22 if (!padapter->bFWReady) {
23 DBG_88E("bFWReady == false call reset 8051...\n");
24 _8051Reset88E(padapter);
25 }
26
27 } else {
28
29 reg_0xf0 = rtw_read8(padapter, REG_SYS_CFG);
30 rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
31 }
32}
33
34static s32 iol_execute(struct adapter *padapter, u8 control)
35{
36 s32 status = _FAIL;
37 u8 reg_0x88 = 0;
38 u32 start = 0, passing_time = 0;
39
40 control = control & 0x0f;
41 reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
42 rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control);
43
44 start = jiffies;
45 while ((reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0)) & control &&
46 (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
47 ;
48 }
49
50 reg_0x88 = rtw_read8(padapter, REG_HMEBOX_E0);
51 status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
52 if (reg_0x88 & control << 4)
53 status = _FAIL;
54 return status;
55}
56
57static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
58{
59 s32 rst = _SUCCESS;
60 iol_mode_enable(padapter, 1);
61 rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
62 rst = iol_execute(padapter, CMD_INIT_LLT);
63 iol_mode_enable(padapter, 0);
64 return rst;
65}
66
67static void
68efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 _size_byte, u8 *pbuf)
69{
70 u8 *efuseTbl = NULL;
71 u8 rtemp8;
72 u16 eFuse_Addr = 0;
73 u8 offset, wren;
74 u16 i, j;
75 u16 **eFuseWord = NULL;
76 u16 efuse_utilized = 0;
77 u8 u1temp = 0;
78
79 efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
80 if (!efuseTbl) {
81 DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
82 goto exit;
83 }
84
85 eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
86 if (!eFuseWord) {
87 DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
88 goto exit;
89 }
90
91
92 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
93 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
94 eFuseWord[i][j] = 0xFFFF;
95
96
97
98
99
100 rtemp8 = *(phymap + eFuse_Addr);
101 if (rtemp8 != 0xFF) {
102 efuse_utilized++;
103 eFuse_Addr++;
104 } else {
105 DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, rtemp8);
106 goto exit;
107 }
108
109
110
111
112 while ((rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
113
114 if ((rtemp8 & 0x1F) == 0x0F) {
115 u1temp = ((rtemp8 & 0xE0) >> 5);
116 rtemp8 = *(phymap + eFuse_Addr);
117 if ((rtemp8 & 0x0F) == 0x0F) {
118 eFuse_Addr++;
119 rtemp8 = *(phymap + eFuse_Addr);
120
121 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
122 eFuse_Addr++;
123 continue;
124 } else {
125 offset = ((rtemp8 & 0xF0) >> 1) | u1temp;
126 wren = (rtemp8 & 0x0F);
127 eFuse_Addr++;
128 }
129 } else {
130 offset = ((rtemp8 >> 4) & 0x0f);
131 wren = (rtemp8 & 0x0f);
132 }
133
134 if (offset < EFUSE_MAX_SECTION_88E) {
135
136 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
137
138 if (!(wren & 0x01)) {
139 rtemp8 = *(phymap + eFuse_Addr);
140 eFuse_Addr++;
141 efuse_utilized++;
142 eFuseWord[offset][i] = (rtemp8 & 0xff);
143 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
144 break;
145 rtemp8 = *(phymap + eFuse_Addr);
146 eFuse_Addr++;
147 efuse_utilized++;
148 eFuseWord[offset][i] |= (((u16)rtemp8 << 8) & 0xff00);
149
150 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
151 break;
152 }
153 wren >>= 1;
154 }
155 }
156
157 rtemp8 = *(phymap + eFuse_Addr);
158
159 if (rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
160 efuse_utilized++;
161 eFuse_Addr++;
162 }
163 }
164
165
166
167
168 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
169 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
170 efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
171 efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
172 }
173 }
174
175
176
177
178 for (i = 0; i < _size_byte; i++)
179 pbuf[i] = efuseTbl[_offset + i];
180
181
182
183
184
185exit:
186 kfree(efuseTbl);
187 kfree(eFuseWord);
188}
189
190static void efuse_read_phymap_from_txpktbuf(
191 struct adapter *adapter,
192 int bcnhead,
193 u8 *content,
194 u16 *size
195 )
196{
197 u16 dbg_addr = 0;
198 u32 start = 0, passing_time = 0;
199 u8 reg_0x143 = 0;
200 __le32 lo32 = 0, hi32 = 0;
201 u16 len = 0, count = 0;
202 int i = 0;
203 u16 limit = *size;
204
205 u8 *pos = content;
206
207 if (bcnhead < 0)
208 bcnhead = rtw_read8(adapter, REG_TDECTRL + 1);
209
210 DBG_88E("%s bcnhead:%d\n", __func__, bcnhead);
211
212 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
213
214 dbg_addr = bcnhead * 128 / 8;
215
216 while (1) {
217 rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, dbg_addr + i);
218
219 rtw_write8(adapter, REG_TXPKTBUF_DBG, 0);
220 start = jiffies;
221 while (!(reg_0x143 = rtw_read8(adapter, REG_TXPKTBUF_DBG)) &&
222 (passing_time = rtw_get_passing_time_ms(start)) < 1000) {
223 DBG_88E("%s polling reg_0x143:0x%02x, reg_0x106:0x%02x\n", __func__, reg_0x143, rtw_read8(adapter, 0x106));
224 rtw_usleep_os(100);
225 }
226
227
228 lo32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L));
229 hi32 = cpu_to_le32(rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H));
230
231 if (i == 0) {
232
233
234
235
236 u16 lenc = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L);
237
238 len = le32_to_cpu(lo32) & 0x0000ffff;
239
240 limit = (len - 2 < limit) ? len - 2 : limit;
241
242 DBG_88E("%s len:%u, lenc:%u\n", __func__, len, lenc);
243
244 memcpy(pos, ((u8 *)&lo32) + 2, (limit >= count + 2) ? 2 : limit - count);
245 count += (limit >= count + 2) ? 2 : limit - count;
246 pos = content + count;
247 } else {
248 memcpy(pos, ((u8 *)&lo32), (limit >= count + 4) ? 4 : limit - count);
249 count += (limit >= count + 4) ? 4 : limit - count;
250 pos = content + count;
251 }
252
253 if (limit > count && len - 2 > count) {
254 memcpy(pos, (u8 *)&hi32, (limit >= count + 4) ? 4 : limit - count);
255 count += (limit >= count + 4) ? 4 : limit - count;
256 pos = content + count;
257 }
258
259 if (limit <= count || len - 2 <= count)
260 break;
261 i++;
262 }
263 rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, DISABLE_TRXPKT_BUF_ACCESS);
264 DBG_88E("%s read count:%u\n", __func__, count);
265 *size = count;
266}
267
268static s32 iol_read_efuse(struct adapter *padapter, u8 txpktbuf_bndy, u16 offset, u16 size_byte, u8 *logical_map)
269{
270 s32 status = _FAIL;
271 u8 physical_map[512];
272 u16 size = 512;
273
274 rtw_write8(padapter, REG_TDECTRL + 1, txpktbuf_bndy);
275 memset(physical_map, 0xFF, 512);
276 rtw_write8(padapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
277 status = iol_execute(padapter, CMD_READ_EFUSE_MAP);
278 if (status == _SUCCESS)
279 efuse_read_phymap_from_txpktbuf(padapter, txpktbuf_bndy, physical_map, &size);
280 efuse_phymap_to_logical(physical_map, offset, size_byte, logical_map);
281 return status;
282}
283
284s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
285{
286 s32 result = _SUCCESS;
287
288 DBG_88E("==> %s\n", __func__);
289 if (rtw_IOL_applied(padapter)) {
290 iol_mode_enable(padapter, 1);
291 result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
292 if (result == _SUCCESS)
293 result = iol_execute(padapter, CMD_EFUSE_PATCH);
294
295 iol_mode_enable(padapter, 0);
296 }
297 return result;
298}
299
300static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy)
301{
302 s32 rst = _SUCCESS;
303
304 rtw_write8(padapter, REG_TDECTRL + 1, iocfg_bndy);
305 rst = iol_execute(padapter, CMD_IOCONFIG);
306 return rst;
307}
308
309static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
310{
311 struct pkt_attrib *pattrib = &xmit_frame->attrib;
312 u8 i;
313 int ret = _FAIL;
314
315 if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
316 goto exit;
317 if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE + pattrib->last_txcmdsz)) {
318 if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)
319 goto exit;
320 }
321
322 dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);
323
324 iol_mode_enable(adapter, 1);
325 for (i = 0; i < bndy_cnt; i++) {
326 u8 page_no = 0;
327 page_no = i * 2;
328 ret = iol_ioconfig(adapter, page_no);
329 if (ret != _SUCCESS)
330 break;
331 }
332 iol_mode_enable(adapter, 0);
333exit:
334
335 rtw_write8(adapter, REG_TDECTRL + 1, 0);
336 return ret;
337}
338
339void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len)
340{
341 u32 fifo_data, reg_140;
342 u32 addr, rstatus, loop = 0;
343 u16 data_cnts = (data_len / 8) + 1;
344 u8 *pbuf = vzalloc(data_len + 10);
345 DBG_88E("###### %s ######\n", __func__);
346
347 rtw_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT);
348 if (pbuf) {
349 for (addr = 0; addr < data_cnts; addr++) {
350 rtw_write32(Adapter, 0x140, addr);
351 rtw_usleep_os(2);
352 loop = 0;
353 do {
354 rstatus = (reg_140 = rtw_read32(Adapter, REG_PKTBUF_DBG_CTRL) & BIT(24));
355 if (rstatus) {
356 fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_L);
357 memcpy(pbuf + (addr * 8), &fifo_data, 4);
358
359 fifo_data = rtw_read32(Adapter, REG_PKTBUF_DBG_DATA_H);
360 memcpy(pbuf + (addr * 8 + 4), &fifo_data, 4);
361 }
362 rtw_usleep_os(2);
363 } while (!rstatus && (loop++ < 10));
364 }
365 rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf);
366 vfree(pbuf);
367 }
368 DBG_88E("###### %s ######\n", __func__);
369}
370
371static void _FWDownloadEnable(struct adapter *padapter, bool enable)
372{
373 u8 tmp;
374
375 if (enable) {
376
377 tmp = rtw_read8(padapter, REG_MCUFWDL);
378 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
379
380
381 tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
382 rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
383 } else {
384
385 tmp = rtw_read8(padapter, REG_MCUFWDL);
386 rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
387
388
389 rtw_write8(padapter, REG_MCUFWDL + 1, 0x00);
390 }
391}
392
393#define MAX_REG_BOLCK_SIZE 196
394
395static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize)
396{
397 int ret = _SUCCESS;
398 u32 blockSize_p1 = 4;
399 u32 blockSize_p2 = 8;
400 u32 blockSize_p3 = 1;
401 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
402 u32 remainSize_p1 = 0, remainSize_p2 = 0;
403 u8 *bufferPtr = (u8 *)buffer;
404 u32 i = 0, offset = 0;
405
406 blockSize_p1 = MAX_REG_BOLCK_SIZE;
407
408
409 blockCount_p1 = buffSize / blockSize_p1;
410 remainSize_p1 = buffSize % blockSize_p1;
411
412 for (i = 0; i < blockCount_p1; i++) {
413 ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
414 if (ret == _FAIL)
415 goto exit;
416 }
417
418
419 if (remainSize_p1) {
420 offset = blockCount_p1 * blockSize_p1;
421
422 blockCount_p2 = remainSize_p1 / blockSize_p2;
423 remainSize_p2 = remainSize_p1 % blockSize_p2;
424
425 for (i = 0; i < blockCount_p2; i++) {
426 ret = rtw_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));
427
428 if (ret == _FAIL)
429 goto exit;
430 }
431 }
432
433
434 if (remainSize_p2) {
435 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
436
437 blockCount_p3 = remainSize_p2 / blockSize_p3;
438
439 for (i = 0; i < blockCount_p3; i++) {
440 ret = rtw_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
441
442 if (ret == _FAIL)
443 goto exit;
444 }
445 }
446
447exit:
448 return ret;
449}
450
451static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size)
452{
453 u8 value8;
454 u8 u8Page = (u8)(page & 0x07);
455
456 value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page;
457 rtw_write8(padapter, REG_MCUFWDL + 2, value8);
458
459 return _BlockWrite(padapter, buffer, size);
460}
461
462static int _WriteFW(struct adapter *padapter, void *buffer, u32 size)
463{
464
465
466 int ret = _SUCCESS;
467 u32 pageNums, remainSize;
468 u32 page, offset;
469 u8 *bufferPtr = (u8 *)buffer;
470
471 pageNums = size / MAX_PAGE_SIZE;
472 remainSize = size % MAX_PAGE_SIZE;
473
474 for (page = 0; page < pageNums; page++) {
475 offset = page * MAX_PAGE_SIZE;
476 ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_PAGE_SIZE);
477
478 if (ret == _FAIL)
479 goto exit;
480 }
481 if (remainSize) {
482 offset = pageNums * MAX_PAGE_SIZE;
483 page = pageNums;
484 ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize);
485
486 if (ret == _FAIL)
487 goto exit;
488 }
489exit:
490 return ret;
491}
492
493void _8051Reset88E(struct adapter *padapter)
494{
495 u8 u1bTmp;
496
497 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
498 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT(2)));
499 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp | (BIT(2)));
500 DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
501}
502
503static s32 _FWFreeToGo(struct adapter *padapter)
504{
505 u32 counter = 0;
506 u32 value32;
507
508
509 do {
510 value32 = rtw_read32(padapter, REG_MCUFWDL);
511 if (value32 & FWDL_ChkSum_rpt)
512 break;
513 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
514
515 if (counter >= POLLING_READY_TIMEOUT_COUNT) {
516 DBG_88E("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __func__, value32);
517 return _FAIL;
518 }
519 DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32);
520
521 value32 = rtw_read32(padapter, REG_MCUFWDL);
522 value32 |= MCUFWDL_RDY;
523 value32 &= ~WINTINI_RDY;
524 rtw_write32(padapter, REG_MCUFWDL, value32);
525
526 _8051Reset88E(padapter);
527
528
529 counter = 0;
530 do {
531 value32 = rtw_read32(padapter, REG_MCUFWDL);
532 if (value32 & WINTINI_RDY) {
533 DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32);
534 return _SUCCESS;
535 }
536 udelay(5);
537 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
538
539 DBG_88E("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __func__, value32);
540 return _FAIL;
541}
542
543#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
544
545static int load_firmware(struct rt_firmware *pFirmware, struct device *device)
546{
547 s32 rtStatus = _SUCCESS;
548 const struct firmware *fw;
549 const char *fw_name = "rtlwifi/rtl8188eufw.bin";
550 int err = request_firmware(&fw, fw_name, device);
551
552 if (err) {
553 pr_err("Request firmware failed with error 0x%x\n", err);
554 rtStatus = _FAIL;
555 goto Exit;
556 }
557 if (!fw) {
558 pr_err("Firmware %s not available\n", fw_name);
559 rtStatus = _FAIL;
560 goto Exit;
561 }
562 if (fw->size > FW_8188E_SIZE) {
563 rtStatus = _FAIL;
564 goto Exit;
565 }
566
567 pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL);
568 if (!pFirmware->szFwBuffer) {
569 pr_err("Failed to allocate pFirmware->szFwBuffer\n");
570 rtStatus = _FAIL;
571 goto Exit;
572 }
573 memcpy(pFirmware->szFwBuffer, fw->data, fw->size);
574 pFirmware->ulFwLength = fw->size;
575 release_firmware(fw);
576 DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, pFirmware->ulFwLength);
577
578Exit:
579 return rtStatus;
580}
581
582s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
583{
584 s32 rtStatus = _SUCCESS;
585 u8 writeFW_retry = 0;
586 u32 fwdl_start_time;
587 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
588 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
589 struct device *device = dvobj_to_dev(dvobj);
590 struct rt_firmware_hdr *pFwHdr = NULL;
591 u8 *pFirmwareBuf;
592 u32 FirmwareLen;
593 static int log_version;
594
595 if (!dvobj->firmware.szFwBuffer)
596 rtStatus = load_firmware(&dvobj->firmware, device);
597 if (rtStatus == _FAIL) {
598 dvobj->firmware.szFwBuffer = NULL;
599 goto Exit;
600 }
601 pFirmwareBuf = dvobj->firmware.szFwBuffer;
602 FirmwareLen = dvobj->firmware.ulFwLength;
603
604
605 pFwHdr = (struct rt_firmware_hdr *)dvobj->firmware.szFwBuffer;
606
607 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
608 pHalData->FirmwareSubVersion = pFwHdr->Subversion;
609 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
610
611 if (!log_version++)
612 pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n",
613 DRIVER_PREFIX, pHalData->FirmwareVersion,
614 pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
615
616 if (IS_FW_HEADER_EXIST(pFwHdr)) {
617
618 pFirmwareBuf = pFirmwareBuf + 32;
619 FirmwareLen = FirmwareLen - 32;
620 }
621
622
623
624 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
625 rtw_write8(padapter, REG_MCUFWDL, 0x00);
626 _8051Reset88E(padapter);
627 }
628
629 _FWDownloadEnable(padapter, true);
630 fwdl_start_time = jiffies;
631 while (1) {
632
633 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
634
635 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
636
637 if (rtStatus == _SUCCESS ||
638 (rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3))
639 break;
640
641 DBG_88E("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n",
642 __func__, writeFW_retry, rtw_get_passing_time_ms(fwdl_start_time)
643 );
644 }
645 _FWDownloadEnable(padapter, false);
646 if (_SUCCESS != rtStatus) {
647 DBG_88E("DL Firmware failed!\n");
648 goto Exit;
649 }
650
651 rtStatus = _FWFreeToGo(padapter);
652 if (_SUCCESS != rtStatus) {
653 DBG_88E("DL Firmware failed!\n");
654 goto Exit;
655 }
656
657Exit:
658 return rtStatus;
659}
660
661void rtl8188e_InitializeFirmwareVars(struct adapter *padapter)
662{
663 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
664
665
666 padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
667
668
669 pHalData->LastHMEBoxNum = 0;
670}
671
672static void rtl8188e_free_hal_data(struct adapter *padapter)
673{
674
675 kfree(padapter->HalData);
676 padapter->HalData = NULL;
677
678}
679
680
681
682
683enum{
684 VOLTAGE_V25 = 0x03,
685 LDOE25_SHIFT = 28,
686 };
687
688static bool
689hal_EfusePgPacketWrite2ByteHeader(
690 struct adapter *pAdapter,
691 u8 efuseType,
692 u16 *pAddr,
693 struct pgpkt *pTargetPkt,
694 bool bPseudoTest);
695static bool
696hal_EfusePgPacketWrite1ByteHeader(
697 struct adapter *pAdapter,
698 u8 efuseType,
699 u16 *pAddr,
700 struct pgpkt *pTargetPkt,
701 bool bPseudoTest);
702static bool
703hal_EfusePgPacketWriteData(
704 struct adapter *pAdapter,
705 u8 efuseType,
706 u16 *pAddr,
707 struct pgpkt *pTargetPkt,
708 bool bPseudoTest);
709
710static void
711hal_EfusePowerSwitch_RTL8188E(
712 struct adapter *pAdapter,
713 u8 bWrite,
714 u8 PwrState)
715{
716 u8 tempval;
717 u16 tmpV16;
718
719 if (PwrState) {
720 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
721
722
723 tmpV16 = rtw_read16(pAdapter, REG_SYS_ISO_CTRL);
724 if (!(tmpV16 & PWC_EV12V)) {
725 tmpV16 |= PWC_EV12V;
726 rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16);
727 }
728
729 tmpV16 = rtw_read16(pAdapter, REG_SYS_FUNC_EN);
730 if (!(tmpV16 & FEN_ELDR)) {
731 tmpV16 |= FEN_ELDR;
732 rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);
733 }
734
735
736 tmpV16 = rtw_read16(pAdapter, REG_SYS_CLKR);
737 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
738 tmpV16 |= (LOADER_CLK_EN | ANA8M);
739 rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);
740 }
741
742 if (bWrite) {
743
744 tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
745 tempval &= 0x0F;
746 tempval |= (VOLTAGE_V25 << 4);
747 rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));
748 }
749 } else {
750 rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
751
752 if (bWrite) {
753
754 tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);
755 rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));
756 }
757 }
758}
759
760static void
761rtl8188e_EfusePowerSwitch(
762 struct adapter *pAdapter,
763 u8 bWrite,
764 u8 PwrState)
765{
766 hal_EfusePowerSwitch_RTL8188E(pAdapter, bWrite, PwrState);
767}
768
769static void Hal_EfuseReadEFuse88E(struct adapter *Adapter,
770 u16 _offset,
771 u16 _size_byte,
772 u8 *pbuf,
773 bool bPseudoTest
774 )
775{
776 u8 *efuseTbl = NULL;
777 u8 rtemp8[1];
778 u16 eFuse_Addr = 0;
779 u8 offset, wren;
780 u16 i, j;
781 u16 **eFuseWord = NULL;
782 u16 efuse_utilized = 0;
783 u8 u1temp = 0;
784
785
786
787
788 if ((_offset + _size_byte) > EFUSE_MAP_LEN_88E) {
789 DBG_88E("Hal_EfuseReadEFuse88E(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);
790 goto exit;
791 }
792
793 efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL);
794 if (!efuseTbl) {
795 DBG_88E("%s: alloc efuseTbl fail!\n", __func__);
796 goto exit;
797 }
798
799 eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16));
800 if (!eFuseWord) {
801 DBG_88E("%s: alloc eFuseWord fail!\n", __func__);
802 goto exit;
803 }
804
805
806 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++)
807 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
808 eFuseWord[i][j] = 0xFFFF;
809
810
811
812
813
814 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
815 if (*rtemp8 != 0xFF) {
816 efuse_utilized++;
817 eFuse_Addr++;
818 } else {
819 DBG_88E("EFUSE is empty efuse_Addr-%d efuse_data =%x\n", eFuse_Addr, *rtemp8);
820 goto exit;
821 }
822
823
824
825
826 while ((*rtemp8 != 0xFF) && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
827
828 if ((*rtemp8 & 0x1F) == 0x0F) {
829 u1temp = ((*rtemp8 & 0xE0) >> 5);
830
831 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
832
833 if ((*rtemp8 & 0x0F) == 0x0F) {
834 eFuse_Addr++;
835 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
836
837 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E))
838 eFuse_Addr++;
839 continue;
840 } else {
841 offset = ((*rtemp8 & 0xF0) >> 1) | u1temp;
842 wren = (*rtemp8 & 0x0F);
843 eFuse_Addr++;
844 }
845 } else {
846 offset = ((*rtemp8 >> 4) & 0x0f);
847 wren = (*rtemp8 & 0x0f);
848 }
849
850 if (offset < EFUSE_MAX_SECTION_88E) {
851
852
853 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
854
855 if (!(wren & 0x01)) {
856 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
857 eFuse_Addr++;
858 efuse_utilized++;
859 eFuseWord[offset][i] = (*rtemp8 & 0xff);
860 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
861 break;
862 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
863 eFuse_Addr++;
864 efuse_utilized++;
865 eFuseWord[offset][i] |= (((u16)*rtemp8 << 8) & 0xff00);
866 if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E)
867 break;
868 }
869 wren >>= 1;
870 }
871 }
872
873
874 ReadEFuseByte(Adapter, eFuse_Addr, rtemp8, bPseudoTest);
875
876 if (*rtemp8 != 0xFF && (eFuse_Addr < EFUSE_REAL_CONTENT_LEN_88E)) {
877 efuse_utilized++;
878 eFuse_Addr++;
879 }
880 }
881
882
883 for (i = 0; i < EFUSE_MAX_SECTION_88E; i++) {
884 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
885 efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);
886 efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);
887 }
888 }
889
890
891 for (i = 0; i < _size_byte; i++)
892 pbuf[i] = efuseTbl[_offset + i];
893
894
895 rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);
896
897exit:
898 kfree(efuseTbl);
899 kfree(eFuseWord);
900}
901
902static void ReadEFuseByIC(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
903{
904 if (!bPseudoTest) {
905 int ret = _FAIL;
906 if (rtw_IOL_applied(Adapter)) {
907 rtw_hal_power_on(Adapter);
908
909 iol_mode_enable(Adapter, 1);
910 ret = iol_read_efuse(Adapter, 0, _offset, _size_byte, pbuf);
911 iol_mode_enable(Adapter, 0);
912
913 if (_SUCCESS == ret)
914 goto exit;
915 }
916 }
917 Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
918
919exit:
920 return;
921}
922
923static void ReadEFuse_Pseudo(struct adapter *Adapter, u8 efuseType, u16 _offset, u16 _size_byte, u8 *pbuf, bool bPseudoTest)
924{
925 Hal_EfuseReadEFuse88E(Adapter, _offset, _size_byte, pbuf, bPseudoTest);
926}
927
928static void rtl8188e_ReadEFuse(struct adapter *Adapter, u8 efuseType,
929 u16 _offset, u16 _size_byte, u8 *pbuf,
930 bool bPseudoTest)
931{
932 if (bPseudoTest)
933 ReadEFuse_Pseudo(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
934 else
935 ReadEFuseByIC(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
936}
937
938
939static void Hal_EFUSEGetEfuseDefinition88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
940{
941 switch (type) {
942 case TYPE_EFUSE_MAX_SECTION:
943 {
944 u8 *pMax_section;
945 pMax_section = (u8 *)pOut;
946 *pMax_section = EFUSE_MAX_SECTION_88E;
947 }
948 break;
949 case TYPE_EFUSE_REAL_CONTENT_LEN:
950 {
951 u16 *pu2Tmp;
952 pu2Tmp = (u16 *)pOut;
953 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
954 }
955 break;
956 case TYPE_EFUSE_CONTENT_LEN_BANK:
957 {
958 u16 *pu2Tmp;
959 pu2Tmp = (u16 *)pOut;
960 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
961 }
962 break;
963 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
964 {
965 u16 *pu2Tmp;
966 pu2Tmp = (u16 *)pOut;
967 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E);
968 }
969 break;
970 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
971 {
972 u16 *pu2Tmp;
973 pu2Tmp = (u16 *)pOut;
974 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E);
975 }
976 break;
977 case TYPE_EFUSE_MAP_LEN:
978 {
979 u16 *pu2Tmp;
980 pu2Tmp = (u16 *)pOut;
981 *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
982 }
983 break;
984 case TYPE_EFUSE_PROTECT_BYTES_BANK:
985 {
986 u8 *pu1Tmp;
987 pu1Tmp = (u8 *)pOut;
988 *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
989 }
990 break;
991 default:
992 {
993 u8 *pu1Tmp;
994 pu1Tmp = (u8 *)pOut;
995 *pu1Tmp = 0;
996 }
997 break;
998 }
999}
1000
1001static void Hal_EFUSEGetEfuseDefinition_Pseudo88E(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut)
1002{
1003 switch (type) {
1004 case TYPE_EFUSE_MAX_SECTION:
1005 {
1006 u8 *pMax_section;
1007 pMax_section = (u8 *)pOut;
1008 *pMax_section = EFUSE_MAX_SECTION_88E;
1009 }
1010 break;
1011 case TYPE_EFUSE_REAL_CONTENT_LEN:
1012 {
1013 u16 *pu2Tmp;
1014 pu2Tmp = (u16 *)pOut;
1015 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1016 }
1017 break;
1018 case TYPE_EFUSE_CONTENT_LEN_BANK:
1019 {
1020 u16 *pu2Tmp;
1021 pu2Tmp = (u16 *)pOut;
1022 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_88E;
1023 }
1024 break;
1025 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1026 {
1027 u16 *pu2Tmp;
1028 pu2Tmp = (u16 *)pOut;
1029 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E);
1030 }
1031 break;
1032 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1033 {
1034 u16 *pu2Tmp;
1035 pu2Tmp = (u16 *)pOut;
1036 *pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_88E - EFUSE_OOB_PROTECT_BYTES_88E);
1037 }
1038 break;
1039 case TYPE_EFUSE_MAP_LEN:
1040 {
1041 u16 *pu2Tmp;
1042 pu2Tmp = (u16 *)pOut;
1043 *pu2Tmp = (u16)EFUSE_MAP_LEN_88E;
1044 }
1045 break;
1046 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1047 {
1048 u8 *pu1Tmp;
1049 pu1Tmp = (u8 *)pOut;
1050 *pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES_88E);
1051 }
1052 break;
1053 default:
1054 {
1055 u8 *pu1Tmp;
1056 pu1Tmp = (u8 *)pOut;
1057 *pu1Tmp = 0;
1058 }
1059 break;
1060 }
1061}
1062
1063static void rtl8188e_EFUSE_GetEfuseDefinition(struct adapter *pAdapter, u8 efuseType, u8 type, void *pOut, bool bPseudoTest)
1064{
1065 if (bPseudoTest)
1066 Hal_EFUSEGetEfuseDefinition_Pseudo88E(pAdapter, efuseType, type, pOut);
1067 else
1068 Hal_EFUSEGetEfuseDefinition88E(pAdapter, efuseType, type, pOut);
1069}
1070
1071static u8 Hal_EfuseWordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1072{
1073 u16 tmpaddr = 0;
1074 u16 start_addr = efuse_addr;
1075 u8 badworden = 0x0F;
1076 u8 tmpdata[8];
1077
1078 memset((void *)tmpdata, 0xff, PGPKT_DATA_SIZE);
1079
1080 if (!(word_en & BIT(0))) {
1081 tmpaddr = start_addr;
1082 efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);
1083 efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);
1084
1085 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[0], bPseudoTest);
1086 efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[1], bPseudoTest);
1087 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
1088 badworden &= (~BIT(0));
1089 }
1090 if (!(word_en & BIT(1))) {
1091 tmpaddr = start_addr;
1092 efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);
1093 efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);
1094
1095 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[2], bPseudoTest);
1096 efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[3], bPseudoTest);
1097 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
1098 badworden &= (~BIT(1));
1099 }
1100 if (!(word_en & BIT(2))) {
1101 tmpaddr = start_addr;
1102 efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);
1103 efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);
1104
1105 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[4], bPseudoTest);
1106 efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[5], bPseudoTest);
1107 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
1108 badworden &= (~BIT(2));
1109 }
1110 if (!(word_en & BIT(3))) {
1111 tmpaddr = start_addr;
1112 efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);
1113 efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);
1114
1115 efuse_OneByteRead(pAdapter, tmpaddr, &tmpdata[6], bPseudoTest);
1116 efuse_OneByteRead(pAdapter, tmpaddr + 1, &tmpdata[7], bPseudoTest);
1117 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
1118 badworden &= (~BIT(3));
1119 }
1120 return badworden;
1121}
1122
1123static u8 Hal_EfuseWordEnableDataWrite_Pseudo(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1124{
1125 u8 ret;
1126
1127 ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1128 return ret;
1129}
1130
1131static u8 rtl8188e_Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_en, u8 *data, bool bPseudoTest)
1132{
1133 u8 ret = 0;
1134
1135 if (bPseudoTest)
1136 ret = Hal_EfuseWordEnableDataWrite_Pseudo(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1137 else
1138 ret = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
1139 return ret;
1140}
1141
1142static u16 hal_EfuseGetCurrentSize_8188e(struct adapter *pAdapter, bool bPseudoTest)
1143{
1144 int bContinual = true;
1145 u16 efuse_addr = 0;
1146 u8 hoffset = 0, hworden = 0;
1147 u8 efuse_data, word_cnts = 0;
1148
1149 if (bPseudoTest)
1150 efuse_addr = (u16)(fakeEfuseUsedBytes);
1151 else
1152 rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1153
1154 while (bContinual &&
1155 efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) &&
1156 AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1157 if (efuse_data != 0xFF) {
1158 if ((efuse_data & 0x1F) == 0x0F) {
1159 hoffset = efuse_data;
1160 efuse_addr++;
1161 efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
1162 if ((efuse_data & 0x0F) == 0x0F) {
1163 efuse_addr++;
1164 continue;
1165 } else {
1166 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1167 hworden = efuse_data & 0x0F;
1168 }
1169 } else {
1170 hoffset = (efuse_data >> 4) & 0x0F;
1171 hworden = efuse_data & 0x0F;
1172 }
1173 word_cnts = Efuse_CalculateWordCnts(hworden);
1174
1175 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1176 } else {
1177 bContinual = false;
1178 }
1179 }
1180
1181 if (bPseudoTest)
1182 fakeEfuseUsedBytes = efuse_addr;
1183 else
1184 rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1185
1186 return efuse_addr;
1187}
1188
1189static u16 Hal_EfuseGetCurrentSize_Pseudo(struct adapter *pAdapter, bool bPseudoTest)
1190{
1191 u16 ret = 0;
1192
1193 ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1194 return ret;
1195}
1196
1197static u16 rtl8188e_EfuseGetCurrentSize(struct adapter *pAdapter, u8 efuseType, bool bPseudoTest)
1198{
1199 u16 ret = 0;
1200
1201 if (bPseudoTest)
1202 ret = Hal_EfuseGetCurrentSize_Pseudo(pAdapter, bPseudoTest);
1203 else
1204 ret = hal_EfuseGetCurrentSize_8188e(pAdapter, bPseudoTest);
1205 return ret;
1206}
1207
1208static int hal_EfusePgPacketRead_8188e(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1209{
1210 u8 ReadState = PG_STATE_HEADER;
1211 int bContinual = true;
1212 int bDataEmpty = true;
1213 u8 efuse_data, word_cnts = 0;
1214 u16 efuse_addr = 0;
1215 u8 hoffset = 0, hworden = 0;
1216 u8 tmpidx = 0;
1217 u8 tmpdata[8];
1218 u8 max_section = 0;
1219 u8 tmp_header = 0;
1220
1221 EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, (void *)&max_section, bPseudoTest);
1222
1223 if (!data)
1224 return false;
1225 if (offset > max_section)
1226 return false;
1227
1228 memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
1229 memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);
1230
1231
1232
1233
1234 while (bContinual && AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1235
1236 if (ReadState & PG_STATE_HEADER) {
1237 if (efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1238 if (EXT_HEADER(efuse_data)) {
1239 tmp_header = efuse_data;
1240 efuse_addr++;
1241 efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);
1242 if (!ALL_WORDS_DISABLED(efuse_data)) {
1243 hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1244 hworden = efuse_data & 0x0F;
1245 } else {
1246 DBG_88E("Error, All words disabled\n");
1247 efuse_addr++;
1248 continue;
1249 }
1250 } else {
1251 hoffset = (efuse_data >> 4) & 0x0F;
1252 hworden = efuse_data & 0x0F;
1253 }
1254 word_cnts = Efuse_CalculateWordCnts(hworden);
1255 bDataEmpty = true;
1256
1257 if (hoffset == offset) {
1258 for (tmpidx = 0; tmpidx < word_cnts * 2; tmpidx++) {
1259 if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx, &efuse_data, bPseudoTest)) {
1260 tmpdata[tmpidx] = efuse_data;
1261 if (efuse_data != 0xff)
1262 bDataEmpty = false;
1263 }
1264 }
1265 if (!bDataEmpty) {
1266 ReadState = PG_STATE_DATA;
1267 } else {
1268 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1269 ReadState = PG_STATE_HEADER;
1270 }
1271 } else {
1272 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1273 ReadState = PG_STATE_HEADER;
1274 }
1275 } else {
1276 bContinual = false;
1277 }
1278 } else if (ReadState & PG_STATE_DATA) {
1279
1280 efuse_WordEnableDataRead(hworden, tmpdata, data);
1281 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
1282 ReadState = PG_STATE_HEADER;
1283 }
1284
1285 }
1286
1287 if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff) && (data[3] == 0xff) &&
1288 (data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff) && (data[7] == 0xff))
1289 return false;
1290 else
1291 return true;
1292}
1293
1294static int Hal_EfusePgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1295{
1296 int ret;
1297
1298 ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1299 return ret;
1300}
1301
1302static int Hal_EfusePgPacketRead_Pseudo(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1303{
1304 int ret;
1305
1306 ret = hal_EfusePgPacketRead_8188e(pAdapter, offset, data, bPseudoTest);
1307 return ret;
1308}
1309
1310static int rtl8188e_Efuse_PgPacketRead(struct adapter *pAdapter, u8 offset, u8 *data, bool bPseudoTest)
1311{
1312 int ret;
1313
1314 if (bPseudoTest)
1315 ret = Hal_EfusePgPacketRead_Pseudo(pAdapter, offset, data, bPseudoTest);
1316 else
1317 ret = Hal_EfusePgPacketRead(pAdapter, offset, data, bPseudoTest);
1318 return ret;
1319}
1320
1321static bool hal_EfuseFixHeaderProcess(struct adapter *pAdapter, u8 efuseType, struct pgpkt *pFixPkt, u16 *pAddr, bool bPseudoTest)
1322{
1323 u8 originaldata[8], badworden = 0;
1324 u16 efuse_addr = *pAddr;
1325 u32 PgWriteSuccess = 0;
1326
1327 memset((void *)originaldata, 0xff, 8);
1328
1329 if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
1330
1331 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest);
1332
1333 if (badworden != 0xf) {
1334 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
1335
1336 if (!PgWriteSuccess)
1337 return false;
1338 else
1339 efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
1340 } else {
1341 efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
1342 }
1343 } else {
1344 efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;
1345 }
1346 *pAddr = efuse_addr;
1347 return true;
1348}
1349
1350static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1351{
1352 bool bRet = false;
1353 u16 efuse_addr = *pAddr, efuse_max_available_len = 0;
1354 u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
1355 u8 repeatcnt = 0;
1356
1357 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
1358
1359 while (efuse_addr < efuse_max_available_len) {
1360 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1361 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1362 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1363
1364 while (tmp_header == 0xFF) {
1365 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1366 return false;
1367
1368 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1369 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1370 }
1371
1372
1373 if (tmp_header == pg_header) {
1374 efuse_addr++;
1375 pg_header_temp = pg_header;
1376 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1377
1378 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1379 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1380
1381 while (tmp_header == 0xFF) {
1382 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1383 return false;
1384
1385 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1386 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1387 }
1388
1389 if ((tmp_header & 0x0F) == 0x0F) {
1390 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
1391 return false;
1392 } else {
1393 efuse_addr++;
1394 continue;
1395 }
1396 } else if (pg_header != tmp_header) {
1397 struct pgpkt fixPkt;
1398 fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
1399 fixPkt.word_en = tmp_header & 0x0F;
1400 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
1401 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
1402 return false;
1403 } else {
1404 bRet = true;
1405 break;
1406 }
1407 } else if ((tmp_header & 0x1F) == 0x0F) {
1408 efuse_addr += 2;
1409 continue;
1410 }
1411 }
1412
1413 *pAddr = efuse_addr;
1414 return bRet;
1415}
1416
1417static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1418{
1419 bool bRet = false;
1420 u8 pg_header = 0, tmp_header = 0;
1421 u16 efuse_addr = *pAddr;
1422 u8 repeatcnt = 0;
1423
1424 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1425
1426 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1427 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1428
1429 while (tmp_header == 0xFF) {
1430 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1431 return false;
1432 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1433 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1434 }
1435
1436 if (pg_header == tmp_header) {
1437 bRet = true;
1438 } else {
1439 struct pgpkt fixPkt;
1440 fixPkt.offset = (tmp_header >> 4) & 0x0F;
1441 fixPkt.word_en = tmp_header & 0x0F;
1442 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
1443 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
1444 return false;
1445 }
1446
1447 *pAddr = efuse_addr;
1448 return bRet;
1449}
1450
1451static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1452{
1453 u16 efuse_addr = *pAddr;
1454 u8 badworden = 0;
1455 u32 PgWriteSuccess = 0;
1456
1457 badworden = 0x0f;
1458 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
1459 if (badworden == 0x0F) {
1460
1461 return true;
1462 } else {
1463
1464 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1465 if (!PgWriteSuccess)
1466 return false;
1467 else
1468 return true;
1469 }
1470}
1471
1472static bool
1473hal_EfusePgPacketWriteHeader(
1474 struct adapter *pAdapter,
1475 u8 efuseType,
1476 u16 *pAddr,
1477 struct pgpkt *pTargetPkt,
1478 bool bPseudoTest)
1479{
1480 bool bRet = false;
1481
1482 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
1483 bRet = hal_EfusePgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1484 else
1485 bRet = hal_EfusePgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1486
1487 return bRet;
1488}
1489
1490static bool wordEnMatched(struct pgpkt *pTargetPkt, struct pgpkt *pCurPkt,
1491 u8 *pWden)
1492{
1493 u8 match_word_en = 0x0F;
1494
1495
1496 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
1497 ((pCurPkt->word_en & BIT(0)) == 0))
1498 match_word_en &= ~BIT(0);
1499 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
1500 ((pCurPkt->word_en & BIT(1)) == 0))
1501 match_word_en &= ~BIT(1);
1502 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
1503 ((pCurPkt->word_en & BIT(2)) == 0))
1504 match_word_en &= ~BIT(2);
1505 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
1506 ((pCurPkt->word_en & BIT(3)) == 0))
1507 match_word_en &= ~BIT(3);
1508
1509 *pWden = match_word_en;
1510
1511 if (match_word_en != 0xf)
1512 return true;
1513 else
1514 return false;
1515}
1516
1517static bool hal_EfuseCheckIfDatafollowed(struct adapter *pAdapter, u8 word_cnts, u16 startAddr, bool bPseudoTest)
1518{
1519 bool bRet = false;
1520 u8 i, efuse_data;
1521
1522 for (i = 0; i < (word_cnts * 2); i++) {
1523 if (efuse_OneByteRead(pAdapter, (startAddr + i), &efuse_data, bPseudoTest) && (efuse_data != 0xFF))
1524 bRet = true;
1525 }
1526 return bRet;
1527}
1528
1529static bool hal_EfusePartialWriteCheck(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
1530{
1531 bool bRet = false;
1532 u8 i, efuse_data = 0, cur_header = 0;
1533 u8 matched_wden = 0, badworden = 0;
1534 u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
1535 struct pgpkt curPkt;
1536
1537 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, (void *)&efuse_max_available_len, bPseudoTest);
1538 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&efuse_max, bPseudoTest);
1539
1540 if (efuseType == EFUSE_WIFI) {
1541 if (bPseudoTest) {
1542 startAddr = (u16)(fakeEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
1543 } else {
1544 rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
1545 startAddr %= EFUSE_REAL_CONTENT_LEN;
1546 }
1547 } else {
1548 if (bPseudoTest)
1549 startAddr = (u16)(fakeBTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
1550 else
1551 startAddr = (u16)(BTEfuseUsedBytes % EFUSE_REAL_CONTENT_LEN);
1552 }
1553
1554 while (1) {
1555 if (startAddr >= efuse_max_available_len) {
1556 bRet = false;
1557 break;
1558 }
1559
1560 if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
1561 if (EXT_HEADER(efuse_data)) {
1562 cur_header = efuse_data;
1563 startAddr++;
1564 efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);
1565 if (ALL_WORDS_DISABLED(efuse_data)) {
1566 bRet = false;
1567 break;
1568 } else {
1569 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1570 curPkt.word_en = efuse_data & 0x0F;
1571 }
1572 } else {
1573 cur_header = efuse_data;
1574 curPkt.offset = (cur_header >> 4) & 0x0F;
1575 curPkt.word_en = cur_header & 0x0F;
1576 }
1577
1578 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
1579
1580
1581 if ((curPkt.offset == pTargetPkt->offset) &&
1582 (!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) &&
1583 wordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {
1584
1585 badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);
1586 if (badworden != 0x0F) {
1587 u32 PgWriteSuccess = 0;
1588
1589
1590 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1591
1592 if (!PgWriteSuccess) {
1593 bRet = false;
1594 break;
1595 }
1596 }
1597
1598 for (i = 0; i < 4; i++) {
1599 if ((matched_wden & (0x1 << i)) == 0)
1600 pTargetPkt->word_en |= (0x1 << i);
1601 }
1602 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1603 }
1604
1605 startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
1606 } else {
1607
1608 *pAddr = startAddr;
1609 bRet = true;
1610 break;
1611 }
1612 }
1613 return bRet;
1614}
1615
1616static bool
1617hal_EfusePgCheckAvailableAddr(
1618 struct adapter *pAdapter,
1619 u8 efuseType,
1620 bool bPseudoTest
1621 )
1622{
1623 u16 efuse_max_available_len = 0;
1624
1625
1626 EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
1627
1628 if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
1629 return false;
1630 return true;
1631}
1632
1633static void hal_EfuseConstructPGPkt(u8 offset, u8 word_en, u8 *pData, struct pgpkt *pTargetPkt)
1634{
1635 memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8);
1636 pTargetPkt->offset = offset;
1637 pTargetPkt->word_en = word_en;
1638 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1639 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1640}
1641
1642static bool hal_EfusePgPacketWrite_8188e(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pData, bool bPseudoTest)
1643{
1644 struct pgpkt targetPkt;
1645 u16 startAddr = 0;
1646 u8 efuseType = EFUSE_WIFI;
1647
1648 if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
1649 return false;
1650
1651 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1652
1653 if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1654 return false;
1655
1656 if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1657 return false;
1658
1659 if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1660 return false;
1661
1662 return true;
1663}
1664
1665static int Hal_EfusePgPacketWrite_Pseudo(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1666{
1667 int ret;
1668
1669 ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
1670 return ret;
1671}
1672
1673static int Hal_EfusePgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1674{
1675 int ret = 0;
1676 ret = hal_EfusePgPacketWrite_8188e(pAdapter, offset, word_en, data, bPseudoTest);
1677
1678 return ret;
1679}
1680
1681static int rtl8188e_Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *data, bool bPseudoTest)
1682{
1683 int ret;
1684
1685 if (bPseudoTest)
1686 ret = Hal_EfusePgPacketWrite_Pseudo(pAdapter, offset, word_en, data, bPseudoTest);
1687 else
1688 ret = Hal_EfusePgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
1689 return ret;
1690}
1691
1692static struct HAL_VERSION ReadChipVersion8188E(struct adapter *padapter)
1693{
1694 u32 value32;
1695 struct HAL_VERSION ChipVersion;
1696 struct hal_data_8188e *pHalData;
1697
1698 pHalData = GET_HAL_DATA(padapter);
1699
1700 value32 = rtw_read32(padapter, REG_SYS_CFG);
1701 ChipVersion.ICType = CHIP_8188E;
1702 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
1703
1704 ChipVersion.RFType = RF_TYPE_1T1R;
1705 ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
1706 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT;
1707
1708
1709 pHalData->RegulatorMode = ((value32 & TRP_BT_EN) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
1710
1711 ChipVersion.ROMVer = 0;
1712 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
1713
1714 dump_chip_info(ChipVersion);
1715
1716 pHalData->VersionID = ChipVersion;
1717
1718 if (IS_1T2R(ChipVersion)) {
1719 pHalData->rf_type = RF_1T2R;
1720 pHalData->NumTotalRFPath = 2;
1721 } else if (IS_2T2R(ChipVersion)) {
1722 pHalData->rf_type = RF_2T2R;
1723 pHalData->NumTotalRFPath = 2;
1724 } else {
1725 pHalData->rf_type = RF_1T1R;
1726 pHalData->NumTotalRFPath = 1;
1727 }
1728
1729 MSG_88E("RF_Type is %x!!\n", pHalData->rf_type);
1730
1731 return ChipVersion;
1732}
1733
1734static void rtl8188e_read_chip_version(struct adapter *padapter)
1735{
1736 ReadChipVersion8188E(padapter);
1737}
1738
1739static void rtl8188e_GetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
1740{
1741}
1742
1743static void rtl8188e_SetHalODMVar(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
1744{
1745 struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
1746 struct odm_dm_struct *podmpriv = &pHalData->odmpriv;
1747 switch (eVariable) {
1748 case HAL_ODM_STA_INFO:
1749 {
1750 struct sta_info *psta = (struct sta_info *)pValue1;
1751 if (bSet) {
1752 DBG_88E("### Set STA_(%d) info\n", psta->mac_id);
1753 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
1754 ODM_RAInfo_Init(podmpriv, psta->mac_id);
1755 } else {
1756 DBG_88E("### Clean STA_(%d) info\n", psta->mac_id);
1757 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
1758 }
1759 }
1760 break;
1761 case HAL_ODM_P2P_STATE:
1762 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DIRECT, bSet);
1763 break;
1764 case HAL_ODM_WIFI_DISPLAY_STATE:
1765 ODM_CmnInfoUpdate(podmpriv, ODM_CMNINFO_WIFI_DISPLAY, bSet);
1766 break;
1767 default:
1768 break;
1769 }
1770}
1771
1772void rtl8188e_clone_haldata(struct adapter *dst_adapter, struct adapter *src_adapter)
1773{
1774 memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
1775}
1776
1777void rtl8188e_start_thread(struct adapter *padapter)
1778{
1779}
1780
1781void rtl8188e_stop_thread(struct adapter *padapter)
1782{
1783}
1784
1785static void hal_notch_filter_8188e(struct adapter *adapter, bool enable)
1786{
1787 if (enable) {
1788 DBG_88E("Enable notch filter\n");
1789 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT(1));
1790 } else {
1791 DBG_88E("Disable notch filter\n");
1792 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT(1));
1793 }
1794}
1795void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
1796{
1797 pHalFunc->free_hal_data = &rtl8188e_free_hal_data;
1798
1799 pHalFunc->dm_init = &rtl8188e_init_dm_priv;
1800 pHalFunc->dm_deinit = &rtl8188e_deinit_dm_priv;
1801
1802 pHalFunc->read_chip_version = &rtl8188e_read_chip_version;
1803
1804 pHalFunc->set_bwmode_handler = &PHY_SetBWMode8188E;
1805 pHalFunc->set_channel_handler = &PHY_SwChnl8188E;
1806
1807 pHalFunc->hal_dm_watchdog = &rtl8188e_HalDmWatchDog;
1808
1809 pHalFunc->Add_RateATid = &rtl8188e_Add_RateATid;
1810 pHalFunc->run_thread = &rtl8188e_start_thread;
1811 pHalFunc->cancel_thread = &rtl8188e_stop_thread;
1812
1813 pHalFunc->AntDivBeforeLinkHandler = &AntDivBeforeLink8188E;
1814 pHalFunc->AntDivCompareHandler = &AntDivCompare8188E;
1815 pHalFunc->read_bbreg = &rtl8188e_PHY_QueryBBReg;
1816 pHalFunc->write_bbreg = &rtl8188e_PHY_SetBBReg;
1817 pHalFunc->read_rfreg = &rtl8188e_PHY_QueryRFReg;
1818 pHalFunc->write_rfreg = &rtl8188e_PHY_SetRFReg;
1819
1820
1821 pHalFunc->EfusePowerSwitch = &rtl8188e_EfusePowerSwitch;
1822 pHalFunc->ReadEFuse = &rtl8188e_ReadEFuse;
1823 pHalFunc->EFUSEGetEfuseDefinition = &rtl8188e_EFUSE_GetEfuseDefinition;
1824 pHalFunc->EfuseGetCurrentSize = &rtl8188e_EfuseGetCurrentSize;
1825 pHalFunc->Efuse_PgPacketRead = &rtl8188e_Efuse_PgPacketRead;
1826 pHalFunc->Efuse_PgPacketWrite = &rtl8188e_Efuse_PgPacketWrite;
1827 pHalFunc->Efuse_WordEnableDataWrite = &rtl8188e_Efuse_WordEnableDataWrite;
1828
1829 pHalFunc->sreset_init_value = &sreset_init_value;
1830 pHalFunc->sreset_reset_value = &sreset_reset_value;
1831 pHalFunc->silentreset = &rtl8188e_silentreset_for_specific_platform;
1832 pHalFunc->sreset_xmit_status_check = &rtl8188e_sreset_xmit_status_check;
1833 pHalFunc->sreset_linked_status_check = &rtl8188e_sreset_linked_status_check;
1834 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
1835
1836 pHalFunc->GetHalODMVarHandler = &rtl8188e_GetHalODMVar;
1837 pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar;
1838
1839 pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync;
1840
1841 pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
1842}
1843
1844u8 GetEEPROMSize8188E(struct adapter *padapter)
1845{
1846 u8 size = 0;
1847 u32 cr;
1848
1849 cr = rtw_read16(padapter, REG_9346CR);
1850
1851 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
1852
1853 MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
1854
1855 return size;
1856}
1857
1858
1859
1860
1861
1862
1863static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
1864{
1865 s32 status = _SUCCESS;
1866 s32 count = 0;
1867 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
1868 u16 LLTReg = REG_LLT_INIT;
1869
1870 rtw_write32(padapter, LLTReg, value);
1871
1872
1873 do {
1874 value = rtw_read32(padapter, LLTReg);
1875 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
1876 break;
1877
1878 if (count > POLLING_LLT_THRESHOLD) {
1879 status = _FAIL;
1880 break;
1881 }
1882 } while (count++);
1883
1884 return status;
1885}
1886
1887s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
1888{
1889 s32 status = _FAIL;
1890 u32 i;
1891 u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
1892
1893 if (rtw_IOL_applied(padapter)) {
1894 status = iol_InitLLTTable(padapter, txpktbuf_bndy);
1895 } else {
1896 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
1897 status = _LLTWrite(padapter, i, i + 1);
1898 if (_SUCCESS != status)
1899 return status;
1900 }
1901
1902
1903 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
1904 if (_SUCCESS != status)
1905 return status;
1906
1907
1908
1909
1910 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
1911 status = _LLTWrite(padapter, i, (i + 1));
1912 if (_SUCCESS != status)
1913 return status;
1914 }
1915
1916
1917 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
1918 if (_SUCCESS != status) {
1919 return status;
1920 }
1921 }
1922
1923 return status;
1924}
1925
1926void
1927Hal_InitPGData88E(struct adapter *padapter)
1928{
1929 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1930
1931 if (!pEEPROM->bautoload_fail_flag) {
1932 if (!is_boot_from_eeprom(padapter)) {
1933
1934 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
1935 }
1936 } else {
1937
1938 if (!is_boot_from_eeprom(padapter))
1939 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, false);
1940 }
1941}
1942
1943void
1944Hal_EfuseParseIDCode88E(
1945 struct adapter *padapter,
1946 u8 *hwinfo
1947 )
1948{
1949 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1950 u16 EEPROMId;
1951
1952
1953 EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
1954 if (EEPROMId != RTL_EEPROM_ID) {
1955 pr_err("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
1956 pEEPROM->bautoload_fail_flag = true;
1957 } else {
1958 pEEPROM->bautoload_fail_flag = false;
1959 }
1960
1961 pr_info("EEPROM ID = 0x%04x\n", EEPROMId);
1962}
1963
1964static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
1965{
1966 u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
1967
1968 memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
1969
1970 if (AutoLoadFail) {
1971 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
1972
1973 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1974 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1975 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1976 }
1977 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
1978 if (TxCount == 0) {
1979 pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
1980 pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
1981 } else {
1982 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1983 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1984 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1985 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
1986 }
1987 }
1988 }
1989 return;
1990 }
1991
1992 for (rfPath = 0; rfPath < RF_PATH_MAX; rfPath++) {
1993
1994 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1995 pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++];
1996 if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
1997 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
1998 }
1999 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
2000 pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++];
2001 if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
2002 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
2003 }
2004 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2005 if (TxCount == 0) {
2006 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
2007 if (PROMContent[eeAddr] == 0xFF) {
2008 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
2009 } else {
2010 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
2011 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))
2012 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2013 }
2014
2015 if (PROMContent[eeAddr] == 0xFF) {
2016 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF;
2017 } else {
2018 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
2019 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))
2020 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2021 }
2022 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
2023 eeAddr++;
2024 } else {
2025 if (PROMContent[eeAddr] == 0xFF) {
2026 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2027 } else {
2028 pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
2029 if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3))
2030 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
2031 }
2032
2033 if (PROMContent[eeAddr] == 0xFF) {
2034 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2035 } else {
2036 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
2037 if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))
2038 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
2039 }
2040 eeAddr++;
2041
2042 if (PROMContent[eeAddr] == 0xFF) {
2043 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2044 } else {
2045 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0xf0) >> 4;
2046 if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))
2047 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
2048 }
2049
2050 if (PROMContent[eeAddr] == 0xFF) {
2051 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
2052 } else {
2053 pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr] & 0x0f);
2054 if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3))
2055 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
2056 }
2057 eeAddr++;
2058 }
2059 }
2060 }
2061}
2062
2063static void hal_get_chnl_group_88e(u8 chnl, u8 *group)
2064{
2065 if (chnl < 3)
2066 *group = 0;
2067 else if (chnl < 6)
2068 *group = 1;
2069 else if (chnl < 9)
2070 *group = 2;
2071 else if (chnl < 12)
2072 *group = 3;
2073 else if (chnl < 14)
2074 *group = 4;
2075 else if (chnl == 14)
2076 *group = 5;
2077}
2078
2079void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2080{
2081 if (AutoLoadFail) {
2082 padapter->pwrctrlpriv.bHWPowerdown = false;
2083 padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
2084 } else {
2085
2086
2087 if (padapter->registrypriv.hwpdn_mode == 2)
2088 padapter->pwrctrlpriv.bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT(4));
2089 else
2090 padapter->pwrctrlpriv.bHWPowerdown = padapter->registrypriv.hwpdn_mode;
2091
2092
2093
2094 padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false;
2095
2096 DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__,
2097 padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup);
2098
2099 DBG_88E("### PS params => power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable);
2100 }
2101}
2102
2103void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
2104{
2105 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
2106 struct txpowerinfo24g pwrInfo24G;
2107 u8 rfPath, ch, group;
2108 u8 TxCount;
2109
2110 Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
2111
2112 if (!AutoLoadFail)
2113 pHalData->bTXPowerDataReadFromEEPORM = true;
2114
2115 for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) {
2116 for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
2117 hal_get_chnl_group_88e(ch, &group);
2118
2119 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
2120 if (ch == 14)
2121 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][4];
2122 else
2123 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
2124
2125 DBG_88E("======= Path %d, Channel %d =======\n", rfPath, ch);
2126 DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_CCK_Base[rfPath][ch]);
2127 DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", rfPath, ch, pHalData->Index24G_BW40_Base[rfPath][ch]);
2128 }
2129 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
2130 pHalData->CCK_24G_Diff[rfPath][TxCount] = pwrInfo24G.CCK_Diff[rfPath][TxCount];
2131 pHalData->OFDM_24G_Diff[rfPath][TxCount] = pwrInfo24G.OFDM_Diff[rfPath][TxCount];
2132 pHalData->BW20_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW20_Diff[rfPath][TxCount];
2133 pHalData->BW40_24G_Diff[rfPath][TxCount] = pwrInfo24G.BW40_Diff[rfPath][TxCount];
2134 DBG_88E("======= TxCount %d =======\n", TxCount);
2135 DBG_88E("CCK_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->CCK_24G_Diff[rfPath][TxCount]);
2136 DBG_88E("OFDM_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->OFDM_24G_Diff[rfPath][TxCount]);
2137 DBG_88E("BW20_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW20_24G_Diff[rfPath][TxCount]);
2138 DBG_88E("BW40_24G_Diff[%d][%d] = %d\n", rfPath, TxCount, pHalData->BW40_24G_Diff[rfPath][TxCount]);
2139 }
2140 }
2141
2142
2143 if (!AutoLoadFail) {
2144 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x7);
2145 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2146 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7);
2147 } else {
2148 pHalData->EEPROMRegulatory = 0;
2149 }
2150 DBG_88E("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
2151}
2152
2153void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
2154{
2155 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
2156
2157 if (!AutoLoadFail) {
2158 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
2159 if (pHalData->CrystalCap == 0xFF)
2160 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
2161 } else {
2162 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
2163 }
2164 DBG_88E("CrystalCap: 0x%2x\n", pHalData->CrystalCap);
2165}
2166
2167void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
2168{
2169 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
2170
2171 if (!AutoLoadFail)
2172 pHalData->BoardType = ((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5);
2173 else
2174 pHalData->BoardType = 0;
2175 DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType);
2176}
2177
2178void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2179{
2180 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
2181
2182 if (!AutoLoadFail) {
2183 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
2184 if (pHalData->EEPROMVersion == 0xFF)
2185 pHalData->EEPROMVersion = EEPROM_Default_Version;
2186 } else {
2187 pHalData->EEPROMVersion = 1;
2188 }
2189}
2190
2191void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2192{
2193 padapter->mlmepriv.ChannelPlan =
2194 hal_com_get_channel_plan(padapter,
2195 hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
2196 padapter->registrypriv.channel_plan,
2197 RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
2198
2199 DBG_88E("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan);
2200}
2201
2202void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
2203{
2204 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
2205
2206 if (!AutoLoadFail) {
2207 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E];
2208 } else {
2209 pHalData->EEPROMCustomerID = 0;
2210 pHalData->EEPROMSubCustomerID = 0;
2211 }
2212 DBG_88E("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
2213}
2214
2215void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
2216{
2217 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
2218 struct registry_priv *registry_par = &pAdapter->registrypriv;
2219
2220 if (!AutoLoadFail) {
2221
2222 if (registry_par->antdiv_cfg == 2) {
2223 pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
2224 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2225 pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION & 0x18) >> 3;
2226 } else {
2227 pHalData->AntDivCfg = registry_par->antdiv_cfg;
2228 }
2229
2230 if (registry_par->antdiv_type == 0) {
2231
2232 pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
2233 if (pHalData->TRxAntDivType == 0xFF)
2234 pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV;
2235 } else {
2236 pHalData->TRxAntDivType = registry_par->antdiv_type;
2237 }
2238
2239 if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
2240 pHalData->AntDivCfg = 1;
2241 } else {
2242 pHalData->AntDivCfg = 0;
2243 pHalData->TRxAntDivType = pHalData->TRxAntDivType;
2244 }
2245 DBG_88E("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType);
2246}
2247
2248void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
2249{
2250 struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
2251
2252
2253 if (!AutoloadFail)
2254 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
2255 else
2256 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
2257
2258 if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail) {
2259 pHalData->bAPKThermalMeterIgnore = true;
2260 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
2261 }
2262 DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter);
2263}
2264
2265void Hal_InitChannelPlan(struct adapter *padapter)
2266{
2267}
2268
2269bool HalDetectPwrDownMode88E(struct adapter *Adapter)
2270{
2271 u8 tmpvalue = 0;
2272 struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter);
2273 struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
2274
2275 EFUSE_ShadowRead(Adapter, 1, EEPROM_RF_FEATURE_OPTION_88E, (u32 *)&tmpvalue);
2276
2277
2278 if (tmpvalue & BIT(4) && pwrctrlpriv->reg_pdnmode)
2279 pHalData->pwrdown = true;
2280 else
2281 pHalData->pwrdown = false;
2282
2283 DBG_88E("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown);
2284
2285 return pHalData->pwrdown;
2286}
2287
2288
2289
2290
2291
2292
2293
2294void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits)
2295{
2296 struct hal_data_8188e *pHalData;
2297
2298 pHalData = GET_HAL_DATA(padapter);
2299
2300 pHalData->RegBcnCtrlVal |= SetBits;
2301 pHalData->RegBcnCtrlVal &= ~ClearBits;
2302
2303 rtw_write8(padapter, REG_BCN_CTRL, (u8)pHalData->RegBcnCtrlVal);
2304}
2305