1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. |
5 | * |
6 | ******************************************************************************/ |
7 | |
8 | #include "odm_precomp.h" |
9 | |
10 | static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = { |
11 | /*UNKNOWN, REALTEK_90, ALTEK_92SE BROADCOM, LINK ATHEROS, |
12 | *CISCO, MERU, MARVELL, 92U_AP, SELF_AP |
13 | */ |
14 | 0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322, |
15 | 0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b |
16 | }; |
17 | |
18 | static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { |
19 | /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS, |
20 | *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(DownLink/Tx) |
21 | */ |
22 | 0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322, |
23 | 0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322}; |
24 | |
25 | static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { |
26 | /*UNKNOWN, REALTEK_90, REALTEK_92SE, BROADCOM, RALINK, ATHEROS, |
27 | *CISCO, MERU, MARVELL, 92U_AP, SELF_AP(UpLink/Rx) |
28 | */ |
29 | 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630, |
30 | 0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b}; |
31 | |
32 | void ODM_EdcaTurboInit(void *pDM_VOID) |
33 | { |
34 | struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; |
35 | struct adapter *Adapter = pDM_Odm->Adapter; |
36 | |
37 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; |
38 | pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false; |
39 | Adapter->recvpriv.bIsAnyNonBEPkts = false; |
40 | } /* ODM_InitEdcaTurbo */ |
41 | |
42 | void odm_EdcaTurboCheck(void *pDM_VOID) |
43 | { |
44 | /* In HW integration first stage, we provide 4 different handles to |
45 | * operate at the same time. In stage2/3, we need to prove universal |
46 | * interface and merge all HW dynamic mechanism. |
47 | */ |
48 | struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; |
49 | |
50 | if (!(pDM_Odm->SupportAbility & ODM_MAC_EDCA_TURBO)) |
51 | return; |
52 | |
53 | odm_EdcaTurboCheckCE(pDM_VOID: pDM_Odm); |
54 | } /* odm_CheckEdcaTurbo */ |
55 | |
56 | void odm_EdcaTurboCheckCE(void *pDM_VOID) |
57 | { |
58 | struct dm_odm_t *pDM_Odm = (struct dm_odm_t *)pDM_VOID; |
59 | struct adapter *Adapter = pDM_Odm->Adapter; |
60 | struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter); |
61 | struct recv_priv *precvpriv = &(Adapter->recvpriv); |
62 | struct registry_priv *pregpriv = &Adapter->registrypriv; |
63 | struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); |
64 | struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); |
65 | u32 EDCA_BE_UL = 0x5ea42b; |
66 | u32 EDCA_BE_DL = 0x5ea42b; |
67 | u32 iot_peer = 0; |
68 | u8 wirelessmode = 0xFF; /* invalid value */ |
69 | u32 trafficIndex; |
70 | u32 edca_param; |
71 | u64 cur_tx_bytes = 0; |
72 | u64 cur_rx_bytes = 0; |
73 | u8 bbtchange = false; |
74 | u8 biasonrx = false; |
75 | struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); |
76 | |
77 | if (!pDM_Odm->bLinked) { |
78 | precvpriv->bIsAnyNonBEPkts = false; |
79 | return; |
80 | } |
81 | |
82 | if (pregpriv->wifi_spec == 1) { |
83 | precvpriv->bIsAnyNonBEPkts = false; |
84 | return; |
85 | } |
86 | |
87 | if (pDM_Odm->pwirelessmode) |
88 | wirelessmode = *(pDM_Odm->pwirelessmode); |
89 | |
90 | iot_peer = pmlmeinfo->assoc_AP_vendor; |
91 | |
92 | if (iot_peer >= HT_IOT_PEER_MAX) { |
93 | precvpriv->bIsAnyNonBEPkts = false; |
94 | return; |
95 | } |
96 | |
97 | /* Check if the status needs to be changed. */ |
98 | if ((bbtchange) || (!precvpriv->bIsAnyNonBEPkts)) { |
99 | cur_tx_bytes = pdvobjpriv->traffic_stat.cur_tx_bytes; |
100 | cur_rx_bytes = pdvobjpriv->traffic_stat.cur_rx_bytes; |
101 | |
102 | /* traffic, TX or RX */ |
103 | if (biasonrx) { |
104 | if (cur_tx_bytes > (cur_rx_bytes << 2)) { |
105 | /* Uplink TP is present. */ |
106 | trafficIndex = UP_LINK; |
107 | } else { /* Balance TP is present. */ |
108 | trafficIndex = DOWN_LINK; |
109 | } |
110 | } else { |
111 | if (cur_rx_bytes > (cur_tx_bytes << 2)) { |
112 | /* Downlink TP is present. */ |
113 | trafficIndex = DOWN_LINK; |
114 | } else { /* Balance TP is present. */ |
115 | trafficIndex = UP_LINK; |
116 | } |
117 | } |
118 | |
119 | /* 92D txop can't be set to 0x3e for cisco1250 */ |
120 | if ((iot_peer == HT_IOT_PEER_CISCO) && |
121 | (wirelessmode == ODM_WM_N24G)) { |
122 | EDCA_BE_DL = edca_setting_DL[iot_peer]; |
123 | EDCA_BE_UL = edca_setting_UL[iot_peer]; |
124 | } else if ((iot_peer == HT_IOT_PEER_CISCO) && |
125 | ((wirelessmode == ODM_WM_G) || |
126 | (wirelessmode == (ODM_WM_B | ODM_WM_G)) || |
127 | (wirelessmode == ODM_WM_B))) { |
128 | EDCA_BE_DL = edca_setting_DL_GMode[iot_peer]; |
129 | } else if ((iot_peer == HT_IOT_PEER_AIRGO) && |
130 | (wirelessmode == ODM_WM_G)) { |
131 | EDCA_BE_DL = 0xa630; |
132 | } else if (iot_peer == HT_IOT_PEER_MARVELL) { |
133 | EDCA_BE_DL = edca_setting_DL[iot_peer]; |
134 | EDCA_BE_UL = edca_setting_UL[iot_peer]; |
135 | } else if (iot_peer == HT_IOT_PEER_ATHEROS) { |
136 | /* Set DL EDCA for Atheros peer to 0x3ea42b. */ |
137 | EDCA_BE_DL = edca_setting_DL[iot_peer]; |
138 | } |
139 | |
140 | if (trafficIndex == DOWN_LINK) |
141 | edca_param = EDCA_BE_DL; |
142 | else |
143 | edca_param = EDCA_BE_UL; |
144 | |
145 | rtw_write32(adapter: Adapter, REG_EDCA_BE_PARAM, val: edca_param); |
146 | |
147 | pDM_Odm->DM_EDCA_Table.prv_traffic_idx = trafficIndex; |
148 | |
149 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = true; |
150 | } else { |
151 | /* Turn Off EDCA turbo here. */ |
152 | /* Restore original EDCA according to the declaration of AP. */ |
153 | if (pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA) { |
154 | rtw_write32(adapter: Adapter, REG_EDCA_BE_PARAM, val: pHalData->AcParam_BE); |
155 | pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false; |
156 | } |
157 | } |
158 | } |
159 | |