OSDN Git Service

staging: rtl8723bs: update to the latest driver
[android-x86/kernel.git] / drivers / staging / rtl8723bs / hal / sdio_halinit.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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 _SDIO_HALINIT_C_
16
17 #include <drv_types.h>
18 #include <rtw_debug.h>
19 #include <rtl8723b_hal.h>
20
21 #include "hal_com_h2c.h"
22 /*
23  * Description:
24  *Call power on sequence to enable card
25  *
26  * Return:
27  *_SUCCESS      enable success
28  *_FAIL         enable fail
29  */
30 static u8 CardEnable(struct adapter *padapter)
31 {
32         u8 bMacPwrCtrlOn;
33         u8 ret = _FAIL;
34
35
36         rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
37         if (bMacPwrCtrlOn == false)
38         {
39                 /*  RSV_CTRL 0x1C[7:0] = 0x00 */
40                 /*  unlock ISO/CLK/Power control register */
41                 rtw_write8(padapter, REG_RSV_CTRL, 0x0);
42
43                 ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8723B_card_enable_flow);
44                 if (ret == _SUCCESS) {
45                         u8 bMacPwrCtrlOn = true;
46                         rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
47                 }
48         } else
49                 ret = _SUCCESS;
50
51         return ret;
52 }
53
54 #ifdef CONFIG_GPIO_WAKEUP
55 /* we set it high under init and fw will */
56 /* give us Low Pulse when host wake up */
57 void HostWakeUpGpioClear(struct adapter * Adapter)
58 {
59         u32 value32;
60
61         value32 = rtw_read32(Adapter, REG_GPIO_PIN_CTRL_2);
62
63         /* set GPIO 12 1 */
64         value32 |= BIT(12);/* 4+8 */
65         /* GPIO 12 out put */
66         value32 |= BIT(20);/* 4+16 */
67
68         rtw_write32(Adapter, REG_GPIO_PIN_CTRL_2, value32);
69 } /* HostWakeUpGpioClear */
70
71 void HalSetOutPutGPIO(struct adapter *padapter, u8 index, u8 OutPutValue)
72 {
73         if (index <= 7) {
74                 /* config GPIO mode */
75                 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 3, rtw_read8(padapter, REG_GPIO_PIN_CTRL + 3) & ~BIT(index));
76
77                 /* config GPIO Sel */
78                 /* 0: input */
79                 /* 1: output */
80                 rtw_write8(padapter, REG_GPIO_PIN_CTRL + 2, rtw_read8(padapter, REG_GPIO_PIN_CTRL + 2) | BIT(index));
81
82                 /* set output value */
83                 if (OutPutValue) {
84                         rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) | BIT(index));
85                 } else {
86                         rtw_write8(padapter, REG_GPIO_PIN_CTRL + 1, rtw_read8(padapter, REG_GPIO_PIN_CTRL + 1) & ~BIT(index));
87                 }
88         } else {
89                 /* 88C Series: */
90                 /* index: 11~8 transform to 3~0 */
91                 /* 8723 Series: */
92                 /* index: 12~8 transform to 4~0 */
93                 index -= 8;
94
95                 /* config GPIO mode */
96                 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 3, rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 3) & ~BIT(index));
97
98                 /* config GPIO Sel */
99                 /* 0: input */
100                 /* 1: output */
101                 rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 2, rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 2) | BIT(index));
102
103                 /* set output value */
104                 if (OutPutValue) {
105                         rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1, rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) | BIT(index));
106                 } else {
107                         rtw_write8(padapter, REG_GPIO_PIN_CTRL_2 + 1, rtw_read8(padapter, REG_GPIO_PIN_CTRL_2 + 1) & ~BIT(index));
108                 }
109         }
110 }
111 #endif
112
113 static
114 u8 _InitPowerOn_8723BS(struct adapter *padapter)
115 {
116         u8 value8;
117         u16 value16;
118         u32 value32;
119         u8 ret;
120 /*      u8 bMacPwrCtrlOn; */
121
122
123         /*  all of these MUST be configured before power on */
124 #ifdef CONFIG_EXT_CLK
125         /*  Use external crystal(XTAL) */
126         value8 = rtw_read8(padapter, REG_PAD_CTRL1_8723B+2);
127         value8 |=  BIT(7);
128         rtw_write8(padapter, REG_PAD_CTRL1_8723B+2, value8);
129
130         /*  CLK_REQ High active or Low Active */
131         /*  Request GPIO polarity: */
132         /*  0: low active */
133         /*  1: high active */
134         value8 = rtw_read8(padapter, REG_MULTI_FUNC_CTRL+1);
135         value8 |= BIT(5);
136         rtw_write8(padapter, REG_MULTI_FUNC_CTRL+1, value8);
137 #endif /*  CONFIG_EXT_CLK */
138
139         /*  only cmd52 can be used before power on(card enable) */
140         ret = CardEnable(padapter);
141         if (ret == false) {
142                 RT_TRACE(_module_hci_hal_init_c_, _drv_emerg_,
143                                 ("%s: run power on flow fail\n", __func__));
144                 return _FAIL;
145         }
146
147         /*  Radio-Off Pin Trigger */
148         value8 = rtw_read8(padapter, REG_GPIO_INTM+1);
149         value8 |= BIT(1); /*  Enable falling edge triggering interrupt */
150         rtw_write8(padapter, REG_GPIO_INTM+1, value8);
151         value8 = rtw_read8(padapter, REG_GPIO_IO_SEL_2+1);
152         value8 |= BIT(1);
153         rtw_write8(padapter, REG_GPIO_IO_SEL_2+1, value8);
154
155         /*  Enable power down and GPIO interrupt */
156         value16 = rtw_read16(padapter, REG_APS_FSMCO);
157         value16 |= EnPDN; /*  Enable HW power down and RF on */
158         rtw_write16(padapter, REG_APS_FSMCO, value16);
159
160         /*  Enable CMD53 R/W Operation */
161 /*      bMacPwrCtrlOn = true; */
162 /*      rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); */
163
164         rtw_write8(padapter, REG_CR, 0x00);
165         /*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
166         value16 = rtw_read16(padapter, REG_CR);
167         value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
168                                 | PROTOCOL_EN | SCHEDULE_EN | ENSEC | CALTMR_EN);
169         rtw_write16(padapter, REG_CR, value16);
170
171         rtw_btcoex_PowerOnSetting(padapter);
172
173         /*  external switch to S1 */
174         /*  0x38[11] = 0x1 */
175         /*  0x4c[23] = 0x1 */
176         /*  0x64[0] = 0 */
177         value16 = rtw_read16(padapter, REG_PWR_DATA);
178         /*  Switch the control of EESK, EECS to RFC for DPDT or Antenna switch */
179         value16 |= BIT(11); /*  BIT_EEPRPAD_RFE_CTRL_EN */
180         rtw_write16(padapter, REG_PWR_DATA, value16);
181 /*      DBG_8192C("%s: REG_PWR_DATA(0x%x) = 0x%04X\n", __func__, REG_PWR_DATA, rtw_read16(padapter, REG_PWR_DATA)); */
182
183         value32 = rtw_read32(padapter, REG_LEDCFG0);
184         value32 |= BIT(23); /*  DPDT_SEL_EN, 1 for SW control */
185         rtw_write32(padapter, REG_LEDCFG0, value32);
186 /*      DBG_8192C("%s: REG_LEDCFG0(0x%x) = 0x%08X\n", __func__, REG_LEDCFG0, rtw_read32(padapter, REG_LEDCFG0)); */
187
188         value8 = rtw_read8(padapter, REG_PAD_CTRL1_8723B);
189         value8 &= ~BIT(0); /*  BIT_SW_DPDT_SEL_DATA, DPDT_SEL default configuration */
190         rtw_write8(padapter, REG_PAD_CTRL1_8723B, value8);
191 /*      DBG_8192C("%s: REG_PAD_CTRL1(0x%x) = 0x%02X\n", __func__, REG_PAD_CTRL1_8723B, rtw_read8(padapter, REG_PAD_CTRL1_8723B)); */
192
193 #ifdef CONFIG_GPIO_WAKEUP
194         HostWakeUpGpioClear(padapter);
195 #endif
196
197         return _SUCCESS;
198 }
199
200 /* Tx Page FIFO threshold */
201 static void _init_available_page_threshold(struct adapter *padapter, u8 numHQ, u8 numNQ, u8 numLQ, u8 numPubQ)
202 {
203         u16 HQ_threshold, NQ_threshold, LQ_threshold;
204
205         HQ_threshold = (numPubQ + numHQ + 1) >> 1;
206         HQ_threshold |= (HQ_threshold<<8);
207
208         NQ_threshold = (numPubQ + numNQ + 1) >> 1;
209         NQ_threshold |= (NQ_threshold<<8);
210
211         LQ_threshold = (numPubQ + numLQ + 1) >> 1;
212         LQ_threshold |= (LQ_threshold<<8);
213
214         rtw_write16(padapter, 0x218, HQ_threshold);
215         rtw_write16(padapter, 0x21A, NQ_threshold);
216         rtw_write16(padapter, 0x21C, LQ_threshold);
217         DBG_8192C("%s(): Enable Tx FIFO Page Threshold H:0x%x, N:0x%x, L:0x%x\n", __func__, HQ_threshold, NQ_threshold, LQ_threshold);
218 }
219
220 static void _InitQueueReservedPage(struct adapter *padapter)
221 {
222         struct hal_com_data             *pHalData = GET_HAL_DATA(padapter);
223         struct registry_priv *pregistrypriv = &padapter->registrypriv;
224         u32             numHQ           = 0;
225         u32             numLQ           = 0;
226         u32             numNQ           = 0;
227         u32             numPubQ;
228         u32             value32;
229         u8      value8;
230         bool                    bWiFiConfig     = pregistrypriv->wifi_spec;
231
232         if (pHalData->OutEpQueueSel & TX_SELE_HQ)
233         {
234                 numHQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_HPQ_8723B : NORMAL_PAGE_NUM_HPQ_8723B;
235         }
236
237         if (pHalData->OutEpQueueSel & TX_SELE_LQ)
238         {
239                 numLQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_LPQ_8723B : NORMAL_PAGE_NUM_LPQ_8723B;
240         }
241
242         /*  NOTE: This step shall be proceed before writting REG_RQPN. */
243         if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
244                 numNQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_NPQ_8723B : NORMAL_PAGE_NUM_NPQ_8723B;
245         }
246
247         numPubQ = TX_TOTAL_PAGE_NUMBER_8723B - numHQ - numLQ - numNQ;
248
249         value8 = (u8)_NPQ(numNQ);
250         rtw_write8(padapter, REG_RQPN_NPQ, value8);
251
252         /*  TX DMA */
253         value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
254         rtw_write32(padapter, REG_RQPN, value32);
255
256         rtw_hal_set_sdio_tx_max_length(padapter, numHQ, numNQ, numLQ, numPubQ);
257
258         _init_available_page_threshold(padapter, numHQ, numNQ, numLQ, numPubQ);
259 }
260
261 static void _InitTxBufferBoundary(struct adapter *padapter)
262 {
263         struct registry_priv *pregistrypriv = &padapter->registrypriv;
264
265         /* u16 txdmactrl; */
266         u8 txpktbuf_bndy;
267
268         if (!pregistrypriv->wifi_spec) {
269                 txpktbuf_bndy = TX_PAGE_BOUNDARY_8723B;
270         } else {
271                 /* for WMM */
272                 txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
273         }
274
275         rtw_write8(padapter, REG_TXPKTBUF_BCNQ_BDNY_8723B, txpktbuf_bndy);
276         rtw_write8(padapter, REG_TXPKTBUF_MGQ_BDNY_8723B, txpktbuf_bndy);
277         rtw_write8(padapter, REG_TXPKTBUF_WMAC_LBK_BF_HD_8723B, txpktbuf_bndy);
278         rtw_write8(padapter, REG_TRXFF_BNDY, txpktbuf_bndy);
279         rtw_write8(padapter, REG_TDECTRL+1, txpktbuf_bndy);
280 }
281
282 static void
283 _InitNormalChipRegPriority(
284 struct adapter *Adapter,
285 u16     beQ,
286 u16     bkQ,
287 u16     viQ,
288 u16     voQ,
289 u16     mgtQ,
290 u16     hiQ
291         )
292 {
293         u16 value16             = (rtw_read16(Adapter, REG_TRXDMA_CTRL) & 0x7);
294
295         value16 |=      _TXDMA_BEQ_MAP(beQ)     | _TXDMA_BKQ_MAP(bkQ) |
296                                 _TXDMA_VIQ_MAP(viQ)     | _TXDMA_VOQ_MAP(voQ) |
297                                 _TXDMA_MGQ_MAP(mgtQ)| _TXDMA_HIQ_MAP(hiQ);
298
299         rtw_write16(Adapter, REG_TRXDMA_CTRL, value16);
300 }
301
302 static void
303 _InitNormalChipOneOutEpPriority(
304 struct adapter * Adapter
305         )
306 {
307         struct hal_com_data     *pHalData       = GET_HAL_DATA(Adapter);
308
309         u16 value = 0;
310         switch (pHalData->OutEpQueueSel)
311         {
312                 case TX_SELE_HQ:
313                         value = QUEUE_HIGH;
314                         break;
315                 case TX_SELE_LQ:
316                         value = QUEUE_LOW;
317                         break;
318                 case TX_SELE_NQ:
319                         value = QUEUE_NORMAL;
320                         break;
321                 default:
322                         /* RT_ASSERT(false, ("Shall not reach here!\n")); */
323                         break;
324         }
325
326         _InitNormalChipRegPriority(Adapter,
327                                                                 value,
328                                                                 value,
329                                                                 value,
330                                                                 value,
331                                                                 value,
332                                                                 value
333                                                                 );
334
335 }
336
337 static void
338 _InitNormalChipTwoOutEpPriority(
339 struct adapter * Adapter
340         )
341 {
342         struct hal_com_data     *pHalData       = GET_HAL_DATA(Adapter);
343         struct registry_priv *pregistrypriv = &Adapter->registrypriv;
344         u16             beQ, bkQ, viQ, voQ, mgtQ, hiQ;
345
346
347         u16 valueHi = 0;
348         u16 valueLow = 0;
349
350         switch (pHalData->OutEpQueueSel)
351         {
352                 case (TX_SELE_HQ | TX_SELE_LQ):
353                         valueHi = QUEUE_HIGH;
354                         valueLow = QUEUE_LOW;
355                         break;
356                 case (TX_SELE_NQ | TX_SELE_LQ):
357                         valueHi = QUEUE_NORMAL;
358                         valueLow = QUEUE_LOW;
359                         break;
360                 case (TX_SELE_HQ | TX_SELE_NQ):
361                         valueHi = QUEUE_HIGH;
362                         valueLow = QUEUE_NORMAL;
363                         break;
364                 default:
365                         /* RT_ASSERT(false, ("Shall not reach here!\n")); */
366                         break;
367         }
368
369         if (!pregistrypriv->wifi_spec) {
370                 beQ             = valueLow;
371                 bkQ             = valueLow;
372                 viQ             = valueHi;
373                 voQ             = valueHi;
374                 mgtQ    = valueHi;
375                 hiQ             = valueHi;
376         }
377         else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */
378                 beQ             = valueLow;
379                 bkQ             = valueHi;
380                 viQ             = valueHi;
381                 voQ             = valueLow;
382                 mgtQ    = valueHi;
383                 hiQ             = valueHi;
384         }
385
386         _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
387
388 }
389
390 static void
391 _InitNormalChipThreeOutEpPriority(
392 struct adapter *padapter
393         )
394 {
395         struct registry_priv *pregistrypriv = &padapter->registrypriv;
396         u16             beQ, bkQ, viQ, voQ, mgtQ, hiQ;
397
398         if (!pregistrypriv->wifi_spec) {/*  typical setting */
399                 beQ             = QUEUE_LOW;
400                 bkQ             = QUEUE_LOW;
401                 viQ             = QUEUE_NORMAL;
402                 voQ             = QUEUE_HIGH;
403                 mgtQ    = QUEUE_HIGH;
404                 hiQ             = QUEUE_HIGH;
405         }
406         else {/*  for WMM */
407                 beQ             = QUEUE_LOW;
408                 bkQ             = QUEUE_NORMAL;
409                 viQ             = QUEUE_NORMAL;
410                 voQ             = QUEUE_HIGH;
411                 mgtQ    = QUEUE_HIGH;
412                 hiQ             = QUEUE_HIGH;
413         }
414         _InitNormalChipRegPriority(padapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
415 }
416
417 static void
418 _InitNormalChipQueuePriority(
419 struct adapter * Adapter
420         )
421 {
422         struct hal_com_data     *pHalData       = GET_HAL_DATA(Adapter);
423
424         switch (pHalData->OutEpNumber)
425         {
426                 case 1:
427                         _InitNormalChipOneOutEpPriority(Adapter);
428                         break;
429                 case 2:
430                         _InitNormalChipTwoOutEpPriority(Adapter);
431                         break;
432                 case 3:
433                         _InitNormalChipThreeOutEpPriority(Adapter);
434                         break;
435                 default:
436                         /* RT_ASSERT(false, ("Shall not reach here!\n")); */
437                         break;
438         }
439
440
441 }
442
443 static void _InitQueuePriority(struct adapter *padapter)
444 {
445         _InitNormalChipQueuePriority(padapter);
446 }
447
448 static void _InitPageBoundary(struct adapter *padapter)
449 {
450         /*  RX Page Boundary */
451         u16 rxff_bndy = RX_DMA_BOUNDARY_8723B;
452
453         rtw_write16(padapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
454 }
455
456 static void _InitTransferPageSize(struct adapter *padapter)
457 {
458         /*  Tx page size is always 128. */
459
460         u8 value8;
461         value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
462         rtw_write8(padapter, REG_PBP, value8);
463 }
464
465 static void _InitDriverInfoSize(struct adapter *padapter, u8 drvInfoSize)
466 {
467         rtw_write8(padapter, REG_RX_DRVINFO_SZ, drvInfoSize);
468 }
469
470 static void _InitNetworkType(struct adapter *padapter)
471 {
472         u32 value32;
473
474         value32 = rtw_read32(padapter, REG_CR);
475
476         /*  TODO: use the other function to set network type */
477 /*      value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AD_HOC); */
478         value32 = (value32 & ~MASK_NETTYPE) | _NETTYPE(NT_LINK_AP);
479
480         rtw_write32(padapter, REG_CR, value32);
481 }
482
483 static void _InitWMACSetting(struct adapter *padapter)
484 {
485         struct hal_com_data *pHalData;
486         u16 value16;
487
488
489         pHalData = GET_HAL_DATA(padapter);
490
491         pHalData->ReceiveConfig = 0;
492         pHalData->ReceiveConfig |= RCR_APM | RCR_AM | RCR_AB;
493         pHalData->ReceiveConfig |= RCR_CBSSID_DATA | RCR_CBSSID_BCN | RCR_AMF;
494         pHalData->ReceiveConfig |= RCR_HTC_LOC_CTRL;
495         pHalData->ReceiveConfig |= RCR_APP_PHYST_RXFF | RCR_APP_ICV | RCR_APP_MIC;
496         rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
497
498         /*  Accept all multicast address */
499         rtw_write32(padapter, REG_MAR, 0xFFFFFFFF);
500         rtw_write32(padapter, REG_MAR + 4, 0xFFFFFFFF);
501
502         /*  Accept all data frames */
503         value16 = 0xFFFF;
504         rtw_write16(padapter, REG_RXFLTMAP2, value16);
505
506         /*  2010.09.08 hpfan */
507         /*  Since ADF is removed from RCR, ps-poll will not be indicate to driver, */
508         /*  RxFilterMap should mask ps-poll to gurantee AP mode can rx ps-poll. */
509         value16 = 0x400;
510         rtw_write16(padapter, REG_RXFLTMAP1, value16);
511
512         /*  Accept all management frames */
513         value16 = 0xFFFF;
514         rtw_write16(padapter, REG_RXFLTMAP0, value16);
515 }
516
517 static void _InitAdaptiveCtrl(struct adapter *padapter)
518 {
519         u16 value16;
520         u32 value32;
521
522         /*  Response Rate Set */
523         value32 = rtw_read32(padapter, REG_RRSR);
524         value32 &= ~RATE_BITMAP_ALL;
525         value32 |= RATE_RRSR_CCK_ONLY_1M;
526         rtw_write32(padapter, REG_RRSR, value32);
527
528         /*  CF-END Threshold */
529         /* m_spIoBase->rtw_write8(REG_CFEND_TH, 0x1); */
530
531         /*  SIFS (used in NAV) */
532         value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
533         rtw_write16(padapter, REG_SPEC_SIFS, value16);
534
535         /*  Retry Limit */
536         value16 = _LRL(0x30) | _SRL(0x30);
537         rtw_write16(padapter, REG_RL, value16);
538 }
539
540 static void _InitEDCA(struct adapter *padapter)
541 {
542         /*  Set Spec SIFS (used in NAV) */
543         rtw_write16(padapter, REG_SPEC_SIFS, 0x100a);
544         rtw_write16(padapter, REG_MAC_SPEC_SIFS, 0x100a);
545
546         /*  Set SIFS for CCK */
547         rtw_write16(padapter, REG_SIFS_CTX, 0x100a);
548
549         /*  Set SIFS for OFDM */
550         rtw_write16(padapter, REG_SIFS_TRX, 0x100a);
551
552         /*  TXOP */
553         rtw_write32(padapter, REG_EDCA_BE_PARAM, 0x005EA42B);
554         rtw_write32(padapter, REG_EDCA_BK_PARAM, 0x0000A44F);
555         rtw_write32(padapter, REG_EDCA_VI_PARAM, 0x005EA324);
556         rtw_write32(padapter, REG_EDCA_VO_PARAM, 0x002FA226);
557 }
558
559 static void _InitRetryFunction(struct adapter *padapter)
560 {
561         u8 value8;
562
563         value8 = rtw_read8(padapter, REG_FWHW_TXQ_CTRL);
564         value8 |= EN_AMPDU_RTY_NEW;
565         rtw_write8(padapter, REG_FWHW_TXQ_CTRL, value8);
566
567         /*  Set ACK timeout */
568         rtw_write8(padapter, REG_ACKTO, 0x40);
569 }
570
571 static void HalRxAggr8723BSdio(struct adapter *padapter)
572 {
573         struct registry_priv *pregistrypriv;
574         u8 valueDMATimeout;
575         u8 valueDMAPageCount;
576
577
578         pregistrypriv = &padapter->registrypriv;
579
580         if (pregistrypriv->wifi_spec)
581         {
582                 /*  2010.04.27 hpfan */
583                 /*  Adjust RxAggrTimeout to close to zero disable RxAggr, suggested by designer */
584                 /*  Timeout value is calculated by 34 / (2^n) */
585                 valueDMATimeout = 0x06;
586                 valueDMAPageCount = 0x06;
587         }
588         else
589         {
590                 /*  20130530, Isaac@SD1 suggest 3 kinds of parameter */
591                 /*  TX/RX Balance */
592                 valueDMATimeout = 0x06;
593                 valueDMAPageCount = 0x06;
594         }
595
596         rtw_write8(padapter, REG_RXDMA_AGG_PG_TH+1, valueDMATimeout);
597         rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, valueDMAPageCount);
598 }
599
600 static void sdio_AggSettingRxUpdate(struct adapter *padapter)
601 {
602         struct hal_com_data *pHalData;
603         u8 valueDMA;
604         u8 valueRxAggCtrl = 0;
605         u8 aggBurstNum = 3;  /* 0:1, 1:2, 2:3, 3:4 */
606         u8 aggBurstSize = 0;  /* 0:1K, 1:512Byte, 2:256Byte... */
607
608         pHalData = GET_HAL_DATA(padapter);
609
610         valueDMA = rtw_read8(padapter, REG_TRXDMA_CTRL);
611         valueDMA |= RXDMA_AGG_EN;
612         rtw_write8(padapter, REG_TRXDMA_CTRL, valueDMA);
613
614         valueRxAggCtrl |= RXDMA_AGG_MODE_EN;
615         valueRxAggCtrl |= ((aggBurstNum<<2) & 0x0C);
616         valueRxAggCtrl |= ((aggBurstSize<<4) & 0x30);
617         rtw_write8(padapter, REG_RXDMA_MODE_CTRL_8723B, valueRxAggCtrl);/* RxAggLowThresh = 4*1K */
618 }
619
620 static void _initSdioAggregationSetting(struct adapter *padapter)
621 {
622         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
623
624         /*  Tx aggregation setting */
625 /*      sdio_AggSettingTxUpdate(padapter); */
626
627         /*  Rx aggregation setting */
628         HalRxAggr8723BSdio(padapter);
629
630         sdio_AggSettingRxUpdate(padapter);
631
632         /*  201/12/10 MH Add for USB agg mode dynamic switch. */
633         pHalData->UsbRxHighSpeedMode = false;
634 }
635
636 static void _InitOperationMode(struct adapter *padapter)
637 {
638         struct hal_com_data *pHalData;
639         struct mlme_ext_priv *pmlmeext;
640         u8              regBwOpMode = 0;
641         u32                     regRATR = 0, regRRSR = 0;
642
643         pHalData = GET_HAL_DATA(padapter);
644         pmlmeext = &padapter->mlmeextpriv;
645
646         /* 1 This part need to modified according to the rate set we filtered!! */
647         /*  */
648         /*  Set RRSR, RATR, and REG_BWOPMODE registers */
649         /*  */
650         switch (pmlmeext->cur_wireless_mode)
651         {
652                 case WIRELESS_MODE_B:
653                         regBwOpMode = BW_OPMODE_20MHZ;
654                         regRATR = RATE_ALL_CCK;
655                         regRRSR = RATE_ALL_CCK;
656                         break;
657                 case WIRELESS_MODE_A:
658 /*                      RT_ASSERT(false, ("Error wireless a mode\n")); */
659                         break;
660                 case WIRELESS_MODE_G:
661                         regBwOpMode = BW_OPMODE_20MHZ;
662                         regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
663                         regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
664                         break;
665                 case WIRELESS_MODE_AUTO:
666                         regBwOpMode = BW_OPMODE_20MHZ;
667                         regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
668                         regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
669                         break;
670                 case WIRELESS_MODE_N_24G:
671                         /*  It support CCK rate by default. */
672                         /*  CCK rate will be filtered out only when associated AP does not support it. */
673                         regBwOpMode = BW_OPMODE_20MHZ;
674                         regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
675                         regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
676                         break;
677                 case WIRELESS_MODE_N_5G:
678 /*                      RT_ASSERT(false, ("Error wireless mode")); */
679                         regBwOpMode = BW_OPMODE_5G;
680                         regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
681                         regRRSR = RATE_ALL_OFDM_AG;
682                         break;
683
684                 default: /* for MacOSX compiler warning. */
685                         break;
686         }
687
688         rtw_write8(padapter, REG_BWOPMODE, regBwOpMode);
689
690 }
691
692 static void _InitInterrupt(struct adapter *padapter)
693 {
694         /*  HISR - turn all off */
695         rtw_write32(padapter, REG_HISR, 0);
696
697         /*  HIMR - turn all off */
698         rtw_write32(padapter, REG_HIMR, 0);
699
700         /*  */
701         /*  Initialize and enable SDIO Host Interrupt. */
702         /*  */
703         InitInterrupt8723BSdio(padapter);
704
705         /*  */
706         /*  Initialize system Host Interrupt. */
707         /*  */
708         InitSysInterrupt8723BSdio(padapter);
709 }
710
711 static void _InitRFType(struct adapter *padapter)
712 {
713         struct hal_com_data *pHalData = GET_HAL_DATA(padapter);
714
715 #if     DISABLE_BB_RF
716         pHalData->rf_chip       = RF_PSEUDO_11N;
717         return;
718 #endif
719
720         pHalData->rf_chip       = RF_6052;
721
722         pHalData->rf_type = RF_1T1R;
723         DBG_8192C("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n");
724 }
725
726 static void _RfPowerSave(struct adapter *padapter)
727 {
728 /* YJ, TODO */
729 }
730
731 /*  */
732 /*  2010/08/09 MH Add for power down check. */
733 /*  */
734 static bool HalDetectPwrDownMode(struct adapter * Adapter)
735 {
736         u8 tmpvalue;
737         struct hal_com_data *pHalData = GET_HAL_DATA(Adapter);
738         struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(Adapter);
739
740
741         EFUSE_ShadowRead(Adapter, 1, 0x7B/*EEPROM_RF_OPT3_92C*/, (u32 *)&tmpvalue);
742
743         /*  2010/08/25 MH INF priority > PDN Efuse value. */
744         if (tmpvalue & BIT4 && pwrctrlpriv->reg_pdnmode)
745         {
746                 pHalData->pwrdown = true;
747         }
748         else
749         {
750                 pHalData->pwrdown = false;
751         }
752
753         DBG_8192C("HalDetectPwrDownMode(): PDN =%d\n", pHalData->pwrdown);
754
755         return pHalData->pwrdown;
756 }       /*  HalDetectPwrDownMode */
757
758 static u32 rtl8723bs_hal_init(struct adapter *padapter)
759 {
760         s32 ret;
761         struct hal_com_data *pHalData;
762         struct pwrctrl_priv *pwrctrlpriv;
763         struct registry_priv *pregistrypriv;
764         u32 NavUpper = WiFiNavUpperUs;
765         u8 u1bTmp;
766
767         pHalData = GET_HAL_DATA(padapter);
768         pwrctrlpriv = adapter_to_pwrctl(padapter);
769         pregistrypriv = &padapter->registrypriv;
770
771         if (adapter_to_pwrctl(padapter)->bips_processing == true
772                 && adapter_to_pwrctl(padapter)->pre_ips_type == 0)
773         {
774                 unsigned long start_time;
775                 u8 cpwm_orig, cpwm_now;
776                 u8 val8, bMacPwrCtrlOn = true;
777
778                 DBG_871X("%s: Leaving IPS in FWLPS state\n", __func__);
779
780                 /* for polling cpwm */
781                 cpwm_orig = 0;
782                 rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_orig);
783
784                 /* ser rpwm */
785                 val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1);
786                 val8 &= 0x80;
787                 val8 += 0x80;
788                 val8 |= BIT(6);
789                 rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
790                 DBG_871X("%s: write rpwm =%02x\n", __func__, val8);
791                 adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
792
793                 /* do polling cpwm */
794                 start_time = jiffies;
795                 do {
796
797                         mdelay(1);
798
799                         rtw_hal_get_hwreg(padapter, HW_VAR_CPWM, &cpwm_now);
800                         if ((cpwm_orig ^ cpwm_now) & 0x80)
801                         {
802                                 break;
803                         }
804
805                         if (jiffies_to_msecs(jiffies - start_time) > 100)
806                         {
807                                 DBG_871X("%s: polling cpwm timeout when leaving IPS in FWLPS state\n", __func__);
808                                 break;
809                         }
810                 } while (1);
811
812                 rtl8723b_set_FwPwrModeInIPS_cmd(padapter, 0);
813
814                 rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
815
816                 rtw_btcoex_HAL_Initialize(padapter, false);
817
818                 return _SUCCESS;
819         }
820
821 #ifdef CONFIG_WOWLAN
822         if (rtw_read8(padapter, REG_MCUFWDL)&BIT7) {
823                 u8 reg_val = 0;
824                 DBG_871X("+Reset Entry+\n");
825                 rtw_write8(padapter, REG_MCUFWDL, 0x00);
826                 _8051Reset8723(padapter);
827                 /* reset BB */
828                 reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN);
829                 reg_val &= ~(BIT(0) | BIT(1));
830                 rtw_write8(padapter, REG_SYS_FUNC_EN, reg_val);
831                 /* reset RF */
832                 rtw_write8(padapter, REG_RF_CTRL, 0);
833                 /* reset TRX path */
834                 rtw_write16(padapter, REG_CR, 0);
835                 /* reset MAC, Digital Core */
836                 reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
837                 reg_val &= ~(BIT(4) | BIT(7));
838                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, reg_val);
839                 reg_val = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
840                 reg_val |= BIT(4) | BIT(7);
841                 rtw_write8(padapter, REG_SYS_FUNC_EN+1, reg_val);
842                 DBG_871X("-Reset Entry-\n");
843         }
844 #endif /* CONFIG_WOWLAN */
845         /*  Disable Interrupt first. */
846 /*      rtw_hal_disable_interrupt(padapter); */
847
848         ret = _InitPowerOn_8723BS(padapter);
849         if (_FAIL == ret) {
850                 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("Failed to init Power On!\n"));
851                 return _FAIL;
852         }
853
854         rtw_write8(padapter, REG_EARLY_MODE_CONTROL, 0);
855
856         ret = rtl8723b_FirmwareDownload(padapter, false);
857         if (ret != _SUCCESS) {
858                 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: Download Firmware failed!!\n", __func__));
859                 padapter->bFWReady = false;
860                 pHalData->fw_ractrl = false;
861                 return ret;
862         } else {
863                 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("rtl8723bs_hal_init(): Download Firmware Success!!\n"));
864                 padapter->bFWReady = true;
865                 pHalData->fw_ractrl = true;
866         }
867
868         rtl8723b_InitializeFirmwareVars(padapter);
869
870 /*      SIC_Init(padapter); */
871
872         if (pwrctrlpriv->reg_rfoff == true) {
873                 pwrctrlpriv->rf_pwrstate = rf_off;
874         }
875
876         /*  2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
877         /*  HW GPIO pin. Before PHY_RFConfig8192C. */
878         HalDetectPwrDownMode(padapter);
879
880         /*  Set RF type for BB/RF configuration */
881         _InitRFType(padapter);
882
883         /*  Save target channel */
884         /*  <Roger_Notes> Current Channel will be updated again later. */
885         pHalData->CurrentChannel = 6;
886
887 #if (HAL_MAC_ENABLE == 1)
888         ret = PHY_MACConfig8723B(padapter);
889         if (ret != _SUCCESS) {
890                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure MAC!!\n"));
891                 return ret;
892         }
893 #endif
894         /*  */
895         /* d. Initialize BB related configurations. */
896         /*  */
897 #if (HAL_BB_ENABLE == 1)
898         ret = PHY_BBConfig8723B(padapter);
899         if (ret != _SUCCESS) {
900                 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure BB!!\n"));
901                 return ret;
902         }
903 #endif
904
905         /*  If RF is on, we need to init RF. Otherwise, skip the procedure. */
906         /*  We need to follow SU method to change the RF cfg.txt. Default disable RF TX/RX mode. */
907         /* if (pHalData->eRFPowerState == eRfOn) */
908         {
909 #if (HAL_RF_ENABLE == 1)
910                 ret = PHY_RFConfig8723B(padapter);
911                 if (ret != _SUCCESS) {
912                         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Initializepadapter8192CSdio(): Fail to configure RF!!\n"));
913                         return ret;
914                 }
915 #endif
916         }
917
918         /*  */
919         /*  Joseph Note: Keep RfRegChnlVal for later use. */
920         /*  */
921         pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(padapter, (enum RF_PATH)0, RF_CHNLBW, bRFRegOffsetMask);
922         pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(padapter, (enum RF_PATH)1, RF_CHNLBW, bRFRegOffsetMask);
923
924
925         /* if (!pHalData->bMACFuncEnable) { */
926         _InitQueueReservedPage(padapter);
927         _InitTxBufferBoundary(padapter);
928
929         /*  init LLT after tx buffer boundary is defined */
930         ret = rtl8723b_InitLLTTable(padapter);
931         if (_SUCCESS != ret) {
932                 DBG_8192C("%s: Failed to init LLT Table!\n", __func__);
933                 return _FAIL;
934         }
935         /*  */
936         _InitQueuePriority(padapter);
937         _InitPageBoundary(padapter);
938         _InitTransferPageSize(padapter);
939
940         /*  Get Rx PHY status in order to report RSSI and others. */
941         _InitDriverInfoSize(padapter, DRVINFO_SZ);
942         hal_init_macaddr(padapter);
943         _InitNetworkType(padapter);
944         _InitWMACSetting(padapter);
945         _InitAdaptiveCtrl(padapter);
946         _InitEDCA(padapter);
947         _InitRetryFunction(padapter);
948         _initSdioAggregationSetting(padapter);
949         _InitOperationMode(padapter);
950         rtl8723b_InitBeaconParameters(padapter);
951         _InitInterrupt(padapter);
952         _InitBurstPktLen_8723BS(padapter);
953
954         /* YJ, TODO */
955         rtw_write8(padapter, REG_SECONDARY_CCA_CTRL_8723B, 0x3);        /*  CCA */
956         rtw_write8(padapter, 0x976, 0); /*  hpfan_todo: 2nd CCA related */
957
958         rtw_write16(padapter, REG_PKT_VO_VI_LIFE_TIME, 0x0400); /*  unit: 256us. 256ms */
959         rtw_write16(padapter, REG_PKT_BE_BK_LIFE_TIME, 0x0400); /*  unit: 256us. 256ms */
960
961         invalidate_cam_all(padapter);
962
963         rtw_hal_set_chnl_bw(padapter, padapter->registrypriv.channel,
964                 CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
965
966         /*  Record original value for template. This is arough data, we can only use the data */
967         /*  for power adjust. The value can not be adjustde according to different power!!! */
968 /*      pHalData->OriginalCckTxPwrIdx = pHalData->CurrentCckTxPwrIdx; */
969 /*      pHalData->OriginalOfdm24GTxPwrIdx = pHalData->CurrentOfdm24GTxPwrIdx; */
970
971         rtl8723b_InitAntenna_Selection(padapter);
972
973         /*  */
974         /*  Disable BAR, suggested by Scott */
975         /*  2010.04.09 add by hpfan */
976         /*  */
977         rtw_write32(padapter, REG_BAR_MODE_CTRL, 0x0201ffff);
978
979         /*  HW SEQ CTRL */
980         /*  set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
981         rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF);
982
983
984         /*  */
985         /*  Configure SDIO TxRx Control to enable Rx DMA timer masking. */
986         /*  2010.02.24. */
987         /*  */
988         rtw_write32(padapter, SDIO_LOCAL_BASE|SDIO_REG_TX_CTRL, 0);
989
990         _RfPowerSave(padapter);
991
992
993         rtl8723b_InitHalDm(padapter);
994
995         /* DbgPrint("pHalData->DefaultTxPwrDbm = %d\n", pHalData->DefaultTxPwrDbm); */
996
997         /*  */
998         /*  Update current Tx FIFO page status. */
999         /*  */
1000         HalQueryTxBufferStatus8723BSdio(padapter);
1001         HalQueryTxOQTBufferStatus8723BSdio(padapter);
1002         pHalData->SdioTxOQTMaxFreeSpace = pHalData->SdioTxOQTFreeSpace;
1003
1004         /*  Enable MACTXEN/MACRXEN block */
1005         u1bTmp = rtw_read8(padapter, REG_CR);
1006         u1bTmp |= (MACTXEN | MACRXEN);
1007         rtw_write8(padapter, REG_CR, u1bTmp);
1008
1009         rtw_hal_set_hwreg(padapter, HW_VAR_NAV_UPPER, (u8 *)&NavUpper);
1010
1011         /* ack for xmit mgmt frames. */
1012         rtw_write32(padapter, REG_FWHW_TXQ_CTRL, rtw_read32(padapter, REG_FWHW_TXQ_CTRL)|BIT(12));
1013
1014 /*      pHalData->PreRpwmVal = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HRPWM1) & 0x80; */
1015
1016         {
1017                 pwrctrlpriv->rf_pwrstate = rf_on;
1018
1019                 if (pwrctrlpriv->rf_pwrstate == rf_on)
1020                 {
1021                         struct pwrctrl_priv *pwrpriv;
1022                         unsigned long start_time;
1023                         u8 restore_iqk_rst;
1024                         u8 b2Ant;
1025                         u8 h2cCmdBuf;
1026
1027                         pwrpriv = adapter_to_pwrctl(padapter);
1028
1029                         PHY_LCCalibrate_8723B(&pHalData->odmpriv);
1030
1031                         /* Inform WiFi FW that it is the beginning of IQK */
1032                         h2cCmdBuf = 1;
1033                         FillH2CCmd8723B(padapter, H2C_8723B_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf);
1034
1035                         start_time = jiffies;
1036                         do {
1037                                 if (rtw_read8(padapter, 0x1e7) & 0x01)
1038                                         break;
1039
1040                                 msleep(50);
1041                         } while (jiffies_to_msecs(jiffies - start_time) <= 400);
1042
1043                         rtw_btcoex_IQKNotify(padapter, true);
1044
1045                         restore_iqk_rst = (pwrpriv->bips_processing ==true)?true:false;
1046                         b2Ant = pHalData->EEPROMBluetoothAntNum ==Ant_x2?true:false;
1047                         PHY_IQCalibrate_8723B(padapter, false, restore_iqk_rst, b2Ant, pHalData->ant_path);
1048                         pHalData->odmpriv.RFCalibrateInfo.bIQKInitialized = true;
1049
1050                         rtw_btcoex_IQKNotify(padapter, false);
1051
1052                         /* Inform WiFi FW that it is the finish of IQK */
1053                         h2cCmdBuf = 0;
1054                         FillH2CCmd8723B(padapter, H2C_8723B_BT_WLAN_CALIBRATION, 1, &h2cCmdBuf);
1055
1056                         ODM_TXPowerTrackingCheck(&pHalData->odmpriv);
1057                 }
1058         }
1059
1060         /*  Init BT hw config. */
1061         rtw_btcoex_HAL_Initialize(padapter, false);
1062
1063         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("-%s\n", __func__));
1064
1065         return _SUCCESS;
1066 }
1067
1068 /*  */
1069 /*  Description: */
1070 /*      RTL8723e card disable power sequence v003 which suggested by Scott. */
1071 /*  */
1072 /*  First created by tynli. 2011.01.28. */
1073 /*  */
1074 static void CardDisableRTL8723BSdio(struct adapter *padapter)
1075 {
1076         u8 u1bTmp;
1077         u8 bMacPwrCtrlOn;
1078         u8 ret = _FAIL;
1079
1080         /*  Run LPS WL RFOFF flow */
1081         ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8723B_enter_lps_flow);
1082         if (ret == _FAIL) {
1083                 DBG_8192C(KERN_ERR "%s: run RF OFF flow fail!\n", __func__);
1084         }
1085
1086         /*      ==== Reset digital sequence   ====== */
1087
1088         u1bTmp = rtw_read8(padapter, REG_MCUFWDL);
1089         if ((u1bTmp & RAM_DL_SEL) && padapter->bFWReady) /* 8051 RAM code */
1090                 rtl8723b_FirmwareSelfReset(padapter);
1091
1092         /*  Reset MCU 0x2[10]= 0. Suggested by Filen. 2011.01.26. by tynli. */
1093         u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
1094         u1bTmp &= ~BIT(2);      /*  0x2[10], FEN_CPUEN */
1095         rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp);
1096
1097         /*  MCUFWDL 0x80[1:0]= 0 */
1098         /*  reset MCU ready status */
1099         rtw_write8(padapter, REG_MCUFWDL, 0);
1100
1101         /*  Reset MCU IO Wrapper, added by Roger, 2011.08.30 */
1102         u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
1103         u1bTmp &= ~BIT(0);
1104         rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
1105         u1bTmp = rtw_read8(padapter, REG_RSV_CTRL+1);
1106         u1bTmp |= BIT(0);
1107         rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp);
1108
1109         /*      ==== Reset digital sequence end ====== */
1110
1111         bMacPwrCtrlOn = false;  /*  Disable CMD53 R/W */
1112         ret = false;
1113         rtw_hal_set_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
1114         ret = HalPwrSeqCmdParsing(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, rtl8723B_card_disable_flow);
1115         if (ret == false) {
1116                 DBG_8192C(KERN_ERR "%s: run CARD DISABLE flow fail!\n", __func__);
1117         }
1118 }
1119
1120 static u32 rtl8723bs_hal_deinit(struct adapter *padapter)
1121 {
1122         struct dvobj_priv *psdpriv = padapter->dvobj;
1123         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1124
1125         if (padapter->hw_init_completed == true)
1126         {
1127                 if (adapter_to_pwrctl(padapter)->bips_processing == true)
1128                 {
1129                         if (padapter->netif_up == true)
1130                         {
1131                                 int cnt = 0;
1132                                 u8 val8 = 0;
1133
1134                                 DBG_871X("%s: issue H2C to FW when entering IPS\n", __func__);
1135
1136                                 rtl8723b_set_FwPwrModeInIPS_cmd(padapter, 0x3);
1137                                 /* poll 0x1cc to make sure H2C command already finished by FW; MAC_0x1cc = 0 means H2C done by FW. */
1138                                 do{
1139                                         val8 = rtw_read8(padapter, REG_HMETFR);
1140                                         cnt++;
1141                                         DBG_871X("%s  polling REG_HMETFR = 0x%x, cnt =%d\n", __func__, val8, cnt);
1142                                         mdelay(10);
1143                                 }while (cnt<100 && (val8!= 0));
1144                                 /* H2C done, enter 32k */
1145                                 if (val8 == 0)
1146                                 {
1147                                         /* ser rpwm to enter 32k */
1148                                         val8 = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1);
1149                                         val8 += 0x80;
1150                                         val8 |= BIT(0);
1151                                         rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
1152                                         DBG_871X("%s: write rpwm =%02x\n", __func__, val8);
1153                                         adapter_to_pwrctl(padapter)->tog = (val8 + 0x80) & 0x80;
1154                                         cnt = val8 = 0;
1155                                         do{
1156                                                 val8 = rtw_read8(padapter, REG_CR);
1157                                                 cnt++;
1158                                                 DBG_871X("%s  polling 0x100 = 0x%x, cnt =%d\n", __func__, val8, cnt);
1159                                                 mdelay(10);
1160                                         }while (cnt<100 && (val8!= 0xEA));
1161                                 }
1162                                 else
1163                                 {
1164                                         DBG_871X("MAC_1C0 =%08x, MAC_1C4 =%08x, MAC_1C8 =%08x, MAC_1CC =%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
1165                                         , rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
1166                                 }
1167
1168                                 DBG_871X("polling done when entering IPS, check result : 0x100 = 0x%x, cnt =%d, MAC_1cc = 0x%02x\n"
1169                                 , rtw_read8(padapter, REG_CR), cnt, rtw_read8(padapter, REG_HMETFR));
1170
1171                                 adapter_to_pwrctl(padapter)->pre_ips_type = 0;
1172
1173                         }
1174                         else
1175                         {
1176                                 pdbgpriv->dbg_carddisable_cnt++;
1177                                 CardDisableRTL8723BSdio(padapter);
1178
1179                                 adapter_to_pwrctl(padapter)->pre_ips_type = 1;
1180                         }
1181
1182                 }
1183                 else
1184                 {
1185                         pdbgpriv->dbg_carddisable_cnt++;
1186                         CardDisableRTL8723BSdio(padapter);
1187                 }
1188         }
1189         else
1190         {
1191                 pdbgpriv->dbg_deinit_fail_cnt++;
1192         }
1193
1194         return _SUCCESS;
1195 }
1196
1197 static u32 rtl8723bs_inirp_init(struct adapter *padapter)
1198 {
1199         return _SUCCESS;
1200 }
1201
1202 static u32 rtl8723bs_inirp_deinit(struct adapter *padapter)
1203 {
1204         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+rtl8723bs_inirp_deinit\n"));
1205
1206         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("-rtl8723bs_inirp_deinit\n"));
1207
1208         return _SUCCESS;
1209 }
1210
1211 static void rtl8723bs_init_default_value(struct adapter *padapter)
1212 {
1213         struct hal_com_data *pHalData;
1214
1215
1216         pHalData = GET_HAL_DATA(padapter);
1217
1218         rtl8723b_init_default_value(padapter);
1219
1220         /*  interface related variable */
1221         pHalData->SdioRxFIFOCnt = 0;
1222 }
1223
1224 static void rtl8723bs_interface_configure(struct adapter *padapter)
1225 {
1226         struct hal_com_data             *pHalData = GET_HAL_DATA(padapter);
1227         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
1228         struct registry_priv *pregistrypriv = &padapter->registrypriv;
1229         bool            bWiFiConfig     = pregistrypriv->wifi_spec;
1230
1231
1232         pdvobjpriv->RtOutPipe[0] = WLAN_TX_HIQ_DEVICE_ID;
1233         pdvobjpriv->RtOutPipe[1] = WLAN_TX_MIQ_DEVICE_ID;
1234         pdvobjpriv->RtOutPipe[2] = WLAN_TX_LOQ_DEVICE_ID;
1235
1236         if (bWiFiConfig)
1237                 pHalData->OutEpNumber = 2;
1238         else
1239                 pHalData->OutEpNumber = SDIO_MAX_TX_QUEUE;
1240
1241         switch (pHalData->OutEpNumber) {
1242                 case 3:
1243                         pHalData->OutEpQueueSel =TX_SELE_HQ| TX_SELE_LQ|TX_SELE_NQ;
1244                         break;
1245                 case 2:
1246                         pHalData->OutEpQueueSel =TX_SELE_HQ| TX_SELE_NQ;
1247                         break;
1248                 case 1:
1249                         pHalData->OutEpQueueSel =TX_SELE_HQ;
1250                         break;
1251                 default:
1252                         break;
1253         }
1254
1255         Hal_MappingOutPipe(padapter, pHalData->OutEpNumber);
1256 }
1257
1258 /*  */
1259 /*      Description: */
1260 /*              We should set Efuse cell selection to WiFi cell in default. */
1261 /*  */
1262 /*      Assumption: */
1263 /*              PASSIVE_LEVEL */
1264 /*  */
1265 /*      Added by Roger, 2010.11.23. */
1266 /*  */
1267 static void
1268 _EfuseCellSel(
1269 struct adapter *padapter
1270         )
1271 {
1272         u32             value32;
1273
1274         value32 = rtw_read32(padapter, EFUSE_TEST);
1275         value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1276         rtw_write32(padapter, EFUSE_TEST, value32);
1277 }
1278
1279 static void
1280 _ReadRFType(
1281 struct adapter *Adapter
1282         )
1283 {
1284         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
1285
1286 #if DISABLE_BB_RF
1287         pHalData->rf_chip = RF_PSEUDO_11N;
1288 #else
1289         pHalData->rf_chip = RF_6052;
1290 #endif
1291 }
1292
1293
1294 static void
1295 Hal_EfuseParseMACAddr_8723BS(
1296 struct adapter *        padapter,
1297 u8*             hwinfo,
1298 bool                    AutoLoadFail
1299         )
1300 {
1301         u16             i;
1302         u8      sMacAddr[6] = {0x00, 0xE0, 0x4C, 0xb7, 0x23, 0x00};
1303         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1304
1305         if (AutoLoadFail)
1306         {
1307 /*              sMacAddr[5] = (u8)GetRandomNumber(1, 254); */
1308                 for (i = 0; i<6; i++)
1309                         pEEPROM->mac_addr[i] = sMacAddr[i];
1310         }
1311         else
1312         {
1313                 /* Read Permanent MAC address */
1314                 memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723BS], ETH_ALEN);
1315         }
1316 /*      NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
1317
1318         RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1319                  ("Hal_EfuseParseMACAddr_8723BS: Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
1320                   pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
1321                   pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
1322                   pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]));
1323 }
1324
1325 static void
1326 Hal_EfuseParseBoardType_8723BS(
1327 struct adapter *        padapter,
1328 u8*             hwinfo,
1329 bool                    AutoLoadFail
1330         )
1331 {
1332         struct hal_com_data     *pHalData = GET_HAL_DATA(padapter);
1333
1334         if (!AutoLoadFail)
1335         {
1336                 pHalData->BoardType = (hwinfo[EEPROM_RF_BOARD_OPTION_8723B] & 0xE0) >> 5;
1337                 if (pHalData->BoardType == 0xFF)
1338                         pHalData->BoardType = (EEPROM_DEFAULT_BOARD_OPTION&0xE0)>>5;
1339         }
1340         else
1341                 pHalData->BoardType = 0;
1342         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Board Type: 0x%2x\n", pHalData->BoardType));
1343 }
1344
1345 static void
1346 _ReadEfuseInfo8723BS(
1347         struct adapter *                padapter
1348         )
1349 {
1350         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1351         u8*             hwinfo = NULL;
1352
1353         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("====>_ReadEfuseInfo8723BS()\n"));
1354
1355         /*  */
1356         /*  This part read and parse the eeprom/efuse content */
1357         /*  */
1358
1359         if (sizeof(pEEPROM->efuse_eeprom_data) < HWSET_MAX_SIZE_8723B)
1360                 DBG_871X("[WARNING] size of efuse_eeprom_data is less than HWSET_MAX_SIZE_8723B!\n");
1361
1362         hwinfo = pEEPROM->efuse_eeprom_data;
1363
1364         Hal_InitPGData(padapter, hwinfo);
1365
1366         Hal_EfuseParseIDCode(padapter, hwinfo);
1367         Hal_EfuseParseEEPROMVer_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1368
1369         Hal_EfuseParseMACAddr_8723BS(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1370
1371         Hal_EfuseParseTxPowerInfo_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1372         Hal_EfuseParseBoardType_8723BS(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1373
1374         /*  */
1375         /*  Read Bluetooth co-exist and initialize */
1376         /*  */
1377         Hal_EfuseParseBTCoexistInfo_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1378         Hal_EfuseParseChnlPlan_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1379         Hal_EfuseParseXtal_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1380         Hal_EfuseParsePackageType_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1381         Hal_EfuseParseThermalMeter_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1382         Hal_EfuseParseAntennaDiversity_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1383         Hal_EfuseParseCustomerID_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1384
1385         Hal_EfuseParseVoltage_8723B(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1386
1387 #ifdef CONFIG_WOWLAN
1388         Hal_DetectWoWMode(padapter);
1389 #endif
1390
1391         Hal_ReadRFGainOffset(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1392
1393         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==== _ReadEfuseInfo8723BS()\n"));
1394 }
1395
1396 static void _ReadPROMContent(
1397         struct adapter *        padapter
1398         )
1399 {
1400         struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1401         u8      eeValue;
1402
1403         eeValue = rtw_read8(padapter, REG_9346CR);
1404         /*  To check system boot selection. */
1405         pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
1406         pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
1407
1408         RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1409                  ("%s: 9346CR = 0x%02X, Boot from %s, Autoload %s\n",
1410                   __func__, eeValue,
1411                   (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
1412                   (pEEPROM->bautoload_fail_flag ? "Fail" : "OK")));
1413
1414 /*      pHalData->EEType = IS_BOOT_FROM_EEPROM(Adapter) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; */
1415
1416         _ReadEfuseInfo8723BS(padapter);
1417 }
1418
1419 static void
1420 _InitOtherVariable(
1421         struct adapter *        Adapter
1422         )
1423 {
1424 }
1425
1426 /*  */
1427 /*      Description: */
1428 /*              Read HW adapter information by E-Fuse or EEPROM according CR9346 reported. */
1429 /*  */
1430 /*      Assumption: */
1431 /*              PASSIVE_LEVEL (SDIO interface) */
1432 /*  */
1433 /*  */
1434 static s32 _ReadAdapterInfo8723BS(struct adapter *padapter)
1435 {
1436         u8 val8;
1437         unsigned long start;
1438
1439         RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+_ReadAdapterInfo8723BS\n"));
1440
1441         /*  before access eFuse, make sure card enable has been called */
1442         if (padapter->hw_init_completed == false)
1443                 _InitPowerOn_8723BS(padapter);
1444
1445
1446         val8 = rtw_read8(padapter, 0x4e);
1447         MSG_8192C("%s, 0x4e = 0x%x\n", __func__, val8);
1448         val8 |= BIT(6);
1449         rtw_write8(padapter, 0x4e, val8);
1450
1451
1452         start = jiffies;
1453
1454         _EfuseCellSel(padapter);
1455         _ReadRFType(padapter);
1456         _ReadPROMContent(padapter);
1457         _InitOtherVariable(padapter);
1458
1459         if (padapter->hw_init_completed == false)
1460         {
1461                 rtw_write8(padapter, 0x67, 0x00); /*  for BT, Switch Ant control to BT */
1462                 CardDisableRTL8723BSdio(padapter);/* for the power consumption issue,  wifi ko module is loaded during booting, but wifi GUI is off */
1463         }
1464
1465
1466         MSG_8192C("<==== _ReadAdapterInfo8723BS in %d ms\n", jiffies_to_msecs(jiffies - start));
1467
1468         return _SUCCESS;
1469 }
1470
1471 static void ReadAdapterInfo8723BS(struct adapter *padapter)
1472 {
1473         /*  Read EEPROM size before call any EEPROM function */
1474         padapter->EepromAddressSize = GetEEPROMSize8723B(padapter);
1475
1476         _ReadAdapterInfo8723BS(padapter);
1477 }
1478
1479 /*
1480  * If variable not handled here,
1481  * some variables will be processed in SetHwReg8723B()
1482  */
1483 static void SetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val)
1484 {
1485         struct hal_com_data *pHalData;
1486         u8 val8;
1487
1488 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1489         struct wowlan_ioctl_param *poidparam;
1490         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
1491         int res;
1492         u32 tmp;
1493         u16 len = 0;
1494         u8 trycnt = 100;
1495         u32 himr = 0;
1496 #if defined(CONFIG_WOWLAN)
1497         struct security_priv *psecuritypriv = &padapter->securitypriv;
1498         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1499         struct sta_info *psta = NULL;
1500         u64 iv_low = 0, iv_high = 0;
1501         u8 mstatus = (*(u8 *)val);
1502 #endif
1503 #endif
1504
1505         pHalData = GET_HAL_DATA(padapter);
1506
1507         switch (variable)
1508         {
1509                 case HW_VAR_SET_RPWM:
1510                         /*  rpwm value only use BIT0(clock bit) , BIT6(Ack bit), and BIT7(Toggle bit) */
1511                         /*  BIT0 value - 1: 32k, 0:40MHz. */
1512                         /*  BIT6 value - 1: report cpwm value after success set, 0:do not report. */
1513                         /*  BIT7 value - Toggle bit change. */
1514                         {
1515                                 val8 = *val;
1516                                 val8 &= 0xC1;
1517                                 rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1, val8);
1518                         }
1519                         break;
1520                 case HW_VAR_SET_REQ_FW_PS:
1521                         {
1522                                 u8 req_fw_ps = 0;
1523                                 req_fw_ps = rtw_read8(padapter, 0x8f);
1524                                 req_fw_ps |= 0x10;
1525                                 rtw_write8(padapter, 0x8f, req_fw_ps);
1526                         }
1527                         break;
1528                 case HW_VAR_RXDMA_AGG_PG_TH:
1529                         val8 = *val;
1530                         break;
1531
1532 #ifdef CONFIG_WOWLAN
1533                 case HW_VAR_WOWLAN:
1534                 {
1535                         poidparam = (struct wowlan_ioctl_param *)val;
1536                         switch (poidparam->subcode) {
1537                                 case WOWLAN_ENABLE:
1538                                         DBG_871X_LEVEL(_drv_always_, "WOWLAN_ENABLE\n");
1539
1540                                         /* backup data rate to register 0x8b for wowlan FW */
1541                                         rtw_write8(padapter, 0x8d, 1);
1542                                         rtw_write8(padapter, 0x8c, 0);
1543                                         rtw_write8(padapter, 0x8f, 0x40);
1544                                         rtw_write8(padapter, 0x8b,
1545                                         rtw_read8(padapter, 0x2f0));
1546
1547                                         /*  1. Download WOWLAN FW */
1548                                         DBG_871X_LEVEL(_drv_always_, "Re-download WoWlan FW!\n");
1549                                         SetFwRelatedForWoWLAN8723b(padapter, true);
1550
1551                                         /*  2. RX DMA stop */
1552                                         DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
1553                                         rtw_write32(padapter, REG_RXPKT_NUM, (rtw_read32(padapter, REG_RXPKT_NUM)|RW_RELEASE_EN));
1554                                         do{
1555                                                 if ((rtw_read32(padapter, REG_RXPKT_NUM)&RXDMA_IDLE)) {
1556                                                         DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n");
1557                                                         break;
1558                                                 } else {
1559                                                         /*  If RX_DMA is not idle, receive one pkt from DMA */
1560                                                         res = sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
1561                                                         len = le16_to_cpu(tmp);
1562                                                         DBG_871X_LEVEL(_drv_always_, "RX len:%d\n", len);
1563                                                         if (len > 0)
1564                                                                         res = RecvOnePkt(padapter, len);
1565                                                         else
1566                                                                         DBG_871X_LEVEL(_drv_always_, "read length fail %d\n", len);
1567
1568                                                         DBG_871X_LEVEL(_drv_always_, "RecvOnePkt Result: %d\n", res);
1569                                                 }
1570                                         }while (trycnt--);
1571                                         if (trycnt == 0)
1572                                                 DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed......\n");
1573
1574                                         /*  3. Clear IMR and ISR */
1575                                         DBG_871X_LEVEL(_drv_always_, "Clear IMR and ISR\n");
1576                                         tmp = 0;
1577                                         sdio_local_write(padapter, SDIO_REG_HIMR_ON, 4, (u8 *)&tmp);
1578                                         sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1579                                         sdio_local_read(padapter, SDIO_REG_HISR, 4, (u8 *)&tmp);
1580                                         sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8 *)&tmp);
1581
1582                                         /*  4. Enable CPWM2 only */
1583                                         DBG_871X_LEVEL(_drv_always_, "Enable only CPWM2\n");
1584                                         sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1585                                         DBG_871X("DisableInterruptButCpwm28723BSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
1586
1587                                         himr = cpu_to_le32(SDIO_HIMR_DISABLED)|SDIO_HIMR_CPWM2_MSK;
1588                                         sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1589
1590                                         sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1591                                         DBG_871X("DisableInterruptButCpwm28723BSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1592
1593                                         /*  5. Set Enable WOWLAN H2C command. */
1594                                         DBG_871X_LEVEL(_drv_always_, "Set Enable WOWLan cmd\n");
1595                                         rtl8723b_set_wowlan_cmd(padapter, 1);
1596
1597                                         /*  6. Check EnableWoWlan CMD is ready */
1598                                         if (!pwrctl->wowlan_pno_enable) {
1599                                                 DBG_871X_LEVEL(_drv_always_, "Check EnableWoWlan CMD is ready\n");
1600                                                 mstatus = rtw_read8(padapter, REG_WOW_CTRL);
1601                                                 trycnt = 10;
1602                                                 while (!(mstatus&BIT1) && trycnt>1) {
1603                                                         mstatus = rtw_read8(padapter, REG_WOW_CTRL);
1604                                                         DBG_871X("Loop index: %d :0x%02x\n", trycnt, mstatus);
1605                                                         trycnt --;
1606                                                         msleep(2);
1607                                                 }
1608                                         }
1609                                         break;
1610
1611                                 case WOWLAN_DISABLE:
1612                                         DBG_871X_LEVEL(_drv_always_, "WOWLAN_DISABLE\n");
1613
1614                                         psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(pmlmepriv));
1615                                         if (psta != NULL)
1616                                                 rtl8723b_set_FwMediaStatusRpt_cmd(padapter, RT_MEDIA_DISCONNECT, psta->mac_id);
1617                                         else
1618                                                 DBG_871X("psta is null\n");
1619
1620                                         /*  1. Read wakeup reason */
1621                                         pwrctl->wowlan_wake_reason = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
1622                                         DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x, mac_630 = 0x%08x, mac_634 = 0x%08x, mac_1c0 = 0x%08x, mac_1c4 = 0x%08x"
1623                                         ", mac_494 = 0x%08x, , mac_498 = 0x%08x, mac_49c = 0x%08x, mac_608 = 0x%08x, mac_4a0 = 0x%08x, mac_4a4 = 0x%08x\n"
1624                                         ", mac_1cc = 0x%08x, mac_2f0 = 0x%08x, mac_2f4 = 0x%08x, mac_2f8 = 0x%08x, mac_2fc = 0x%08x, mac_8c = 0x%08x"
1625                                         , pwrctl->wowlan_wake_reason, rtw_read32(padapter, REG_WOWLAN_GTK_DBG1), rtw_read32(padapter, REG_WOWLAN_GTK_DBG2)
1626                                         , rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
1627                                         , rtw_read32(padapter, 0x494), rtw_read32(padapter, 0x498), rtw_read32(padapter, 0x49c), rtw_read32(padapter, 0x608)
1628                                         , rtw_read32(padapter, 0x4a0), rtw_read32(padapter, 0x4a4)
1629                                         , rtw_read32(padapter, 0x1cc), rtw_read32(padapter, 0x2f0), rtw_read32(padapter, 0x2f4), rtw_read32(padapter, 0x2f8)
1630                                         , rtw_read32(padapter, 0x2fc), rtw_read32(padapter, 0x8c));
1631 #ifdef CONFIG_PNO_SET_DEBUG
1632                                         DBG_871X("0x1b9: 0x%02x, 0x632: 0x%02x\n", rtw_read8(padapter, 0x1b9), rtw_read8(padapter, 0x632));
1633                                         DBG_871X("0x4fc: 0x%02x, 0x4fd: 0x%02x\n", rtw_read8(padapter, 0x4fc), rtw_read8(padapter, 0x4fd));
1634                                         DBG_871X("TXDMA STATUS: 0x%08x\n", rtw_read32(padapter, REG_TXDMA_STATUS));
1635 #endif
1636
1637                                         {
1638                                                 /*  2.  Set Disable WOWLAN H2C command. */
1639                                                 DBG_871X_LEVEL(_drv_always_, "Set Disable WOWLan cmd\n");
1640                                                 rtl8723b_set_wowlan_cmd(padapter, 0);
1641
1642                                                 /*  3. Check Disable WoWlan CMD ready. */
1643                                                 DBG_871X_LEVEL(_drv_always_, "Check DisableWoWlan CMD is ready\n");
1644                                                 mstatus = rtw_read8(padapter, REG_WOW_CTRL);
1645                                                 trycnt = 50;
1646                                                 while (mstatus&BIT1 && trycnt>1) {
1647                                                         mstatus = rtw_read8(padapter, REG_WOW_CTRL);
1648                                                         DBG_871X_LEVEL(_drv_always_, "Loop index: %d :0x%02x\n", trycnt, mstatus);
1649                                                         trycnt --;
1650                                                         msleep(10);
1651                                                 }
1652
1653                                                 if (mstatus & BIT1) {
1654                                                         DBG_871X_LEVEL(_drv_always_, "Disable WOW mode fail!!\n");
1655                                                         DBG_871X("Set 0x690 = 0x00\n");
1656                                                         rtw_write8(padapter, REG_WOW_CTRL, (rtw_read8(padapter, REG_WOW_CTRL)&0xf0));
1657                                                         DBG_871X_LEVEL(_drv_always_, "Release RXDMA\n");
1658                                                         rtw_write32(padapter, REG_RXPKT_NUM, (rtw_read32(padapter, REG_RXPKT_NUM)&(~RW_RELEASE_EN)));
1659                                                 }
1660
1661                                                 /*  3.1 read fw iv */
1662                                                 iv_low = rtw_read32(padapter, REG_TXPKTBUF_IV_LOW);
1663                                                         /* only low two bytes is PN, check AES_IV macro for detail */
1664                                                         iv_low &= 0xffff;
1665                                                 iv_high = rtw_read32(padapter, REG_TXPKTBUF_IV_HIGH);
1666                                                         /* get the real packet number */
1667                                                         pwrctl->wowlan_fw_iv = iv_high << 16 | iv_low;
1668                                                 DBG_871X_LEVEL(_drv_always_, "fw_iv: 0x%016llx\n", pwrctl->wowlan_fw_iv);
1669                                                 /* Update TX iv data. */
1670                                                         rtw_set_sec_pn(padapter);
1671
1672                                                 /*  3.2 read GTK index and key */
1673                                                 if (psecuritypriv->binstallKCK_KEK == true && psecuritypriv->dot11PrivacyAlgrthm == _AES_)
1674                                                 {
1675                                                         u8 gtk_keyindex = 0;
1676                                                         u8 get_key[16];
1677                                                         /* read gtk key index */
1678                                                         gtk_keyindex = rtw_read8(padapter, 0x48c);
1679
1680                                                         if (gtk_keyindex < 4)
1681                                                         {
1682                                                                 psecuritypriv->dot118021XGrpKeyid = gtk_keyindex;
1683                                                                 read_cam(padapter , gtk_keyindex, get_key);
1684                                                                 memcpy(psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, get_key, 16);
1685                                                                 DBG_871X_LEVEL(_drv_always_, "GTK (%d) = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", gtk_keyindex,
1686                                                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[0],
1687                                                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[1],
1688                                                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[2],
1689                                                                 psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].lkey[3]);
1690                                                         }
1691                                                         else
1692                                                                 DBG_871X_LEVEL(_drv_always_, "GTK index =%d\n", gtk_keyindex);
1693                                                 }
1694
1695                                                 /*  4. Re-download Normal FW. */
1696                                                 DBG_871X_LEVEL(_drv_always_, "Re-download Normal FW!\n");
1697                                                 SetFwRelatedForWoWLAN8723b(padapter, false);
1698                                         }
1699 #ifdef CONFIG_GPIO_WAKEUP
1700                                         DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to high for default.\n");
1701                                         HalSetOutPutGPIO(padapter, WAKEUP_GPIO_IDX, 1);
1702 #endif
1703
1704                                         /*  5. Download reserved pages and report media status if needed. */
1705                                         if ((pwrctl->wowlan_wake_reason != FWDecisionDisconnect) &&
1706                                                 (pwrctl->wowlan_wake_reason != Rx_Pairwisekey) &&
1707                                                 (pwrctl->wowlan_wake_reason != Rx_DisAssoc) &&
1708                                                 (pwrctl->wowlan_wake_reason != Rx_DeAuth))
1709                                         {
1710                                                 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);
1711                                                 if (psta != NULL)
1712                                                         rtl8723b_set_FwMediaStatusRpt_cmd(padapter, RT_MEDIA_CONNECT, psta->mac_id);
1713                                         }
1714 #ifdef CONFIG_PNO_SUPPORT
1715                                         rtw_write8(padapter, 0x1b8, 0);
1716                                         DBG_871X("reset 0x1b8: %d\n", rtw_read8(padapter, 0x1b8));
1717                                         rtw_write8(padapter, 0x1b9, 0);
1718                                         DBG_871X("reset 0x1b9: %d\n", rtw_read8(padapter, 0x1b9));
1719                                         rtw_write8(padapter, REG_PNO_STATUS, 0);
1720                                         DBG_871X("reset REG_PNO_STATUS: %d\n", rtw_read8(padapter, REG_PNO_STATUS));
1721 #endif
1722                                         break;
1723
1724                                 default:
1725                                         break;
1726                         }
1727                 }
1728                 break;
1729 #endif /* CONFIG_WOWLAN */
1730 #ifdef CONFIG_AP_WOWLAN
1731         case HW_VAR_AP_WOWLAN:
1732         {
1733                 poidparam = (struct wowlan_ioctl_param *)val;
1734                 switch (poidparam->subcode) {
1735                 case WOWLAN_AP_ENABLE:
1736                         DBG_871X("%s, WOWLAN_AP_ENABLE\n", __func__);
1737                         /*  1. Download WOWLAN FW */
1738                         DBG_871X_LEVEL(_drv_always_, "Re-download WoWlan FW!\n");
1739                         SetFwRelatedForWoWLAN8723b(padapter, true);
1740
1741                         /*  2. RX DMA stop */
1742                         DBG_871X_LEVEL(_drv_always_, "Pause DMA\n");
1743                         rtw_write32(padapter, REG_RXPKT_NUM,
1744                                 (rtw_read32(padapter, REG_RXPKT_NUM)|RW_RELEASE_EN));
1745                         do {
1746                                 if ((rtw_read32(padapter, REG_RXPKT_NUM)&RXDMA_IDLE)) {
1747                                         DBG_871X_LEVEL(_drv_always_, "RX_DMA_IDLE is true\n");
1748                                         break;
1749                                 } else {
1750                                         /*  If RX_DMA is not idle, receive one pkt from DMA */
1751                                         res = sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
1752                                         len = le16_to_cpu(tmp);
1753
1754                                         DBG_871X_LEVEL(_drv_always_, "RX len:%d\n", len);
1755                                         if (len > 0)
1756                                                 res = RecvOnePkt(padapter, len);
1757                                         else
1758                                                 DBG_871X_LEVEL(_drv_always_, "read length fail %d\n", len);
1759
1760                                         DBG_871X_LEVEL(_drv_always_, "RecvOnePkt Result: %d\n", res);
1761                                 }
1762                         } while (trycnt--);
1763
1764                         if (trycnt == 0)
1765                                 DBG_871X_LEVEL(_drv_always_, "Stop RX DMA failed......\n");
1766
1767                         /*  3. Clear IMR and ISR */
1768                         DBG_871X_LEVEL(_drv_always_, "Clear IMR and ISR\n");
1769                         tmp = 0;
1770                         sdio_local_write(padapter, SDIO_REG_HIMR_ON, 4, (u8 *)&tmp);
1771                         sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1772                         sdio_local_read(padapter, SDIO_REG_HISR, 4, (u8 *)&tmp);
1773                         sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8 *)&tmp);
1774
1775                         /*  4. Enable CPWM2 only */
1776                         DBG_871X_LEVEL(_drv_always_, "Enable only CPWM2\n");
1777                         sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1778                         DBG_871X("DisableInterruptButCpwm28723BSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
1779
1780                         himr = cpu_to_le32(SDIO_HIMR_DISABLED)|SDIO_HIMR_CPWM2_MSK;
1781                         sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1782
1783                         sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1784                         DBG_871X("DisableInterruptButCpwm28723BSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1785
1786                         /*  5. Set Enable WOWLAN H2C command. */
1787                         DBG_871X_LEVEL(_drv_always_, "Set Enable AP WOWLan cmd\n");
1788                         rtl8723b_set_ap_wowlan_cmd(padapter, 1);
1789                         /*  6. add some delay for H2C cmd ready */
1790                         msleep(10);
1791
1792                         rtw_write8(padapter, REG_WOWLAN_WAKE_REASON, 0);
1793                         break;
1794                 case WOWLAN_AP_DISABLE:
1795                         DBG_871X("%s, WOWLAN_AP_DISABLE\n", __func__);
1796                         /*  1. Read wakeup reason */
1797                         pwrctl->wowlan_wake_reason =
1798                                 rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
1799
1800                         DBG_871X_LEVEL(_drv_always_, "wakeup_reason: 0x%02x\n",
1801                                         pwrctl->wowlan_wake_reason);
1802
1803                         /*  2.  Set Disable WOWLAN H2C command. */
1804                         DBG_871X_LEVEL(_drv_always_, "Set Disable WOWLan cmd\n");
1805                         rtl8723b_set_ap_wowlan_cmd(padapter, 0);
1806                         /*  6. add some delay for H2C cmd ready */
1807                         msleep(2);
1808
1809                         DBG_871X_LEVEL(_drv_always_, "Release RXDMA\n");
1810
1811                         rtw_write32(padapter, REG_RXPKT_NUM,
1812                                 (rtw_read32(padapter, REG_RXPKT_NUM) & (~RW_RELEASE_EN)));
1813
1814                         SetFwRelatedForWoWLAN8723b(padapter, false);
1815
1816 #ifdef CONFIG_GPIO_WAKEUP
1817                         DBG_871X_LEVEL(_drv_always_, "Set Wake GPIO to high for default.\n");
1818                         HalSetOutPutGPIO(padapter, WAKEUP_GPIO_IDX, 1);
1819 #endif /* CONFIG_GPIO_WAKEUP */
1820                         rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);
1821                         issue_beacon(padapter, 0);
1822                         break;
1823                 default:
1824                         break;
1825                 }
1826         }
1827                 break;
1828 #endif /* CONFIG_AP_WOWLAN */
1829                 case HW_VAR_DM_IN_LPS:
1830                         rtl8723b_hal_dm_in_lps(padapter);
1831                         break;
1832                 default:
1833                         SetHwReg8723B(padapter, variable, val);
1834                         break;
1835         }
1836 }
1837
1838 /*
1839  * If variable not handled here,
1840  * some variables will be processed in GetHwReg8723B()
1841  */
1842 static void GetHwReg8723BS(struct adapter *padapter, u8 variable, u8 *val)
1843 {
1844         switch (variable) {
1845         case HW_VAR_CPWM:
1846                 *val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HCPWM1_8723B);
1847                 break;
1848
1849         case HW_VAR_FW_PS_STATE:
1850                 {
1851                         /* 3. read dword 0x88               driver read fw ps state */
1852                         *((u16*)val) = rtw_read16(padapter, 0x88);
1853                 }
1854                 break;
1855         default:
1856                 GetHwReg8723B(padapter, variable, val);
1857                 break;
1858         }
1859 }
1860
1861 static void SetHwRegWithBuf8723B(struct adapter *padapter, u8 variable, u8 *pbuf, int len)
1862 {
1863         switch (variable) {
1864         case HW_VAR_C2H_HANDLE:
1865                 /* DBG_8192C("%s len =%d\n", __func__, len); */
1866                 C2HPacketHandler_8723B(padapter, pbuf, len);
1867                 break;
1868         default:
1869                 break;
1870         }
1871 }
1872
1873 /*  */
1874 /*      Description: */
1875 /*              Query setting of specified variable. */
1876 /*  */
1877 static u8
1878 GetHalDefVar8723BSDIO(
1879 struct adapter *                        Adapter,
1880 enum HAL_DEF_VARIABLE           eVariable,
1881 void *                          pValue
1882         )
1883 {
1884         u8      bResult = _SUCCESS;
1885
1886         switch (eVariable)
1887         {
1888                 case HAL_DEF_IS_SUPPORT_ANT_DIV:
1889                         break;
1890                 case HAL_DEF_CURRENT_ANTENNA:
1891                         break;
1892                 case HW_VAR_MAX_RX_AMPDU_FACTOR:
1893                         /*  Stanley@BB.SD3 suggests 16K can get stable performance */
1894                         /*  coding by Lucas@20130730 */
1895                         *(u32*)pValue = MAX_AMPDU_FACTOR_16K;
1896                         break;
1897                 default:
1898                         bResult = GetHalDefVar8723B(Adapter, eVariable, pValue);
1899                         break;
1900         }
1901
1902         return bResult;
1903 }
1904
1905 /*  */
1906 /*      Description: */
1907 /*              Change default setting of specified variable. */
1908 /*  */
1909 static u8 SetHalDefVar8723BSDIO(struct adapter *Adapter,
1910                                 enum HAL_DEF_VARIABLE eVariable, void *pValue)
1911 {
1912         return SetHalDefVar8723B(Adapter, eVariable, pValue);
1913 }
1914
1915 void rtl8723bs_set_hal_ops(struct adapter *padapter)
1916 {
1917         struct hal_ops *pHalFunc = &padapter->HalFunc;
1918
1919         rtl8723b_set_hal_ops(pHalFunc);
1920
1921         pHalFunc->hal_init = &rtl8723bs_hal_init;
1922         pHalFunc->hal_deinit = &rtl8723bs_hal_deinit;
1923
1924         pHalFunc->inirp_init = &rtl8723bs_inirp_init;
1925         pHalFunc->inirp_deinit = &rtl8723bs_inirp_deinit;
1926
1927         pHalFunc->init_xmit_priv = &rtl8723bs_init_xmit_priv;
1928         pHalFunc->free_xmit_priv = &rtl8723bs_free_xmit_priv;
1929
1930         pHalFunc->init_recv_priv = &rtl8723bs_init_recv_priv;
1931         pHalFunc->free_recv_priv = &rtl8723bs_free_recv_priv;
1932
1933         pHalFunc->init_default_value = &rtl8723bs_init_default_value;
1934         pHalFunc->intf_chip_configure = &rtl8723bs_interface_configure;
1935         pHalFunc->read_adapter_info = &ReadAdapterInfo8723BS;
1936
1937         pHalFunc->enable_interrupt = &EnableInterrupt8723BSdio;
1938         pHalFunc->disable_interrupt = &DisableInterrupt8723BSdio;
1939         pHalFunc->check_ips_status = &CheckIPSStatus;
1940 #ifdef CONFIG_WOWLAN
1941         pHalFunc->clear_interrupt = &ClearInterrupt8723BSdio;
1942 #endif
1943         pHalFunc->SetHwRegHandler = &SetHwReg8723BS;
1944         pHalFunc->GetHwRegHandler = &GetHwReg8723BS;
1945         pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B;
1946         pHalFunc->GetHalDefVarHandler = &GetHalDefVar8723BSDIO;
1947         pHalFunc->SetHalDefVarHandler = &SetHalDefVar8723BSDIO;
1948
1949         pHalFunc->hal_xmit = &rtl8723bs_hal_xmit;
1950         pHalFunc->mgnt_xmit = &rtl8723bs_mgnt_xmit;
1951         pHalFunc->hal_xmitframe_enqueue = &rtl8723bs_hal_xmitframe_enqueue;
1952
1953 #if defined(CONFIG_CHECK_BT_HANG)
1954         pHalFunc->hal_init_checkbthang_workqueue = &rtl8723bs_init_checkbthang_workqueue;
1955         pHalFunc->hal_free_checkbthang_workqueue = &rtl8723bs_free_checkbthang_workqueue;
1956         pHalFunc->hal_cancle_checkbthang_workqueue = &rtl8723bs_cancle_checkbthang_workqueue;
1957         pHalFunc->hal_checke_bt_hang = &rtl8723bs_hal_check_bt_hang;
1958 #endif
1959 }