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