extractedLnx/linux-2.6.38/drivers/staging/rt2860/common/mlme.c_MlmeUpdateTxRates.c
void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx)
{
int i, num;
u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
u8 MinSupport = RATE_54;
unsigned long BasicRateBitmap = 0;
u8 CurrBasicRate = RATE_1;
u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
PHTTRANSMIT_SETTING pHtPhy = NULL;
PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
PHTTRANSMIT_SETTING pMinHtPhy = NULL;
BOOLEAN *auto_rate_cur_p;
u8 HtMcs = MCS_AUTO;
/* find max desired rate */
UpdateBasicRateBitmap(pAd);
num = 0;
auto_rate_cur_p = NULL;
for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
switch (pAd->CommonCfg.DesireRate[i] & 0x7f) {
case 2:
Rate = RATE_1;
num++;
break;
case 4:
Rate = RATE_2;
num++;
break;
case 11:
Rate = RATE_5_5;
num++;
break;
case 22:
Rate = RATE_11;
num++;
break;
case 12:
Rate = RATE_6;
num++;
break;
case 18:
Rate = RATE_9;
num++;
break;
case 24:
Rate = RATE_12;
num++;
break;
case 36:
Rate = RATE_18;
num++;
break;
case 48:
Rate = RATE_24;
num++;
break;
case 72:
Rate = RATE_36;
num++;
break;
case 96:
Rate = RATE_48;
num++;
break;
case 108:
Rate = RATE_54;
num++;
break;
/*default: Rate = RATE_1; break; */
}
if (MaxDesire < Rate)
MaxDesire = Rate;
}
/*=========================================================================== */
/*=========================================================================== */
{
pHtPhy = &pAd->StaCfg.HTPhyMode;
pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
(pAd->CommonCfg.PhyMode == PHY_11B) &&
(MaxDesire > RATE_11)) {
MaxDesire = RATE_11;
}
}
pAd->CommonCfg.MaxDesiredRate = MaxDesire;
pMinHtPhy->word = 0;
pMaxHtPhy->word = 0;
pHtPhy->word = 0;
/* Auto rate switching is enabled only if more than one DESIRED RATES are */
/* specified; otherwise disabled */
if (num <= 1) {
/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
/*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */
*auto_rate_cur_p = FALSE;
} else {
/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
/*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */
*auto_rate_cur_p = TRUE;
}
if (HtMcs != MCS_AUTO) {
/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
/*pAd->CommonCfg.bAutoTxRateSwitch = FALSE; */
*auto_rate_cur_p = FALSE;
} else {
/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
/*pAd->CommonCfg.bAutoTxRateSwitch = TRUE; */
*auto_rate_cur_p = TRUE;
}
if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
pSupRate = &pAd->StaActive.SupRate[0];
pExtRate = &pAd->StaActive.ExtRate[0];
SupRateLen = pAd->StaActive.SupRateLen;
ExtRateLen = pAd->StaActive.ExtRateLen;
} else {
pSupRate = &pAd->CommonCfg.SupRate[0];
pExtRate = &pAd->CommonCfg.ExtRate[0];
SupRateLen = pAd->CommonCfg.SupRateLen;
ExtRateLen = pAd->CommonCfg.ExtRateLen;
}
/* find max supported rate */
for (i = 0; i < SupRateLen; i++) {
switch (pSupRate[i] & 0x7f) {
case 2:
Rate = RATE_1;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0001;
break;
case 4:
Rate = RATE_2;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0002;
break;
case 11:
Rate = RATE_5_5;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0004;
break;
case 22:
Rate = RATE_11;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0008;
break;
case 12:
Rate = RATE_6; /*if (pSupRate[i] & 0x80) */
BasicRateBitmap |= 0x0010;
break;
case 18:
Rate = RATE_9;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0020;
break;
case 24:
Rate = RATE_12; /*if (pSupRate[i] & 0x80) */
BasicRateBitmap |= 0x0040;
break;
case 36:
Rate = RATE_18;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0080;
break;
case 48:
Rate = RATE_24; /*if (pSupRate[i] & 0x80) */
BasicRateBitmap |= 0x0100;
break;
case 72:
Rate = RATE_36;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0200;
break;
case 96:
Rate = RATE_48;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0400;
break;
case 108:
Rate = RATE_54;
if (pSupRate[i] & 0x80)
BasicRateBitmap |= 0x0800;
break;
default:
Rate = RATE_1;
break;
}
if (MaxSupport < Rate)
MaxSupport = Rate;
if (MinSupport > Rate)
MinSupport = Rate;
}
for (i = 0; i < ExtRateLen; i++) {
switch (pExtRate[i] & 0x7f) {
case 2:
Rate = RATE_1;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0001;
break;
case 4:
Rate = RATE_2;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0002;
break;
case 11:
Rate = RATE_5_5;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0004;
break;
case 22:
Rate = RATE_11;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0008;
break;
case 12:
Rate = RATE_6; /*if (pExtRate[i] & 0x80) */
BasicRateBitmap |= 0x0010;
break;
case 18:
Rate = RATE_9;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0020;
break;
case 24:
Rate = RATE_12; /*if (pExtRate[i] & 0x80) */
BasicRateBitmap |= 0x0040;
break;
case 36:
Rate = RATE_18;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0080;
break;
case 48:
Rate = RATE_24; /*if (pExtRate[i] & 0x80) */
BasicRateBitmap |= 0x0100;
break;
case 72:
Rate = RATE_36;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0200;
break;
case 96:
Rate = RATE_48;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0400;
break;
case 108:
Rate = RATE_54;
if (pExtRate[i] & 0x80)
BasicRateBitmap |= 0x0800;
break;
default:
Rate = RATE_1;
break;
}
if (MaxSupport < Rate)
MaxSupport = Rate;
if (MinSupport > Rate)
MinSupport = Rate;
}
RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
/* bug fix */
/* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */
/* calculate the exptected ACK rate for each TX rate. This info is used to caculate */
/* the DURATION field of outgoing uniicast DATA/MGMT frame */
for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
if (BasicRateBitmap & (0x01 << i))
CurrBasicRate = (u8)i;
pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
}
DBGPRINT(RT_DEBUG_TRACE,
("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n",
RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
/* max tx rate = min {max desire rate, max supported rate} */
if (MaxSupport < MaxDesire)
pAd->CommonCfg.MaxTxRate = MaxSupport;
else
pAd->CommonCfg.MaxTxRate = MaxDesire;
pAd->CommonCfg.MinTxRate = MinSupport;
/* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */
/* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */
/* on average RSSI */
/* 1. RSSI >= -70db, start at 54 Mbps (short distance) */
/* 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */
/* 3. -75 > RSSI, start at 11 Mbps (long distance) */
if (*auto_rate_cur_p) {
short dbm = 0;
dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
if (bLinkUp == TRUE)
pAd->CommonCfg.TxRate = RATE_24;
else
pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
if (dbm < -75)
pAd->CommonCfg.TxRate = RATE_11;
else if (dbm < -70)
pAd->CommonCfg.TxRate = RATE_24;
/* should never exceed MaxTxRate (consider 11B-only mode) */
if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
pAd->CommonCfg.TxRateIndex = 0;
} else {
pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
pHtPhy->field.MCS =
(pAd->CommonCfg.MaxTxRate >
3) ? (pAd->CommonCfg.MaxTxRate -
4) : pAd->CommonCfg.MaxTxRate;
pHtPhy->field.MODE =
(pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC =
pHtPhy->field.STBC;
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI =
pHtPhy->field.ShortGI;
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS =
pHtPhy->field.MCS;
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE =
pHtPhy->field.MODE;
}
if (pAd->CommonCfg.TxRate <= RATE_11) {
pMaxHtPhy->field.MODE = MODE_CCK;
pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
} else {
pMaxHtPhy->field.MODE = MODE_OFDM;
pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
if (pAd->CommonCfg.MinTxRate >= RATE_6
&& (pAd->CommonCfg.MinTxRate <= RATE_54)) {
pMinHtPhy->field.MCS =
OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];
} else {
pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
}
}
pHtPhy->word = (pMaxHtPhy->word);
if (bLinkUp && (pAd->OpMode == OPMODE_STA)) {
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word =
pMaxHtPhy->word;
pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word =
pMinHtPhy->word;
} else {
switch (pAd->CommonCfg.PhyMode) {
case PHY_11BG_MIXED:
case PHY_11B:
case PHY_11BGN_MIXED:
pAd->CommonCfg.MlmeRate = RATE_1;
pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
/*#ifdef WIFI_TEST */
pAd->CommonCfg.RtsRate = RATE_11;
/*#else */
/* pAd->CommonCfg.RtsRate = RATE_1; */
/*#endif */
break;
case PHY_11G:
case PHY_11A:
case PHY_11AGN_MIXED:
case PHY_11GN_MIXED:
case PHY_11N_2_4G:
case PHY_11AN_MIXED:
case PHY_11N_5G:
pAd->CommonCfg.MlmeRate = RATE_6;
pAd->CommonCfg.RtsRate = RATE_6;
pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
pAd->CommonCfg.MlmeTransmit.field.MCS =
OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
break;
case PHY_11ABG_MIXED:
case PHY_11ABGN_MIXED:
if (pAd->CommonCfg.Channel <= 14) {
pAd->CommonCfg.MlmeRate = RATE_1;
pAd->CommonCfg.RtsRate = RATE_1;
pAd->CommonCfg.MlmeTransmit.field.MODE =
MODE_CCK;
pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
} else {
pAd->CommonCfg.MlmeRate = RATE_6;
pAd->CommonCfg.RtsRate = RATE_6;
pAd->CommonCfg.MlmeTransmit.field.MODE =
MODE_OFDM;
pAd->CommonCfg.MlmeTransmit.field.MCS =
OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
}
break;
default: /* error */
pAd->CommonCfg.MlmeRate = RATE_6;
pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
pAd->CommonCfg.MlmeTransmit.field.MCS =
OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
pAd->CommonCfg.RtsRate = RATE_1;
break;
}
/* */
/* Keep Basic Mlme Rate. */
/* */
pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word =
pAd->CommonCfg.MlmeTransmit.word;
if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
OfdmRateToRxwiMCS[RATE_24];
else
pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
RATE_1;
pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
}
DBGPRINT(RT_DEBUG_TRACE,
(" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport],
RateIdToMbps[pAd->CommonCfg.MaxTxRate],
RateIdToMbps[pAd->CommonCfg.MinTxRate],
/*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */
*auto_rate_cur_p));
DBGPRINT(RT_DEBUG_TRACE,
(" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
RateIdToMbps[pAd->CommonCfg.TxRate],
RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
DBGPRINT(RT_DEBUG_TRACE,
("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
pAd->CommonCfg.MlmeTransmit.word,
pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word,
pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word,
pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
}
Generated by GNU enscript 1.6.4.