GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / staging / rtl8723bs / hal / odm_EdcaTurboCheck.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15
16 #include "odm_precomp.h"
17
18 static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
19 /*UNKNOWN, REALTEK_90, ALTEK_92SE       BROADCOM, LINK  ATHEROS,
20  *CISCO, MERU, MARVELL, 92U_AP, SELF_AP
21  */
22         0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322,
23         0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b
24 };
25
26 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
27 /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS,
28  *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(DownLink/Tx)
29  */
30         0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322,
31         0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322};
32
33 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
34 /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS,
35  *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(UpLink/Rx)
36  */
37         0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630,
38         0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b};
39
40 void ODM_EdcaTurboInit(void *pDM_VOID)
41 {
42         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
43         struct adapter *Adapter = pDM_Odm->Adapter;
44
45         pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
46         pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false;
47         Adapter->recvpriv.bIsAnyNonBEPkts = false;
48
49         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
50                      ("Orginial VO PARAM: 0x%x\n",
51                       rtw_read32(pDM_Odm->Adapter, ODM_EDCA_VO_PARAM)));
52         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
53                      ("Orginial VI PARAM: 0x%x\n",
54                       rtw_read32(pDM_Odm->Adapter, ODM_EDCA_VI_PARAM)));
55         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
56                      ("Orginial BE PARAM: 0x%x\n",
57                       rtw_read32(pDM_Odm->Adapter, ODM_EDCA_BE_PARAM)));
58         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
59                      ("Orginial BK PARAM: 0x%x\n",
60                       rtw_read32(pDM_Odm->Adapter, ODM_EDCA_BK_PARAM)));
61 }       /*  ODM_InitEdcaTurbo */
62
63 void odm_EdcaTurboCheck(void *pDM_VOID)
64 {
65         /*  In HW integration first stage, we provide 4 different handles to
66          *  operate at the same time. In stage2/3, we need to prove universal
67          *  interface and merge all HW dynamic mechanism.
68          */
69         PDM_ODM_T               pDM_Odm = (PDM_ODM_T)pDM_VOID;
70
71         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
72                      ("odm_EdcaTurboCheck ========================>\n"));
73
74         if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO))
75                 return;
76
77         odm_EdcaTurboCheckCE(pDM_Odm);
78         ODM_RT_TRACE(pDM_Odm, ODM_COMP_EDCA_TURBO, ODM_DBG_LOUD,
79                      ("<========================odm_EdcaTurboCheck\n"));
80 }       /*  odm_CheckEdcaTurbo */
81
82 void odm_EdcaTurboCheckCE(void *pDM_VOID)
83 {
84         PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID;
85         struct adapter *Adapter = pDM_Odm->Adapter;
86         struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
87         struct recv_priv *precvpriv = &(Adapter->recvpriv);
88         struct registry_priv *pregpriv = &Adapter->registrypriv;
89         struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv);
90         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
91         u32 EDCA_BE_UL = 0x5ea42b;
92         u32 EDCA_BE_DL = 0x5ea42b;
93         u32 iot_peer = 0;
94         u8 wirelessmode = 0xFF;         /* invalid value */
95         u32 trafficIndex;
96         u32 edca_param;
97         u64     cur_tx_bytes = 0;
98         u64     cur_rx_bytes = 0;
99         u8 bbtchange = false;
100         u8 biasonrx = false;
101         struct hal_com_data     *pHalData = GET_HAL_DATA(Adapter);
102
103         if (!pDM_Odm->bLinked) {
104                 precvpriv->bIsAnyNonBEPkts = false;
105                 return;
106         }
107
108         if ((pregpriv->wifi_spec == 1)) {
109                 precvpriv->bIsAnyNonBEPkts = false;
110                 return;
111         }
112
113         if (pDM_Odm->pwirelessmode)
114                 wirelessmode = *(pDM_Odm->pwirelessmode);
115
116         iot_peer = pmlmeinfo->assoc_AP_vendor;
117
118         if (iot_peer >=  HT_IOT_PEER_MAX) {
119                 precvpriv->bIsAnyNonBEPkts = false;
120                 return;
121         }
122
123         /*  Check if the status needs to be changed. */
124         if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) {
125                 cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes;
126                 cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes;
127
128                 /* traffic, TX or RX */
129                 if (biasonrx) {
130                         if (cur_tx_bytes > (cur_rx_bytes << 2)) {
131                                 /*  Uplink TP is present. */
132                                 trafficIndex = UP_LINK;
133                         } else { /*  Balance TP is present. */
134                                 trafficIndex = DOWN_LINK;
135                         }
136                 } else {
137                         if (cur_rx_bytes > (cur_tx_bytes << 2)) {
138                                 /*  Downlink TP is present. */
139                                 trafficIndex = DOWN_LINK;
140                         } else { /*  Balance TP is present. */
141                                 trafficIndex = UP_LINK;
142                         }
143                 }
144
145                 /* 92D txop can't be set to 0x3e for cisco1250 */
146                 if ((iot_peer == HT_IOT_PEER_CISCO) &&
147                     (wirelessmode == ODM_WM_N24G)) {
148                         EDCA_BE_DL = edca_setting_DL[iot_peer];
149                         EDCA_BE_UL = edca_setting_UL[iot_peer];
150                 } else if ((iot_peer == HT_IOT_PEER_CISCO) &&
151                            ((wirelessmode == ODM_WM_G) ||
152                             (wirelessmode == (ODM_WM_B | ODM_WM_G)) ||
153                             (wirelessmode == ODM_WM_A) ||
154                             (wirelessmode == ODM_WM_B))) {
155                         EDCA_BE_DL = edca_setting_DL_GMode[iot_peer];
156                 } else if ((iot_peer == HT_IOT_PEER_AIRGO) &&
157                            ((wirelessmode == ODM_WM_G) ||
158                             (wirelessmode == ODM_WM_A))) {
159                         EDCA_BE_DL = 0xa630;
160                 } else if (iot_peer == HT_IOT_PEER_MARVELL) {
161                         EDCA_BE_DL = edca_setting_DL[iot_peer];
162                         EDCA_BE_UL = edca_setting_UL[iot_peer];
163                 } else if (iot_peer == HT_IOT_PEER_ATHEROS) {
164                         /*  Set DL EDCA for Atheros peer to 0x3ea42b. */
165                         EDCA_BE_DL = edca_setting_DL[iot_peer];
166                 }
167
168                 if (trafficIndex == DOWN_LINK)
169                         edca_param = EDCA_BE_DL;
170                 else
171                         edca_param = EDCA_BE_UL;
172
173                 rtw_write32(Adapter, REG_EDCA_BE_PARAM, edca_param);
174
175                 pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex;
176
177                 pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true;
178         } else {
179                 /*  Turn Off EDCA turbo here. */
180                 /*  Restore original EDCA according to the declaration of AP. */
181                  if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) {
182                         rtw_write32(Adapter, REG_EDCA_BE_PARAM, pHalData->AcParam_BE);
183                         pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
184                 }
185         }
186 }