mlme.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,669 行 · 第 1/5 页
C
1,669 行
(pEntry->TxQuality[CurrRate] <= 1) &&
(pEntry->TxQuality[UpRate] <= 1))
{
DBGPRINT(RT_DEBUG_TRACE,"2 test frames at UpRate = %d Mbps\n",RateIdToMbps[UpRate]);
// tag PID for later on per-client/WDS TX statistics caculation
PID = PTYPE_NULL_AT_HIGH_RATE + WDS_PAIRWISE_KEY_OFFSET + i;
ApEnqueueNullFrame(pAd, pEntry->WdsAddr, UpRate, PID, MAIN_MBSSID, FALSE, FALSE, 0);
ApEnqueueNullFrame(pAd, pEntry->WdsAddr, UpRate, PID, MAIN_MBSSID, FALSE, FALSE, 0);
}
// perform DRS - consider TxRate Down frist, then rate up
// rate down, if current TX rate's quality is not good
// rate up, if UPRate's quality is very good
if ((pEntry->TxQuality[CurrRate] >= DRS_TX_QUALITY_WORST_BOUND) && (CurrRate != DownRate))
{
pEntry->CurrTxRate = DownRate;
}
else if ((pEntry->TxQuality[CurrRate] <=0) && (pEntry->TxQuality[UpRate] <=0) && (CurrRate != UpRate))
{
pEntry->CurrTxRate = UpRate;
}
// if rate-up happen, clear all bad history of all TX rates
if (pEntry->CurrTxRate > CurrRate)
{
DBGPRINT(RT_DEBUG_TRACE,"WDS: ++TX rate = %d Mbps\n", RateIdToMbps[UpRate]);
pEntry->CurrTxRateStableTime = 0;
pEntry->TxRateUpPenalty = 0;
NdisZeroMemory(pEntry->TxQuality, MAX_LEN_OF_SUPPORTED_RATES);
}
// if rate-down happen, only clear DownRate's bad history
else if (pEntry->CurrTxRate < CurrRate)
{
DBGPRINT(RT_DEBUG_TRACE,"WDS: --TX rate = %d Mbps\n", RateIdToMbps[DownRate]);
// shorter stable time require more penalty in next rate UP criteria
if (pEntry->CurrTxRateStableTime < 4) // less then 4 sec
pEntry->TxRateUpPenalty = DRS_PENALTY; // add 8 sec penalty
else if (pEntry->CurrTxRateStableTime < 8) // less then 8 sec
pEntry->TxRateUpPenalty = 2; // add 2 sec penalty
else
pEntry->TxRateUpPenalty = 0; // no penalty
pEntry->CurrTxRateStableTime = 0;
pEntry->TxQuality[pEntry->CurrTxRate] = 0;
}
// reset all OneSecxxx counters
pEntry->OneSecTxFailCount = 0;
pEntry->OneSecTxOkCount = 0;
pEntry->OneSecTxRetryOkCount = 0;
}
}
#endif /* WDS_SUPPORT */
#ifdef APCLI_SUPPORT
// AP Client tx rate tuning
for(i=0; i<MAX_APCLI_ENTRY; i++)
{
USHORT TxTotalCnt, TxErrorRatio;
BOOLEAN fUpgradeQuality = FALSE;
RT_802_11_APCLI_ENTRY *pEntry = &pAd->ApCliTab.ApCliEntry[i];
if(pEntry->Valid == FALSE || pEntry->Enable == FALSE)
continue;
pEntry->CurrTxRateStableTime ++;
TxTotalCnt = pEntry->OneSecTxOkCount + pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount;
AllTxTotalCnt += TxTotalCnt;
// skip those STA that has no traffic in the past period
if(TxTotalCnt == 0)
{
pEntry->TxRateUpPenalty = 0;
continue;
}
// decide the next upgrade rate and downgrade rate, if any
CurrRate = pEntry->CurrTxRate;
if(pAd->PortCfg.Channel > 14) // must be in 802.11A band
{
if(Phy11ANextRateUpward[CurrRate] <= pEntry->MaxSupportedRate)
UpRate = Phy11ANextRateUpward[CurrRate];
else
UpRate = CurrRate;
DownRate = Phy11ANextRateDownward[CurrRate];
} else
{
if(pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
{
if(Phy11BNextRateUpward[CurrRate] <= pEntry->MaxSupportedRate)
UpRate = Phy11BNextRateUpward[CurrRate];
else
UpRate = CurrRate;
DownRate = Phy11BNextRateDownward[CurrRate];
} else
{
if(Phy11BGNextRateUpward[CurrRate] <= pEntry->MaxSupportedRate)
UpRate = Phy11BGNextRateUpward[CurrRate];
else
UpRate = CurrRate;
DownRate = Phy11BGNextRateDownward[CurrRate];
}
}
// calculate Tx with retry ratio when enough samples are available
if(TxTotalCnt > 15)
{
TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) *100) / TxTotalCnt;
// downgrade TX quality if retry+error ratio reached
if(TxErrorRatio >= RateDownPER[CurrRate])
{
pEntry->TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND;
}
// upgrade TX quality if retry+error ratio reached
else if(TxErrorRatio <= RateUpPER[CurrRate])
{
fUpgradeQuality = TRUE;
if(pEntry->TxQuality[CurrRate])
pEntry->TxQuality[CurrRate] --; // quality very good in CurrRate
if(pEntry->TxRateUpPenalty)
pEntry->TxRateUpPenalty --;
else if(pEntry->TxQuality[UpRate])
pEntry->TxQuality[UpRate] --; // may improve next UP rate's quality
}
} else
{
TxErrorRatio = 0; // too few samples
// Downgrade TX quality upon any TX failure in the past second
if(pEntry->OneSecTxFailCount)
{
if((pEntry->OneSecTxFailCount <= 1) && (pEntry->OneSecTxOkCount + pEntry->OneSecTxRetryOkCount))
{
pEntry->TxQuality[CurrRate] += 2; // degrade quality
if(pEntry->TxQuality[CurrRate] > DRS_TX_QUALITY_WORST_BOUND)
pEntry->TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND;
} else // more than 2 failure, or no TX ok cases
{
pEntry->TxQuality[CurrRate] = DRS_TX_QUALITY_WORST_BOUND;
}
}
// upgrade TX quality if -
// 1. no TX failure but do have TX ok case, and
// 2. there's more one-time-ok cases than retry-ok cases in the past second
else if(pEntry->OneSecTxOkCount > pEntry->OneSecTxRetryOkCount)
{
fUpgradeQuality = TRUE;
if(pEntry->TxQuality[CurrRate])
pEntry->TxQuality[CurrRate] --; // quality very good in CurrRate
if(pEntry->TxRateUpPenalty)
pEntry->TxRateUpPenalty --;
else if(pEntry->TxQuality[UpRate])
pEntry->TxQuality[UpRate] --; // may improve next UP rate's quality
}
}
DBGPRINT(RT_DEBUG_TRACE,"APCLI: Qty[%d]=%d PER=%d%% %d-sec, Qty[%d]=%d Pty=%d\n",
RateIdToMbps[CurrRate], pEntry->TxQuality[CurrRate],
TxErrorRatio, pEntry->CurrTxRateStableTime,
RateIdToMbps[UpRate], pEntry->TxQuality[UpRate],
pEntry->TxRateUpPenalty);
// we're going to ugrade CurrRate to UpRate at next few seconds,
// but before that, we'd better try a NULL frame @ UpRate and
// see if UpRate is stable or not. If this NULL frame fails, it will
// downgrade TxQuality[CurrRate], so that STA won't switch to
// to UpRate in the next second
if((fUpgradeQuality == TRUE) &&
(UpRate != CurrRate) &&
(pEntry->TxQuality[CurrRate] <= 1) &&
(pEntry->TxQuality[UpRate] <= 1))
{
DBGPRINT(RT_DEBUG_TRACE,"2 test frames at UpRate = %d Mbps\n",RateIdToMbps[UpRate]);
// tag PID for later on per-client/APCLI TX statistics caculation
PID = PTYPE_NULL_AT_HIGH_RATE + APCLI_PAIRWISE_KEY_OFFSET + i;
ApEnqueueNullFrame(pAd, pEntry->ApCliBssid, UpRate, PID, MAIN_MBSSID, FALSE, FALSE, 0);
ApEnqueueNullFrame(pAd, pEntry->ApCliBssid, UpRate, PID, MAIN_MBSSID, FALSE, FALSE, 0);
}
// perform DRS - consider TxRate Down frist, then rate up
// rate down, if current TX rate's quality is not good
// rate up, if UPRate's quality is very good
if((pEntry->TxQuality[CurrRate] >= DRS_TX_QUALITY_WORST_BOUND) && (CurrRate != DownRate))
{
pEntry->CurrTxRate = DownRate;
} else if((pEntry->TxQuality[CurrRate] <=0) && (pEntry->TxQuality[UpRate] <=0) && (CurrRate != UpRate))
{
pEntry->CurrTxRate = UpRate;
}
// if rate-up happen, clear all bad history of all TX rates
if(pEntry->CurrTxRate > CurrRate)
{
DBGPRINT(RT_DEBUG_TRACE,"APCLI: ++TX rate = %d Mbps\n", RateIdToMbps[UpRate]);
pEntry->CurrTxRateStableTime = 0;
pEntry->TxRateUpPenalty = 0;
NdisZeroMemory(pEntry->TxQuality, MAX_LEN_OF_SUPPORTED_RATES);
}
// if rate-down happen, only clear DownRate's bad history
else if(pEntry->CurrTxRate < CurrRate)
{
DBGPRINT(RT_DEBUG_TRACE,"APCLI: --TX rate = %d Mbps\n", RateIdToMbps[DownRate]);
// shorter stable time require more penalty in next rate UP criteria
if(pEntry->CurrTxRateStableTime < 4) // less then 4 sec
pEntry->TxRateUpPenalty = DRS_PENALTY; // add 8 sec penalty
else if(pEntry->CurrTxRateStableTime < 8) // less then 8 sec
pEntry->TxRateUpPenalty = 2; // add 2 sec penalty
else
pEntry->TxRateUpPenalty = 0; // no penalty
pEntry->CurrTxRateStableTime = 0;
pEntry->TxQuality[pEntry->CurrTxRate] = 0;
}
// reset all OneSecxxx counters
pEntry->OneSecTxFailCount = 0;
pEntry->OneSecTxOkCount = 0;
pEntry->OneSecTxRetryOkCount = 0;
}
#endif /* APCLI_SUPPORT */
#if 0
//if (pAd->Mlme.PeriodicRound % 5 == 2)
{
if ((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE) && RadarChannelCheck(pAd, pAd->PortCfg.Channel) && (pAd->PortCfg.RadarDetect.RDMode == RD_NORMAL_MODE))
{
UCHAR Pattern = 0;
if (AllTxTotalCnt > 400)
{
Pattern = 3;
}
else if (AllTxTotalCnt > 200)
{
Pattern = 2;
}
else if (AllTxTotalCnt > 50)
{
Pattern = 1;
}
else
{
Pattern = 0;
}
if (Pattern != pAd->PortCfg.RadarDetect.DetectPattern)
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, Pattern);
}
pAd->PortCfg.RadarDetect.DetectPattern = Pattern;
}
}
#endif
#if 1
DBGPRINT(RT_DEBUG_INFO,"AllTxTotalCnt=%d, OneSecRxOkCnt=%d, dlstest=%d\n", AllTxTotalCnt, pAd->RalinkCounters.OneSecRxOkCnt, pAd->dfstest);
if (pAd->dfstest == 0)
{
if ((pAd->PortCfg.PhyMode == PHY_11A) && (pAd->PortCfg.RadarDetect.IEEE80211H == TRUE) && RadarChannelCheck(pAd, pAd->PortCfg.Channel) && (pAd->PortCfg.RadarDetect.RDMode == RD_NORMAL_MODE))
{
if ((AllTxTotalCnt > 1201) || (pAd->RalinkCounters.OneSecRxOkCnt > 1001))
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, 0x03);
}
else if ((AllTxTotalCnt > 1200) || (pAd->RalinkCounters.OneSecRxOkCnt > 1000))
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, 0x02);
}
else if ((AllTxTotalCnt > 50) || (pAd->RalinkCounters.OneSecRxOkCnt > 50))
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, 0x01);
}
else
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, 0x00);
}
}
}
else
{
AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x01, 0x01);
}
#endif
}
VOID MlmeSetTxPreamble(
IN PRTMP_ADAPTER pAd,
IN USHORT TxPreamble)
{
TXRX_CSR4_STRUC csr4;
//
// Please refer to windows driver
//
//TxPreamble = Rt802_11PreambleLong;
RTMP_IO_READ32(pAd, TXRX_CSR4, &csr4.word);
if (TxPreamble == Rt802_11PreambleShort)
{
// NOTE: 1Mbps should always use long preamble
DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= SHORT PREAMBLE)\n");
pAd->PortCfg.TxPreambleInUsed = Rt802_11PreambleShort;
csr4.field.AutoResponderPreamble = 1;
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "MlmeSetTxPreamble (= LONG PREAMBLE)\n");
pAd->PortCfg.TxPreambleInUsed = Rt802_11PreambleLong;
csr4.field.AutoResponderPreamble = 0;
}
RTMP_IO_WRITE32(pAd, TXRX_CSR4, csr4.word);
}
// bLinkUp is to identify the inital link speed.
// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
VOID MlmeUpdateTxRates(
IN PRTMP_ADAPTER pAd)
{
int i, j, num;
ULONG BasicRateBitmap = 0;
UCHAR CurrBasicRate = RATE_1;
// UCHAR AutoRespTxPower = pAd->LatchBBPR94;
// update basic rate bitmap according to pAdapter->PortCfg.BasicRateBitMap
UpdateBasicRateBitmap(pAd);
for (j=0; j<pAd->PortCfg.BssidNum; j++)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?