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 
odm_SetTxRPTTiming_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo,u8 extend)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 
odm_RateDown_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)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 
odm_RateUp_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)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 
odm_ResetRaCounter_8188E(struct odm_ra_info * pRaInfo)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 
odm_RateDecision_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)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 
odm_ARFBRefresh_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)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 
odm_PTTryState_8188E(struct odm_ra_info * pRaInfo)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 
odm_PTDecision_8188E(struct odm_ra_info * pRaInfo)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
odm_RATxRPTTimerSetting(struct odm_dm_struct * dm_odm,u16 minRptTime)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 
ODM_RAInfo_Init(struct odm_dm_struct * dm_odm,u8 macid)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 
ODM_RAInfo_Init_all(struct odm_dm_struct * dm_odm)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 
ODM_RA_GetShortGI_8188E(struct odm_dm_struct * dm_odm,u8 macid)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 
ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct * dm_odm,u8 macid)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 
ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct * dm_odm,u8 macid)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 
ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct * dm_odm,u8 macid,u8 RateID,u32 RateMask,u8 SGIEnable)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 
ODM_RA_SetRSSI_8188E(struct odm_dm_struct * dm_odm,u8 macid,u8 Rssi)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 
ODM_RA_Set_TxRPT_Time(struct odm_dm_struct * dm_odm,u16 minRptTime)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 
ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct * dm_odm,u8 * TxRPT_Buf,u16 TxRPT_Len,u32 macid_entry0,u32 macid_entry1)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 }
772