Commit | Line | Data |
---|---|---|
a0da203b LF |
1 | /*++ |
2 | Copyright (c) Realtek Semiconductor Corp. All rights reserved. | |
3 | ||
4 | Module Name: | |
5 | RateAdaptive.c | |
6 | ||
7 | Abstract: | |
8 | Implement Rate Adaptive functions for common operations. | |
9 | ||
10 | Major 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 | ||
20 | static 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 | ||
46 | static u8 PT_PENALTY[RETRYSIZE+1] = {34, 31, 30, 24, 0, 32}; | |
47 | ||
48 | /* wilson modify */ | |
49 | static 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 | ||
59 | static 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 | ||
65 | static 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 | ||
71 | static 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}; | |
76 | static 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 | ||
82 | static 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 | ||
88 | static u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; | |
89 | static u16 DynamicTxRPTTiming[6] = { | |
e703f237 | 90 | 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /* 200ms-1200ms */ |
a0da203b LF |
91 | |
92 | /* End Rate adaptive parameters */ | |
93 | ||
94 | static 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 |
122 | static 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 | } | |
158 | RateDownFinish: | |
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 | ||
186 | static 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 | } | |
232 | RateUpfinish: | |
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 | ||
250 | static 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 | ||
259 | static 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 | ||
350 | static 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 | ||
440 | static 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 | ||
492 | static 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 | ||
527 | static void | |
528 | odm_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 | ||
544 | void | |
545 | ODM_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 | ||
554 | int 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 | ||
612 | int 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 | ||
625 | u8 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 | ||
634 | u8 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 | ||
646 | u8 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 | ||
658 | void 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 | ||
675 | void 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 | ||
688 | void 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 | ||
695 | void 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 | } |