fab385774400f5996249b7f89b2192423b2f8efe
[linux-2.6-microblaze.git] / drivers / staging / r8188eu / hal / rtl8188e_dm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 /*  This file is for 92CE/92CU dynamic mechanism only */
5 #define _RTL8188E_DM_C_
6
7 #include "../include/osdep_service.h"
8 #include "../include/drv_types.h"
9 #include "../include/rtl8188e_hal.h"
10
11 static void dm_CheckStatistics(struct adapter *Adapter)
12 {
13 }
14
15 /*  Initialize GPIO setting registers */
16 static void dm_InitGPIOSetting(struct adapter *Adapter)
17 {
18         u8      tmp1byte;
19
20         tmp1byte = rtw_read8(Adapter, REG_GPIO_MUXCFG);
21         tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
22
23         rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
24 }
25
26 /*  */
27 /*  functions */
28 /*  */
29 static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
30 {
31         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
32         struct dm_priv  *pdmpriv = &hal_data->dmpriv;
33         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
34         u8 cut_ver, fab_ver;
35
36         /*  Init Value */
37         memset(dm_odm, 0, sizeof(*dm_odm));
38
39         dm_odm->Adapter = Adapter;
40
41         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PLATFORM, ODM_CE);
42
43         if (Adapter->interface_type == RTW_GSPI)
44                 ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, ODM_ITRF_SDIO);
45         else
46                 ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_INTERFACE, Adapter->interface_type);/* RTL871X_HCI_TYPE */
47
48         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_IC_TYPE, ODM_RTL8188E);
49
50         fab_ver = ODM_TSMC;
51         cut_ver = ODM_CUT_A;
52
53         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_FAB_VER, fab_ver);
54         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_CUT_VER, cut_ver);
55
56         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID));
57
58         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_PATCH_ID, hal_data->CustomerID);
59         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_BWIFI_TEST, Adapter->registrypriv.wifi_spec);
60
61         if (hal_data->rf_type == RF_1T1R)
62                 ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T1R);
63         else if (hal_data->rf_type == RF_2T2R)
64                 ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_2T2R);
65         else if (hal_data->rf_type == RF_1T2R)
66                 ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_RF_TYPE, ODM_1T2R);
67
68         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
69
70         pdmpriv->InitODMFlag =  ODM_RF_CALIBRATION |
71                                 ODM_RF_TX_PWR_TRACK;
72
73         ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
74 }
75
76 static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
77 {
78         struct mlme_ext_priv    *pmlmeext = &Adapter->mlmeextpriv;
79         struct mlme_priv        *pmlmepriv = &Adapter->mlmepriv;
80         struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
81         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
82         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
83         struct dm_priv  *pdmpriv = &hal_data->dmpriv;
84         int i;
85
86         pdmpriv->InitODMFlag =  ODM_BB_DIG |
87                                 ODM_BB_RA_MASK |
88                                 ODM_BB_DYNAMIC_TXPWR |
89                                 ODM_BB_FA_CNT |
90                                 ODM_BB_RSSI_MONITOR |
91                                 ODM_BB_CCK_PD |
92                                 ODM_BB_PWR_SAVE |
93                                 ODM_MAC_EDCA_TURBO |
94                                 ODM_RF_CALIBRATION |
95                                 ODM_RF_TX_PWR_TRACK;
96         if (hal_data->AntDivCfg)
97                 pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV;
98
99         if (Adapter->registrypriv.mp_mode == 1) {
100                 pdmpriv->InitODMFlag =  ODM_RF_CALIBRATION |
101                                         ODM_RF_TX_PWR_TRACK;
102         }
103
104         ODM_CmnInfoUpdate(dm_odm, ODM_CMNINFO_ABILITY, pdmpriv->InitODMFlag);
105
106         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_TX_UNI, &Adapter->xmitpriv.tx_bytes);
107         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_RX_UNI, &Adapter->recvpriv.rx_bytes);
108         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_WM_MODE, &pmlmeext->cur_wireless_mode);
109         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_CHNL_OFFSET, &hal_data->nCur40MhzPrimeSC);
110         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SEC_MODE, &Adapter->securitypriv.dot11PrivacyAlgrthm);
111         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_BW, &hal_data->CurrentChannelBW);
112         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_CHNL, &hal_data->CurrentChannel);
113         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_NET_CLOSED, &Adapter->net_closed);
114         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_MP_MODE, &Adapter->registrypriv.mp_mode);
115         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_SCAN, &pmlmepriv->bScanInProcess);
116         ODM_CmnInfoHook(dm_odm, ODM_CMNINFO_POWER_SAVING, &pwrctrlpriv->bpower_saving);
117         ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType);
118
119         for (i = 0; i < NUM_STA; i++)
120                 ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i, NULL);
121 }
122
123 void rtl8188e_InitHalDm(struct adapter *Adapter)
124 {
125         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
126         struct dm_priv  *pdmpriv = &hal_data->dmpriv;
127         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
128
129         dm_InitGPIOSetting(Adapter);
130         pdmpriv->DM_Type = DM_Type_ByDriver;
131         pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
132         Update_ODM_ComInfo_88E(Adapter);
133         ODM_DMInit(dm_odm);
134         Adapter->fix_rate = 0xFF;
135 }
136
137 void rtl8188e_HalDmWatchDog(struct adapter *Adapter)
138 {
139         bool fw_cur_in_ps = false;
140         bool fw_ps_awake = true;
141         u8 hw_init_completed = false;
142         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
143
144
145         hw_init_completed = Adapter->hw_init_completed;
146
147         if (!hw_init_completed)
148                 return;
149
150         fw_cur_in_ps = Adapter->pwrctrlpriv.bFwCurrentInPSMode;
151         rtw_hal_get_hwreg(Adapter, HW_VAR_FWLPS_RF_ON, (u8 *)(&fw_ps_awake));
152
153         /*  Fw is under p2p powersaving mode, driver should stop dynamic mechanism. */
154         /*  modifed by thomas. 2011.06.11. */
155         if (Adapter->wdinfo.p2p_ps_mode)
156                 fw_ps_awake = false;
157
158         if (hw_init_completed && ((!fw_cur_in_ps) && fw_ps_awake)) {
159                 /*  Calculate Tx/Rx statistics. */
160                 dm_CheckStatistics(Adapter);
161
162
163         }
164
165         /* ODM */
166         if (hw_init_completed) {
167                 struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
168                 u8 bLinked = false;
169
170                 if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
171                     (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))) {
172                         if (Adapter->stapriv.asoc_sta_count > 2)
173                                 bLinked = true;
174                 } else {/* Station mode */
175                         if (check_fwstate(pmlmepriv, _FW_LINKED))
176                                 bLinked = true;
177                 }
178
179                 ODM_CmnInfoUpdate(&hal_data->odmpriv, ODM_CMNINFO_LINK, bLinked);
180                 ODM_DMWatchdog(&hal_data->odmpriv);
181         }
182 }
183
184 void rtl8188e_init_dm_priv(struct adapter *Adapter)
185 {
186         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
187         struct dm_priv  *pdmpriv = &hal_data->dmpriv;
188         struct odm_dm_struct *podmpriv = &hal_data->odmpriv;
189
190         memset(pdmpriv, 0, sizeof(struct dm_priv));
191         Init_ODM_ComInfo_88E(Adapter);
192 }
193
194 void rtl8188e_deinit_dm_priv(struct adapter *Adapter)
195 {
196 }
197
198 /*  Add new function to reset the state of antenna diversity before link. */
199 /*  Compare RSSI for deciding antenna */
200 void AntDivCompare8188E(struct adapter *Adapter, struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src)
201 {
202         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
203
204         if (0 != hal_data->AntDivCfg) {
205                 /* select optimum_antenna for before linked =>For antenna diversity */
206                 if (dst->Rssi >=  src->Rssi) {/* keep org parameter */
207                         src->Rssi = dst->Rssi;
208                         src->PhyInfo.Optimum_antenna = dst->PhyInfo.Optimum_antenna;
209                 }
210         }
211 }
212
213 /*  Add new function to reset the state of antenna diversity before link. */
214 u8 AntDivBeforeLink8188E(struct adapter *Adapter)
215 {
216         struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter);
217         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
218         struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table;
219         struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
220
221         /*  Condition that does not need to use antenna diversity. */
222         if (hal_data->AntDivCfg == 0)
223                 return false;
224
225         if (check_fwstate(pmlmepriv, _FW_LINKED))
226                 return false;
227
228         if (dm_swat_tbl->SWAS_NoLink_State == 0) {
229                 /* switch channel */
230                 dm_swat_tbl->SWAS_NoLink_State = 1;
231                 dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ? Antenna_B : Antenna_A;
232
233                 rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false);
234                 return true;
235         } else {
236                 dm_swat_tbl->SWAS_NoLink_State = 0;
237                 return false;
238         }
239 }