static void rtl_get_rate( void *ppriv, struct ieee80211_sta *sta,
			 void *priv_sta, struct ieee80211_tx_rate_control *txrc )
{
	struct rtl_priv *rtlpriv = ppriv;
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB( skb );
	struct ieee80211_tx_rate *rates = tx_info->control.rates;
	__le16 fc = rtl_get_fc( skb );
	u8 try_per_rate, i, rix;
	bool not_data = !ieee80211_is_data( fc );

	if ( rate_control_send_low( sta, priv_sta, txrc ) )
		return;

	rix = _rtl_rc_get_highest_rix( rtlpriv, sta, skb, not_data );
	try_per_rate = 1;
	_rtl_rc_rate_set_series( rtlpriv, sta, &rates[0], txrc,
				try_per_rate, rix, 1, not_data );

	if ( !not_data ) {
		for ( i = 1; i < 4; i++ )
			_rtl_rc_rate_set_series( rtlpriv, sta, &rates[i],
						txrc, i, ( rix - i ), 1,
						not_data );
	}
}
static void
rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
			  void *priv_sta,
			  struct ieee80211_tx_rate_control *txrc)
{
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_supported_band *sband = txrc->sband;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct rc_pid_sta_info *spinfo = priv_sta;
	int rateidx;

	if (txrc->rts)
		info->control.rates[0].count =
			txrc->hw->conf.long_frame_max_tx_count;
	else
		info->control.rates[0].count =
			txrc->hw->conf.short_frame_max_tx_count;

	/* Send management frames and NO_ACK data using lowest rate. */
	if (rate_control_send_low(sta, priv_sta, txrc))
		return;

	rateidx = spinfo->txrate_idx;

	if (rateidx >= sband->n_bitrates)
		rateidx = sband->n_bitrates - 1;

	info->control.rates[0].idx = rateidx;

#ifdef CONFIG_MAC80211_DEBUGFS
	rate_control_pid_event_tx_rate(&spinfo->events,
		rateidx, sband->bitrates[rateidx].bitrate);
#endif
}
static void
minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
                     struct ieee80211_tx_rate_control *txrc)
{
	const struct mcs_group *sample_group;
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
	struct ieee80211_tx_rate *rate = &info->status.rates[0];
	struct minstrel_ht_sta_priv *msp = priv_sta;
	struct minstrel_ht_sta *mi = &msp->ht;
	struct minstrel_priv *mp = priv;
	int sample_idx;

	if (rate_control_send_low(sta, priv_sta, txrc))
		return;

	if (!msp->is_ht)
		return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);

	info->flags |= mi->tx_flags;
	minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);

#ifdef CPTCFG_MAC80211_DEBUGFS
	if (mp->fixed_rate_idx != -1)
		return;
#endif

	/* Don't use EAPOL frames for sampling on non-mrr hw */
	if (mp->hw->max_rates == 1 &&
	    (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
		sample_idx = -1;
	else
		sample_idx = minstrel_get_sample_rate(mp, mi);

	mi->total_packets++;

	/* wraparound */
	if (mi->total_packets == ~0) {
		mi->total_packets = 0;
		mi->sample_packets = 0;
	}

	if (sample_idx < 0)
		return;

	sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
	info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
	rate->count = 1;

	if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) {
		int idx = sample_idx % ARRAY_SIZE(mp->cck_rates);
		rate->idx = mp->cck_rates[idx];
		rate->flags = 0;
		return;
	}

	rate->idx = sample_idx % MCS_GROUP_RATES +
		    (sample_group->streams - 1) * MCS_GROUP_RATES;
	rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
}
예제 #4
0
static void
indra_get_rate(void *priv, struct ieee80211_sta *sta,
		  void *priv_sta, struct ieee80211_tx_rate_control *txrc)
{
	struct indra_priv *ip = priv;
	struct indra_sta_info *ii = priv_sta;
	struct sk_buff *skb = txrc->skb;
	struct ieee80211_hdr *hdr = (void *)skb->data;
	u8 dst[ETH_ALEN];
	int record, i, status = 0, snr;
	unsigned int per, previous_per;
	bool found = false;
	char* p_data;
	
	/* Search for entry in signals memory from the same 
	 * node that this packet is destined to */
	memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
	for (record=0; record<signals_index; record++) {
		found = true;
		for (i=0; i<ETH_ALEN; i++){
			if (signals[record].address[i] != dst[i]) {
				found = false;  
				break;
			}
		}
		if (found) break;
	}
	
	/* Write received signals data on the new packet and retrieve 
	 * SNR index at the destination node */
	p_data = (char*)skb->data;
    p_data = p_data + 42;
	if (found) {
		p_data[0] = signals[record].rx_signal;
		p_data[1] = signals[record].rx_noise;
		status = signals[record].status;
		if (status == 2) {
			snr = signals[record].tx_signal - signals[record].tx_noise;
			ii->last_snr = snr + SNR_MIN;
			if (ii->last_snr < 0)
				ii->last_snr = 0;
			if (ii->last_snr > SNR_RANGE - 1)
				ii->last_snr = SNR_RANGE - 1;
			printk("MICHELE: SNR index = %i\n",ii->last_snr);
		}
	}
	
	/* Update SNR-PER map */
	if (status == 2) {
		for (i = 0; i < ii->n_rates; i++) {
			if (ii->r[i].last_attempts != 0) {
				per = INDRA_TRUNC(INDRA_FRAC(ii->r[i].last_attempts-ii->r[i].last_success,ii->r[i].last_attempts));
				previous_per = ii->r[i].per_snr_map[ii->last_snr];
				ii->r[i].per_snr_map[ii->last_snr] = INDRA_TRUNC(INDRA_FRAC(ALPHA_INDRA,100)*previous_per) + INDRA_TRUNC(INDRA_FRAC(100-ALPHA_INDRA,100)*per);
				printk("MICHELE: per = %u, previous per = %u, new per = %u\n",per,previous_per,ii->r[i].per_snr_map[ii->last_snr]);
				ii->r[i].last_attempts = 0;
				ii->r[i].last_success = 0;
			}
		}
	}
	
	/* management/no-ack frames do not use rate control */
	if (rate_control_send_low(sta, priv_sta, txrc))
		return;
		
	/* Rate selection algorithm */
	indra_update_rates(ip, ii);

}