rtl8188eu/hal/Hal8188ERateAdaptive.c

1000 lines
26 KiB
C
Raw Normal View History

/*++
Copyright (c) Realtek Semiconductor Corp. All rights reserved.
Module Name:
RateAdaptive.c
Abstract:
Implement Rate Adaptive functions for common operations.
Major Change History:
When Who What
---------- --------------- -------------------------------
2011-08-12 Page Create.
--*/
#include "odm_precomp.h"
#if (RATE_ADAPTIVE_SUPPORT == 1)
/* Rate adaptive parameters */
static u1Byte RETRY_PENALTY[PERENTRY][RETRYSIZE+1] = {
{5,4,3,2,0,3},/* 92 , idx=0 */
{6,5,4,3,0,4},/* 86 , idx=1 */
{6,5,4,2,0,4},/* 81 , idx=2 */
{8,7,6,4,0,6},/* 75 , idx=3 */
{10,9,8,6,0,8},/* 71 , idx=4 */
{10,9,8,4,0,8},/* 66 , idx=5 */
{10,9,8,2,0,8},/* 62 , idx=6 */
{10,9,8,0,0,8},/* 59 , idx=7 */
{18,17,16,8,0,16},/* 53 , idx=8 */
{26,25,24,16,0,24},/* 50 , idx=9 */
{34,33,32,24,0,32},/* 47 , idx=0x0a */
{34,31,28,20,0,32},/* 43 , idx=0x0b */
{34,31,27,18,0,32},/* 40 , idx=0x0c */
{34,31,26,16,0,32},/* 37 , idx=0x0d */
{34,30,22,16,0,32},/* 32 , idx=0x0e */
{34,30,24,16,0,32},/* 26 , idx=0x0f */
{49,46,40,16,0,48},/* 20 , idx=0x10 */
{49,45,32,0,0,48},/* 17 , idx=0x11 */
{49,45,22,18,0,48},/* 15 , idx=0x12 */
{49,40,24,16,0,48},/* 12 , idx=0x13 */
{49,32,18,12,0,48},/* 9 , idx=0x14 */
{49,22,18,14,0,48},/* 6 , idx=0x15 */
{49,16,16,0,0,48}};/* 3, idx=0x16 */
static u1Byte RETRY_PENALTY_UP[RETRYSIZE+1]={49,44,16,16,0,48}; /* 12% for rate up */
static u1Byte PT_PENALTY[RETRYSIZE+1]={34,31,30,24,0,32};
/* wilson modify */
static u1Byte RETRY_PENALTY_IDX[2][RATESIZE] = {
{4,4,4,5,4,4,5,7,7,7,8,0x0a, /* SS>TH */
4,4,4,4,6,0x0a,0x0b,0x0d,
5,5,7,7,8,0x0b,0x0d,0x0f}, /* 0329 R01 */
{0x0a,0x0a,0x0b,0x0c,0x0a,
0x0a,0x0b,0x0c,0x0d,0x10,0x13,0x14, /* SS<TH */
0x0b,0x0c,0x0d,0x0e,0x0f,0x11,0x13,0x15,
9,9,9,9,0x0c,0x0e,0x11,0x13}};
static u1Byte RETRY_PENALTY_UP_IDX[RATESIZE] = {
0x0c,0x0d,0x0d,0x0f,0x0d,0x0e,
0x0f,0x0f,0x10,0x12,0x13,0x14, /* SS>TH */
0x0f,0x10,0x10,0x12,0x12,0x13,0x14,0x15,
0x11,0x11,0x12,0x13,0x13,0x13,0x14,0x15};
static u1Byte RSSI_THRESHOLD[RATESIZE] = {
0,0,0,0,
0,0,0,0,0,0x24,0x26,0x2a,
0x18,0x1a,0x1d,0x1f,0x21,0x27,0x29,0x2a,
0,0,0,0x1f,0x23,0x28,0x2a,0x2c};
static u2Byte N_THRESHOLD_HIGH[RATESIZE] = {
4,4,8,16,
24,36,48,72,96,144,192,216,
60,80,100,160,240,400,560,640,
300,320,480,720,1000,1200,1600,2000};
static u2Byte N_THRESHOLD_LOW[RATESIZE] = {
2,2,4,8,
12,18,24,36,48,72,96,108,
30,40,50,80,120,200,280,320,
150,160,240,360,500,600,800,1000};
static u1Byte TRYING_NECESSARY[RATESIZE] = {
2,2,2,2,
2,2,3,3,4,4,5,7,
4,4,7,10,10,12,12,18,
5,7,7,8,11,18,36,60}; /* 0329 1207 */
static u1Byte DROPING_NECESSARY[RATESIZE] = {
1,1,1,1,
1,2,3,4,5,6,7,8,
1,2,3,4,5,6,7,8,
5,6,7,8,9,10,11,12};
static u4Byte INIT_RATE_FALLBACK_TABLE[16]={
0x0f8ff015, /* 0: 40M BGN mode */
0x0f8ff010, /* 1: 40M GN mode */
0x0f8ff005, /* 2: BN mode/ 40M BGN mode */
0x0f8ff000, /* 3: N mode */
0x00000ff5, /* 4: BG mode */
0x00000ff0, /* 5: G mode */
0x0000000d, /* 6: B mode */
0, /* 7: */
0, /* 8: */
0, /* 9: */
0, /* 10: */
0, /* 11: */
0, /* 12: */
0, /* 13: */
0, /* 14: */
0, /* 15: */
};
static u1Byte PendingForRateUpFail[5] = {2,10,24,40,60};
static u2Byte DynamicTxRPTTiming[6] = {
0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12 ,0x927c}; /* 200ms-1200ms */
/* End Rate adaptive parameters */
static void odm_SetTxRPTTiming_8188E(
struct odm_dm_struct * pDM_Odm,
struct odm_ra_info *pRaInfo,
u1Byte extend
)
{
u1Byte idx = 0;
for (idx=0; idx<5; idx++)
if (DynamicTxRPTTiming[idx] == pRaInfo->RptTime)
break;
if (extend==0) /* back to default timing */
idx=0; /* 200ms */
else if (extend==1) {/* increase the timing */
idx+=1;
if (idx>5)
idx=5;
}
else if (extend==2) {/* decrease the timing */
if (idx!=0)
idx-=1;
}
pRaInfo->RptTime=DynamicTxRPTTiming[idx];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("pRaInfo->RptTime=0x%x\n", pRaInfo->RptTime));
}
static int odm_RateDown_8188E(
struct odm_dm_struct *pDM_Odm,
struct odm_ra_info *pRaInfo
)
{
u1Byte RateID, LowestRate, HighestRate;
u1Byte i;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n"));
if (NULL == pRaInfo)
{
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_RateDown_8188E(): pRaInfo is NULL\n"));
return -1;
}
RateID = pRaInfo->PreRate;
LowestRate = pRaInfo->LowestRate;
HighestRate = pRaInfo->HighestRate;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" RateID=%d LowestRate=%d HighestRate=%d RateSGI=%d\n",
RateID, LowestRate, HighestRate, pRaInfo->RateSGI));
if (RateID > HighestRate) {
RateID=HighestRate;
} else if (pRaInfo->RateSGI) {
pRaInfo->RateSGI=0;
} else if (RateID > LowestRate) {
if (RateID > 0) {
for (i=RateID-1; i>LowestRate;i--) {
if (pRaInfo->RAUseRate & BIT(i)) {
RateID=i;
goto RateDownFinish;
}
}
}
} else if (RateID <= LowestRate) {
RateID = LowestRate;
}
RateDownFinish:
if (pRaInfo->RAWaitingCounter==1){
pRaInfo->RAWaitingCounter+=1;
pRaInfo->RAPendingCounter+=1;
} else if (pRaInfo->RAWaitingCounter==0){
} else {
pRaInfo->RAWaitingCounter=0;
pRaInfo->RAPendingCounter=0;
}
if (pRaInfo->RAPendingCounter>=4)
pRaInfo->RAPendingCounter=4;
pRaInfo->DecisionRate=RateID;
odm_SetTxRPTTiming_8188E(pDM_Odm,pRaInfo, 2);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate down, RPT Timing default\n"));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("RAWaitingCounter %d, RAPendingCounter %d",pRaInfo->RAWaitingCounter,pRaInfo->RAPendingCounter));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate down to RateID %d RateSGI %d\n", RateID, pRaInfo->RateSGI));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_RateDown_8188E()\n"));
return 0;
}
static int odm_RateUp_8188E(
struct odm_dm_struct * pDM_Odm,
struct odm_ra_info *pRaInfo
)
{
u1Byte RateID, HighestRate;
u1Byte i;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n"));
if (NULL == pRaInfo) {
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_RateUp_8188E(): pRaInfo is NULL\n"));
return -1;
}
RateID = pRaInfo->PreRate;
HighestRate = pRaInfo->HighestRate;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" RateID=%d HighestRate=%d\n",
RateID, HighestRate));
if (pRaInfo->RAWaitingCounter==1){
pRaInfo->RAWaitingCounter=0;
pRaInfo->RAPendingCounter=0;
} else if (pRaInfo->RAWaitingCounter>1){
pRaInfo->PreRssiStaRA=pRaInfo->RssiStaRA;
goto RateUpfinish;
}
odm_SetTxRPTTiming_8188E(pDM_Odm,pRaInfo, 0);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("odm_RateUp_8188E():Decrease RPT Timing\n"));
if (RateID < HighestRate) {
for (i=RateID+1; i<=HighestRate; i++) {
if (pRaInfo->RAUseRate & BIT(i)) {
RateID=i;
goto RateUpfinish;
}
}
} else if (RateID == HighestRate) {
if (pRaInfo->SGIEnable && (pRaInfo->RateSGI != 1))
pRaInfo->RateSGI = 1;
else if ((pRaInfo->SGIEnable) !=1 )
pRaInfo->RateSGI = 0;
} else {
RateID = HighestRate;
}
RateUpfinish:
if (pRaInfo->RAWaitingCounter==(4+PendingForRateUpFail[pRaInfo->RAPendingCounter]))
pRaInfo->RAWaitingCounter=0;
else
pRaInfo->RAWaitingCounter++;
pRaInfo->DecisionRate=RateID;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("Rate up to RateID %d\n", RateID));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("RAWaitingCounter %d, RAPendingCounter %d",pRaInfo->RAWaitingCounter,pRaInfo->RAPendingCounter));
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_RateUp_8188E()\n"));
return 0;
}
static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo){
u1Byte RateID;
RateID=pRaInfo->DecisionRate;
pRaInfo->NscUp=(N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1;
pRaInfo->NscDown=(N_THRESHOLD_HIGH[RateID]+N_THRESHOLD_LOW[RateID])>>1;
}
static void odm_RateDecision_8188E(struct odm_dm_struct * pDM_Odm,
struct odm_ra_info *pRaInfo
)
{
u1Byte RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0;
/* u4Byte pool_retry; */
static u1Byte DynamicTxRPTTimingCounter=0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("=====>odm_RateDecision_8188E()\n"));
if (pRaInfo->Active && (pRaInfo->TOTAL > 0)) /* STA used and data packet exits */
{
if ( (pRaInfo->RssiStaRA<(pRaInfo->PreRssiStaRA-3))|| (pRaInfo->RssiStaRA>(pRaInfo->PreRssiStaRA+3))){
pRaInfo->RAWaitingCounter=0;
pRaInfo->RAPendingCounter=0;
}
/* Start RA decision */
if (pRaInfo->PreRate > pRaInfo->HighestRate)
RateID = pRaInfo->HighestRate;
else
RateID = pRaInfo->PreRate;
if (pRaInfo->RssiStaRA > RSSI_THRESHOLD[RateID])
RtyPtID=0;
else
RtyPtID=1;
PenaltyID1 = RETRY_PENALTY_IDX[RtyPtID][RateID]; /* TODO by page */
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" NscDown init is %d\n", pRaInfo->NscDown));
pRaInfo->NscDown += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID1][0];
pRaInfo->NscDown += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID1][1];
pRaInfo->NscDown += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID1][2];
pRaInfo->NscDown += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID1][3];
pRaInfo->NscDown += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID1][4];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" NscDown is %d, total*penalty[5] is %d\n",
pRaInfo->NscDown, (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5])));
if (pRaInfo->NscDown > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5]))
pRaInfo->NscDown -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID1][5];
else
pRaInfo->NscDown=0;
/* rate up */
PenaltyID2 = RETRY_PENALTY_UP_IDX[RateID];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" NscUp init is %d\n", pRaInfo->NscUp));
pRaInfo->NscUp += pRaInfo->RTY[0] * RETRY_PENALTY[PenaltyID2][0];
pRaInfo->NscUp += pRaInfo->RTY[1] * RETRY_PENALTY[PenaltyID2][1];
pRaInfo->NscUp += pRaInfo->RTY[2] * RETRY_PENALTY[PenaltyID2][2];
pRaInfo->NscUp += pRaInfo->RTY[3] * RETRY_PENALTY[PenaltyID2][3];
pRaInfo->NscUp += pRaInfo->RTY[4] * RETRY_PENALTY[PenaltyID2][4];
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
("NscUp is %d, total*up[5] is %d\n",
pRaInfo->NscUp, (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5])));
if (pRaInfo->NscUp > (pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5]))
pRaInfo->NscUp -= pRaInfo->TOTAL * RETRY_PENALTY[PenaltyID2][5];
else
pRaInfo->NscUp = 0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE|ODM_COMP_INIT, ODM_DBG_LOUD,
(" RssiStaRa= %d RtyPtID=%d PenaltyID1=0x%x PenaltyID2=0x%x RateID=%d NscDown=%d NscUp=%d SGI=%d\n",
pRaInfo->RssiStaRA,RtyPtID, PenaltyID1,PenaltyID2, RateID, pRaInfo->NscDown, pRaInfo->NscUp, pRaInfo->RateSGI));
if ((pRaInfo->NscDown < N_THRESHOLD_LOW[RateID]) ||(pRaInfo->DROP>DROPING_NECESSARY[RateID]))
odm_RateDown_8188E(pDM_Odm,pRaInfo);
else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID])
odm_RateUp_8188E(pDM_Odm,pRaInfo);
if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
pRaInfo->DecisionRate = pRaInfo->HighestRate;
if ((pRaInfo->DecisionRate)==(pRaInfo->PreRate))
DynamicTxRPTTimingCounter+=1;
else
DynamicTxRPTTimingCounter=0;
if (DynamicTxRPTTimingCounter>=4) {
odm_SetTxRPTTiming_8188E(pDM_Odm,pRaInfo, 1);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<=====Rate don't change 4 times, Extend RPT Timing\n"));
DynamicTxRPTTimingCounter=0;
}
pRaInfo->PreRate = pRaInfo->DecisionRate; /* YJ,add,120120 */
odm_ResetRaCounter_8188E( pRaInfo);
}
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<=====odm_RateDecision_8188E()\n"));
}
static int
odm_ARFBRefresh_8188E(
struct odm_dm_struct * pDM_Odm,
struct odm_ra_info *pRaInfo
)
{ /* Wilson 2011/10/26 */
u4Byte MaskFromReg;
s1Byte i;
switch (pRaInfo->RateID){
case RATR_INX_WIRELESS_NGB:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x0f8ff015;
break;
case RATR_INX_WIRELESS_NG:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x0f8ff010;
break;
case RATR_INX_WIRELESS_NB:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x0f8ff005;
break;
case RATR_INX_WIRELESS_N:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x0f8ff000;
break;
case RATR_INX_WIRELESS_GB:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x00000ff5;
break;
case RATR_INX_WIRELESS_G:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x00000ff0;
break;
case RATR_INX_WIRELESS_B:
pRaInfo->RAUseRate=(pRaInfo->RateMask)&0x0000000d;
break;
case 12:
MaskFromReg=ODM_Read4Byte(pDM_Odm, REG_ARFR0);
pRaInfo->RAUseRate=(pRaInfo->RateMask)&MaskFromReg;
break;
case 13:
MaskFromReg=ODM_Read4Byte(pDM_Odm, REG_ARFR1);
pRaInfo->RAUseRate=(pRaInfo->RateMask)&MaskFromReg;
break;
case 14:
MaskFromReg=ODM_Read4Byte(pDM_Odm, REG_ARFR2);
pRaInfo->RAUseRate=(pRaInfo->RateMask)&MaskFromReg;
break;
case 15:
MaskFromReg=ODM_Read4Byte(pDM_Odm, REG_ARFR3);
pRaInfo->RAUseRate=(pRaInfo->RateMask)&MaskFromReg;
break;
default:
pRaInfo->RAUseRate=(pRaInfo->RateMask);
break;
}
/* Highest rate */
if (pRaInfo->RAUseRate){
for (i=RATESIZE;i>=0;i--)
{
if ((pRaInfo->RAUseRate)&BIT(i)){
pRaInfo->HighestRate=i;
break;
}
}
}
else{
pRaInfo->HighestRate=0;
}
/* Lowest rate */
if (pRaInfo->RAUseRate){
for (i=0;i<RATESIZE;i++)
{
if ((pRaInfo->RAUseRate)&BIT(i))
{
pRaInfo->LowestRate=i;
break;
}
}
}
else{
pRaInfo->LowestRate=0;
}
#if POWER_TRAINING_ACTIVE == 1
if (pRaInfo->HighestRate >0x13)
pRaInfo->PTModeSS=3;
else if (pRaInfo->HighestRate >0x0b)
pRaInfo->PTModeSS=2;
else if (pRaInfo->HighestRate >0x0b)
pRaInfo->PTModeSS=1;
else
pRaInfo->PTModeSS=0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
("ODM_ARFBRefresh_8188E(): PTModeSS=%d\n", pRaInfo->PTModeSS));
#endif
if (pRaInfo->DecisionRate > pRaInfo->HighestRate)
pRaInfo->DecisionRate = pRaInfo->HighestRate;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
("ODM_ARFBRefresh_8188E(): RateID=%d RateMask=%8.8x RAUseRate=%8.8x HighestRate=%d,DecisionRate=%d\n",
pRaInfo->RateID, pRaInfo->RateMask, pRaInfo->RAUseRate, pRaInfo->HighestRate,pRaInfo->DecisionRate));
return 0;
}
#if POWER_TRAINING_ACTIVE == 1
static void
odm_PTTryState_8188E(
struct odm_ra_info *pRaInfo
)
{
pRaInfo->PTTryState=0;
switch (pRaInfo->PTModeSS)
{
case 3:
if (pRaInfo->DecisionRate>=0x19)
pRaInfo->PTTryState=1;
break;
case 2:
if (pRaInfo->DecisionRate>=0x11)
pRaInfo->PTTryState=1;
break;
case 1:
if (pRaInfo->DecisionRate>=0x0a)
pRaInfo->PTTryState=1;
break;
case 0:
if (pRaInfo->DecisionRate>=0x03)
pRaInfo->PTTryState=1;
break;
default:
pRaInfo->PTTryState=0;
}
if (pRaInfo->RssiStaRA<48)
{
pRaInfo->PTStage=0;
}
else if (pRaInfo->PTTryState==1)
{
if ((pRaInfo->PTStopCount>=10)||(pRaInfo->PTPreRssi>pRaInfo->RssiStaRA+5)
||(pRaInfo->PTPreRssi<pRaInfo->RssiStaRA-5)||(pRaInfo->DecisionRate!=pRaInfo->PTPreRate))
{
if (pRaInfo->PTStage==0)
pRaInfo->PTStage=1;
else if (pRaInfo->PTStage==1)
pRaInfo->PTStage=3;
else
pRaInfo->PTStage=5;
pRaInfo->PTPreRssi=pRaInfo->RssiStaRA;
pRaInfo->PTStopCount=0;
}
else{
pRaInfo->RAstage=0;
pRaInfo->PTStopCount++;
}
}
else{
pRaInfo->PTStage=0;
pRaInfo->RAstage=0;
}
pRaInfo->PTPreRate=pRaInfo->DecisionRate;
}
static void
odm_PTDecision_8188E(
struct odm_ra_info *pRaInfo
)
{
u1Byte j;
u1Byte temp_stage;
u4Byte numsc;
u4Byte num_total;
u1Byte stage_id;
numsc = 0;
num_total= pRaInfo->TOTAL* PT_PENALTY[5];
for (j=0;j<=4;j++)
{
numsc += pRaInfo->RTY[j] * PT_PENALTY[j];
if (numsc>num_total)
break;
}
j=j>>1;
temp_stage= (pRaInfo->PTStage +1)>>1;
if (temp_stage>j)
stage_id=temp_stage-j;
else
stage_id=0;
pRaInfo->PTSmoothFactor=(pRaInfo->PTSmoothFactor>>1) + (pRaInfo->PTSmoothFactor>>2) + stage_id*16+2;
if (pRaInfo->PTSmoothFactor>192)
pRaInfo->PTSmoothFactor=192;
stage_id =pRaInfo->PTSmoothFactor>>6;
temp_stage=stage_id*2;
if (temp_stage!=0)
temp_stage-=1;
if (pRaInfo->DROP>3)
temp_stage=0;
pRaInfo->PTStage=temp_stage;
}
#endif
static void
odm_RATxRPTTimerSetting(
struct odm_dm_struct * pDM_Odm,
u2Byte minRptTime
)
{
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,(" =====>odm_RATxRPTTimerSetting()\n"));
if (pDM_Odm->CurrminRptTime != minRptTime){
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
(" CurrminRptTime =0x%04x minRptTime=0x%04x\n", pDM_Odm->CurrminRptTime, minRptTime));
rtw_rpt_timer_cfg_cmd(pDM_Odm->Adapter,minRptTime);
pDM_Odm->CurrminRptTime = minRptTime;
}
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,(" <=====odm_RATxRPTTimerSetting()\n"));
}
void
ODM_RASupport_Init(
struct odm_dm_struct *pDM_Odm
)
{
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>ODM_RASupport_Init()\n"));
/* 2012/02/14 MH Be noticed, the init must be after IC type is recognized!!!!! */
if (pDM_Odm->SupportICType == ODM_RTL8188E)
pDM_Odm->RaSupport88E = true;
}
int
ODM_RAInfo_Init(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
struct odm_ra_info *pRaInfo = &pDM_Odm->RAInfo[MacID];
#if 1
u1Byte WirelessMode=0xFF; /* invalid value */
u1Byte max_rate_idx = 0x13; /* MCS7 */
if (pDM_Odm->pWirelessMode!=NULL){
WirelessMode=*(pDM_Odm->pWirelessMode);
}
if (WirelessMode != 0xFF ){
if (WirelessMode & ODM_WM_N24G)
max_rate_idx = 0x13;
else if (WirelessMode & ODM_WM_G)
max_rate_idx = 0x0b;
else if (WirelessMode & ODM_WM_B)
max_rate_idx = 0x03;
}
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
("ODM_RAInfo_Init(): WirelessMode:0x%08x ,max_raid_idx:0x%02x\n",
WirelessMode,max_rate_idx));
pRaInfo->DecisionRate = max_rate_idx;
pRaInfo->PreRate = max_rate_idx;
pRaInfo->HighestRate=max_rate_idx;
#else
pRaInfo->DecisionRate = 0x13;
pRaInfo->PreRate = 0x13;
pRaInfo->HighestRate= 0x13;
#endif
pRaInfo->LowestRate=0;
pRaInfo->RateID=0;
pRaInfo->RateMask=0xffffffff;
pRaInfo->RssiStaRA=0;
pRaInfo->PreRssiStaRA=0;
pRaInfo->SGIEnable=0;
pRaInfo->RAUseRate=0xffffffff;
pRaInfo->NscDown=(N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
pRaInfo->NscUp=(N_THRESHOLD_HIGH[0x13]+N_THRESHOLD_LOW[0x13])/2;
pRaInfo->RateSGI=0;
pRaInfo->Active=1; /* Active is not used at present. by page, 110819 */
pRaInfo->RptTime = 0x927c;
pRaInfo->DROP=0;
pRaInfo->RTY[0]=0;
pRaInfo->RTY[1]=0;
pRaInfo->RTY[2]=0;
pRaInfo->RTY[3]=0;
pRaInfo->RTY[4]=0;
pRaInfo->TOTAL=0;
pRaInfo->RAWaitingCounter=0;
pRaInfo->RAPendingCounter=0;
#if POWER_TRAINING_ACTIVE == 1
pRaInfo->PTActive=1; /* Active when this STA is use */
pRaInfo->PTTryState=0;
pRaInfo->PTStage=5; /* Need to fill into HW_PWR_STATUS */
pRaInfo->PTSmoothFactor=192;
pRaInfo->PTStopCount=0;
pRaInfo->PTPreRate=0;
pRaInfo->PTPreRssi=0;
pRaInfo->PTModeSS=0;
pRaInfo->RAstage=0;
#endif
return 0;
}
int
ODM_RAInfo_Init_all(
struct odm_dm_struct * pDM_Odm
)
{
u1Byte MacID = 0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n"));
pDM_Odm->CurrminRptTime = 0;
for (MacID=0; MacID<ODM_ASSOCIATE_ENTRY_NUM; MacID++)
ODM_RAInfo_Init(pDM_Odm,MacID);
return 0;
}
u1Byte
ODM_RA_GetShortGI_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
if ((NULL == pDM_Odm) || (MacID >= ASSOCIATE_ENTRY_NUM))
return 0;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
("MacID=%d SGI=%d\n", MacID, pDM_Odm->RAInfo[MacID].RateSGI));
return pDM_Odm->RAInfo[MacID].RateSGI;
}
u1Byte
ODM_RA_GetDecisionRate_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
u1Byte DecisionRate = 0;
if ((NULL == pDM_Odm) || (MacID >= ASSOCIATE_ENTRY_NUM))
return 0;
DecisionRate = (pDM_Odm->RAInfo[MacID].DecisionRate);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" MacID=%d DecisionRate=0x%x\n", MacID, DecisionRate));
return DecisionRate;
}
u1Byte
ODM_RA_GetHwPwrStatus_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
u1Byte PTStage = 5;
if ((NULL == pDM_Odm) || (MacID >= ASSOCIATE_ENTRY_NUM))
return 0;
PTStage = (pDM_Odm->RAInfo[MacID].PTStage);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
("MacID=%d PTStage=0x%x\n", MacID, PTStage));
return PTStage;
}
void
ODM_RA_UpdateRateInfo_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID,
u1Byte RateID,
u4Byte RateMask,
u1Byte SGIEnable
)
{
struct odm_ra_info *pRaInfo = NULL;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
("MacID=%d RateID=0x%x RateMask=0x%x SGIEnable=%d\n",
MacID, RateID, RateMask, SGIEnable));
if ((NULL == pDM_Odm) || (MacID >= ASSOCIATE_ENTRY_NUM))
return;
pRaInfo = &(pDM_Odm->RAInfo[MacID]);
pRaInfo->RateID = RateID;
pRaInfo->RateMask = RateMask;
pRaInfo->SGIEnable = SGIEnable;
odm_ARFBRefresh_8188E(pDM_Odm, pRaInfo);
}
void
ODM_RA_SetRSSI_8188E(
struct odm_dm_struct * pDM_Odm,
u1Byte MacID,
u1Byte Rssi
)
{
struct odm_ra_info *pRaInfo = NULL;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE,
(" MacID=%d Rssi=%d\n", MacID, Rssi));
if ((NULL == pDM_Odm) || (MacID >= ASSOCIATE_ENTRY_NUM))
return;
pRaInfo = &(pDM_Odm->RAInfo[MacID]);
pRaInfo->RssiStaRA = Rssi;
}
void
ODM_RA_Set_TxRPT_Time(
struct odm_dm_struct * pDM_Odm,
u2Byte minRptTime
)
{
ODM_Write2Byte(pDM_Odm, REG_TX_RPT_TIME, minRptTime);
}
void
ODM_RA_TxRPT2Handle_8188E(
struct odm_dm_struct * pDM_Odm,
pu1Byte TxRPT_Buf,
u2Byte TxRPT_Len,
u4Byte MacIDValidEntry0,
u4Byte MacIDValidEntry1
)
{
struct odm_ra_info *pRAInfo = NULL;
u1Byte MacId = 0;
pu1Byte pBuffer = NULL;
u4Byte valid = 0, ItemNum = 0;
u2Byte minRptTime = 0x927c;
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>ODM_RA_TxRPT2Handle_8188E(): valid0=%d valid1=%d BufferLength=%d\n",
MacIDValidEntry0, MacIDValidEntry1, TxRPT_Len));
ItemNum = TxRPT_Len >> 3;
pBuffer = TxRPT_Buf;
do
{
if (MacId >= ASSOCIATE_ENTRY_NUM)
valid = 0;
else if (MacId >= 32)
valid = (1<<(MacId-32)) & MacIDValidEntry1;
else
valid = (1<<MacId) & MacIDValidEntry0;
pRAInfo = &(pDM_Odm->RAInfo[MacId]);
if (valid)
{
pRAInfo->RTY[0] = (u2Byte)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer);
pRAInfo->RTY[1] = (u2Byte)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer);
pRAInfo->RTY[2] = (u2Byte)GET_TX_REPORT_TYPE1_RERTY_2(pBuffer);
pRAInfo->RTY[3] = (u2Byte)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer);
pRAInfo->RTY[4] = (u2Byte)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer);
pRAInfo->DROP = (u2Byte)GET_TX_REPORT_TYPE1_DROP_0(pBuffer);
pRAInfo->TOTAL = pRAInfo->RTY[0] + \
pRAInfo->RTY[1] + \
pRAInfo->RTY[2] + \
pRAInfo->RTY[3] + \
pRAInfo->RTY[4] + \
pRAInfo->DROP;
if (pRAInfo->TOTAL != 0)
{
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD,
("macid=%d Total=%d R0=%d R1=%d R2=%d R3=%d R4=%d D0=%d valid0=%x valid1=%x\n",
MacId,
pRAInfo->TOTAL,
pRAInfo->RTY[0],
pRAInfo->RTY[1],
pRAInfo->RTY[2],
pRAInfo->RTY[3],
pRAInfo->RTY[4],
pRAInfo->DROP,
MacIDValidEntry0 ,
MacIDValidEntry1));
#if POWER_TRAINING_ACTIVE == 1
if (pRAInfo->PTActive){
if (pRAInfo->RAstage<5){
odm_RateDecision_8188E(pDM_Odm,pRAInfo);
}
else if (pRAInfo->RAstage==5){ /* Power training try state */
odm_PTTryState_8188E(pRAInfo);
}
else {/* RAstage==6 */
odm_PTDecision_8188E(pRAInfo);
}
/* Stage_RA counter */
if (pRAInfo->RAstage<=5)
pRAInfo->RAstage++;
else
pRAInfo->RAstage=0;
}
else{
odm_RateDecision_8188E(pDM_Odm,pRAInfo);
}
#else
odm_RateDecision_8188E(pDM_Odm, pRAInfo);
#endif
ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD,
("macid=%d R0=%d R1=%d R2=%d R3=%d R4=%d drop=%d valid0=%x RateID=%d SGI=%d\n",
MacId,
pRAInfo->RTY[0],
pRAInfo->RTY[1],
pRAInfo->RTY[2],
pRAInfo->RTY[3],
pRAInfo->RTY[4],
pRAInfo->DROP,
MacIDValidEntry0,
pRAInfo->DecisionRate,
pRAInfo->RateSGI));
}
else
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, (" TOTAL=0!!!!\n"));
}
if (minRptTime > pRAInfo->RptTime)
minRptTime = pRAInfo->RptTime;
pBuffer += TX_RPT2_ITEM_SIZE;
MacId++;
}while (MacId < ItemNum);
odm_RATxRPTTimerSetting(pDM_Odm,minRptTime);
ODM_RT_TRACE(pDM_Odm,ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== ODM_RA_TxRPT2Handle_8188E()\n"));
}
#else
static void
odm_RATxRPTTimerSetting(
struct odm_dm_struct * pDM_Odm,
u2Byte minRptTime
)
{
return;
}
void
ODM_RASupport_Init(
struct odm_dm_struct *pDM_Odm
)
{
return;
}
int
ODM_RAInfo_Init(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
return 0;
}
int
ODM_RAInfo_Init_all(
struct odm_dm_struct * pDM_Odm
)
{
return 0;
}
u1Byte
ODM_RA_GetShortGI_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
return 0;
}
u1Byte
ODM_RA_GetDecisionRate_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
return 0;
}
u1Byte
ODM_RA_GetHwPwrStatus_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID
)
{
return 0;
}
void
ODM_RA_UpdateRateInfo_8188E(
struct odm_dm_struct *pDM_Odm,
u1Byte MacID,
u1Byte RateID,
u4Byte RateMask,
u1Byte SGIEnable
)
{
return;
}
void
ODM_RA_SetRSSI_8188E(
struct odm_dm_struct * pDM_Odm,
u1Byte MacID,
u1Byte Rssi
)
{
return;
}
void
ODM_RA_Set_TxRPT_Time(
struct odm_dm_struct * pDM_Odm,
u2Byte minRptTime
)
{
return;
}
void
ODM_RA_TxRPT2Handle_8188E(
struct odm_dm_struct * pDM_Odm,
pu1Byte TxRPT_Buf,
u2Byte TxRPT_Len,
u4Byte MacIDValidEntry0,
u4Byte MacIDValidEntry1
)
{
return;
}
#endif