]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
a0da203b LF |
2 | /*++ |
3 | Copyright (c) Realtek Semiconductor Corp. All rights reserved. | |
4 | ||
5 | Module Name: | |
6 | RateAdaptive.c | |
7 | ||
8 | Abstract: | |
9 | Implement Rate Adaptive functions for common operations. | |
10 | ||
11 | Major Change History: | |
12 | When Who What | |
13 | ---------- --------------- ------------------------------- | |
14 | 2011-08-12 Page Create. | |
15 | ||
16 | --*/ | |
17 | #include "odm_precomp.h" | |
18 | ||
19 | /* Rate adaptive parameters */ | |
20 | ||
21 | static u8 RETRY_PENALTY[PERENTRY][RETRYSIZE+1] = { | |
22 | {5, 4, 3, 2, 0, 3}, /* 92 , idx = 0 */ | |
23 | {6, 5, 4, 3, 0, 4}, /* 86 , idx = 1 */ | |
24 | {6, 5, 4, 2, 0, 4}, /* 81 , idx = 2 */ | |
25 | {8, 7, 6, 4, 0, 6}, /* 75 , idx = 3 */ | |
26 | {10, 9, 8, 6, 0, 8}, /* 71 , idx = 4 */ | |
27 | {10, 9, 8, 4, 0, 8}, /* 66 , idx = 5 */ | |
28 | {10, 9, 8, 2, 0, 8}, /* 62 , idx = 6 */ | |
29 | {10, 9, 8, 0, 0, 8}, /* 59 , idx = 7 */ | |
30 | {18, 17, 16, 8, 0, 16}, /* 53 , idx = 8 */ | |
31 | {26, 25, 24, 16, 0, 24}, /* 50 , idx = 9 */ | |
32 | {34, 33, 32, 24, 0, 32}, /* 47 , idx = 0x0a */ | |
33 | {34, 31, 28, 20, 0, 32}, /* 43 , idx = 0x0b */ | |
34 | {34, 31, 27, 18, 0, 32}, /* 40 , idx = 0x0c */ | |
35 | {34, 31, 26, 16, 0, 32}, /* 37 , idx = 0x0d */ | |
36 | {34, 30, 22, 16, 0, 32}, /* 32 , idx = 0x0e */ | |
37 | {34, 30, 24, 16, 0, 32}, /* 26 , idx = 0x0f */ | |
38 | {49, 46, 40, 16, 0, 48}, /* 20 , idx = 0x10 */ | |
39 | {49, 45, 32, 0, 0, 48}, /* 17 , idx = 0x11 */ | |
40 | {49, 45, 22, 18, 0, 48}, /* 15 , idx = 0x12 */ | |
41 | {49, 40, 24, 16, 0, 48}, /* 12 , idx = 0x13 */ | |
42 | {49, 32, 18, 12, 0, 48}, /* 9 , idx = 0x14 */ | |
43 | {49, 22, 18, 14, 0, 48}, /* 6 , idx = 0x15 */ | |
44 | {49, 16, 16, 0, 0, 48} | |
45 | }; /* 3, idx = 0x16 */ | |
46 | ||
47 | static u8 PT_PENALTY[RETRYSIZE+1] = {34, 31, 30, 24, 0, 32}; | |
48 | ||
49 | /* wilson modify */ | |
50 | static u8 RETRY_PENALTY_IDX[2][RATESIZE] = { | |
51 | {4, 4, 4, 5, 4, 4, 5, 7, 7, 7, 8, 0x0a, /* SS>TH */ | |
52 | 4, 4, 4, 4, 6, 0x0a, 0x0b, 0x0d, | |
53 | 5, 5, 7, 7, 8, 0x0b, 0x0d, 0x0f}, /* 0329 R01 */ | |
54 | {0x0a, 0x0a, 0x0b, 0x0c, 0x0a, | |
55 | 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x13, 0x14, /* SS<TH */ | |
56 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x15, | |
57 | 9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13} | |
58 | }; | |
59 | ||
60 | static u8 RETRY_PENALTY_UP_IDX[RATESIZE] = { | |
61 | 0x0c, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, | |
62 | 0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14, /* SS>TH */ | |
63 | 0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15, | |
64 | 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15}; | |
65 | ||
66 | static u8 RSSI_THRESHOLD[RATESIZE] = { | |
67 | 0, 0, 0, 0, | |
68 | 0, 0, 0, 0, 0, 0x24, 0x26, 0x2a, | |
69 | 0x18, 0x1a, 0x1d, 0x1f, 0x21, 0x27, 0x29, 0x2a, | |
70 | 0, 0, 0, 0x1f, 0x23, 0x28, 0x2a, 0x2c}; | |
71 | ||
72 | static u16 N_THRESHOLD_HIGH[RATESIZE] = { | |
73 | 4, 4, 8, 16, | |
74 | 24, 36, 48, 72, 96, 144, 192, 216, | |
75 | 60, 80, 100, 160, 240, 400, 560, 640, | |
76 | 300, 320, 480, 720, 1000, 1200, 1600, 2000}; | |
77 | static u16 N_THRESHOLD_LOW[RATESIZE] = { | |
78 | 2, 2, 4, 8, | |
79 | 12, 18, 24, 36, 48, 72, 96, 108, | |
80 | 30, 40, 50, 80, 120, 200, 280, 320, | |
81 | 150, 160, 240, 360, 500, 600, 800, 1000}; | |
82 | ||
83 | static u8 DROPING_NECESSARY[RATESIZE] = { | |
84 | 1, 1, 1, 1, | |
85 | 1, 2, 3, 4, 5, 6, 7, 8, | |
86 | 1, 2, 3, 4, 5, 6, 7, 8, | |
87 | 5, 6, 7, 8, 9, 10, 11, 12}; | |
88 | ||
89 | static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; | |
90 | static u16 DynamicTxRPTTiming[6] = { | |
e703f237 | 91 | 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /* 200ms-1200ms */ |
a0da203b LF |
92 | |
93 | /* End Rate adaptive parameters */ | |
94 | ||
95 | static void odm_SetTxRPTTiming_8188E( | |
96 | struct odm_dm_struct *dm_odm, | |
97 | struct odm_ra_info *pRaInfo, | |
98 | u8 extend | |
99 | ) | |
100 | { | |
101 | u8 idx = 0; | |
102 | ||
103 | for (idx = 0; idx < 5; idx++) | |
104 | if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime) | |
105 | break; | |
106 | ||
107 | if (extend == 0) { /* back to default timing */ | |
108 | idx = 0; /* 200ms */ | |
109 | } else if (extend == 1) {/* increase the timing */ | |
110 | idx += 1; | |
111 | if (idx > 5) | |
112 | idx = 5; | |
113 | } else if (extend == 2) {/* decrease the timing */ | |
114 | if (idx != 0) | |
115 | idx -= 1; | |
116 | } | |
117 | pRaInfo->RptTime = DynamicTxRPTTiming[idx]; | |
118 | ||
bf952515 VH |
119 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
120 | ("pRaInfo->RptTime = 0x%x\n", pRaInfo->RptTime)); | |
a0da203b LF |
121 | } |
122 | ||
bf952515 VH |
123 | static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm, |
124 | struct odm_ra_info *pRaInfo) | |
a0da203b LF |
125 | { |
126 | u8 RateID, LowestRate, HighestRate; | |
127 | u8 i; | |
128 | ||
bf952515 VH |
129 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, |
130 | ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n")); | |
cfd23644 | 131 | if (!pRaInfo) { |
bf952515 VH |
132 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
133 | ("odm_RateDown_8188E(): pRaInfo is NULL\n")); | |
a0da203b LF |
134 | return -1; |
135 | } | |
136 | RateID = pRaInfo->PreRate; | |
137 | LowestRate = pRaInfo->LowestRate; | |
138 | HighestRate = pRaInfo->HighestRate; | |
139 | ||
140 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
141 | (" RateID =%d LowestRate =%d HighestRate =%d RateSGI =%d\n", | |
142 | RateID, LowestRate, HighestRate, pRaInfo->RateSGI)); | |
143 | if (RateID > HighestRate) { | |
144 | RateID = HighestRate; | |
145 | } else if (pRaInfo->RateSGI) { | |
146 | pRaInfo->RateSGI = 0; | |
147 | } else if (RateID > LowestRate) { | |
148 | if (RateID > 0) { | |
149 | for (i = RateID-1; i > LowestRate; i--) { | |
150 | if (pRaInfo->RAUseRate & BIT(i)) { | |
151 | RateID = i; | |
152 | goto RateDownFinish; | |
153 | } | |
154 | } | |
155 | } | |
156 | } else if (RateID <= LowestRate) { | |
157 | RateID = LowestRate; | |
158 | } | |
159 | RateDownFinish: | |
160 | if (pRaInfo->RAWaitingCounter == 1) { | |
161 | pRaInfo->RAWaitingCounter += 1; | |
162 | pRaInfo->RAPendingCounter += 1; | |
163 | } else if (pRaInfo->RAWaitingCounter == 0) { | |
164 | ; | |
165 | } else { | |
166 | pRaInfo->RAWaitingCounter = 0; | |
167 | pRaInfo->RAPendingCounter = 0; | |
168 | } | |
169 | ||
170 | if (pRaInfo->RAPendingCounter >= 4) | |
171 | pRaInfo->RAPendingCounter = 4; | |
172 | ||
173 | pRaInfo->DecisionRate = RateID; | |
174 | odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 2); | |
bf952515 VH |
175 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, |
176 | ODM_DBG_LOUD, ("Rate down, RPT Timing default\n")); | |
177 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
178 | ("RAWaitingCounter %d, RAPendingCounter %d", | |
179 | pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter)); | |
180 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
181 | ("Rate down to RateID %d RateSGI %d\n", RateID, pRaInfo->RateSGI)); | |
182 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
183 | ("<===== odm_RateDown_8188E()\n")); | |
a0da203b LF |
184 | return 0; |
185 | } | |
186 | ||
187 | static int odm_RateUp_8188E( | |
188 | struct odm_dm_struct *dm_odm, | |
189 | struct odm_ra_info *pRaInfo | |
190 | ) | |
191 | { | |
192 | u8 RateID, HighestRate; | |
193 | u8 i; | |
194 | ||
bf952515 VH |
195 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, |
196 | ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n")); | |
cfd23644 | 197 | if (!pRaInfo) { |
bf952515 VH |
198 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
199 | ("odm_RateUp_8188E(): pRaInfo is NULL\n")); | |
a0da203b LF |
200 | return -1; |
201 | } | |
202 | RateID = pRaInfo->PreRate; | |
203 | HighestRate = pRaInfo->HighestRate; | |
204 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
205 | (" RateID =%d HighestRate =%d\n", | |
206 | RateID, HighestRate)); | |
207 | if (pRaInfo->RAWaitingCounter == 1) { | |
208 | pRaInfo->RAWaitingCounter = 0; | |
209 | pRaInfo->RAPendingCounter = 0; | |
210 | } else if (pRaInfo->RAWaitingCounter > 1) { | |
211 | pRaInfo->PreRssiStaRA = pRaInfo->RssiStaRA; | |
212 | goto RateUpfinish; | |
213 | } | |
214 | odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 0); | |
bf952515 VH |
215 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
216 | ("odm_RateUp_8188E():Decrease RPT Timing\n")); | |
a0da203b LF |
217 | |
218 | if (RateID < HighestRate) { | |
219 | for (i = RateID+1; i <= HighestRate; i++) { | |
220 | if (pRaInfo->RAUseRate & BIT(i)) { | |
221 | RateID = i; | |
222 | goto RateUpfinish; | |
223 | } | |
224 | } | |
225 | } else if (RateID == HighestRate) { | |
226 | if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1)) | |
227 | pRaInfo->RateSGI = 1; | |
228 | else if ((pRaInfo->SGIEnable) != 1) | |
229 | pRaInfo->RateSGI = 0; | |
230 | } else { | |
231 | RateID = HighestRate; | |
232 | } | |
233 | RateUpfinish: | |
bf952515 VH |
234 | if (pRaInfo->RAWaitingCounter == |
235 | (4+PendingForRateUpFail[pRaInfo->RAPendingCounter])) | |
a0da203b LF |
236 | pRaInfo->RAWaitingCounter = 0; |
237 | else | |
238 | pRaInfo->RAWaitingCounter++; | |
239 | ||
240 | pRaInfo->DecisionRate = RateID; | |
bf952515 VH |
241 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
242 | ("Rate up to RateID %d\n", RateID)); | |
243 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
244 | ("RAWaitingCounter %d, RAPendingCounter %d", | |
245 | pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter)); | |
246 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, | |
247 | ODM_DBG_TRACE, ("<===== odm_RateUp_8188E()\n")); | |
a0da203b LF |
248 | return 0; |
249 | } | |
250 | ||
251 | static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo) | |
252 | { | |
253 | u8 RateID; | |
254 | ||
255 | RateID = pRaInfo->DecisionRate; | |
256 | pRaInfo->NscUp = (N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1; | |
257 | pRaInfo->NscDown = (N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1; | |
258 | } | |
259 | ||
260 | static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm, | |
261 | struct odm_ra_info *pRaInfo | |
262 | ) | |
263 | { | |
175bbae0 | 264 | u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0, i = 0; |
a0da203b LF |
265 | /* u32 pool_retry; */ |
266 | static u8 DynamicTxRPTTimingCounter; | |
267 | ||
bf952515 VH |
268 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
269 | ("=====>odm_RateDecision_8188E()\n")); | |
a0da203b LF |
270 | |
271 | if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) { /* STA used and data packet exits */ | |
272 | if ((pRaInfo->RssiStaRA < (pRaInfo->PreRssiStaRA - 3)) || | |
273 | (pRaInfo->RssiStaRA > (pRaInfo->PreRssiStaRA + 3))) { | |
274 | pRaInfo->RAWaitingCounter = 0; | |
275 | pRaInfo->RAPendingCounter = 0; | |
276 | } | |
277 | /* Start RA decision */ | |
278 | if (pRaInfo->PreRate > pRaInfo->HighestRate) | |
279 | RateID = pRaInfo->HighestRate; | |
280 | else | |
281 | RateID = pRaInfo->PreRate; | |
282 | if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID]) | |
283 | RtyPtID = 0; | |
284 | else | |
285 | RtyPtID = 1; | |
286 | PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */ | |
287 | ||
288 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
289 | (" NscDown init is %d\n", pRaInfo->NscDown)); | |
175bbae0 VH |
290 | |
291 | for (i = 0 ; i <= 4 ; i++) | |
292 | pRaInfo->NscDown += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID1][i]; | |
293 | ||
a0da203b | 294 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
175bbae0 VH |
295 | (" NscDown is %d, total*penalty[5] is %d\n", pRaInfo->NscDown, |
296 | (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]))); | |
297 | ||
a0da203b LF |
298 | if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])) |
299 | pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]; | |
300 | else | |
301 | pRaInfo->NscDown = 0; | |
302 | ||
303 | /* rate up */ | |
304 | PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID]; | |
305 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
306 | (" NscUp init is %d\n", pRaInfo->NscUp)); | |
175bbae0 VH |
307 | |
308 | for (i = 0 ; i <= 4 ; i++) | |
309 | pRaInfo->NscUp += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID2][i]; | |
310 | ||
a0da203b LF |
311 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
312 | ("NscUp is %d, total*up[5] is %d\n", | |
313 | pRaInfo->NscUp, (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]))); | |
175bbae0 | 314 | |
a0da203b LF |
315 | if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5])) |
316 | pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]; | |
317 | else | |
318 | pRaInfo->NscUp = 0; | |
319 | ||
320 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE|ODM_COMP_INIT, ODM_DBG_LOUD, | |
321 | (" RssiStaRa = %d RtyPtID =%d PenaltyID1 = 0x%x PenaltyID2 = 0x%x RateID =%d NscDown =%d NscUp =%d SGI =%d\n", | |
322 | pRaInfo->RssiStaRA, RtyPtID, PenaltyID1, PenaltyID2, RateID, pRaInfo->NscDown, pRaInfo->NscUp, pRaInfo->RateSGI)); | |
323 | if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) || | |
324 | (pRaInfo->DROP > DROPING_NECESSARY[RateID])) | |
325 | odm_RateDown_8188E(dm_odm, pRaInfo); | |
326 | else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID]) | |
327 | odm_RateUp_8188E(dm_odm, pRaInfo); | |
328 | ||
329 | if (pRaInfo->DecisionRate > pRaInfo->HighestRate) | |
330 | pRaInfo->DecisionRate = pRaInfo->HighestRate; | |
331 | ||
332 | if ((pRaInfo->DecisionRate) == (pRaInfo->PreRate)) | |
333 | DynamicTxRPTTimingCounter += 1; | |
334 | else | |
335 | DynamicTxRPTTimingCounter = 0; | |
336 | ||
337 | if (DynamicTxRPTTimingCounter >= 4) { | |
338 | odm_SetTxRPTTiming_8188E(dm_odm, pRaInfo, 1); | |
339 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, | |
340 | ODM_DBG_LOUD, ("<===== Rate don't change 4 times, Extend RPT Timing\n")); | |
341 | DynamicTxRPTTimingCounter = 0; | |
342 | } | |
343 | ||
344 | pRaInfo->PreRate = pRaInfo->DecisionRate; /* YJ, add, 120120 */ | |
345 | ||
346 | odm_ResetRaCounter_8188E(pRaInfo); | |
347 | } | |
348 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<===== odm_RateDecision_8188E()\n")); | |
349 | } | |
350 | ||
351 | static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) | |
352 | { /* Wilson 2011/10/26 */ | |
2325182f | 353 | struct adapter *adapt = dm_odm->Adapter; |
a0da203b LF |
354 | u32 MaskFromReg; |
355 | s8 i; | |
356 | ||
357 | switch (pRaInfo->RateID) { | |
358 | case RATR_INX_WIRELESS_NGB: | |
359 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff015; | |
360 | break; | |
361 | case RATR_INX_WIRELESS_NG: | |
362 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff010; | |
363 | break; | |
364 | case RATR_INX_WIRELESS_NB: | |
365 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff005; | |
366 | break; | |
367 | case RATR_INX_WIRELESS_N: | |
368 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0f8ff000; | |
369 | break; | |
370 | case RATR_INX_WIRELESS_GB: | |
371 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x00000ff5; | |
372 | break; | |
373 | case RATR_INX_WIRELESS_G: | |
374 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x00000ff0; | |
375 | break; | |
376 | case RATR_INX_WIRELESS_B: | |
377 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&0x0000000d; | |
378 | break; | |
379 | case 12: | |
99ecfb06 | 380 | MaskFromReg = usb_read32(adapt, REG_ARFR0); |
a0da203b LF |
381 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; |
382 | break; | |
383 | case 13: | |
99ecfb06 | 384 | MaskFromReg = usb_read32(adapt, REG_ARFR1); |
a0da203b LF |
385 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; |
386 | break; | |
387 | case 14: | |
99ecfb06 | 388 | MaskFromReg = usb_read32(adapt, REG_ARFR2); |
a0da203b LF |
389 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; |
390 | break; | |
391 | case 15: | |
99ecfb06 | 392 | MaskFromReg = usb_read32(adapt, REG_ARFR3); |
a0da203b LF |
393 | pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; |
394 | break; | |
395 | default: | |
396 | pRaInfo->RAUseRate = (pRaInfo->RateMask); | |
397 | break; | |
398 | } | |
399 | /* Highest rate */ | |
400 | if (pRaInfo->RAUseRate) { | |
401 | for (i = RATESIZE; i >= 0; i--) { | |
402 | if ((pRaInfo->RAUseRate)&BIT(i)) { | |
403 | pRaInfo->HighestRate = i; | |
404 | break; | |
405 | } | |
406 | } | |
407 | } else { | |
408 | pRaInfo->HighestRate = 0; | |
409 | } | |
410 | /* Lowest rate */ | |
411 | if (pRaInfo->RAUseRate) { | |
412 | for (i = 0; i < RATESIZE; i++) { | |
413 | if ((pRaInfo->RAUseRate) & BIT(i)) { | |
414 | pRaInfo->LowestRate = i; | |
415 | break; | |
416 | } | |
417 | } | |
418 | } else { | |
419 | pRaInfo->LowestRate = 0; | |
420 | } | |
421 | if (pRaInfo->HighestRate > 0x13) | |
422 | pRaInfo->PTModeSS = 3; | |
423 | else if (pRaInfo->HighestRate > 0x0b) | |
424 | pRaInfo->PTModeSS = 2; | |
425 | else if (pRaInfo->HighestRate > 0x0b) | |
426 | pRaInfo->PTModeSS = 1; | |
427 | else | |
428 | pRaInfo->PTModeSS = 0; | |
429 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
430 | ("ODM_ARFBRefresh_8188E(): PTModeSS =%d\n", pRaInfo->PTModeSS)); | |
431 | ||
432 | if (pRaInfo->DecisionRate > pRaInfo->HighestRate) | |
433 | pRaInfo->DecisionRate = pRaInfo->HighestRate; | |
434 | ||
435 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
436 | ("ODM_ARFBRefresh_8188E(): RateID =%d RateMask =%8.8x RAUseRate =%8.8x HighestRate =%d, DecisionRate =%d\n", | |
437 | pRaInfo->RateID, pRaInfo->RateMask, pRaInfo->RAUseRate, pRaInfo->HighestRate, pRaInfo->DecisionRate)); | |
438 | return 0; | |
439 | } | |
440 | ||
441 | static void odm_PTTryState_8188E(struct odm_ra_info *pRaInfo) | |
442 | { | |
443 | pRaInfo->PTTryState = 0; | |
444 | switch (pRaInfo->PTModeSS) { | |
445 | case 3: | |
446 | if (pRaInfo->DecisionRate >= 0x19) | |
447 | pRaInfo->PTTryState = 1; | |
448 | break; | |
449 | case 2: | |
450 | if (pRaInfo->DecisionRate >= 0x11) | |
451 | pRaInfo->PTTryState = 1; | |
452 | break; | |
453 | case 1: | |
454 | if (pRaInfo->DecisionRate >= 0x0a) | |
455 | pRaInfo->PTTryState = 1; | |
456 | break; | |
457 | case 0: | |
458 | if (pRaInfo->DecisionRate >= 0x03) | |
459 | pRaInfo->PTTryState = 1; | |
460 | break; | |
461 | default: | |
462 | pRaInfo->PTTryState = 0; | |
463 | break; | |
464 | } | |
465 | ||
466 | if (pRaInfo->RssiStaRA < 48) { | |
467 | pRaInfo->PTStage = 0; | |
468 | } else if (pRaInfo->PTTryState == 1) { | |
469 | if ((pRaInfo->PTStopCount >= 10) || | |
470 | (pRaInfo->PTPreRssi > pRaInfo->RssiStaRA + 5) || | |
471 | (pRaInfo->PTPreRssi < pRaInfo->RssiStaRA - 5) || | |
472 | (pRaInfo->DecisionRate != pRaInfo->PTPreRate)) { | |
473 | if (pRaInfo->PTStage == 0) | |
474 | pRaInfo->PTStage = 1; | |
475 | else if (pRaInfo->PTStage == 1) | |
476 | pRaInfo->PTStage = 3; | |
477 | else | |
478 | pRaInfo->PTStage = 5; | |
479 | ||
480 | pRaInfo->PTPreRssi = pRaInfo->RssiStaRA; | |
481 | pRaInfo->PTStopCount = 0; | |
482 | } else { | |
483 | pRaInfo->RAstage = 0; | |
484 | pRaInfo->PTStopCount++; | |
485 | } | |
486 | } else { | |
487 | pRaInfo->PTStage = 0; | |
488 | pRaInfo->RAstage = 0; | |
489 | } | |
490 | pRaInfo->PTPreRate = pRaInfo->DecisionRate; | |
491 | } | |
492 | ||
493 | static void odm_PTDecision_8188E(struct odm_ra_info *pRaInfo) | |
494 | { | |
495 | u8 j; | |
496 | u8 temp_stage; | |
497 | u32 numsc; | |
498 | u32 num_total; | |
499 | u8 stage_id; | |
500 | ||
501 | numsc = 0; | |
502 | num_total = pRaInfo->TOTAL * PT_PENALTY[5]; | |
503 | for (j = 0; j <= 4; j++) { | |
504 | numsc += pRaInfo->RTY[j] * PT_PENALTY[j]; | |
505 | if (numsc > num_total) | |
506 | break; | |
507 | } | |
508 | ||
74ff8799 | 509 | j >>= 1; |
a0da203b LF |
510 | temp_stage = (pRaInfo->PTStage + 1) >> 1; |
511 | if (temp_stage > j) | |
512 | stage_id = temp_stage-j; | |
513 | else | |
514 | stage_id = 0; | |
515 | ||
516 | pRaInfo->PTSmoothFactor = (pRaInfo->PTSmoothFactor>>1) + (pRaInfo->PTSmoothFactor>>2) + stage_id*16+2; | |
517 | if (pRaInfo->PTSmoothFactor > 192) | |
518 | pRaInfo->PTSmoothFactor = 192; | |
519 | stage_id = pRaInfo->PTSmoothFactor >> 6; | |
520 | temp_stage = stage_id*2; | |
521 | if (temp_stage != 0) | |
522 | temp_stage -= 1; | |
523 | if (pRaInfo->DROP > 3) | |
524 | temp_stage = 0; | |
525 | pRaInfo->PTStage = temp_stage; | |
526 | } | |
527 | ||
528 | static void | |
529 | odm_RATxRPTTimerSetting( | |
530 | struct odm_dm_struct *dm_odm, | |
531 | u16 minRptTime | |
532 | ) | |
533 | { | |
534 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" =====>odm_RATxRPTTimerSetting()\n")); | |
535 | ||
536 | if (dm_odm->CurrminRptTime != minRptTime) { | |
537 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
538 | (" CurrminRptTime = 0x%04x minRptTime = 0x%04x\n", dm_odm->CurrminRptTime, minRptTime)); | |
539 | rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime); | |
540 | dm_odm->CurrminRptTime = minRptTime; | |
541 | } | |
542 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" <===== odm_RATxRPTTimerSetting()\n")); | |
543 | } | |
544 | ||
545 | void | |
546 | ODM_RASupport_Init( | |
547 | struct odm_dm_struct *dm_odm | |
548 | ) | |
549 | { | |
550 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>ODM_RASupport_Init()\n")); | |
551 | ||
6c0a555e | 552 | dm_odm->RaSupport88E = true; |
a0da203b LF |
553 | } |
554 | ||
555 | int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid) | |
556 | { | |
557 | struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid]; | |
558 | u8 WirelessMode = 0xFF; /* invalid value */ | |
559 | u8 max_rate_idx = 0x13; /* MCS7 */ | |
1068fb67 | 560 | |
7f69e09a | 561 | if (dm_odm->pWirelessMode) |
a0da203b LF |
562 | WirelessMode = *(dm_odm->pWirelessMode); |
563 | ||
564 | if (WirelessMode != 0xFF) { | |
565 | if (WirelessMode & ODM_WM_N24G) | |
566 | max_rate_idx = 0x13; | |
567 | else if (WirelessMode & ODM_WM_G) | |
568 | max_rate_idx = 0x0b; | |
569 | else if (WirelessMode & ODM_WM_B) | |
570 | max_rate_idx = 0x03; | |
571 | } | |
572 | ||
573 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
574 | ("ODM_RAInfo_Init(): WirelessMode:0x%08x , max_raid_idx:0x%02x\n", | |
575 | WirelessMode, max_rate_idx)); | |
576 | ||
577 | pRaInfo->DecisionRate = max_rate_idx; | |
578 | pRaInfo->PreRate = max_rate_idx; | |
579 | pRaInfo->HighestRate = max_rate_idx; | |
580 | pRaInfo->LowestRate = 0; | |
581 | pRaInfo->RateID = 0; | |
582 | pRaInfo->RateMask = 0xffffffff; | |
583 | pRaInfo->RssiStaRA = 0; | |
584 | pRaInfo->PreRssiStaRA = 0; | |
585 | pRaInfo->SGIEnable = 0; | |
586 | pRaInfo->RAUseRate = 0xffffffff; | |
587 | pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2; | |
588 | pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2; | |
589 | pRaInfo->RateSGI = 0; | |
590 | pRaInfo->Active = 1; /* Active is not used at present. by page, 110819 */ | |
591 | pRaInfo->RptTime = 0x927c; | |
592 | pRaInfo->DROP = 0; | |
593 | pRaInfo->RTY[0] = 0; | |
594 | pRaInfo->RTY[1] = 0; | |
595 | pRaInfo->RTY[2] = 0; | |
596 | pRaInfo->RTY[3] = 0; | |
597 | pRaInfo->RTY[4] = 0; | |
598 | pRaInfo->TOTAL = 0; | |
599 | pRaInfo->RAWaitingCounter = 0; | |
600 | pRaInfo->RAPendingCounter = 0; | |
601 | pRaInfo->PTActive = 1; /* Active when this STA is use */ | |
602 | pRaInfo->PTTryState = 0; | |
603 | pRaInfo->PTStage = 5; /* Need to fill into HW_PWR_STATUS */ | |
604 | pRaInfo->PTSmoothFactor = 192; | |
605 | pRaInfo->PTStopCount = 0; | |
606 | pRaInfo->PTPreRate = 0; | |
607 | pRaInfo->PTPreRssi = 0; | |
608 | pRaInfo->PTModeSS = 0; | |
609 | pRaInfo->RAstage = 0; | |
610 | return 0; | |
611 | } | |
612 | ||
613 | int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm) | |
614 | { | |
615 | u8 macid = 0; | |
616 | ||
617 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n")); | |
618 | dm_odm->CurrminRptTime = 0; | |
619 | ||
620 | for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) | |
621 | ODM_RAInfo_Init(dm_odm, macid); | |
622 | ||
623 | return 0; | |
624 | } | |
625 | ||
626 | u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid) | |
627 | { | |
cfd23644 | 628 | if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) |
a0da203b LF |
629 | return 0; |
630 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, | |
631 | ("macid =%d SGI =%d\n", macid, dm_odm->RAInfo[macid].RateSGI)); | |
632 | return dm_odm->RAInfo[macid].RateSGI; | |
633 | } | |
634 | ||
635 | u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid) | |
636 | { | |
637 | u8 DecisionRate = 0; | |
638 | ||
cfd23644 | 639 | if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) |
a0da203b | 640 | return 0; |
adb3d770 | 641 | DecisionRate = dm_odm->RAInfo[macid].DecisionRate; |
a0da203b LF |
642 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
643 | (" macid =%d DecisionRate = 0x%x\n", macid, DecisionRate)); | |
644 | return DecisionRate; | |
645 | } | |
646 | ||
647 | u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid) | |
648 | { | |
649 | u8 PTStage = 5; | |
650 | ||
cfd23644 | 651 | if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) |
a0da203b | 652 | return 0; |
adb3d770 | 653 | PTStage = dm_odm->RAInfo[macid].PTStage; |
a0da203b LF |
654 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
655 | ("macid =%d PTStage = 0x%x\n", macid, PTStage)); | |
656 | return PTStage; | |
657 | } | |
658 | ||
659 | void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable) | |
660 | { | |
661 | struct odm_ra_info *pRaInfo = NULL; | |
662 | ||
cfd23644 | 663 | if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) |
f1126b1d | 664 | return; |
a0da203b LF |
665 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, |
666 | ("macid =%d RateID = 0x%x RateMask = 0x%x SGIEnable =%d\n", | |
667 | macid, RateID, RateMask, SGIEnable)); | |
a0da203b LF |
668 | |
669 | pRaInfo = &(dm_odm->RAInfo[macid]); | |
670 | pRaInfo->RateID = RateID; | |
671 | pRaInfo->RateMask = RateMask; | |
672 | pRaInfo->SGIEnable = SGIEnable; | |
673 | odm_ARFBRefresh_8188E(dm_odm, pRaInfo); | |
674 | } | |
675 | ||
676 | void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi) | |
677 | { | |
678 | struct odm_ra_info *pRaInfo = NULL; | |
679 | ||
cfd23644 | 680 | if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) |
a0da203b | 681 | return; |
f1126b1d SM |
682 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, |
683 | (" macid =%d Rssi =%d\n", macid, Rssi)); | |
a0da203b LF |
684 | |
685 | pRaInfo = &(dm_odm->RAInfo[macid]); | |
686 | pRaInfo->RssiStaRA = Rssi; | |
687 | } | |
688 | ||
689 | void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime) | |
690 | { | |
4107a998 LF |
691 | struct adapter *adapt = dm_odm->Adapter; |
692 | ||
9764ed04 | 693 | usb_write16(adapt, REG_TX_RPT_TIME, minRptTime); |
a0da203b LF |
694 | } |
695 | ||
696 | void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1) | |
697 | { | |
698 | struct odm_ra_info *pRAInfo = NULL; | |
699 | u8 MacId = 0; | |
700 | u8 *pBuffer = NULL; | |
701 | u32 valid = 0, ItemNum = 0; | |
702 | u16 minRptTime = 0x927c; | |
703 | ||
704 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
705 | ("=====>ODM_RA_TxRPT2Handle_8188E(): valid0 =%d valid1 =%d BufferLength =%d\n", | |
706 | macid_entry0, macid_entry1, TxRPT_Len)); | |
707 | ||
708 | ItemNum = TxRPT_Len >> 3; | |
709 | pBuffer = TxRPT_Buf; | |
710 | ||
711 | do { | |
712 | if (MacId >= ASSOCIATE_ENTRY_NUM) | |
713 | valid = 0; | |
714 | else if (MacId >= 32) | |
715 | valid = (1 << (MacId - 32)) & macid_entry1; | |
716 | else | |
717 | valid = (1 << MacId) & macid_entry0; | |
718 | ||
719 | pRAInfo = &(dm_odm->RAInfo[MacId]); | |
720 | if (valid) { | |
721 | pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer); | |
722 | pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer); | |
723 | pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2(pBuffer); | |
724 | pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer); | |
725 | pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer); | |
726 | pRAInfo->DROP = (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer); | |
727 | pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] + | |
728 | pRAInfo->RTY[2] + pRAInfo->RTY[3] + | |
729 | pRAInfo->RTY[4] + pRAInfo->DROP; | |
730 | if (pRAInfo->TOTAL != 0) { | |
731 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, | |
732 | ("macid =%d Total =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d D0 =%d valid0 =%x valid1 =%x\n", | |
733 | MacId, pRAInfo->TOTAL, | |
734 | pRAInfo->RTY[0], pRAInfo->RTY[1], | |
735 | pRAInfo->RTY[2], pRAInfo->RTY[3], | |
736 | pRAInfo->RTY[4], pRAInfo->DROP, | |
37c00229 | 737 | macid_entry0, macid_entry1)); |
a0da203b LF |
738 | if (pRAInfo->PTActive) { |
739 | if (pRAInfo->RAstage < 5) | |
740 | odm_RateDecision_8188E(dm_odm, pRAInfo); | |
741 | else if (pRAInfo->RAstage == 5) /* Power training try state */ | |
742 | odm_PTTryState_8188E(pRAInfo); | |
743 | else /* RAstage == 6 */ | |
744 | odm_PTDecision_8188E(pRAInfo); | |
745 | ||
746 | /* Stage_RA counter */ | |
747 | if (pRAInfo->RAstage <= 5) | |
748 | pRAInfo->RAstage++; | |
749 | else | |
750 | pRAInfo->RAstage = 0; | |
751 | } else { | |
752 | odm_RateDecision_8188E(dm_odm, pRAInfo); | |
753 | } | |
754 | ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, | |
755 | ("macid =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d drop =%d valid0 =%x RateID =%d SGI =%d\n", | |
756 | MacId, | |
757 | pRAInfo->RTY[0], | |
758 | pRAInfo->RTY[1], | |
759 | pRAInfo->RTY[2], | |
760 | pRAInfo->RTY[3], | |
761 | pRAInfo->RTY[4], | |
762 | pRAInfo->DROP, | |
763 | macid_entry0, | |
764 | pRAInfo->DecisionRate, | |
765 | pRAInfo->RateSGI)); | |
766 | } else { | |
767 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (" TOTAL = 0!!!!\n")); | |
768 | } | |
769 | } | |
770 | ||
771 | if (minRptTime > pRAInfo->RptTime) | |
772 | minRptTime = pRAInfo->RptTime; | |
773 | ||
774 | pBuffer += TX_RPT2_ITEM_SIZE; | |
775 | MacId++; | |
776 | } while (MacId < ItemNum); | |
777 | ||
778 | odm_RATxRPTTimerSetting(dm_odm, minRptTime); | |
779 | ||
780 | ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== ODM_RA_TxRPT2Handle_8188E()\n")); | |
781 | } |