• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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] = {
90 	0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12, 0x927c}; /*  200ms-1200ms */
91 
92 /*  End Rate adaptive parameters */
93 
odm_SetTxRPTTiming_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo,u8 extend)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 
118 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
119 			("pRaInfo->RptTime = 0x%x\n", pRaInfo->RptTime));
120 }
121 
odm_RateDown_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)122 static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm,
123 				struct odm_ra_info *pRaInfo)
124 {
125 	u8 RateID, LowestRate, HighestRate;
126 	u8 i;
127 
128 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
129 			ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n"));
130 	if (!pRaInfo) {
131 		ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
132 				("odm_RateDown_8188E(): pRaInfo is NULL\n"));
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);
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"));
183 	return 0;
184 }
185 
odm_RateUp_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)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 
194 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE,
195 			ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n"));
196 	if (!pRaInfo) {
197 		ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
198 				("odm_RateUp_8188E(): pRaInfo is NULL\n"));
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);
214 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
215 			("odm_RateUp_8188E():Decrease RPT Timing\n"));
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:
233 	if (pRaInfo->RAWaitingCounter ==
234 		(4+PendingForRateUpFail[pRaInfo->RAPendingCounter]))
235 		pRaInfo->RAWaitingCounter = 0;
236 	else
237 		pRaInfo->RAWaitingCounter++;
238 
239 	pRaInfo->DecisionRate = RateID;
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"));
247 	return 0;
248 }
249 
odm_ResetRaCounter_8188E(struct odm_ra_info * pRaInfo)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 
odm_RateDecision_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)259 static void odm_RateDecision_8188E(struct odm_dm_struct *dm_odm,
260 		struct odm_ra_info *pRaInfo
261 	)
262 {
263 	u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0, i = 0;
264 	/* u32 pool_retry; */
265 	static u8 DynamicTxRPTTimingCounter;
266 
267 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
268 			("=====>odm_RateDecision_8188E()\n"));
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));
289 
290 		for (i = 0 ; i <= 4 ; i++)
291 			pRaInfo->NscDown += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID1][i];
292 
293 		ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
294 			     (" NscDown is %d, total*penalty[5] is %d\n", pRaInfo->NscDown,
295 			      (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])));
296 
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));
306 
307 		for (i = 0 ; i <= 4 ; i++)
308 			pRaInfo->NscUp += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID2][i];
309 
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])));
313 
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 
odm_ARFBRefresh_8188E(struct odm_dm_struct * dm_odm,struct odm_ra_info * pRaInfo)350 static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo)
351 {  /*  Wilson 2011/10/26 */
352 	struct adapter *adapt = dm_odm->Adapter;
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:
379 		MaskFromReg = usb_read32(adapt, REG_ARFR0);
380 		pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
381 		break;
382 	case 13:
383 		MaskFromReg = usb_read32(adapt, REG_ARFR1);
384 		pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
385 		break;
386 	case 14:
387 		MaskFromReg = usb_read32(adapt, REG_ARFR2);
388 		pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg;
389 		break;
390 	case 15:
391 		MaskFromReg = usb_read32(adapt, REG_ARFR3);
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 
odm_PTTryState_8188E(struct odm_ra_info * pRaInfo)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 
odm_PTDecision_8188E(struct odm_ra_info * pRaInfo)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 
508 	j >>= 1;
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
odm_RATxRPTTimerSetting(struct odm_dm_struct * dm_odm,u16 minRptTime)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
ODM_RASupport_Init(struct odm_dm_struct * dm_odm)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 
551 	dm_odm->RaSupport88E = true;
552 }
553 
ODM_RAInfo_Init(struct odm_dm_struct * dm_odm,u8 macid)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 */
559 
560 	if (dm_odm->pWirelessMode)
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 
ODM_RAInfo_Init_all(struct odm_dm_struct * dm_odm)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 
ODM_RA_GetShortGI_8188E(struct odm_dm_struct * dm_odm,u8 macid)625 u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid)
626 {
627 	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
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 
ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct * dm_odm,u8 macid)634 u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid)
635 {
636 	u8 DecisionRate = 0;
637 
638 	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
639 		return 0;
640 	DecisionRate = dm_odm->RAInfo[macid].DecisionRate;
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 
ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct * dm_odm,u8 macid)646 u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid)
647 {
648 	u8 PTStage = 5;
649 
650 	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
651 		return 0;
652 	PTStage = dm_odm->RAInfo[macid].PTStage;
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 
ODM_RA_UpdateRateInfo_8188E(struct odm_dm_struct * dm_odm,u8 macid,u8 RateID,u32 RateMask,u8 SGIEnable)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 
662 	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
663 		return;
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));
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 
ODM_RA_SetRSSI_8188E(struct odm_dm_struct * dm_odm,u8 macid,u8 Rssi)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 
679 	if ((!dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM))
680 		return;
681 	ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
682 		     (" macid =%d Rssi =%d\n", macid, Rssi));
683 
684 	pRaInfo = &(dm_odm->RAInfo[macid]);
685 	pRaInfo->RssiStaRA = Rssi;
686 }
687 
ODM_RA_Set_TxRPT_Time(struct odm_dm_struct * dm_odm,u16 minRptTime)688 void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime)
689 {
690 	struct adapter *adapt = dm_odm->Adapter;
691 
692 	usb_write16(adapt, REG_TX_RPT_TIME, minRptTime);
693 }
694 
ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct * dm_odm,u8 * TxRPT_Buf,u16 TxRPT_Len,u32 macid_entry0,u32 macid_entry1)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,
736 					     macid_entry0 , macid_entry1));
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 }
781