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