Linux 3.15-rc2
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rtl8723au / hal / rtl8723a_dm.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 /*  */
16 /*  Description: */
17 /*  */
18 /*  This file is for 92CE/92CU dynamic mechanism only */
19 /*  */
20 /*  */
21 /*  */
22 #define _RTL8723A_DM_C_
23
24 /*  */
25 /*  include files */
26 /*  */
27 #include <osdep_service.h>
28 #include <drv_types.h>
29
30 #include <rtl8723a_hal.h>
31
32 /*  */
33 /*  Global var */
34 /*  */
35
36 static void dm_CheckStatistics(struct rtw_adapter *Adapter)
37 {
38 }
39
40 static void dm_CheckPbcGPIO(struct rtw_adapter *padapter)
41 {
42         u8      tmp1byte;
43         u8      bPbcPressed = false;
44
45         if (!padapter->registrypriv.hw_wps_pbc)
46                 return;
47
48         tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
49         tmp1byte |= (HAL_8192C_HW_GPIO_WPS_BIT);
50         rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);    /* enable GPIO[2] as output mode */
51
52         tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
53         rtw_write8(padapter,  GPIO_IN, tmp1byte);               /* reset the floating voltage level */
54
55         tmp1byte = rtw_read8(padapter, GPIO_IO_SEL);
56         tmp1byte &= ~(HAL_8192C_HW_GPIO_WPS_BIT);
57         rtw_write8(padapter, GPIO_IO_SEL, tmp1byte);    /* enable GPIO[2] as input mode */
58
59         tmp1byte = rtw_read8(padapter, GPIO_IN);
60
61         if (tmp1byte == 0xff)
62                 return;
63
64         if (tmp1byte&HAL_8192C_HW_GPIO_WPS_BIT)
65                 bPbcPressed = true;
66
67         if (bPbcPressed) {
68                 /*  Here we only set bPbcPressed to true */
69                 /*  After trigger PBC, the variable will be set to false */
70                 DBG_8723A("CheckPbcGPIO - PBC is pressed\n");
71
72                 if (padapter->pid[0] == 0) {
73                         /* 0 is the default value and it means the application
74                          * monitors the HW PBC doesn't privde its pid to driver.
75                          */
76                         return;
77                 }
78
79                 rtw_signal_process(padapter->pid[0], SIGUSR1);
80         }
81 }
82
83 /*  Initialize GPIO setting registers */
84 /*  functions */
85 static void Init_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
86 {
87
88         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
89         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
90         u8      cut_ver, fab_ver;
91
92         /*  */
93         /*  Init Value */
94         /*  */
95         memset(pDM_Odm, 0, sizeof(*pDM_Odm));
96
97         pDM_Odm->Adapter = Adapter;
98         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PLATFORM, 0x04);
99         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_INTERFACE, RTW_USB);/* RTL871X_HCI_TYPE */
100
101         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8723A);
102
103         if (IS_8723A_A_CUT(pHalData->VersionID)) {
104                 fab_ver = ODM_UMC;
105                 cut_ver = ODM_CUT_A;
106         } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
107                 fab_ver = ODM_UMC;
108                 cut_ver = ODM_CUT_B;
109         } else {
110                 fab_ver = ODM_TSMC;
111                 cut_ver = ODM_CUT_A;
112         }
113         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_FAB_VER, fab_ver);
114         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_CUT_VER, cut_ver);
115         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(pHalData->VersionID));
116
117         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BOARD_TYPE, pHalData->BoardType);
118
119         if (pHalData->BoardType == BOARD_USB_High_PA) {
120                 ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_LNA, true);
121                 ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_EXT_PA, true);
122         }
123         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_PATCH_ID, pHalData->CustomerID);
124         ODM_CmnInfoInit23a(pDM_Odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec);
125
126         if (pHalData->rf_type == RF_1T1R)
127                 ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
128         else if (pHalData->rf_type == RF_2T2R)
129                 ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
130         else if (pHalData->rf_type == RF_1T2R)
131                 ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
132 }
133
134 static void Update_ODM_ComInfo_8723a(struct rtw_adapter *Adapter)
135 {
136         struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
137         struct mlme_priv                *pmlmepriv = &Adapter->mlmepriv;
138         struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
139         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
140         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
141         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
142         int i;
143         pdmpriv->InitODMFlag =  ODM_BB_DIG              |
144                                 ODM_BB_RA_MASK          |
145                                 ODM_BB_DYNAMIC_TXPWR    |
146                                 ODM_BB_FA_CNT           |
147                                 ODM_BB_RSSI_MONITOR     |
148                                 ODM_BB_CCK_PD           |
149                                 ODM_BB_PWR_SAVE         |
150                                 ODM_MAC_EDCA_TURBO      |
151                                 ODM_RF_TX_PWR_TRACK     |
152                                 ODM_RF_CALIBRATION;
153         /*  Pointer reference */
154
155         ODM_CmnInfoUpdate23a(pDM_Odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
156
157         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_TX_UNI,
158                            &Adapter->xmitpriv.tx_bytes);
159         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_RX_UNI,
160                            &Adapter->recvpriv.rx_bytes);
161         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_WM_MODE,
162                            &pmlmeext->cur_wireless_mode);
163         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_CHNL_OFFSET,
164                            &pHalData->nCur40MhzPrimeSC);
165         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SEC_MODE,
166                            &Adapter->securitypriv.dot11PrivacyAlgrthm);
167         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_BW,
168                            &pHalData->CurrentChannelBW);
169         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_CHNL,
170                            &pHalData->CurrentChannel);
171         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed);
172
173         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess);
174         ODM23a_CmnInfoHook(pDM_Odm, ODM_CMNINFO_POWER_SAVING,
175                            &pwrctrlpriv->bpower_saving);
176
177         for (i = 0; i < NUM_STA; i++)
178                 ODM_CmnInfoPtrArrayHook23a(pDM_Odm, ODM_CMNINFO_STA_STATUS, i, NULL);
179 }
180
181 void rtl8723a_InitHalDm(struct rtw_adapter *Adapter)
182 {
183         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
184         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
185         struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
186         u8      i;
187
188         pdmpriv->DM_Type = DM_Type_ByDriver;
189         pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
190
191 #ifdef CONFIG_8723AU_BT_COEXIST
192         pdmpriv->DMFlag |= DYNAMIC_FUNC_BT;
193 #endif
194         pdmpriv->InitDMFlag = pdmpriv->DMFlag;
195
196         Update_ODM_ComInfo_8723a(Adapter);
197         ODM23a_DMInit(pDM_Odm);
198         /*  Save REG_INIDATA_RATE_SEL value for TXDESC. */
199         for (i = 0; i < 32; i++)
200                 pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL+i) & 0x3f;
201 }
202
203 void
204 rtl8723a_HalDmWatchDog(
205         struct rtw_adapter *Adapter
206         )
207 {
208         bool            bFwCurrentInPSMode = false;
209         bool            bFwPSAwake = true;
210         u8 hw_init_completed = false;
211         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
212         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
213
214         hw_init_completed = Adapter->hw_init_completed;
215
216         if (hw_init_completed == false)
217                 goto skip_dm;
218
219         bFwCurrentInPSMode = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
220         rtw23a_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&bFwPSAwake));
221
222 #ifdef CONFIG_8723AU_P2P
223         /*  Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */
224         /*  modifed by thomas. 2011.06.11. */
225         if (Adapter->wdinfo.p2p_ps_mode)
226                 bFwPSAwake = false;
227 #endif /* CONFIG_8723AU_P2P */
228
229         if ((hw_init_completed) && ((!bFwCurrentInPSMode) && bFwPSAwake)) {
230                 /*  Calculate Tx/Rx statistics. */
231                 dm_CheckStatistics(Adapter);
232
233                 /*  Read REG_INIDATA_RATE_SEL value for TXDESC. */
234                 if (check_fwstate(&Adapter->mlmepriv, WIFI_STATION_STATE)) {
235                         pdmpriv->INIDATA_RATE[0] = rtw_read8(Adapter, REG_INIDATA_RATE_SEL) & 0x3f;
236                 } else {
237                         u8      i;
238                         for (i = 1 ; i < (Adapter->stapriv.asoc_sta_count + 1); i++)
239                                 pdmpriv->INIDATA_RATE[i] = rtw_read8(Adapter, (REG_INIDATA_RATE_SEL+i)) & 0x3f;
240                 }
241         }
242
243         /* ODM */
244         if (hw_init_completed == true) {
245                 u8      bLinked = false;
246
247                 if (rtw_linked_check(Adapter))
248                         bLinked = true;
249
250                 ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_LINK,
251                                      bLinked);
252                 ODM_DMWatchdog23a(&pHalData->odmpriv);
253         }
254
255 skip_dm:
256
257         /*  Check GPIO to determine current RF on/off and Pbc status. */
258         /*  Check Hardware Radio ON/OFF or not */
259         dm_CheckPbcGPIO(Adapter);
260 }
261
262 void rtl8723a_init_dm_priv(struct rtw_adapter *Adapter)
263 {
264         struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
265         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
266
267         memset(pdmpriv, 0, sizeof(struct dm_priv));
268         Init_ODM_ComInfo_8723a(Adapter);
269 }
270
271 void rtl8723a_deinit_dm_priv(struct rtw_adapter *Adapter)
272 {
273 }