Пример #1
0
/**
 * rs_tx_status - Update rate control values based on Tx results
 *
 * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
 * the hardware for each rate.
 */
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
			 struct ieee80211_sta *sta, void *priv_sta,
			 struct sk_buff *skb)
{
	s8 retries = 0, current_count;
	int scale_rate_index, first_index, last_index;
	unsigned long flags;
	struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
	struct iwl3945_rs_sta *rs_sta = priv_sta;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

	IWL_DEBUG_RATE("enter\n");

	retries = info->status.rates[0].count;

	first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
	if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
		IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
		return;
	}

	if (!priv_sta) {
		IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
		return;
	}

	rs_sta->tx_packets++;

	scale_rate_index = first_index;
	last_index = first_index;

	/*
	 * Update the window for each rate.  We determine which rates
	 * were Tx'd based on the total number of retries vs. the number
	 * of retries configured for each rate -- currently set to the
	 * priv value 'retry_rate' vs. rate specific
	 *
	 * On exit from this while loop last_index indicates the rate
	 * at which the frame was finally transmitted (or failed if no
	 * ACK)
	 */
	while (retries > 1) {
		if ((retries - 1) < priv->retry_rate) {
			current_count = (retries - 1);
			last_index = scale_rate_index;
		} else {
			current_count = priv->retry_rate;
			last_index = iwl3945_rs_next_rate(priv,
							 scale_rate_index);
		}

		/* Update this rate accounting for as many retries
		 * as was used for it (per current_count) */
		iwl3945_collect_tx_data(rs_sta,
				    &rs_sta->win[scale_rate_index],
				    0, current_count, scale_rate_index);
		IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
			       scale_rate_index, current_count);

		retries -= current_count;

		scale_rate_index = last_index;
	}


	/* Update the last index window with success/failure based on ACK */
	IWL_DEBUG_RATE("Update rate %d with %s.\n",
		       last_index,
		       (info->flags & IEEE80211_TX_STAT_ACK) ?
		       "success" : "failure");
	iwl3945_collect_tx_data(rs_sta,
			    &rs_sta->win[last_index],
			    info->flags & IEEE80211_TX_STAT_ACK, 1, last_index);

	/* We updated the rate scale window -- if its been more than
	 * flush_time since the last run, schedule the flush
	 * again */
	spin_lock_irqsave(&rs_sta->lock, flags);

	if (!rs_sta->flush_pending &&
	    time_after(jiffies, rs_sta->last_flush +
		       rs_sta->flush_time)) {

		rs_sta->last_partial_flush = jiffies;
		rs_sta->flush_pending = 1;
		mod_timer(&rs_sta->rate_scale_flush,
			  jiffies + rs_sta->flush_time);
	}

	spin_unlock_irqrestore(&rs_sta->lock, flags);

	IWL_DEBUG_RATE("leave\n");

	return;
}
Пример #2
0
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
			 struct ieee80211_sta *sta, void *priv_sta,
			 struct sk_buff *skb)
{
	s8 retries = 0, current_count;
	int scale_rate_index, first_index, last_index;
	unsigned long flags;
	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
	struct iwl3945_rs_sta *rs_sta = priv_sta;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

	IWL_DEBUG_RATE(priv, "enter\n");

	retries = info->status.rates[0].count;
	
	if (retries > IWL_RATE_RETRY_TH)
		retries = IWL_RATE_RETRY_TH;

	first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
	if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
		IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index);
		return;
	}

	if (!priv_sta) {
		IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
		return;
	}

	rs_sta->tx_packets++;

	scale_rate_index = first_index;
	last_index = first_index;

	
	while (retries > 1) {
		if ((retries - 1) < priv->retry_rate) {
			current_count = (retries - 1);
			last_index = scale_rate_index;
		} else {
			current_count = priv->retry_rate;
			last_index = iwl3945_rs_next_rate(priv,
							 scale_rate_index);
		}

		
		iwl3945_collect_tx_data(rs_sta,
				    &rs_sta->win[scale_rate_index],
				    0, current_count, scale_rate_index);
		IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n",
			       scale_rate_index, current_count);

		retries -= current_count;

		scale_rate_index = last_index;
	}


	
	IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n",
		       last_index,
		       (info->flags & IEEE80211_TX_STAT_ACK) ?
		       "success" : "failure");
	iwl3945_collect_tx_data(rs_sta,
			    &rs_sta->win[last_index],
			    info->flags & IEEE80211_TX_STAT_ACK, 1, last_index);

	
	spin_lock_irqsave(&rs_sta->lock, flags);

	if (!rs_sta->flush_pending &&
	    time_after(jiffies, rs_sta->last_flush +
		       rs_sta->flush_time)) {

		rs_sta->last_partial_flush = jiffies;
		rs_sta->flush_pending = 1;
		mod_timer(&rs_sta->rate_scale_flush,
			  jiffies + rs_sta->flush_time);
	}

	spin_unlock_irqrestore(&rs_sta->lock, flags);

	IWL_DEBUG_RATE(priv, "leave\n");

	return;
}