GNU Linux-libre 5.10.153-gnu1
[releases.git] / drivers / staging / rtl8188eu / hal / rtl8188e_dm.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 /*  */
8 /*  Description: */
9 /*  */
10 /*  This file is for 92CE/92CU dynamic mechanism only */
11 /*  */
12 /*  */
13 /*  */
14 #define _RTL8188E_DM_C_
15
16 #include <osdep_service.h>
17 #include <drv_types.h>
18
19 #include <rtl8188e_hal.h>
20
21 /*  Initialize GPIO setting registers */
22 static void dm_InitGPIOSetting(struct adapter *Adapter)
23 {
24         u8 tmp1byte;
25
26         tmp1byte = usb_read8(Adapter, REG_GPIO_MUXCFG);
27         tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT);
28
29         usb_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte);
30 }
31
32 static void Init_ODM_ComInfo_88E(struct adapter *Adapter)
33 {
34         struct hal_data_8188e *hal_data = Adapter->HalData;
35         struct dm_priv *pdmpriv = &hal_data->dmpriv;
36         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
37
38         /*  Init Value */
39         memset(dm_odm, 0, sizeof(*dm_odm));
40
41         dm_odm->Adapter = Adapter;
42         dm_odm->SupportPlatform = ODM_CE;
43         dm_odm->SupportICType = ODM_RTL8188E;
44         dm_odm->CutVersion = ODM_CUT_A;
45         dm_odm->bIsMPChip = hal_data->VersionID.ChipType == NORMAL_CHIP;
46         dm_odm->PatchID = hal_data->CustomerID;
47         dm_odm->bWIFITest = Adapter->registrypriv.wifi_spec;
48
49         dm_odm->AntDivType = hal_data->TRxAntDivType;
50
51         /* Tx power tracking BB swing table.
52          * The base index =
53          * 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB
54          */
55         dm_odm->BbSwingIdxOfdm = 12; /*  Set defalut value as index 12. */
56         dm_odm->BbSwingIdxOfdmCurrent = 12;
57         dm_odm->BbSwingFlagOfdm = false;
58
59         pdmpriv->InitODMFlag = ODM_RF_CALIBRATION |
60                                ODM_RF_TX_PWR_TRACK;
61
62         dm_odm->SupportAbility = pdmpriv->InitODMFlag;
63 }
64
65 static void Update_ODM_ComInfo_88E(struct adapter *Adapter)
66 {
67         struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
68         struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
69         struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
70         struct hal_data_8188e *hal_data = Adapter->HalData;
71         struct odm_dm_struct *dm_odm = &hal_data->odmpriv;
72         struct dm_priv *pdmpriv = &hal_data->dmpriv;
73         int i;
74
75         pdmpriv->InitODMFlag = ODM_BB_DIG |
76                                ODM_BB_RA_MASK |
77                                ODM_BB_DYNAMIC_TXPWR |
78                                ODM_BB_FA_CNT |
79                                ODM_BB_RSSI_MONITOR |
80                                ODM_BB_CCK_PD |
81                                ODM_BB_PWR_SAVE |
82                                ODM_MAC_EDCA_TURBO |
83                                ODM_RF_CALIBRATION |
84                                ODM_RF_TX_PWR_TRACK;
85         if (hal_data->AntDivCfg)
86                 pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV;
87
88         if (Adapter->registrypriv.mp_mode == 1) {
89                 pdmpriv->InitODMFlag = ODM_RF_CALIBRATION |
90                                        ODM_RF_TX_PWR_TRACK;
91         }
92
93         dm_odm->SupportAbility = pdmpriv->InitODMFlag;
94
95         dm_odm->pNumTxBytesUnicast = &Adapter->xmitpriv.tx_bytes;
96         dm_odm->pNumRxBytesUnicast = &Adapter->recvpriv.rx_bytes;
97         dm_odm->pWirelessMode = &pmlmeext->cur_wireless_mode;
98         dm_odm->pSecChOffset = &hal_data->nCur40MhzPrimeSC;
99         dm_odm->pSecurity = (u8 *)&Adapter->securitypriv.dot11PrivacyAlgrthm;
100         dm_odm->pBandWidth = (u8 *)&hal_data->CurrentChannelBW;
101         dm_odm->pChannel = &hal_data->CurrentChannel;
102         dm_odm->pbNet_closed = (bool *)&Adapter->net_closed;
103         dm_odm->mp_mode = &Adapter->registrypriv.mp_mode;
104         dm_odm->pbScanInProcess = (bool *)&pmlmepriv->bScanInProcess;
105         dm_odm->pbPowerSaving = (bool *)&pwrctrlpriv->bpower_saving;
106         dm_odm->AntDivType = hal_data->TRxAntDivType;
107
108         /* Tx power tracking BB swing table.
109          * The base index =
110          * 12. +((12-n)/2)dB 13~?? = decrease tx pwr by -((n-12)/2)dB
111          */
112         dm_odm->BbSwingIdxOfdm = 12; /*  Set defalut value as index 12. */
113         dm_odm->BbSwingIdxOfdmCurrent = 12;
114         dm_odm->BbSwingFlagOfdm = false;
115
116         for (i = 0; i < NUM_STA; i++)
117                 ODM_CmnInfoPtrArrayHook(dm_odm, ODM_CMNINFO_STA_STATUS, i,
118                                         NULL);
119 }
120
121 void rtl8188e_InitHalDm(struct adapter *Adapter)
122 {
123         struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
124         struct odm_dm_struct *dm_odm = &Adapter->HalData->odmpriv;
125
126         dm_InitGPIOSetting(Adapter);
127         pdmpriv->DM_Type = DM_Type_ByDriver;
128         pdmpriv->DMFlag = DYNAMIC_FUNC_DISABLE;
129         Update_ODM_ComInfo_88E(Adapter);
130         ODM_DMInit(dm_odm);
131 }
132
133 void rtw_hal_dm_watchdog(struct adapter *Adapter)
134 {
135         u8 hw_init_completed = false;
136         struct mlme_priv *pmlmepriv = NULL;
137         u8 bLinked = false;
138
139         hw_init_completed = Adapter->hw_init_completed;
140
141         if (!hw_init_completed)
142                 goto skip_dm;
143
144         /* ODM */
145         pmlmepriv = &Adapter->mlmepriv;
146
147         if ((check_fwstate(pmlmepriv, WIFI_AP_STATE)) ||
148             (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
149                            WIFI_ADHOC_MASTER_STATE))) {
150                 if (Adapter->stapriv.asoc_sta_count > 2)
151                         bLinked = true;
152         } else {/* Station mode */
153                 if (check_fwstate(pmlmepriv, _FW_LINKED))
154                         bLinked = true;
155         }
156
157         Adapter->HalData->odmpriv.bLinked = bLinked;
158         ODM_DMWatchdog(&Adapter->HalData->odmpriv);
159 skip_dm:
160         /*  Check GPIO to determine current RF on/off and Pbc status. */
161         /*  Check Hardware Radio ON/OFF or not */
162         return;
163 }
164
165 void rtw_hal_dm_init(struct adapter *Adapter)
166 {
167         struct dm_priv *pdmpriv = &Adapter->HalData->dmpriv;
168         struct odm_dm_struct *podmpriv = &Adapter->HalData->odmpriv;
169
170         memset(pdmpriv, 0, sizeof(struct dm_priv));
171         Init_ODM_ComInfo_88E(Adapter);
172         ODM_InitDebugSetting(podmpriv);
173 }
174
175 /*  Add new function to reset the state of antenna diversity before link. */
176 /*  Compare RSSI for deciding antenna */
177 void rtw_hal_antdiv_rssi_compared(struct adapter *Adapter,
178                                   struct wlan_bssid_ex *dst,
179                                   struct wlan_bssid_ex *src)
180 {
181         if (Adapter->HalData->AntDivCfg != 0) {
182                 /* select optimum_antenna for before linked => For antenna
183                  * diversity
184                  */
185                 if (dst->Rssi >= src->Rssi) {/* keep org parameter */
186                         src->Rssi = dst->Rssi;
187                         src->PhyInfo.Optimum_antenna =
188                                 dst->PhyInfo.Optimum_antenna;
189                 }
190         }
191 }
192
193 /*  Add new function to reset the state of antenna diversity before link. */
194 bool rtw_hal_antdiv_before_linked(struct adapter *Adapter)
195 {
196         struct odm_dm_struct *dm_odm = &Adapter->HalData->odmpriv;
197         struct sw_ant_switch *dm_swat_tbl = &dm_odm->DM_SWAT_Table;
198         struct mlme_priv *pmlmepriv = &Adapter->mlmepriv;
199
200         /*  Condition that does not need to use antenna diversity. */
201         if (Adapter->HalData->AntDivCfg == 0)
202                 return false;
203
204         if (check_fwstate(pmlmepriv, _FW_LINKED))
205                 return false;
206
207         if (dm_swat_tbl->SWAS_NoLink_State != 0) {
208                 dm_swat_tbl->SWAS_NoLink_State = 0;
209                 return false;
210         }
211
212         /* switch channel */
213         dm_swat_tbl->SWAS_NoLink_State = 1;
214         dm_swat_tbl->CurAntenna = (dm_swat_tbl->CurAntenna == Antenna_A) ?
215                                   Antenna_B : Antenna_A;
216
217         rtw_antenna_select_cmd(Adapter, dm_swat_tbl->CurAntenna, false);
218         return true;
219 }