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