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