X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fstaging%2Frtl8188eu%2Fhal%2FHal8188ERateAdaptive.c;fp=kernel%2Fdrivers%2Fstaging%2Frtl8188eu%2Fhal%2FHal8188ERateAdaptive.c;h=082f0ca198ef6d1e81f2765554cd903da72b2bc0;hb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;hp=0000000000000000000000000000000000000000;hpb=98260f3884f4a202f9ca5eabed40b1354c489b29;p=kvmfornfv.git diff --git a/kernel/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c b/kernel/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c new file mode 100644 index 000000000..082f0ca19 --- /dev/null +++ b/kernel/drivers/staging/rtl8188eu/hal/Hal8188ERateAdaptive.c @@ -0,0 +1,780 @@ +/*++ +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" + +/* Rate adaptive parameters */ + +static u8 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 u8 PT_PENALTY[RETRYSIZE+1] = {34, 31, 30, 24, 0, 32}; + +/* wilson modify */ +static u8 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, /* SSTH */ + 0x0f, 0x10, 0x10, 0x12, 0x12, 0x13, 0x14, 0x15, + 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x15}; + +static u8 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 u16 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 u16 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 u8 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 u8 PendingForRateUpFail[5] = {2, 10, 24, 40, 60}; +static u16 DynamicTxRPTTiming[6] = { + 0x186a, 0x30d4, 0x493e, 0x61a8, 0x7a12 , 0x927c}; /* 200ms-1200ms */ + +/* End Rate adaptive parameters */ + +static void odm_SetTxRPTTiming_8188E( + struct odm_dm_struct *dm_odm, + struct odm_ra_info *pRaInfo, + u8 extend + ) +{ + u8 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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + ("pRaInfo->RptTime = 0x%x\n", pRaInfo->RptTime)); +} + +static int odm_RateDown_8188E(struct odm_dm_struct *dm_odm, + struct odm_ra_info *pRaInfo) +{ + u8 RateID, LowestRate, HighestRate; + u8 i; + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, + ODM_DBG_TRACE, ("=====>odm_RateDown_8188E()\n")); + if (NULL == pRaInfo) { + ODM_RT_TRACE(dm_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(dm_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(dm_odm, pRaInfo, 2); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, + ODM_DBG_LOUD, ("Rate down, RPT Timing default\n")); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + ("RAWaitingCounter %d, RAPendingCounter %d", + pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter)); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + ("Rate down to RateID %d RateSGI %d\n", RateID, pRaInfo->RateSGI)); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + ("<===== odm_RateDown_8188E()\n")); + return 0; +} + +static int odm_RateUp_8188E( + struct odm_dm_struct *dm_odm, + struct odm_ra_info *pRaInfo + ) +{ + u8 RateID, HighestRate; + u8 i; + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, + ODM_DBG_TRACE, ("=====>odm_RateUp_8188E()\n")); + if (NULL == pRaInfo) { + ODM_RT_TRACE(dm_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(dm_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(dm_odm, pRaInfo, 0); + ODM_RT_TRACE(dm_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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + ("Rate up to RateID %d\n", RateID)); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + ("RAWaitingCounter %d, RAPendingCounter %d", + pRaInfo->RAWaitingCounter, pRaInfo->RAPendingCounter)); + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, + ODM_DBG_TRACE, ("<===== odm_RateUp_8188E()\n")); + return 0; +} + +static void odm_ResetRaCounter_8188E(struct odm_ra_info *pRaInfo) +{ + u8 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 *dm_odm, + struct odm_ra_info *pRaInfo + ) +{ + u8 RateID = 0, RtyPtID = 0, PenaltyID1 = 0, PenaltyID2 = 0, i = 0; + /* u32 pool_retry; */ + static u8 DynamicTxRPTTimingCounter; + + ODM_RT_TRACE(dm_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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + (" NscDown init is %d\n", pRaInfo->NscDown)); + + for (i = 0 ; i <= 4 ; i++) + pRaInfo->NscDown += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID1][i]; + + ODM_RT_TRACE(dm_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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + (" NscUp init is %d\n", pRaInfo->NscUp)); + + for (i = 0 ; i <= 4 ; i++) + pRaInfo->NscUp += pRaInfo->RTY[i] * RETRY_PENALTY[PenaltyID2][i]; + + ODM_RT_TRACE(dm_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(dm_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(dm_odm, pRaInfo); + else if (pRaInfo->NscUp > N_THRESHOLD_HIGH[RateID]) + odm_RateUp_8188E(dm_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(dm_odm, pRaInfo, 1); + ODM_RT_TRACE(dm_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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, ("<===== odm_RateDecision_8188E()\n")); +} + +static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_info *pRaInfo) +{ /* Wilson 2011/10/26 */ + struct adapter *adapt = dm_odm->Adapter; + u32 MaskFromReg; + s8 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 = usb_read32(adapt, REG_ARFR0); + pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; + break; + case 13: + MaskFromReg = usb_read32(adapt, REG_ARFR1); + pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; + break; + case 14: + MaskFromReg = usb_read32(adapt, REG_ARFR2); + pRaInfo->RAUseRate = (pRaInfo->RateMask)&MaskFromReg; + break; + case 15: + MaskFromReg = usb_read32(adapt, 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 (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(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + ("ODM_ARFBRefresh_8188E(): PTModeSS =%d\n", pRaInfo->PTModeSS)); + + if (pRaInfo->DecisionRate > pRaInfo->HighestRate) + pRaInfo->DecisionRate = pRaInfo->HighestRate; + + ODM_RT_TRACE(dm_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; +} + +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; + break; + } + + 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) +{ + u8 j; + u8 temp_stage; + u32 numsc; + u32 num_total; + u8 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 >>= 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; +} + +static void +odm_RATxRPTTimerSetting( + struct odm_dm_struct *dm_odm, + u16 minRptTime +) +{ + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" =====>odm_RATxRPTTimerSetting()\n")); + + if (dm_odm->CurrminRptTime != minRptTime) { + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + (" CurrminRptTime = 0x%04x minRptTime = 0x%04x\n", dm_odm->CurrminRptTime, minRptTime)); + rtw_rpt_timer_cfg_cmd(dm_odm->Adapter, minRptTime); + dm_odm->CurrminRptTime = minRptTime; + } + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, (" <===== odm_RATxRPTTimerSetting()\n")); +} + +void +ODM_RASupport_Init( + struct odm_dm_struct *dm_odm + ) +{ + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>ODM_RASupport_Init()\n")); + + dm_odm->RaSupport88E = true; +} + +int ODM_RAInfo_Init(struct odm_dm_struct *dm_odm, u8 macid) +{ + struct odm_ra_info *pRaInfo = &dm_odm->RAInfo[macid]; + u8 WirelessMode = 0xFF; /* invalid value */ + u8 max_rate_idx = 0x13; /* MCS7 */ + + if (dm_odm->pWirelessMode != NULL) + WirelessMode = *(dm_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(dm_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; + 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; + 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; + return 0; +} + +int ODM_RAInfo_Init_all(struct odm_dm_struct *dm_odm) +{ + u8 macid = 0; + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("=====>\n")); + dm_odm->CurrminRptTime = 0; + + for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) + ODM_RAInfo_Init(dm_odm, macid); + + return 0; +} + +u8 ODM_RA_GetShortGI_8188E(struct odm_dm_struct *dm_odm, u8 macid) +{ + if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) + return 0; + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + ("macid =%d SGI =%d\n", macid, dm_odm->RAInfo[macid].RateSGI)); + return dm_odm->RAInfo[macid].RateSGI; +} + +u8 ODM_RA_GetDecisionRate_8188E(struct odm_dm_struct *dm_odm, u8 macid) +{ + u8 DecisionRate = 0; + + if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) + return 0; + DecisionRate = dm_odm->RAInfo[macid].DecisionRate; + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + (" macid =%d DecisionRate = 0x%x\n", macid, DecisionRate)); + return DecisionRate; +} + +u8 ODM_RA_GetHwPwrStatus_8188E(struct odm_dm_struct *dm_odm, u8 macid) +{ + u8 PTStage = 5; + + if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) + return 0; + PTStage = dm_odm->RAInfo[macid].PTStage; + ODM_RT_TRACE(dm_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 *dm_odm, u8 macid, u8 RateID, u32 RateMask, u8 SGIEnable) +{ + struct odm_ra_info *pRaInfo = NULL; + + ODM_RT_TRACE(dm_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 == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) + return; + + pRaInfo = &(dm_odm->RAInfo[macid]); + pRaInfo->RateID = RateID; + pRaInfo->RateMask = RateMask; + pRaInfo->SGIEnable = SGIEnable; + odm_ARFBRefresh_8188E(dm_odm, pRaInfo); +} + +void ODM_RA_SetRSSI_8188E(struct odm_dm_struct *dm_odm, u8 macid, u8 Rssi) +{ + struct odm_ra_info *pRaInfo = NULL; + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_TRACE, + (" macid =%d Rssi =%d\n", macid, Rssi)); + if ((NULL == dm_odm) || (macid >= ASSOCIATE_ENTRY_NUM)) + return; + + pRaInfo = &(dm_odm->RAInfo[macid]); + pRaInfo->RssiStaRA = Rssi; +} + +void ODM_RA_Set_TxRPT_Time(struct odm_dm_struct *dm_odm, u16 minRptTime) +{ + struct adapter *adapt = dm_odm->Adapter; + + usb_write16(adapt, REG_TX_RPT_TIME, minRptTime); +} + +void ODM_RA_TxRPT2Handle_8188E(struct odm_dm_struct *dm_odm, u8 *TxRPT_Buf, u16 TxRPT_Len, u32 macid_entry0, u32 macid_entry1) +{ + struct odm_ra_info *pRAInfo = NULL; + u8 MacId = 0; + u8 *pBuffer = NULL; + u32 valid = 0, ItemNum = 0; + u16 minRptTime = 0x927c; + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, + ("=====>ODM_RA_TxRPT2Handle_8188E(): valid0 =%d valid1 =%d BufferLength =%d\n", + macid_entry0, macid_entry1, 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)) & macid_entry1; + else + valid = (1 << MacId) & macid_entry0; + + pRAInfo = &(dm_odm->RAInfo[MacId]); + if (valid) { + pRAInfo->RTY[0] = (u16)GET_TX_REPORT_TYPE1_RERTY_0(pBuffer); + pRAInfo->RTY[1] = (u16)GET_TX_REPORT_TYPE1_RERTY_1(pBuffer); + pRAInfo->RTY[2] = (u16)GET_TX_REPORT_TYPE1_RERTY_2(pBuffer); + pRAInfo->RTY[3] = (u16)GET_TX_REPORT_TYPE1_RERTY_3(pBuffer); + pRAInfo->RTY[4] = (u16)GET_TX_REPORT_TYPE1_RERTY_4(pBuffer); + pRAInfo->DROP = (u16)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(dm_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, + macid_entry0 , macid_entry1)); + if (pRAInfo->PTActive) { + if (pRAInfo->RAstage < 5) + odm_RateDecision_8188E(dm_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(dm_odm, pRAInfo); + } + ODM_RT_TRACE(dm_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, + macid_entry0, + pRAInfo->DecisionRate, + pRAInfo->RateSGI)); + } else { + ODM_RT_TRACE(dm_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(dm_odm, minRptTime); + + ODM_RT_TRACE(dm_odm, ODM_COMP_RATE_ADAPTIVE, ODM_DBG_LOUD, ("<===== ODM_RA_TxRPT2Handle_8188E()\n")); +}