Enscript Output

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.