[go: nahoru, domu]

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 ******************************************************************************/
15#define _HCI_HAL_INIT_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19#include <rtw_efuse.h>
20
21#include <HalPwrSeqCmd.h>
22#include <Hal8723PwrSeq.h>
23#include <rtl8723a_hal.h>
24#include <rtl8723a_led.h>
25#include <linux/ieee80211.h>
26
27#include <usb_ops.h>
28
29static void
30_ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe)
31{
32	u8 value8;
33	struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
34
35	pHalData->OutEpQueueSel = 0;
36	pHalData->OutEpNumber = 0;
37
38	/*  Normal and High queue */
39	value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 1));
40
41	if (value8 & USB_NORMAL_SIE_EP_MASK) {
42		pHalData->OutEpQueueSel |= TX_SELE_HQ;
43		pHalData->OutEpNumber++;
44	}
45
46	if ((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
47		pHalData->OutEpQueueSel |= TX_SELE_NQ;
48		pHalData->OutEpNumber++;
49	}
50
51	/*  Low queue */
52	value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 2));
53	if (value8 & USB_NORMAL_SIE_EP_MASK) {
54		pHalData->OutEpQueueSel |= TX_SELE_LQ;
55		pHalData->OutEpNumber++;
56	}
57
58	/*  TODO: Error recovery for this case */
59	/* RT_ASSERT((NumOutPipe == pHalData->OutEpNumber),
60	   ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n",
61	   (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */
62}
63
64static bool rtl8723au_set_queue_pipe_mapping(struct rtw_adapter *pAdapter,
65					     u8 NumInPipe, u8 NumOutPipe)
66{
67	struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
68	bool result = false;
69
70	_ConfigChipOutEP(pAdapter, NumOutPipe);
71
72	/*  Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
73	if (pHalData->OutEpNumber == 1) {
74		if (NumInPipe != 1)
75			return result;
76	}
77
78	result = Hal_MappingOutPipe23a(pAdapter, NumOutPipe);
79
80	return result;
81}
82
83void rtl8723au_chip_configure(struct rtw_adapter *padapter)
84{
85	struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
86	struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
87
88	pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber;
89
90	rtl8723au_set_queue_pipe_mapping(padapter,
91					 pdvobjpriv->RtNumInPipes,
92					 pdvobjpriv->RtNumOutPipes);
93}
94
95static int _InitPowerOn(struct rtw_adapter *padapter)
96{
97	int status = _SUCCESS;
98	u16 value16 = 0;
99	u8 value8 = 0;
100
101	/*  RSV_CTRL 0x1C[7:0] = 0x00
102	    unlock ISO/CLK/Power control register */
103	rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0);
104
105	/*  HW Power on sequence */
106	if (!HalPwrSeqCmdParsing23a(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
107				 PWR_INTF_USB_MSK, rtl8723AU_card_enable_flow))
108		return _FAIL;
109
110	/*  0x04[19] = 1, suggest by Jackie 2011.05.09, reset 8051 */
111	value8 = rtl8723au_read8(padapter, REG_APS_FSMCO+2);
112	rtl8723au_write8(padapter, REG_APS_FSMCO + 2, value8 | BIT(3));
113
114	/*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
115	/*  Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy.
116	    Added by tynli. 2011.08.31. */
117	value16 = rtl8723au_read16(padapter, REG_CR);
118	value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
119		    PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN |
120		    ENSEC | CALTMR_EN);
121	rtl8723au_write16(padapter, REG_CR, value16);
122
123	/* for Efuse PG, suggest by Jackie 2011.11.23 */
124	PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT(28)|BIT(29)|BIT(30), 0x06);
125
126	return status;
127}
128
129/*  Shall USB interface init this? */
130static void _InitInterrupt(struct rtw_adapter *Adapter)
131{
132	u32 value32;
133
134	/*  HISR - turn all on */
135	value32 = 0xFFFFFFFF;
136	rtl8723au_write32(Adapter, REG_HISR, value32);
137
138	/*  HIMR - turn all on */
139	rtl8723au_write32(Adapter, REG_HIMR, value32);
140}
141
142static void _InitQueueReservedPage(struct rtw_adapter *Adapter)
143{
144	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
145	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
146	u32 numHQ = 0;
147	u32 numLQ = 0;
148	u32 numNQ = 0;
149	u32 numPubQ;
150	u32 value32;
151	u8 value8;
152	bool bWiFiConfig = pregistrypriv->wifi_spec;
153
154	/* RT_ASSERT((outEPNum>= 2), ("for WMM , number of out-ep "
155	   "must more than or equal to 2!\n")); */
156
157	numPubQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_PUBQ : NORMAL_PAGE_NUM_PUBQ;
158
159	if (pHalData->OutEpQueueSel & TX_SELE_HQ) {
160		numHQ = bWiFiConfig ?
161			WMM_NORMAL_PAGE_NUM_HPQ : NORMAL_PAGE_NUM_HPQ;
162	}
163
164	if (pHalData->OutEpQueueSel & TX_SELE_LQ) {
165		numLQ = bWiFiConfig ?
166			WMM_NORMAL_PAGE_NUM_LPQ : NORMAL_PAGE_NUM_LPQ;
167	}
168	/*  NOTE: This step shall be proceed before
169	    writting REG_RQPN. */
170	if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
171		numNQ = bWiFiConfig ?
172			WMM_NORMAL_PAGE_NUM_NPQ : NORMAL_PAGE_NUM_NPQ;
173	}
174	value8 = (u8)_NPQ(numNQ);
175	rtl8723au_write8(Adapter, REG_RQPN_NPQ, value8);
176
177	/*  TX DMA */
178	value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
179	rtl8723au_write32(Adapter, REG_RQPN, value32);
180}
181
182static void _InitTxBufferBoundary(struct rtw_adapter *Adapter)
183{
184	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
185
186	u8 txpktbuf_bndy;
187
188	if (!pregistrypriv->wifi_spec)
189		txpktbuf_bndy = TX_PAGE_BOUNDARY;
190	else /* for WMM */
191		txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY;
192
193	rtl8723au_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
194	rtl8723au_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
195	rtl8723au_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
196	rtl8723au_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
197	rtl8723au_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
198}
199
200static void _InitPageBoundary(struct rtw_adapter *Adapter)
201{
202	/*  RX Page Boundary */
203	/* srand(static_cast<unsigned int>(time(NULL))); */
204	u16 rxff_bndy = 0x27FF;/* rand() % 1) ? 0x27FF : 0x23FF; */
205
206	rtl8723au_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
207
208	/*  TODO: ?? shall we set tx boundary? */
209}
210
211static void
212_InitNormalChipRegPriority(struct rtw_adapter *Adapter, u16 beQ, u16 bkQ,
213			   u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ)
214{
215	u16 value16 = rtl8723au_read16(Adapter, REG_TRXDMA_CTRL) & 0x7;
216
217	value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
218		_TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
219		_TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
220
221	rtl8723au_write16(Adapter, REG_TRXDMA_CTRL, value16);
222}
223
224static void _InitNormalChipOneOutEpPriority(struct rtw_adapter *Adapter)
225{
226	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
227	u16 value = 0;
228
229	switch (pHalData->OutEpQueueSel) {
230	case TX_SELE_HQ:
231		value = QUEUE_HIGH;
232		break;
233	case TX_SELE_LQ:
234		value = QUEUE_LOW;
235		break;
236	case TX_SELE_NQ:
237		value = QUEUE_NORMAL;
238		break;
239	default:
240		/* RT_ASSERT(false, ("Shall not reach here!\n")); */
241		break;
242	}
243
244	_InitNormalChipRegPriority(Adapter, value, value, value,
245				   value, value, value);
246}
247
248static void _InitNormalChipTwoOutEpPriority(struct rtw_adapter *Adapter)
249{
250	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
251	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
252	u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
253	u16 valueHi = 0;
254	u16 valueLow = 0;
255
256	switch (pHalData->OutEpQueueSel) {
257	case (TX_SELE_HQ | TX_SELE_LQ):
258		valueHi = QUEUE_HIGH;
259		valueLow = QUEUE_LOW;
260		break;
261	case (TX_SELE_NQ | TX_SELE_LQ):
262		valueHi = QUEUE_NORMAL;
263		valueLow = QUEUE_LOW;
264		break;
265	case (TX_SELE_HQ | TX_SELE_NQ):
266		valueHi = QUEUE_HIGH;
267		valueLow = QUEUE_NORMAL;
268		break;
269	default:
270		/* RT_ASSERT(false, ("Shall not reach here!\n")); */
271		break;
272	}
273
274	if (!pregistrypriv->wifi_spec) {
275		beQ = valueLow;
276		bkQ = valueLow;
277		viQ = valueHi;
278		voQ = valueHi;
279		mgtQ = valueHi;
280		hiQ = valueHi;
281	} else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */
282		beQ = valueLow;
283		bkQ = valueHi;
284		viQ = valueHi;
285		voQ = valueLow;
286		mgtQ = valueHi;
287		hiQ = valueHi;
288	}
289
290	_InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
291}
292
293static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter)
294{
295	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
296	u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
297
298	if (!pregistrypriv->wifi_spec) {/*  typical setting */
299		beQ = QUEUE_LOW;
300		bkQ = QUEUE_LOW;
301		viQ = QUEUE_NORMAL;
302		voQ = QUEUE_HIGH;
303		mgtQ = QUEUE_HIGH;
304		hiQ = QUEUE_HIGH;
305	} else {/*  for WMM */
306		beQ = QUEUE_LOW;
307		bkQ = QUEUE_NORMAL;
308		viQ = QUEUE_NORMAL;
309		voQ = QUEUE_HIGH;
310		mgtQ = QUEUE_HIGH;
311		hiQ = QUEUE_HIGH;
312	}
313	_InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
314}
315
316static void _InitNormalChipQueuePriority(struct rtw_adapter *Adapter)
317{
318	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
319
320	switch (pHalData->OutEpNumber) {
321	case 1:
322		_InitNormalChipOneOutEpPriority(Adapter);
323		break;
324	case 2:
325		_InitNormalChipTwoOutEpPriority(Adapter);
326		break;
327	case 3:
328		_InitNormalChipThreeOutEpPriority(Adapter);
329		break;
330	default:
331		/* RT_ASSERT(false, ("Shall not reach here!\n")); */
332		break;
333	}
334}
335
336static void _InitQueuePriority(struct rtw_adapter *Adapter)
337{
338	_InitNormalChipQueuePriority(Adapter);
339}
340
341static void _InitTransferPageSize(struct rtw_adapter *Adapter)
342{
343	/*  Tx page size is always 128. */
344
345	u8 value8;
346	value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
347	rtl8723au_write8(Adapter, REG_PBP, value8);
348}
349
350static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
351{
352	rtl8723au_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
353}
354
355static void _InitWMACSetting(struct rtw_adapter *Adapter)
356{
357	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
358
359	/*  don't turn on AAP, it will allow all packets to driver */
360	pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA |
361				  RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF |
362				  RCR_HTC_LOC_CTRL | RCR_APP_MIC |
363				  RCR_APP_PHYSTS;
364
365	/*  some REG_RCR will be modified later by
366	    phy_ConfigMACWithHeaderFile() */
367	rtl8723au_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
368
369	/*  Accept all multicast address */
370	rtl8723au_write32(Adapter, REG_MAR, 0xFFFFFFFF);
371	rtl8723au_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
372
373	/*  Accept all data frames */
374	/* value16 = 0xFFFF; */
375	/* rtl8723au_write16(Adapter, REG_RXFLTMAP2, value16); */
376
377	/*  2010.09.08 hpfan */
378	/*  Since ADF is removed from RCR, ps-poll will not be indicate
379	    to driver, */
380	/*  RxFilterMap should mask ps-poll to gurantee AP mode can
381	    rx ps-poll. */
382	/* value16 = 0x400; */
383	/* rtl8723au_write16(Adapter, REG_RXFLTMAP1, value16); */
384
385	/*  Accept all management frames */
386	/* value16 = 0xFFFF; */
387	/* rtl8723au_write16(Adapter, REG_RXFLTMAP0, value16); */
388
389	/* enable RX_SHIFT bits */
390	/* rtl8723au_write8(Adapter, REG_TRXDMA_CTRL, rtl8723au_read8(Adapter,
391	   REG_TRXDMA_CTRL)|BIT(1)); */
392}
393
394static void _InitAdaptiveCtrl(struct rtw_adapter *Adapter)
395{
396	u16 value16;
397	u32 value32;
398
399	/*  Response Rate Set */
400	value32 = rtl8723au_read32(Adapter, REG_RRSR);
401	value32 &= ~RATE_BITMAP_ALL;
402	value32 |= RATE_RRSR_CCK_ONLY_1M;
403	rtl8723au_write32(Adapter, REG_RRSR, value32);
404
405	/*  CF-END Threshold */
406	/* m_spIoBase->rtl8723au_write8(REG_CFEND_TH, 0x1); */
407
408	/*  SIFS (used in NAV) */
409	value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
410	rtl8723au_write16(Adapter, REG_SPEC_SIFS, value16);
411
412	/*  Retry Limit */
413	value16 = _LRL(0x30) | _SRL(0x30);
414	rtl8723au_write16(Adapter, REG_RL, value16);
415}
416
417static void _InitRateFallback(struct rtw_adapter *Adapter)
418{
419	/*  Set Data Auto Rate Fallback Retry Count register. */
420	rtl8723au_write32(Adapter, REG_DARFRC, 0x00000000);
421	rtl8723au_write32(Adapter, REG_DARFRC+4, 0x10080404);
422	rtl8723au_write32(Adapter, REG_RARFRC, 0x04030201);
423	rtl8723au_write32(Adapter, REG_RARFRC+4, 0x08070605);
424}
425
426static void _InitEDCA(struct rtw_adapter *Adapter)
427{
428	/*  Set Spec SIFS (used in NAV) */
429	rtl8723au_write16(Adapter, REG_SPEC_SIFS, 0x100a);
430	rtl8723au_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
431
432	/*  Set SIFS for CCK */
433	rtl8723au_write16(Adapter, REG_SIFS_CTX, 0x100a);
434
435	/*  Set SIFS for OFDM */
436	rtl8723au_write16(Adapter, REG_SIFS_TRX, 0x100a);
437
438	/*  TXOP */
439	rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
440	rtl8723au_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
441	rtl8723au_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
442	rtl8723au_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
443}
444
445static void _InitHWLed(struct rtw_adapter *Adapter)
446{
447	struct led_priv *pledpriv = &Adapter->ledpriv;
448
449	if (pledpriv->LedStrategy != HW_LED)
450		return;
451
452/*  HW led control */
453/*  to do .... */
454/* must consider cases of antenna diversity/ commbo card/solo card/mini card */
455}
456
457static void _InitRDGSetting(struct rtw_adapter *Adapter)
458{
459	rtl8723au_write8(Adapter, REG_RD_CTRL, 0xFF);
460	rtl8723au_write16(Adapter, REG_RD_NAV_NXT, 0x200);
461	rtl8723au_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
462}
463
464static void _InitRetryFunction(struct rtw_adapter *Adapter)
465{
466	u8 value8;
467
468	value8 = rtl8723au_read8(Adapter, REG_FWHW_TXQ_CTRL);
469	value8 |= EN_AMPDU_RTY_NEW;
470	rtl8723au_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
471
472	/*  Set ACK timeout */
473	rtl8723au_write8(Adapter, REG_ACKTO, 0x40);
474}
475
476static void _InitRFType(struct rtw_adapter *Adapter)
477{
478	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
479	bool is92CU = IS_92C_SERIAL(pHalData->VersionID);
480
481	pHalData->rf_chip = RF_6052;
482
483	if (is92CU == false) {
484		pHalData->rf_type = RF_1T1R;
485		DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n");
486		return;
487	}
488
489	/*  TODO: Consider that EEPROM set 92CU to 1T1R later. */
490	/*  Force to overwrite setting according to chip version. Ignore
491	    EEPROM setting. */
492	/* pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; */
493	MSG_8723A("Set RF Chip ID to RF_6052 and RF type to %d.\n",
494		  pHalData->rf_type);
495}
496
497/*  Set CCK and OFDM Block "ON" */
498static void _BBTurnOnBlock(struct rtw_adapter *Adapter)
499{
500	PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
501	PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
502}
503
504#define MgntActSet_RF_State(...)
505static void _RfPowerSave(struct rtw_adapter *padapter)
506{
507}
508
509enum {
510	Antenna_Lfet = 1,
511	Antenna_Right = 2,
512};
513
514enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter)
515{
516	/* struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); */
517	u8 val8;
518	enum rt_rf_power_state rfpowerstate = rf_off;
519
520	rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
521			 rtl8723au_read8(pAdapter,
522					 REG_MAC_PINMUX_CFG) & ~BIT(3));
523	val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
524	DBG_8723A("GPIO_IN =%02x\n", val8);
525	rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
526
527	return rfpowerstate;
528}
529
530void _ps_open_RF23a(struct rtw_adapter *padapter);
531
532int rtl8723au_hal_init(struct rtw_adapter *Adapter)
533{
534	u8 val8 = 0;
535	u32 boundary;
536	int status = _SUCCESS;
537	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
538	struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
539	struct registry_priv *pregistrypriv = &Adapter->registrypriv;
540
541	unsigned long init_start_time = jiffies;
542
543	Adapter->hw_init_completed = false;
544
545	if (Adapter->pwrctrlpriv.bkeepfwalive) {
546		_ps_open_RF23a(Adapter);
547
548		if (pHalData->bIQKInitialized) {
549			rtl8723a_phy_iq_calibrate(Adapter, true);
550		} else {
551			rtl8723a_phy_iq_calibrate(Adapter, false);
552			pHalData->bIQKInitialized = true;
553		}
554		rtl8723a_odm_check_tx_power_tracking(Adapter);
555		rtl8723a_phy_lc_calibrate(Adapter);
556
557		goto exit;
558	}
559
560	/*  Check if MAC has already power on. by tynli. 2011.05.27. */
561	val8 = rtl8723au_read8(Adapter, REG_CR);
562	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
563		 ("%s: REG_CR 0x100 = 0x%02x\n", __func__, val8));
564	/* Fix 92DU-VC S3 hang with the reason is that secondary mac is not
565	   initialized. */
566	/* 0x100 value of first mac is 0xEA while 0x100 value of secondary
567	   is 0x00 */
568	if (val8 == 0xEA) {
569		pHalData->bMACFuncEnable = false;
570	} else {
571		pHalData->bMACFuncEnable = true;
572		RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
573			 ("%s: MAC has already power on\n", __func__));
574	}
575
576	status = _InitPowerOn(Adapter);
577	if (status == _FAIL) {
578		RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
579			 ("Failed to init power on!\n"));
580		goto exit;
581	}
582
583	if (!pregistrypriv->wifi_spec) {
584		boundary = TX_PAGE_BOUNDARY;
585	} else {
586		/*  for WMM */
587		boundary = WMM_NORMAL_TX_PAGE_BOUNDARY;
588	}
589
590	if (!pHalData->bMACFuncEnable) {
591		status =  InitLLTTable23a(Adapter, boundary);
592		if (status == _FAIL) {
593			RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
594				 ("Failed to init LLT table\n"));
595			goto exit;
596		}
597	}
598
599	if (pHalData->bRDGEnable)
600		_InitRDGSetting(Adapter);
601
602	status = rtl8723a_FirmwareDownload(Adapter);
603	if (status != _SUCCESS) {
604		Adapter->bFWReady = false;
605		pHalData->fw_ractrl = false;
606		DBG_8723A("fw download fail!\n");
607		goto exit;
608	} else {
609		Adapter->bFWReady = true;
610		pHalData->fw_ractrl = true;
611		DBG_8723A("fw download ok!\n");
612	}
613
614	rtl8723a_InitializeFirmwareVars(Adapter);
615
616	if (pwrctrlpriv->reg_rfoff == true) {
617		pwrctrlpriv->rf_pwrstate = rf_off;
618	}
619
620	/*  2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
621	/*  HW GPIO pin. Before PHY_RFConfig8192C. */
622	/* HalDetectPwrDownMode(Adapter); */
623	/*  2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
624	/* HalDetectSelectiveSuspendMode(Adapter); */
625
626	/*  Set RF type for BB/RF configuration */
627	_InitRFType(Adapter);/* _ReadRFType() */
628
629	/*  Save target channel */
630	/*  <Roger_Notes> Current Channel will be updated again later. */
631	pHalData->CurrentChannel = 6;/* default set to 6 */
632
633	status = PHY_MACConfig8723A(Adapter);
634	if (status == _FAIL) {
635		DBG_8723A("PHY_MACConfig8723A fault !!\n");
636		goto exit;
637	}
638
639	/*  */
640	/* d. Initialize BB related configurations. */
641	/*  */
642	status = PHY_BBConfig8723A(Adapter);
643	if (status == _FAIL) {
644		DBG_8723A("PHY_BBConfig8723A fault !!\n");
645		goto exit;
646	}
647
648	/*  Add for tx power by rate fine tune. We need to call the function after BB config. */
649	/*  Because the tx power by rate table is inited in BB config. */
650
651	status = PHY_RF6052_Config8723A(Adapter);
652	if (status == _FAIL) {
653		DBG_8723A("PHY_RF6052_Config8723A failed!!\n");
654		goto exit;
655	}
656
657	/* reducing 80M spur */
658	PHY_SetBBReg(Adapter, RF_T_METER, bMaskDWord, 0x0381808d);
659	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
660	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff82);
661	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
662
663	/* RFSW Control */
664	PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003);	/* 0x804[14]= 0 */
665	PHY_SetBBReg(Adapter, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07000760);	/* 0x870[6:5]= b'11 */
666	PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, 0x66F60210); /* 0x860[6:5]= b'00 */
667
668	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: 0x870 = value 0x%x\n", __func__, PHY_QueryBBReg(Adapter, 0x870, bMaskDWord)));
669
670	/*  */
671	/*  Joseph Note: Keep RfRegChnlVal for later use. */
672	/*  */
673	pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask);
674	pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask);
675
676	if (!pHalData->bMACFuncEnable) {
677		_InitQueueReservedPage(Adapter);
678		_InitTxBufferBoundary(Adapter);
679	}
680	_InitQueuePriority(Adapter);
681	_InitPageBoundary(Adapter);
682	_InitTransferPageSize(Adapter);
683
684	/*  Get Rx PHY status in order to report RSSI and others. */
685	_InitDriverInfoSize(Adapter, DRVINFO_SZ);
686
687	_InitInterrupt(Adapter);
688	hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
689	rtl8723a_set_media_status(Adapter, MSR_INFRA);
690	_InitWMACSetting(Adapter);
691	_InitAdaptiveCtrl(Adapter);
692	_InitEDCA(Adapter);
693	_InitRateFallback(Adapter);
694	_InitRetryFunction(Adapter);
695	rtl8723a_InitBeaconParameters(Adapter);
696
697	_InitHWLed(Adapter);
698
699	_BBTurnOnBlock(Adapter);
700	/* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
701
702	rtl8723a_cam_invalidate_all(Adapter);
703
704	/*  2010/12/17 MH We need to set TX power according to EFUSE content at first. */
705	PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel);
706
707	rtl8723a_InitAntenna_Selection(Adapter);
708
709	/*  HW SEQ CTRL */
710	/* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
711	rtl8723au_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
712
713	/*  */
714	/*  Disable BAR, suggested by Scott */
715	/*  2010.04.09 add by hpfan */
716	/*  */
717	rtl8723au_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
718
719	if (pregistrypriv->wifi_spec)
720		rtl8723au_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
721
722	/*  Move by Neo for USB SS from above setp */
723	_RfPowerSave(Adapter);
724
725	/*  2010/08/26 MH Merge from 8192CE. */
726	/* sherry masked that it has been done in _RfPowerSave */
727	/* 20110927 */
728	/* recovery for 8192cu and 9723Au 20111017 */
729	if (pwrctrlpriv->rf_pwrstate == rf_on) {
730		if (pHalData->bIQKInitialized) {
731			rtl8723a_phy_iq_calibrate(Adapter, true);
732		} else {
733			rtl8723a_phy_iq_calibrate(Adapter, false);
734			pHalData->bIQKInitialized = true;
735		}
736
737		rtl8723a_odm_check_tx_power_tracking(Adapter);
738
739		rtl8723a_phy_lc_calibrate(Adapter);
740
741		rtl8723a_dual_antenna_detection(Adapter);
742	}
743
744	/* fixed USB interface interference issue */
745	rtl8723au_write8(Adapter, 0xfe40, 0xe0);
746	rtl8723au_write8(Adapter, 0xfe41, 0x8d);
747	rtl8723au_write8(Adapter, 0xfe42, 0x80);
748	rtl8723au_write32(Adapter, 0x20c, 0xfd0320);
749	/* Solve too many protocol error on USB bus */
750	if (!IS_81xxC_VENDOR_UMC_A_CUT(pHalData->VersionID)) {
751		/*  0xE6 = 0x94 */
752		rtl8723au_write8(Adapter, 0xFE40, 0xE6);
753		rtl8723au_write8(Adapter, 0xFE41, 0x94);
754		rtl8723au_write8(Adapter, 0xFE42, 0x80);
755
756		/*  0xE0 = 0x19 */
757		rtl8723au_write8(Adapter, 0xFE40, 0xE0);
758		rtl8723au_write8(Adapter, 0xFE41, 0x19);
759		rtl8723au_write8(Adapter, 0xFE42, 0x80);
760
761		/*  0xE5 = 0x91 */
762		rtl8723au_write8(Adapter, 0xFE40, 0xE5);
763		rtl8723au_write8(Adapter, 0xFE41, 0x91);
764		rtl8723au_write8(Adapter, 0xFE42, 0x80);
765
766		/*  0xE2 = 0x81 */
767		rtl8723au_write8(Adapter, 0xFE40, 0xE2);
768		rtl8723au_write8(Adapter, 0xFE41, 0x81);
769		rtl8723au_write8(Adapter, 0xFE42, 0x80);
770
771	}
772
773/*	_InitPABias(Adapter); */
774
775	/*  Init BT hw config. */
776	rtl8723a_BT_init_hwconfig(Adapter);
777
778	rtl8723a_InitHalDm(Adapter);
779
780	val8 = ((WiFiNavUpperUs + HAL_8723A_NAV_UPPER_UNIT - 1) /
781		HAL_8723A_NAV_UPPER_UNIT);
782	rtl8723au_write8(Adapter, REG_NAV_UPPER, val8);
783
784	/*  2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
785	if (((rtl8723au_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) !=
786	     0x83000000)) {
787		PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(24), 1);
788		RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: IQK fail recorver\n", __func__));
789	}
790
791	/* ack for xmit mgmt frames. */
792	rtl8723au_write32(Adapter, REG_FWHW_TXQ_CTRL,
793			  rtl8723au_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
794
795exit:
796	if (status == _SUCCESS) {
797		Adapter->hw_init_completed = true;
798
799		if (Adapter->registrypriv.notch_filter == 1)
800			rtl8723a_notch_filter(Adapter, 1);
801	}
802
803	DBG_8723A("%s in %dms\n", __func__,
804		  jiffies_to_msecs(jiffies - init_start_time));
805	return status;
806}
807
808static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
809				enum rt_rf_power_state eRFPowerState,
810				int bRegSSPwrLvl)
811{
812	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
813	u8 value8;
814	u8 bytetmp;
815
816	switch (eRFPowerState) {
817	case rf_on:
818		if (bRegSSPwrLvl == 1) {
819			/*  1. Enable MAC Clock. Can not be enabled now. */
820			/* WriteXBYTE(REG_SYS_CLKR+1,
821			   ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */
822
823			/*  2. Force PWM, Enable SPS18_LDO_Marco_Block */
824			rtl8723au_write8(Adapter, REG_SPS0_CTRL,
825					 rtl8723au_read8(Adapter, REG_SPS0_CTRL) |
826					 BIT(0) | BIT(3));
827
828			/*  3. restore BB, AFE control register. */
829			/* RF */
830			if (pHalData->rf_type ==  RF_2T2R)
831				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
832					     0x380038, 1);
833			else
834				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
835					     0x38, 1);
836			PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
837			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
838
839			/* AFE */
840			if (pHalData->rf_type ==  RF_2T2R)
841				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
842					     0x63DB25A0);
843			else if (pHalData->rf_type ==  RF_1T1R)
844				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
845					     0x631B25A0);
846
847			/*  4. issue 3-wire command that RF set to Rx idle
848			    mode. This is used to re-write the RX idle mode. */
849			/*  We can only prvide a usual value instead and then
850			    HW will modify the value by itself. */
851			PHY_SetRFReg(Adapter, RF_PATH_A, 0,
852				     bRFRegOffsetMask, 0x32D95);
853			if (pHalData->rf_type ==  RF_2T2R) {
854				PHY_SetRFReg(Adapter, RF_PATH_B, 0,
855					     bRFRegOffsetMask, 0x32D95);
856			}
857		} else {		/*  Level 2 or others. */
858			/* h.	AFE_PLL_CTRL 0x28[7:0] = 0x80
859			   disable AFE PLL */
860			rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x81);
861
862			/*  i.	AFE_XTAL_CTRL 0x24[15:0] = 0x880F
863			    gated AFE DIG_CLOCK */
864			rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0x800F);
865			mdelay(1);
866
867			/*  2. Force PWM, Enable SPS18_LDO_Marco_Block */
868			rtl8723au_write8(Adapter, REG_SPS0_CTRL,
869					 rtl8723au_read8(Adapter, REG_SPS0_CTRL) |
870					 BIT(0) | BIT(3));
871
872			/*  3. restore BB, AFE control register. */
873			/* RF */
874			if (pHalData->rf_type ==  RF_2T2R)
875				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
876					     0x380038, 1);
877			else
878				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
879					     0x38, 1);
880			PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
881			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
882
883			/* AFE */
884			if (pHalData->rf_type ==  RF_2T2R)
885				PHY_SetBBReg(Adapter, rRx_Wait_CCA,
886					     bMaskDWord, 0x63DB25A0);
887			else if (pHalData->rf_type ==  RF_1T1R)
888				PHY_SetBBReg(Adapter, rRx_Wait_CCA,
889					     bMaskDWord, 0x631B25A0);
890
891			/*  4. issue 3-wire command that RF set to Rx idle
892			    mode. This is used to re-write the RX idle mode. */
893			/*  We can only prvide a usual value instead and
894			    then HW will modify the value by itself. */
895			PHY_SetRFReg(Adapter, RF_PATH_A, 0,
896				     bRFRegOffsetMask, 0x32D95);
897			if (pHalData->rf_type ==  RF_2T2R) {
898				PHY_SetRFReg(Adapter, RF_PATH_B, 0,
899					     bRFRegOffsetMask, 0x32D95);
900			}
901
902			/*  5. gated MAC Clock */
903			bytetmp = rtl8723au_read8(Adapter, REG_APSD_CTRL);
904			rtl8723au_write8(Adapter, REG_APSD_CTRL,
905					 bytetmp & ~BIT(6));
906
907			mdelay(10);
908
909			/*  Set BB reset at first */
910			/* 0x16 */
911			rtl8723au_write8(Adapter, REG_SYS_FUNC_EN, 0x17);
912
913			/*  Enable TX */
914			rtl8723au_write8(Adapter, REG_TXPAUSE, 0x0);
915		}
916		break;
917	case rf_sleep:
918	case rf_off:
919		value8 = rtl8723au_read8(Adapter, REG_SPS0_CTRL);
920		if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
921			value8 &= ~BIT(0);
922		else
923			value8 &= ~(BIT(0) | BIT(3));
924		if (bRegSSPwrLvl == 1) {
925			RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL1\n"));
926			/*  Disable RF and BB only for SelectSuspend. */
927
928			/*  1. Set BB/RF to shutdown. */
929			/*	(1) Reg878[5:3]= 0	 RF rx_code for
930							preamble power saving */
931			/*	(2)Reg878[21:19]= 0	Turn off RF-B */
932			/*	(3) RegC04[7:4]= 0	Turn off all paths
933							for packet detection */
934			/*	(4) Reg800[1] = 1	enable preamble power
935							saving */
936			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
937				PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter,
938					       bMaskDWord);
939			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
940				PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable,
941					       bMaskDWord);
942			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
943				PHY_QueryBBReg(Adapter, rFPGA0_RFMOD,
944					       bMaskDWord);
945			if (pHalData->rf_type ==  RF_2T2R) {
946				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
947					     0x380038, 0);
948			} else if (pHalData->rf_type ==  RF_1T1R) {
949				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
950					     0x38, 0);
951			}
952			PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
953			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
954
955			/*  2 .AFE control register to power down. bit[30:22] */
956			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
957				PHY_QueryBBReg(Adapter, rRx_Wait_CCA,
958					       bMaskDWord);
959			if (pHalData->rf_type ==  RF_2T2R)
960				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
961					     0x00DB25A0);
962			else if (pHalData->rf_type ==  RF_1T1R)
963				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
964					     0x001B25A0);
965
966			/*  3. issue 3-wire command that RF set to power down.*/
967			PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0);
968			if (pHalData->rf_type ==  RF_2T2R)
969				PHY_SetRFReg(Adapter, RF_PATH_B, 0,
970					     bRFRegOffsetMask, 0);
971
972			/*  4. Force PFM , disable SPS18_LDO_Marco_Block */
973			rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8);
974		} else {	/*  Level 2 or others. */
975			RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL2\n"));
976			{
977				u8 eRFPath = RF_PATH_A, value8 = 0;
978				rtl8723au_write8(Adapter, REG_TXPAUSE, 0xFF);
979				PHY_SetRFReg(Adapter,
980					     (enum RF_RADIO_PATH)eRFPath,
981					     0x0, bMaskByte0, 0x0);
982				value8 |= APSDOFF;
983				/* 0x40 */
984				rtl8723au_write8(Adapter, REG_APSD_CTRL,
985						 value8);
986
987				/*  After switch APSD, we need to delay
988				    for stability */
989				mdelay(10);
990
991				/*  Set BB reset at first */
992				value8 = 0;
993				value8 |= (FEN_USBD | FEN_USBA |
994					   FEN_BB_GLB_RSTn);
995				/* 0x16 */
996				rtl8723au_write8(Adapter, REG_SYS_FUNC_EN,
997						 value8);
998			}
999
1000			/*  Disable RF and BB only for SelectSuspend. */
1001
1002			/*  1. Set BB/RF to shutdown. */
1003			/*	(1) Reg878[5:3]= 0	RF rx_code for
1004							preamble power saving */
1005			/*	(2)Reg878[21:19]= 0	Turn off RF-B */
1006			/*	(3) RegC04[7:4]= 0	Turn off all paths for
1007							packet detection */
1008			/*	(4) Reg800[1] = 1	enable preamble power
1009							saving */
1010			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
1011				PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter,
1012					       bMaskDWord);
1013			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
1014				PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable,
1015					       bMaskDWord);
1016			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
1017				PHY_QueryBBReg(Adapter, rFPGA0_RFMOD,
1018					       bMaskDWord);
1019			if (pHalData->rf_type ==  RF_2T2R)
1020				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
1021					     0x380038, 0);
1022			else if (pHalData->rf_type ==  RF_1T1R)
1023				PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
1024					     0x38, 0);
1025			PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
1026			PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
1027
1028			/*  2 .AFE control register to power down. bit[30:22] */
1029			Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
1030				PHY_QueryBBReg(Adapter, rRx_Wait_CCA,
1031					       bMaskDWord);
1032			if (pHalData->rf_type ==  RF_2T2R)
1033				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
1034					     0x00DB25A0);
1035			else if (pHalData->rf_type ==  RF_1T1R)
1036				PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
1037					     0x001B25A0);
1038
1039			/* 3. issue 3-wire command that RF set to power down. */
1040			PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0);
1041			if (pHalData->rf_type ==  RF_2T2R)
1042				PHY_SetRFReg(Adapter, RF_PATH_B, 0,
1043					     bRFRegOffsetMask, 0);
1044
1045			/*  4. Force PFM , disable SPS18_LDO_Marco_Block */
1046			rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8);
1047
1048			/*  2010/10/13 MH/Isaachsu exchange sequence. */
1049			/* h.	AFE_PLL_CTRL 0x28[7:0] = 0x80
1050				disable AFE PLL */
1051			rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x80);
1052			mdelay(1);
1053
1054			/*  i.	AFE_XTAL_CTRL 0x24[15:0] = 0x880F
1055				gated AFE DIG_CLOCK */
1056			rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0xA80F);
1057		}
1058		break;
1059	default:
1060		break;
1061	}
1062
1063}	/*  phy_PowerSwitch92CU */
1064
1065void _ps_open_RF23a(struct rtw_adapter *padapter)
1066{
1067	/* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */
1068	phy_SsPwrSwitch92CU(padapter, rf_on, 1);
1069}
1070
1071static void CardDisableRTL8723U(struct rtw_adapter *Adapter)
1072{
1073	u8		u1bTmp;
1074
1075	DBG_8723A("CardDisableRTL8723U\n");
1076	/*  USB-MF Card Disable Flow */
1077	/*  1. Run LPS WL RFOFF flow */
1078	HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1079			    PWR_INTF_USB_MSK, rtl8723AU_enter_lps_flow);
1080
1081	/*  2. 0x1F[7:0] = 0		turn off RF */
1082	rtl8723au_write8(Adapter, REG_RF_CTRL, 0x00);
1083
1084	/*	==== Reset digital sequence   ====== */
1085	if ((rtl8723au_read8(Adapter, REG_MCUFWDL) & BIT(7)) &&
1086	    Adapter->bFWReady) /* 8051 RAM code */
1087		rtl8723a_FirmwareSelfReset(Adapter);
1088
1089	/*  Reset MCU. Suggested by Filen. 2011.01.26. by tynli. */
1090	u1bTmp = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN+1);
1091	rtl8723au_write8(Adapter, REG_SYS_FUNC_EN+1, u1bTmp & ~BIT(2));
1092
1093	/*  g.	MCUFWDL 0x80[1:0]= 0		reset MCU ready status */
1094	rtl8723au_write8(Adapter, REG_MCUFWDL, 0x00);
1095
1096	/*	==== Reset digital sequence end ====== */
1097	/*  Card disable power action flow */
1098	HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1099			       PWR_INTF_USB_MSK,
1100			       rtl8723AU_card_disable_flow);
1101
1102	/*  Reset MCU IO Wrapper, added by Roger, 2011.08.30. */
1103	u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
1104	rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp & ~BIT(0));
1105	u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
1106	rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp | BIT(0));
1107
1108	/*  7. RSV_CTRL 0x1C[7:0] = 0x0E  lock ISO/CLK/Power control register */
1109	rtl8723au_write8(Adapter, REG_RSV_CTRL, 0x0e);
1110}
1111
1112int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
1113{
1114	DBG_8723A("==> %s\n", __func__);
1115
1116#ifdef CONFIG_8723AU_BT_COEXIST
1117	BT_HaltProcess(padapter);
1118#endif
1119	/*  2011/02/18 To Fix RU LNA  power leakage problem. We need to
1120	    execute below below in Adapter init and halt sequence.
1121	    According to EEchou's opinion, we can enable the ability for all */
1122	/*  IC. Accord to johnny's opinion, only RU need the support. */
1123	CardDisableRTL8723U(padapter);
1124
1125	padapter->hw_init_completed = false;
1126
1127	return _SUCCESS;
1128}
1129
1130int rtl8723au_inirp_init(struct rtw_adapter *Adapter)
1131{
1132	u8 i;
1133	struct recv_buf *precvbuf;
1134	int status;
1135	struct recv_priv *precvpriv = &Adapter->recvpriv;
1136	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1137
1138	status = _SUCCESS;
1139
1140	RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("===> usb_inirp_init\n"));
1141
1142	/* issue Rx irp to receive data */
1143	precvbuf = (struct recv_buf *)precvpriv->precv_buf;
1144	for (i = 0; i < NR_RECVBUFF; i++) {
1145		if (rtl8723au_read_port(Adapter, RECV_BULK_IN_ADDR, 0,
1146					precvbuf) == _FAIL) {
1147			RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1148				 ("usb_rx_init: usb_read_port error\n"));
1149			status = _FAIL;
1150			goto exit;
1151		}
1152		precvbuf++;
1153	}
1154	if (rtl8723au_read_interrupt(Adapter, RECV_INT_IN_ADDR) == _FAIL) {
1155		RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1156			 ("usb_rx_init: usb_read_interrupt error\n"));
1157		status = _FAIL;
1158	}
1159	pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
1160	MSG_8723A("pHalData->IntrMask = 0x%04x\n", pHalData->IntrMask[0]);
1161	pHalData->IntrMask[0] |= UHIMR_C2HCMD|UHIMR_CPWM;
1162	rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
1163exit:
1164	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1165		 ("<=== usb_inirp_init\n"));
1166	return status;
1167}
1168
1169int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter)
1170{
1171	struct hal_data_8723a	*pHalData = GET_HAL_DATA(Adapter);
1172
1173	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1174		 ("\n ===> usb_rx_deinit\n"));
1175	rtl8723au_read_port_cancel(Adapter);
1176	pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
1177	MSG_8723A("%s pHalData->IntrMask = 0x%04x\n", __func__,
1178		  pHalData->IntrMask[0]);
1179	pHalData->IntrMask[0] = 0x0;
1180	rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
1181	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1182		 ("\n <=== usb_rx_deinit\n"));
1183	return _SUCCESS;
1184}
1185
1186static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent,
1187			   bool AutoloadFail)
1188{
1189	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1190	u8 boardType = BOARD_USB_DONGLE;
1191
1192	if (AutoloadFail) {
1193		if (IS_8723_SERIES(pHalData->VersionID))
1194			pHalData->rf_type = RF_1T1R;
1195		else
1196			pHalData->rf_type = RF_2T2R;
1197		pHalData->BoardType = boardType;
1198		return;
1199	}
1200
1201	boardType = PROMContent[EEPROM_NORMAL_BoardType];
1202	boardType &= BOARD_TYPE_NORMAL_MASK;/* bit[7:5] */
1203	boardType >>= 5;
1204
1205	pHalData->BoardType = boardType;
1206	MSG_8723A("_ReadBoardType(%x)\n", pHalData->BoardType);
1207
1208	if (boardType == BOARD_USB_High_PA)
1209		pHalData->ExternalPA = 1;
1210}
1211
1212static void _ReadLEDSetting(struct rtw_adapter *Adapter, u8 *PROMContent,
1213			    bool AutoloadFail)
1214{
1215	struct led_priv *pledpriv = &Adapter->ledpriv;
1216
1217	pledpriv->LedStrategy = HW_LED;
1218}
1219
1220static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter,
1221					 u8 *hwinfo, bool AutoLoadFail)
1222{
1223	u16 i;
1224	u8 sMacAddr[ETH_ALEN] = {0x00, 0xE0, 0x4C, 0x87, 0x23, 0x00};
1225	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1226
1227	if (AutoLoadFail) {
1228		for (i = 0; i < 6; i++)
1229			pEEPROM->mac_addr[i] = sMacAddr[i];
1230	} else {
1231		/* Read Permanent MAC address */
1232		memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723AU],
1233		       ETH_ALEN);
1234	}
1235
1236	RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1237		 ("Hal_EfuseParseMACAddr_8723AU: Permanent Address =%02x:%02x:"
1238		  "%02x:%02x:%02x:%02x\n",
1239		  pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
1240		  pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
1241		  pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]));
1242}
1243
1244static void readAdapterInfo(struct rtw_adapter *padapter)
1245{
1246	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1247	/* struct hal_data_8723a * pHalData = GET_HAL_DATA(padapter); */
1248	u8 hwinfo[HWSET_MAX_SIZE];
1249
1250	Hal_InitPGData(padapter, hwinfo);
1251	Hal_EfuseParseIDCode(padapter, hwinfo);
1252	Hal_EfuseParseEEPROMVer(padapter, hwinfo,
1253				pEEPROM->bautoload_fail_flag);
1254	Hal_EfuseParseMACAddr_8723AU(padapter, hwinfo,
1255				     pEEPROM->bautoload_fail_flag);
1256	Hal_EfuseParsetxpowerinfo_8723A(padapter, hwinfo,
1257					pEEPROM->bautoload_fail_flag);
1258	_ReadBoardType(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1259	Hal_EfuseParseBTCoexistInfo_8723A(padapter, hwinfo,
1260					  pEEPROM->bautoload_fail_flag);
1261
1262	rtl8723a_EfuseParseChnlPlan(padapter, hwinfo,
1263				    pEEPROM->bautoload_fail_flag);
1264	Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo,
1265					 pEEPROM->bautoload_fail_flag);
1266	_ReadLEDSetting(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1267/*	_ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1268/*	_ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1269	Hal_EfuseParseAntennaDiversity(padapter, hwinfo,
1270				       pEEPROM->bautoload_fail_flag);
1271
1272	Hal_EfuseParseEEPROMVer(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1273	Hal_EfuseParseCustomerID(padapter, hwinfo,
1274				 pEEPROM->bautoload_fail_flag);
1275	Hal_EfuseParseRateIndicationOption(padapter, hwinfo,
1276					   pEEPROM->bautoload_fail_flag);
1277	Hal_EfuseParseXtal_8723A(padapter, hwinfo,
1278				 pEEPROM->bautoload_fail_flag);
1279	/*  */
1280	/*  The following part initialize some vars by PG info. */
1281	/*  */
1282	Hal_InitChannelPlan23a(padapter);
1283
1284	/* hal_CustomizedBehavior_8723U(Adapter); */
1285
1286/*	Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; */
1287	DBG_8723A("%s(): REPLACEMENT = %x\n", __func__, padapter->bDongle);
1288}
1289
1290static void _ReadPROMContent(struct rtw_adapter *Adapter)
1291{
1292	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
1293	u8 eeValue;
1294
1295	eeValue = rtl8723au_read8(Adapter, REG_9346CR);
1296	/*  To check system boot selection. */
1297	pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
1298	pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
1299
1300	DBG_8723A("Boot from %s, Autoload %s !\n",
1301		  (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
1302		  (pEEPROM->bautoload_fail_flag ? "Fail" : "OK"));
1303
1304	readAdapterInfo(Adapter);
1305}
1306
1307static void _ReadRFType(struct rtw_adapter *Adapter)
1308{
1309	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1310
1311	pHalData->rf_chip = RF_6052;
1312}
1313
1314static void _ReadSilmComboMode(struct rtw_adapter *Adapter)
1315{
1316	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1317
1318	pHalData->SlimComboDbg = false;	/*  Default is not debug mode. */
1319}
1320
1321/*  */
1322/*	Description: */
1323/*		We should set Efuse cell selection to WiFi cell in default. */
1324/*  */
1325/*	Assumption: */
1326/*		PASSIVE_LEVEL */
1327/*  */
1328/*	Added by Roger, 2010.11.23. */
1329/*  */
1330static void hal_EfuseCellSel(struct rtw_adapter *Adapter)
1331{
1332	u32 value32;
1333
1334	value32 = rtl8723au_read32(Adapter, EFUSE_TEST);
1335	value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1336	rtl8723au_write32(Adapter, EFUSE_TEST, value32);
1337}
1338
1339void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter)
1340{
1341	unsigned long start = jiffies;
1342
1343	/*  Read EEPROM size before call any EEPROM function */
1344	Adapter->EepromAddressSize = GetEEPROMSize8723A(Adapter);
1345
1346	MSG_8723A("====> _ReadAdapterInfo8723AU\n");
1347
1348	hal_EfuseCellSel(Adapter);
1349
1350	_ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
1351	_ReadPROMContent(Adapter);
1352
1353	/*  2010/10/25 MH THe function must be called after
1354	    borad_type & IC-Version recognize. */
1355	_ReadSilmComboMode(Adapter);
1356
1357	/* MSG_8723A("%s()(done), rf_chip = 0x%x, rf_type = 0x%x\n",
1358	   __func__, pHalData->rf_chip, pHalData->rf_type); */
1359
1360	MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n",
1361		  jiffies_to_msecs(jiffies - start));
1362}
1363
1364/*  */
1365/*	Description: */
1366/*		Query setting of specified variable. */
1367/*  */
1368int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter,
1369			 enum hal_def_variable eVariable, void *pValue)
1370{
1371	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1372	int bResult = _SUCCESS;
1373
1374	switch (eVariable) {
1375	case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
1376		*((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB;
1377		break;
1378	case HAL_DEF_IS_SUPPORT_ANT_DIV:
1379		break;
1380	case HAL_DEF_CURRENT_ANTENNA:
1381		break;
1382	case HAL_DEF_DRVINFO_SZ:
1383		*((u32 *)pValue) = DRVINFO_SZ;
1384		break;
1385	case HAL_DEF_MAX_RECVBUF_SZ:
1386		*((u32 *)pValue) = MAX_RECVBUF_SZ;
1387		break;
1388	case HAL_DEF_RX_PACKET_OFFSET:
1389		*((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ;
1390		break;
1391	case HAL_DEF_DBG_DUMP_RXPKT:
1392		*((u8 *)pValue) = pHalData->bDumpRxPkt;
1393		break;
1394	case HAL_DEF_DBG_DM_FUNC:
1395		*((u32 *)pValue) = pHalData->odmpriv.SupportAbility;
1396		break;
1397	case HW_VAR_MAX_RX_AMPDU_FACTOR:
1398		*((u32 *)pValue) = IEEE80211_HT_MAX_AMPDU_64K;
1399		break;
1400	case HW_DEF_ODM_DBG_FLAG:
1401	{
1402		struct dm_odm_t	*pDM_Odm = &pHalData->odmpriv;
1403		printk("pDM_Odm->DebugComponents = 0x%llx\n",
1404		       pDM_Odm->DebugComponents);
1405	}
1406		break;
1407	default:
1408		/* RT_TRACE(COMP_INIT, DBG_WARNING, ("GetHalDefVar8192CUsb(): "
1409		   "Unkown variable: %d!\n", eVariable)); */
1410		bResult = _FAIL;
1411		break;
1412	}
1413
1414	return bResult;
1415}
1416
1417void rtl8723a_update_ramask(struct rtw_adapter *padapter,
1418			    u32 mac_id, u8 rssi_level)
1419{
1420	u8	init_rate = 0;
1421	u8	networkType, raid;
1422	u32	mask, rate_bitmap;
1423	u8	shortGIrate = false;
1424	int	supportRateNum = 0;
1425	struct sta_info	*psta;
1426	struct hal_data_8723a	*pHalData = GET_HAL_DATA(padapter);
1427	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
1428	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1429	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1430	struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1431
1432	if (mac_id >= NUM_STA) /* CAM_SIZE */
1433		return;
1434
1435	psta = pmlmeinfo->FW_sta_info[mac_id].psta;
1436	if (psta == NULL)
1437		return;
1438
1439	switch (mac_id) {
1440	case 0:/*  for infra mode */
1441		supportRateNum =
1442			rtw_get_rateset_len23a(cur_network->SupportedRates);
1443		networkType = judge_network_type23a(padapter,
1444						 cur_network->SupportedRates,
1445						 supportRateNum) & 0xf;
1446		/* pmlmeext->cur_wireless_mode = networkType; */
1447		raid = networktype_to_raid23a(networkType);
1448
1449		mask = update_supported_rate23a(cur_network->SupportedRates,
1450					     supportRateNum);
1451		mask |= (pmlmeinfo->HT_enable) ?
1452			update_MSC_rate23a(&pmlmeinfo->ht_cap) : 0;
1453
1454		if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
1455			shortGIrate = true;
1456		break;
1457
1458	case 1:/* for broadcast/multicast */
1459		supportRateNum = rtw_get_rateset_len23a(
1460			pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
1461		if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
1462			networkType = WIRELESS_11B;
1463		else
1464			networkType = WIRELESS_11G;
1465		raid = networktype_to_raid23a(networkType);
1466
1467		mask = update_basic_rate23a(cur_network->SupportedRates,
1468					 supportRateNum);
1469		break;
1470
1471	default: /* for each sta in IBSS */
1472		supportRateNum = rtw_get_rateset_len23a(
1473			pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
1474		networkType = judge_network_type23a(padapter,
1475						 pmlmeinfo->FW_sta_info[mac_id].SupportedRates,
1476						 supportRateNum) & 0xf;
1477		/* pmlmeext->cur_wireless_mode = networkType; */
1478		raid = networktype_to_raid23a(networkType);
1479
1480		mask = update_supported_rate23a(cur_network->SupportedRates,
1481					     supportRateNum);
1482
1483		/* todo: support HT in IBSS */
1484		break;
1485	}
1486
1487	/* mask &= 0x0fffffff; */
1488	rate_bitmap = 0x0fffffff;
1489	rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask,
1490					     rssi_level);
1491	DBG_8723A("%s => mac_id:%d, networkType:0x%02x, "
1492		  "mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
1493		  __func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
1494
1495	mask &= rate_bitmap;
1496	mask |= ((raid<<28)&0xf0000000);
1497
1498	init_rate = get_highest_rate_idx23a(mask)&0x3f;
1499
1500	if (pHalData->fw_ractrl == true) {
1501		u8 arg = 0;
1502
1503		/* arg = (cam_idx-4)&0x1f;MACID */
1504		arg = mac_id&0x1f;/* MACID */
1505
1506		arg |= BIT(7);
1507
1508		if (shortGIrate == true)
1509			arg |= BIT(5);
1510
1511		DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n",
1512			  mask, arg);
1513
1514		rtl8723a_set_raid_cmd(padapter, mask, arg);
1515	} else {
1516		if (shortGIrate == true)
1517			init_rate |= BIT(6);
1518
1519		rtl8723au_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id),
1520				 init_rate);
1521	}
1522
1523	/* set ra_id */
1524	psta->raid = raid;
1525	psta->init_rate = init_rate;
1526
1527	/* set correct initial date rate for each mac_id */
1528	pdmpriv->INIDATA_RATE[mac_id] = init_rate;
1529}
1530