cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

Hal8188ERateAdaptive.c (17859B)


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