• 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  ******************************************************************************/
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 
29 static void
_ConfigChipOutEP(struct rtw_adapter * pAdapter,u8 NumOutPipe)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 
rtl8723au_set_queue_pipe_mapping(struct rtw_adapter * pAdapter,u8 NumInPipe,u8 NumOutPipe)64 static 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 
rtl8723au_chip_configure(struct rtw_adapter * padapter)83 void 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 
_InitPowerOn(struct rtw_adapter * padapter)95 static 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? */
_InitInterrupt(struct rtw_adapter * Adapter)130 static 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 
_InitQueueReservedPage(struct rtw_adapter * Adapter)142 static 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 
_InitTxBufferBoundary(struct rtw_adapter * Adapter)182 static 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 
_InitPageBoundary(struct rtw_adapter * Adapter)200 static 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 
211 static void
_InitNormalChipRegPriority(struct rtw_adapter * Adapter,u16 beQ,u16 bkQ,u16 viQ,u16 voQ,u16 mgtQ,u16 hiQ)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 
_InitNormalChipOneOutEpPriority(struct rtw_adapter * Adapter)224 static 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 
_InitNormalChipTwoOutEpPriority(struct rtw_adapter * Adapter)248 static 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 
_InitNormalChipThreeOutEpPriority(struct rtw_adapter * Adapter)293 static 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 
_InitNormalChipQueuePriority(struct rtw_adapter * Adapter)316 static 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 
_InitQueuePriority(struct rtw_adapter * Adapter)336 static void _InitQueuePriority(struct rtw_adapter *Adapter)
337 {
338 	_InitNormalChipQueuePriority(Adapter);
339 }
340 
_InitTransferPageSize(struct rtw_adapter * Adapter)341 static 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 
_InitDriverInfoSize(struct rtw_adapter * Adapter,u8 drvInfoSize)350 static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
351 {
352 	rtl8723au_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
353 }
354 
_InitWMACSetting(struct rtw_adapter * Adapter)355 static 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 
_InitAdaptiveCtrl(struct rtw_adapter * Adapter)394 static 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 
_InitRateFallback(struct rtw_adapter * Adapter)417 static 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 
_InitEDCA(struct rtw_adapter * Adapter)426 static 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 
_InitHWLed(struct rtw_adapter * Adapter)445 static 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 
_InitRDGSetting(struct rtw_adapter * Adapter)457 static 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 
_InitRetryFunction(struct rtw_adapter * Adapter)464 static 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 
_InitRFType(struct rtw_adapter * Adapter)476 static 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" */
_BBTurnOnBlock(struct rtw_adapter * Adapter)498 static 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(...)
_RfPowerSave(struct rtw_adapter * padapter)505 static void _RfPowerSave(struct rtw_adapter *padapter)
506 {
507 }
508 
509 enum {
510 	Antenna_Lfet = 1,
511 	Antenna_Right = 2,
512 };
513 
RfOnOffDetect23a(struct rtw_adapter * pAdapter)514 enum 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 
530 void _ps_open_RF23a(struct rtw_adapter *padapter);
531 
rtl8723au_hal_init(struct rtw_adapter * Adapter)532 int 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 
795 exit:
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 
phy_SsPwrSwitch92CU(struct rtw_adapter * Adapter,enum rt_rf_power_state eRFPowerState,int bRegSSPwrLvl)808 static 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 
_ps_open_RF23a(struct rtw_adapter * padapter)1065 void _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 
CardDisableRTL8723U(struct rtw_adapter * Adapter)1071 static 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 
rtl8723au_hal_deinit(struct rtw_adapter * padapter)1112 int 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 
rtl8723au_inirp_init(struct rtw_adapter * Adapter)1130 int 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]);
1163 exit:
1164 	RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1165 		 ("<=== usb_inirp_init\n"));
1166 	return status;
1167 }
1168 
rtl8723au_inirp_deinit(struct rtw_adapter * Adapter)1169 int 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 
_ReadBoardType(struct rtw_adapter * Adapter,u8 * PROMContent,bool AutoloadFail)1186 static 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 
_ReadLEDSetting(struct rtw_adapter * Adapter,u8 * PROMContent,bool AutoloadFail)1212 static 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 
Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter * padapter,u8 * hwinfo,bool AutoLoadFail)1220 static 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 
readAdapterInfo(struct rtw_adapter * padapter)1244 static 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 
_ReadPROMContent(struct rtw_adapter * Adapter)1290 static 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 
_ReadRFType(struct rtw_adapter * Adapter)1307 static 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 
_ReadSilmComboMode(struct rtw_adapter * Adapter)1314 static 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 /*  */
hal_EfuseCellSel(struct rtw_adapter * Adapter)1330 static 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 
rtl8723a_read_adapter_info(struct rtw_adapter * Adapter)1339 void 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 /*  */
GetHalDefVar8192CUsb(struct rtw_adapter * Adapter,enum hal_def_variable eVariable,void * pValue)1368 int 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 
rtl8723a_update_ramask(struct rtw_adapter * padapter,u32 mac_id,u8 rssi_level)1417 void 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