• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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