GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / staging / rtl8188eu / hal / rtl8188e_hal_init.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _HAL_INIT_C_
8
9 #include <linux/firmware.h>
10 #include <linux/vmalloc.h>
11 #include <drv_types.h>
12 #include <rtw_efuse.h>
13 #include <phy.h>
14 #include <rtl8188e_hal.h>
15
16 #include <rtw_iol.h>
17
18 void iol_mode_enable(struct adapter *padapter, u8 enable)
19 {
20         u8 reg_0xf0 = 0;
21
22         if (enable) {
23                 /* Enable initial offload */
24                 reg_0xf0 = usb_read8(padapter, REG_SYS_CFG);
25                 usb_write8(padapter, REG_SYS_CFG, reg_0xf0|SW_OFFLOAD_EN);
26
27                 if (!padapter->bFWReady) {
28                         DBG_88E("bFWReady == false call reset 8051...\n");
29                         _8051Reset88E(padapter);
30                 }
31
32         } else {
33                 /* disable initial offload */
34                 reg_0xf0 = usb_read8(padapter, REG_SYS_CFG);
35                 usb_write8(padapter, REG_SYS_CFG, reg_0xf0 & ~SW_OFFLOAD_EN);
36         }
37 }
38
39 s32 iol_execute(struct adapter *padapter, u8 control)
40 {
41         s32 status = _FAIL;
42         u8 reg_0x88 = 0;
43         unsigned long start = 0;
44
45         control = control&0x0f;
46         reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0);
47         usb_write8(padapter, REG_HMEBOX_E0,  reg_0x88|control);
48
49         start = jiffies;
50         while ((reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0)) & control &&
51                jiffies_to_msecs(jiffies - start) < 1000) {
52                 udelay(5);
53         }
54
55         reg_0x88 = usb_read8(padapter, REG_HMEBOX_E0);
56         status = (reg_0x88 & control) ? _FAIL : _SUCCESS;
57         if (reg_0x88 & control<<4)
58                 status = _FAIL;
59         return status;
60 }
61
62 static s32 iol_InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
63 {
64         s32 rst = _SUCCESS;
65
66         iol_mode_enable(padapter, 1);
67         usb_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
68         rst = iol_execute(padapter, CMD_INIT_LLT);
69         iol_mode_enable(padapter, 0);
70         return rst;
71 }
72
73 s32 rtl8188e_iol_efuse_patch(struct adapter *padapter)
74 {
75         s32     result = _SUCCESS;
76
77         DBG_88E("==> %s\n", __func__);
78         if (rtw_iol_applied(padapter)) {
79                 iol_mode_enable(padapter, 1);
80                 result = iol_execute(padapter, CMD_READ_EFUSE_MAP);
81                 if (result == _SUCCESS)
82                         result = iol_execute(padapter, CMD_EFUSE_PATCH);
83
84                 iol_mode_enable(padapter, 0);
85         }
86         return result;
87 }
88
89 #define MAX_REG_BOLCK_SIZE      196
90
91 void _8051Reset88E(struct adapter *padapter)
92 {
93         u8 u1bTmp;
94
95         u1bTmp = usb_read8(padapter, REG_SYS_FUNC_EN+1);
96         usb_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT(2)));
97         usb_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp|(BIT(2)));
98         DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n");
99 }
100
101 void rtl8188e_InitializeFirmwareVars(struct adapter *padapter)
102 {
103         /*  Init Fw LPS related. */
104         padapter->pwrctrlpriv.bFwCurrentInPSMode = false;
105
106         /*  Init H2C counter. by tynli. 2009.12.09. */
107         padapter->HalData->LastHMEBoxNum = 0;
108 }
109
110 void rtw_hal_free_data(struct adapter *padapter)
111 {
112         kfree(padapter->HalData);
113         padapter->HalData = NULL;
114 }
115
116 void rtw_hal_read_chip_version(struct adapter *padapter)
117 {
118         u32                             value32;
119         struct HAL_VERSION              ChipVersion;
120         struct hal_data_8188e *pHalData = padapter->HalData;
121
122         value32 = usb_read32(padapter, REG_SYS_CFG);
123         ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
124         ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
125         ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; /*  IC version (CUT) */
126
127         dump_chip_info(ChipVersion);
128
129         pHalData->VersionID = ChipVersion;
130 }
131
132 void rtw_hal_set_odm_var(struct adapter *Adapter, enum hal_odm_variable eVariable, void *pValue1, bool bSet)
133 {
134         struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv;
135
136         switch (eVariable) {
137         case HAL_ODM_STA_INFO:
138                 {
139                         struct sta_info *psta = pValue1;
140
141                         if (bSet) {
142                                 DBG_88E("### Set STA_(%d) info\n", psta->mac_id);
143                                 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, psta);
144                                 ODM_RAInfo_Init(podmpriv, psta->mac_id);
145                         } else {
146                                 DBG_88E("### Clean STA_(%d) info\n", psta->mac_id);
147                                 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS, psta->mac_id, NULL);
148                        }
149                 }
150                 break;
151         case HAL_ODM_P2P_STATE:
152                 podmpriv->bWIFI_Direct = bSet;
153                 break;
154         case HAL_ODM_WIFI_DISPLAY_STATE:
155                 podmpriv->bWIFI_Display = bSet;
156                 break;
157         default:
158                 break;
159         }
160 }
161
162 void rtw_hal_notch_filter(struct adapter *adapter, bool enable)
163 {
164         if (enable) {
165                 DBG_88E("Enable notch filter\n");
166                 usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) | BIT(1));
167         } else {
168                 DBG_88E("Disable notch filter\n");
169                 usb_write8(adapter, rOFDM0_RxDSP+1, usb_read8(adapter, rOFDM0_RxDSP+1) & ~BIT(1));
170         }
171 }
172
173 /*  */
174 /*  */
175 /*  LLT R/W/Init function */
176 /*  */
177 /*  */
178 static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data)
179 {
180         s32     status = _SUCCESS;
181         s32     count = 0;
182         u32     value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
183         u16     LLTReg = REG_LLT_INIT;
184
185         usb_write32(padapter, LLTReg, value);
186
187         /* polling */
188         do {
189                 value = usb_read32(padapter, LLTReg);
190                 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
191                         break;
192
193                 if (count > POLLING_LLT_THRESHOLD) {
194                         RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling write LLT done at address %d!\n", address));
195                         status = _FAIL;
196                         break;
197                 }
198                 udelay(5);
199         } while (count++);
200
201         return status;
202 }
203
204 s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy)
205 {
206         s32     status = _FAIL;
207         u32     i;
208         u32     Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;/*  176, 22k */
209
210         if (rtw_iol_applied(padapter)) {
211                 status = iol_InitLLTTable(padapter, txpktbuf_bndy);
212         } else {
213                 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
214                         status = _LLTWrite(padapter, i, i + 1);
215                         if (status != _SUCCESS)
216                                 return status;
217                 }
218
219                 /*  end of list */
220                 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
221                 if (status != _SUCCESS)
222                         return status;
223
224                 /*  Make the other pages as ring buffer */
225                 /*  This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer. */
226                 /*  Otherwise used as local loopback buffer. */
227                 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
228                         status = _LLTWrite(padapter, i, (i + 1));
229                         if (status != _SUCCESS)
230                                 return status;
231                 }
232
233                 /*  Let last entry point to the start entry of ring buffer */
234                 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
235                 if (status != _SUCCESS) {
236                         return status;
237                 }
238         }
239
240         return status;
241 }
242
243 void
244 Hal_InitPGData88E(struct adapter *padapter)
245 {
246         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
247
248         if (!pEEPROM->bautoload_fail_flag) { /*  autoload OK. */
249                 if (!is_boot_from_eeprom(padapter)) {
250                         /*  Read EFUSE real map to shadow. */
251                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
252                 }
253         } else {/* autoload fail */
254                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
255                 /* update to default value 0xFF */
256                 if (!is_boot_from_eeprom(padapter))
257                         EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI);
258         }
259 }
260
261 void
262 Hal_EfuseParseIDCode88E(
263                 struct adapter *padapter,
264                 u8 *hwinfo
265         )
266 {
267         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
268         u16                     EEPROMId;
269
270         /*  Checl 0x8129 again for making sure autoload status!! */
271         EEPROMId = le16_to_cpu(*((__le16 *)hwinfo));
272         if (EEPROMId != RTL_EEPROM_ID) {
273                 DBG_88E("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
274                 pEEPROM->bautoload_fail_flag = true;
275         } else {
276                 pEEPROM->bautoload_fail_flag = false;
277         }
278
279         DBG_88E("EEPROM ID = 0x%04x\n", EEPROMId);
280 }
281
282 static void Hal_ReadPowerValueFromPROM_8188E(struct txpowerinfo24g *pwrInfo24G, u8 *PROMContent, bool AutoLoadFail)
283 {
284         u32 rfPath, eeAddr = EEPROM_TX_PWR_INX_88E, group, TxCount = 0;
285
286         memset(pwrInfo24G, 0, sizeof(struct txpowerinfo24g));
287
288         if (AutoLoadFail) {
289                 for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
290                         /* 2.4G default value */
291                         for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
292                                 pwrInfo24G->IndexCCK_Base[rfPath][group] =      EEPROM_DEFAULT_24G_INDEX;
293                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
294                         }
295                         for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
296                                 if (TxCount == 0) {
297                                         pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
298                                         pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
299                                 } else {
300                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
301                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
302                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
303                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
304                                 }
305                         }
306                 }
307                 return;
308         }
309
310         for (rfPath = 0; rfPath < MAX_RF_PATH; rfPath++) {
311                 /* 2.4G default value */
312                 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
313                         pwrInfo24G->IndexCCK_Base[rfPath][group] =      PROMContent[eeAddr++];
314                         if (pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
315                                 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
316                 }
317                 for (group = 0; group < MAX_CHNL_GROUP_24G-1; group++) {
318                         pwrInfo24G->IndexBW40_Base[rfPath][group] =     PROMContent[eeAddr++];
319                         if (pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
320                                 pwrInfo24G->IndexBW40_Base[rfPath][group] =     EEPROM_DEFAULT_24G_INDEX;
321                 }
322                 for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
323                         if (TxCount == 0) {
324                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
325                                 if (PROMContent[eeAddr] == 0xFF) {
326                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
327                                 } else {
328                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
329                                         if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
330                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
331                                 }
332
333                                 if (PROMContent[eeAddr] == 0xFF) {
334                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_24G_OFDM_DIFF;
335                                 } else {
336                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);
337                                         if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
338                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
339                                 }
340                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
341                                 eeAddr++;
342                         } else {
343                                 if (PROMContent[eeAddr] == 0xFF) {
344                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
345                                 } else {
346                                         pwrInfo24G->BW40_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;
347                                         if (pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
348                                                 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
349                                 }
350
351                                 if (PROMContent[eeAddr] == 0xFF) {
352                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        EEPROM_DEFAULT_DIFF;
353                                 } else {
354                                         pwrInfo24G->BW20_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0x0f);
355                                         if (pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
356                                                 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
357                                 }
358                                 eeAddr++;
359
360                                 if (PROMContent[eeAddr] == 0xFF) {
361                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
362                                 } else {
363                                         pwrInfo24G->OFDM_Diff[rfPath][TxCount] =        (PROMContent[eeAddr]&0xf0)>>4;
364                                         if (pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT(3))            /* 4bit sign number to 8 bit sign number */
365                                                 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
366                                 }
367
368                                 if (PROMContent[eeAddr] == 0xFF) {
369                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
370                                 } else {
371                                         pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
372                                         if (pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT(3))             /* 4bit sign number to 8 bit sign number */
373                                                 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
374                                 }
375                                 eeAddr++;
376                         }
377                 }
378         }
379 }
380
381 static u8 Hal_GetChnlGroup88E(u8 chnl, u8 *pGroup)
382 {
383         u8 bIn24G = true;
384
385         if (chnl <= 14) {
386                 bIn24G = true;
387
388                 if (chnl < 3)                   /*  Channel 1-2 */
389                         *pGroup = 0;
390                 else if (chnl < 6)              /*  Channel 3-5 */
391                         *pGroup = 1;
392                 else     if (chnl < 9)          /*  Channel 6-8 */
393                         *pGroup = 2;
394                 else if (chnl < 12)             /*  Channel 9-11 */
395                         *pGroup = 3;
396                 else if (chnl < 14)             /*  Channel 12-13 */
397                         *pGroup = 4;
398                 else if (chnl == 14)            /*  Channel 14 */
399                         *pGroup = 5;
400         } else {
401                 /* probably, this branch is suitable only for 5 GHz */
402
403                 bIn24G = false;
404
405                 if (chnl <= 40)
406                         *pGroup = 0;
407                 else if (chnl <= 48)
408                         *pGroup = 1;
409                 else     if (chnl <= 56)
410                         *pGroup = 2;
411                 else if (chnl <= 64)
412                         *pGroup = 3;
413                 else if (chnl <= 104)
414                         *pGroup = 4;
415                 else if (chnl <= 112)
416                         *pGroup = 5;
417                 else if (chnl <= 120)
418                         *pGroup = 5;
419                 else if (chnl <= 128)
420                         *pGroup = 6;
421                 else if (chnl <= 136)
422                         *pGroup = 7;
423                 else if (chnl <= 144)
424                         *pGroup = 8;
425                 else if (chnl <= 153)
426                         *pGroup = 9;
427                 else if (chnl <= 161)
428                         *pGroup = 10;
429                 else if (chnl <= 177)
430                         *pGroup = 11;
431         }
432         return bIn24G;
433 }
434
435 void Hal_ReadPowerSavingMode88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
436 {
437         if (AutoLoadFail) {
438                 padapter->pwrctrlpriv.bHWPowerdown = false;
439                 padapter->pwrctrlpriv.bSupportRemoteWakeup = false;
440         } else {
441                 /* hw power down mode selection , 0:rf-off / 1:power down */
442
443                 if (padapter->registrypriv.hwpdn_mode == 2)
444                         padapter->pwrctrlpriv.bHWPowerdown = (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & BIT(4));
445                 else
446                         padapter->pwrctrlpriv.bHWPowerdown = padapter->registrypriv.hwpdn_mode;
447
448                 /*  decide hw if support remote wakeup function */
449                 /*  if hw supported, 8051 (SIE) will generate WeakUP signal(D+/D- toggle) when autoresume */
450                 padapter->pwrctrlpriv.bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT(1)) ? true : false;
451
452                 DBG_88E("%s...bHWPwrPindetect(%x)-bHWPowerdown(%x) , bSupportRemoteWakeup(%x)\n", __func__,
453                 padapter->pwrctrlpriv.bHWPwrPindetect, padapter->pwrctrlpriv.bHWPowerdown, padapter->pwrctrlpriv.bSupportRemoteWakeup);
454
455                 DBG_88E("### PS params =>  power_mgnt(%x), usbss_enable(%x) ###\n", padapter->registrypriv.power_mgnt, padapter->registrypriv.usbss_enable);
456         }
457 }
458
459 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail)
460 {
461         struct hal_data_8188e *pHalData = padapter->HalData;
462         struct txpowerinfo24g pwrInfo24G;
463         u8 ch, group;
464         u8 bIn24G, TxCount;
465
466         Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail);
467
468         if (!AutoLoadFail)
469                 pHalData->bTXPowerDataReadFromEEPORM = true;
470
471         for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
472                 bIn24G = Hal_GetChnlGroup88E(ch, &group);
473                 if (bIn24G) {
474                         pHalData->Index24G_CCK_Base[0][ch] = pwrInfo24G.IndexCCK_Base[0][group];
475                         if (ch == 14)
476                                 pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][4];
477                         else
478                                 pHalData->Index24G_BW40_Base[0][ch] = pwrInfo24G.IndexBW40_Base[0][group];
479                 }
480                 if (bIn24G) {
481                         DBG_88E("======= Path %d, Channel %d =======\n", 0, ch);
482                         DBG_88E("Index24G_CCK_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_CCK_Base[0][ch]);
483                         DBG_88E("Index24G_BW40_Base[%d][%d] = 0x%x\n", 0, ch, pHalData->Index24G_BW40_Base[0][ch]);
484                 }
485         }
486         for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) {
487                 pHalData->CCK_24G_Diff[0][TxCount] = pwrInfo24G.CCK_Diff[0][TxCount];
488                 pHalData->OFDM_24G_Diff[0][TxCount] = pwrInfo24G.OFDM_Diff[0][TxCount];
489                 pHalData->BW20_24G_Diff[0][TxCount] = pwrInfo24G.BW20_Diff[0][TxCount];
490                 pHalData->BW40_24G_Diff[0][TxCount] = pwrInfo24G.BW40_Diff[0][TxCount];
491                 DBG_88E("======= TxCount %d =======\n", TxCount);
492                 DBG_88E("CCK_24G_Diff[%d][%d] = %d\n", 0, TxCount, pHalData->CCK_24G_Diff[0][TxCount]);
493                 DBG_88E("OFDM_24G_Diff[%d][%d] = %d\n", 0, TxCount, pHalData->OFDM_24G_Diff[0][TxCount]);
494                 DBG_88E("BW20_24G_Diff[%d][%d] = %d\n", 0, TxCount, pHalData->BW20_24G_Diff[0][TxCount]);
495                 DBG_88E("BW40_24G_Diff[%d][%d] = %d\n", 0, TxCount, pHalData->BW40_24G_Diff[0][TxCount]);
496         }
497
498         /*  2010/10/19 MH Add Regulator recognize for CU. */
499         if (!AutoLoadFail) {
500                 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x7);     /* bit0~2 */
501                 if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
502                         pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); /* bit0~2 */
503         } else {
504                 pHalData->EEPROMRegulatory = 0;
505         }
506         DBG_88E("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);
507 }
508
509 void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
510 {
511         struct hal_data_8188e *pHalData = pAdapter->HalData;
512
513         if (!AutoLoadFail) {
514                 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_88E];
515                 if (pHalData->CrystalCap == 0xFF)
516                         pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
517         } else {
518                 pHalData->CrystalCap = EEPROM_Default_CrystalCap_88E;
519         }
520         DBG_88E("CrystalCap: 0x%2x\n", pHalData->CrystalCap);
521 }
522
523 void Hal_EfuseParseBoardType88E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail)
524 {
525         struct hal_data_8188e *pHalData = pAdapter->HalData;
526
527         if (!AutoLoadFail)
528                 pHalData->BoardType = (hwinfo[EEPROM_RF_BOARD_OPTION_88E]
529                                         & 0xE0) >> 5;
530         else
531                 pHalData->BoardType = 0;
532         DBG_88E("Board Type: 0x%2x\n", pHalData->BoardType);
533 }
534
535 void Hal_EfuseParseEEPROMVer88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
536 {
537         struct hal_data_8188e *pHalData = padapter->HalData;
538
539         if (!AutoLoadFail) {
540                 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_88E];
541                 if (pHalData->EEPROMVersion == 0xFF)
542                         pHalData->EEPROMVersion = EEPROM_Default_Version;
543         } else {
544                 pHalData->EEPROMVersion = 1;
545         }
546         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
547                  ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
548                  pHalData->EEPROMVersion));
549 }
550
551 void rtl8188e_EfuseParseChnlPlan(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
552 {
553         padapter->mlmepriv.ChannelPlan =
554                  hal_com_get_channel_plan(padapter,
555                                           hwinfo ? hwinfo[EEPROM_ChannelPlan_88E] : 0xFF,
556                                           padapter->registrypriv.channel_plan,
557                                           RT_CHANNEL_DOMAIN_WORLD_WIDE_13, AutoLoadFail);
558
559         DBG_88E("mlmepriv.ChannelPlan = 0x%02x\n", padapter->mlmepriv.ChannelPlan);
560 }
561
562 void Hal_EfuseParseCustomerID88E(struct adapter *padapter, u8 *hwinfo, bool AutoLoadFail)
563 {
564         struct hal_data_8188e   *pHalData = padapter->HalData;
565
566         if (!AutoLoadFail) {
567                 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CUSTOMERID_88E];
568         } else {
569                 pHalData->EEPROMCustomerID = 0;
570                 pHalData->EEPROMSubCustomerID = 0;
571         }
572         DBG_88E("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID);
573 }
574
575 void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail)
576 {
577         struct hal_data_8188e *pHalData = pAdapter->HalData;
578         struct registry_priv    *registry_par = &pAdapter->registrypriv;
579
580         if (!AutoLoadFail) {
581                 /*  Antenna Diversity setting. */
582                 if (registry_par->antdiv_cfg == 2) { /*  2:By EFUSE */
583                         pHalData->AntDivCfg = (PROMContent[EEPROM_RF_BOARD_OPTION_88E]&0x18)>>3;
584                         if (PROMContent[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
585                                 pHalData->AntDivCfg = (EEPROM_DEFAULT_BOARD_OPTION&0x18)>>3;
586                 } else {
587                         pHalData->AntDivCfg = registry_par->antdiv_cfg;  /*  0:OFF , 1:ON, 2:By EFUSE */
588                 }
589
590                 if (registry_par->antdiv_type == 0) {
591                         /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
592                         pHalData->TRxAntDivType = PROMContent[EEPROM_RF_ANTENNA_OPT_88E];
593                         if (pHalData->TRxAntDivType == 0xFF)
594                                 pHalData->TRxAntDivType = CG_TRX_HW_ANTDIV; /*  For 88EE, 1Tx and 1RxCG are fixed.(1Ant, Tx and RxCG are both on aux port) */
595                 } else {
596                         pHalData->TRxAntDivType = registry_par->antdiv_type;
597                 }
598
599                 if (pHalData->TRxAntDivType == CG_TRX_HW_ANTDIV || pHalData->TRxAntDivType == CGCS_RX_HW_ANTDIV)
600                         pHalData->AntDivCfg = 1; /*  0xC1[3] is ignored. */
601         } else {
602                 pHalData->AntDivCfg = 0;
603                 pHalData->TRxAntDivType = pHalData->TRxAntDivType; /*  The value in the driver setting of device manager. */
604         }
605         DBG_88E("EEPROM : AntDivCfg = %x, TRxAntDivType = %x\n", pHalData->AntDivCfg, pHalData->TRxAntDivType);
606 }
607
608 void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail)
609 {
610         struct hal_data_8188e *pHalData = Adapter->HalData;
611
612         /*  ThermalMeter from EEPROM */
613         if (!AutoloadFail)
614                 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_88E];
615         else
616                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
617
618         if (pHalData->EEPROMThermalMeter == 0xff || AutoloadFail) {
619                 pHalData->bAPKThermalMeterIgnore = true;
620                 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E;
621         }
622         DBG_88E("ThermalMeter = 0x%x\n", pHalData->EEPROMThermalMeter);
623 }