GNU Linux-libre 4.19.268-gnu1
[releases.git] / drivers / staging / rtl8188eu / hal / hal8188e_rate_adaptive.c
1 // SPDX-License-Identifier: GPL-2.0
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] = {
91         0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /*  200ms-1200ms */
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
119         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
120                         ("pRaInfo->RptTime = 0x%x\n", pRaInfo->RptTime));
121 }
122
123 static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm,
124                                 struct odm_ra_info *pRaInfo)
125 {
126         u8 RateID, LowestRate, HighestRate;
127         u8 i;
128
129         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
130                         ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n"));
131         if (!pRaInfo) {
132                 ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
133                                 ("odm_RateDown_8188E(): pRaInfo is NULL\n"));
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);
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"));
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
195         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
196                         ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n"));
197         if (!pRaInfo) {
198                 ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
199                                 ("odm_RateUp_8188E(): pRaInfo is NULL\n"));
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);
215         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
216                         ("odm_RateUp_8188E():Decrease RPT Timing\n"));
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:
234         if (pRaInfo->RAWaitingCounter ==
235                 (4+PendingForRateUpFail[pRaInfo->RAPendingCounter]))
236                 pRaInfo->RAWaitingCounter = 0;
237         else
238                 pRaInfo->RAWaitingCounter++;
239
240         pRaInfo->DecisionRate = RateID;
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"));
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 {
264         u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0, i = 0;
265         /* u32 pool_retry; */
266         static u8 DynamicTxRPTTimingCounter;
267
268         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
269                         ("=====>odm_RateDecision_8188E()\n"));
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));
290
291                 for (i = 0 ; i <= 4 ; i++)
292                         pRaInfo->NscDown += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID1][i];
293
294                 ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
295                              (" NscDown is %d, total*penalty[5] is %d\n", pRaInfo->NscDown,
296                               (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])));
297
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));
307
308                 for (i = 0 ; i <= 4 ; i++)
309                         pRaInfo->NscUp += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID2][i];
310
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])));
314
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 */
353         struct adapter *adapt = dm_odm->Adapter;
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:
380                 MaskFromReg = usb_read32(adapt, REG_ARFR0);
381                 pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
382                 break;
383         case 13:
384                 MaskFromReg = usb_read32(adapt, REG_ARFR1);
385                 pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
386                 break;
387         case 14:
388                 MaskFromReg = usb_read32(adapt, REG_ARFR2);
389                 pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
390                 break;
391         case 15:
392                 MaskFromReg = usb_read32(adapt, REG_ARFR3);
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
509         j >>= 1;
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 int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid)
546 {
547         struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid];
548         u8 WirelessMode = 0xFF; /* invalid value */
549         u8 max_rate_idx = 0x13; /* MCS7 */
550
551         if (dm_odm->pWirelessMode)
552                 WirelessMode = *(dm_odm->pWirelessMode);
553
554         if (WirelessMode != 0xFF) {
555                 if (WirelessMode & ODM_WM_N24G)
556                         max_rate_idx = 0x13;
557                 else if (WirelessMode & ODM_WM_G)
558                         max_rate_idx = 0x0b;
559                 else if (WirelessMode & ODM_WM_B)
560                         max_rate_idx = 0x03;
561         }
562
563         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
564                      ("ODM_RAInfo_Init(): WirelessMode:0x%08x , max_raid_idx:0x%02x\n",
565                      WirelessMode, max_rate_idx));
566
567         pRaInfo->DecisionRate = max_rate_idx;
568         pRaInfo->PreRate = max_rate_idx;
569         pRaInfo->HighestRate = max_rate_idx;
570         pRaInfo->LowestRate = 0;
571         pRaInfo->RateID = 0;
572         pRaInfo->RateMask = 0xffffffff;
573         pRaInfo->RssiStaRA = 0;
574         pRaInfo->PreRssiStaRA = 0;
575         pRaInfo->SGIEnable = 0;
576         pRaInfo->RAUseRate = 0xffffffff;
577         pRaInfo->NscDown = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
578         pRaInfo->NscUp = (N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
579         pRaInfo->RateSGI = 0;
580         pRaInfo->Active = 1;    /* Active is not used at present. by page, 110819 */
581         pRaInfo->RptTime = 0x927c;
582         pRaInfo->DROP = 0;
583         pRaInfo->RTY[0] = 0;
584         pRaInfo->RTY[1] = 0;
585         pRaInfo->RTY[2] = 0;
586         pRaInfo->RTY[3] = 0;
587         pRaInfo->RTY[4] = 0;
588         pRaInfo->TOTAL = 0;
589         pRaInfo->RAWaitingCounter = 0;
590         pRaInfo->RAPendingCounter = 0;
591         pRaInfo->PTActive = 1;   /*  Active when this STA is use */
592         pRaInfo->PTTryState = 0;
593         pRaInfo->PTStage = 5; /*  Need to fill into HW_PWR_STATUS */
594         pRaInfo->PTSmoothFactor = 192;
595         pRaInfo->PTStopCount = 0;
596         pRaInfo->PTPreRate = 0;
597         pRaInfo->PTPreRssi = 0;
598         pRaInfo->PTModeSS = 0;
599         pRaInfo->RAstage = 0;
600         return 0;
601 }
602
603 int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm)
604 {
605         u8 macid = 0;
606
607         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n"));
608         dm_odm->CurrminRptTime = 0;
609
610         for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++)
611                 ODM_RAInfo_Init(dm_odm, macid);
612
613         return 0;
614 }
615
616 u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid)
617 {
618         if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
619                 return 0;
620         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
621                      ("macid =%d SGI =%d\n", macid, dm_odm->RAInfo[macid].RateSGI));
622         return dm_odm->RAInfo[macid].RateSGI;
623 }
624
625 u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid)
626 {
627         u8 DecisionRate = 0;
628
629         if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
630                 return 0;
631         DecisionRate = dm_odm->RAInfo[macid].DecisionRate;
632         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
633                 (" macid =%d DecisionRate = 0x%x\n", macid, DecisionRate));
634         return DecisionRate;
635 }
636
637 u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid)
638 {
639         u8 PTStage = 5;
640
641         if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
642                 return 0;
643         PTStage = dm_odm->RAInfo[macid].PTStage;
644         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
645                      ("macid =%d PTStage = 0x%x\n", macid, PTStage));
646         return PTStage;
647 }
648
649 void ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable)
650 {
651         struct odm_ra_info *pRaInfo = NULL;
652
653         if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
654                 return;
655         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
656                      ("macid =%d RateID = 0x%x RateMask = 0x%x SGIEnable =%d\n",
657                      macid, RateID, RateMask, SGIEnable));
658
659         pRaInfo = &(dm_odm->RAInfo[macid]);
660         pRaInfo->RateID = RateID;
661         pRaInfo->RateMask = RateMask;
662         pRaInfo->SGIEnable = SGIEnable;
663         odm_ARFBRefresh_8188E(dm_odm, pRaInfo);
664 }
665
666 void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi)
667 {
668         struct odm_ra_info *pRaInfo = NULL;
669
670         if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
671                 return;
672         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
673                      (" macid =%d Rssi =%d\n", macid, Rssi));
674
675         pRaInfo = &(dm_odm->RAInfo[macid]);
676         pRaInfo->RssiStaRA = Rssi;
677 }
678
679 void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime)
680 {
681         struct adapter *adapt = dm_odm->Adapter;
682
683         usb_write16(adapt, REG_TX_RPT_TIME, minRptTime);
684 }
685
686 void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1)
687 {
688         struct odm_ra_info *pRAInfo = NULL;
689         u8 MacId = 0;
690         u8 *pBuffer = NULL;
691         u32 valid = 0, ItemNum = 0;
692         u16 minRptTime = 0x927c;
693
694         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
695                      ("=====>ODM_RA_TxRPT2Handle_8188E(): valid0 =%d valid1 =%d BufferLength =%d\n",
696                      macid_entry0, macid_entry1, TxRPT_Len));
697
698         ItemNum = TxRPT_Len >> 3;
699         pBuffer = TxRPT_Buf;
700
701         do {
702                 if (MacId >= ASSOCIATE_ENTRY_NUM)
703                         valid = 0;
704                 else if (MacId >= 32)
705                         valid = (1 << (MacId - 32)) & macid_entry1;
706                 else
707                         valid = (1 << MacId) & macid_entry0;
708
709                 pRAInfo = &(dm_odm->RAInfo[MacId]);
710                 if (valid) {
711                         pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer);
712                         pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer);
713                         pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2(pBuffer);
714                         pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer);
715                         pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer);
716                         pRAInfo->DROP =   (u16)GET_TX_REPORT_TYPE1_DROP_0(pBuffer);
717                         pRAInfo->TOTAL = pRAInfo->RTY[0] + pRAInfo->RTY[1] +
718                                          pRAInfo->RTY[2] + pRAInfo->RTY[3] +
719                                          pRAInfo->RTY[4] + pRAInfo->DROP;
720                         if (pRAInfo->TOTAL != 0) {
721                                 ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
722                                              ("macid =%d Total =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d D0 =%d valid0 =%x valid1 =%x\n",
723                                              MacId, pRAInfo->TOTAL,
724                                              pRAInfo->RTY[0], pRAInfo->RTY[1],
725                                              pRAInfo->RTY[2], pRAInfo->RTY[3],
726                                              pRAInfo->RTY[4], pRAInfo->DROP,
727                                              macid_entry0, macid_entry1));
728                                 if (pRAInfo->PTActive) {
729                                         if (pRAInfo->RAstage < 5)
730                                                 odm_RateDecision_8188E(dm_odm, pRAInfo);
731                                         else if (pRAInfo->RAstage == 5) /*  Power training try state */
732                                                 odm_PTTryState_8188E(pRAInfo);
733                                         else /*  RAstage == 6 */
734                                                 odm_PTDecision_8188E(pRAInfo);
735
736                                         /*  Stage_RA counter */
737                                         if (pRAInfo->RAstage <= 5)
738                                                 pRAInfo->RAstage++;
739                                         else
740                                                 pRAInfo->RAstage = 0;
741                                 } else {
742                                         odm_RateDecision_8188E(dm_odm, pRAInfo);
743                                 }
744                                 ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD,
745                                              ("macid =%d R0 =%d R1 =%d R2 =%d R3 =%d R4 =%d drop =%d valid0 =%x RateID =%d SGI =%d\n",
746                                              MacId,
747                                              pRAInfo->RTY[0],
748                                              pRAInfo->RTY[1],
749                                              pRAInfo->RTY[2],
750                                              pRAInfo->RTY[3],
751                                              pRAInfo->RTY[4],
752                                              pRAInfo->DROP,
753                                              macid_entry0,
754                                              pRAInfo->DecisionRate,
755                                              pRAInfo->RateSGI));
756                         } else {
757                                 ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (" TOTAL = 0!!!!\n"));
758                         }
759                 }
760
761                 if (minRptTime > pRAInfo->RptTime)
762                         minRptTime = pRAInfo->RptTime;
763
764                 pBuffer += TX_RPT2_ITEM_SIZE;
765                 MacId++;
766         } while (MacId < ItemNum);
767
768         odm_RATxRPTTimerSetting(dm_odm, minRptTime);
769
770         ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== ODM_RA_TxRPT2Handle_8188E()\n"));
771 }