diff options
Diffstat (limited to 'net/mac80211/rc80211_pid_algo.c')
| -rw-r--r-- | net/mac80211/rc80211_pid_algo.c | 158 | 
1 files changed, 59 insertions, 99 deletions
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index bc1c4569caa..86eb374e3b8 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c @@ -68,18 +68,14 @@   * exhibited a worse failed frames behaviour and we'll choose the highest rate   * whose failed frames behaviour is not worse than the one of the original rate   * target. While at it, check that the new rate is valid. */ -static void rate_control_pid_adjust_rate(struct ieee80211_local *local, -					 struct sta_info *sta, int adj, +static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband, +					 struct ieee80211_sta *sta, +					 struct rc_pid_sta_info *spinfo, int adj,  					 struct rc_pid_rateinfo *rinfo)  { -	struct ieee80211_sub_if_data *sdata; -	struct ieee80211_supported_band *sband;  	int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; -	struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;  	int cur = spinfo->txrate_idx; -	sdata = sta->sdata; -	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];  	band = sband->band;  	n_bitrates = sband->n_bitrates; @@ -146,13 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)  }  static void rate_control_pid_sample(struct rc_pid_info *pinfo, -				    struct ieee80211_local *local, -				    struct sta_info *sta) +				    struct ieee80211_supported_band *sband, +				    struct ieee80211_sta *sta, +				    struct rc_pid_sta_info *spinfo)  { -	struct ieee80211_sub_if_data *sdata = sta->sdata; -	struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;  	struct rc_pid_rateinfo *rinfo = pinfo->rinfo; -	struct ieee80211_supported_band *sband;  	u32 pf;  	s32 err_avg;  	u32 err_prop; @@ -161,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,  	int adj, i, j, tmp;  	unsigned long period; -	sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; -	spinfo = sta->rate_ctrl_priv; -  	/* In case nothing happened during the previous control interval, turn  	 * the sharpening factor on. */  	period = (HZ * pinfo->sampling_period + 500) / 1000; @@ -179,11 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,  	if (unlikely(spinfo->tx_num_xmit == 0))  		pf = spinfo->last_pf;  	else { +		/* XXX: BAD HACK!!! */ +		struct sta_info *si = container_of(sta, struct sta_info, sta); +  		pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; -		if (ieee80211_vif_is_mesh(&sdata->vif) && pf == 100) -			mesh_plink_broken(sta); + +		if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100) +			mesh_plink_broken(si);  		pf <<= RC_PID_ARITH_SHIFT; -		sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) +		si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)  					>> RC_PID_ARITH_SHIFT;  	} @@ -229,43 +224,25 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,  	/* Change rate. */  	if (adj) -		rate_control_pid_adjust_rate(local, sta, adj, rinfo); +		rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);  } -static void rate_control_pid_tx_status(void *priv, struct net_device *dev, +static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband, +				       struct ieee80211_sta *sta, void *priv_sta,  				       struct sk_buff *skb)  { -	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -	struct ieee80211_sub_if_data *sdata;  	struct rc_pid_info *pinfo = priv; -	struct sta_info *sta; -	struct rc_pid_sta_info *spinfo; +	struct rc_pid_sta_info *spinfo = priv_sta;  	unsigned long period; -	struct ieee80211_supported_band *sband;  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -	rcu_read_lock(); - -	sta = sta_info_get(local, hdr->addr1); -	sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - -	if (!sta) -		goto unlock; - -	spinfo = sta->rate_ctrl_priv; - -	/* Don't update the state if we're not controlling the rate. */ -	sdata = sta->sdata; -	if (sdata->force_unicast_rateidx > -1) { -		spinfo->txrate_idx = sdata->max_ratectrl_rateidx; -		goto unlock; -	} +	if (!spinfo) +		return;  	/* Ignore all frames that were sent with a different rate than the rate  	 * we currently advise mac80211 to use. */  	if (info->tx_rate_idx != spinfo->txrate_idx) -		goto unlock; +		return;  	spinfo->tx_num_xmit++; @@ -289,78 +266,63 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,  	if (!period)  		period = 1;  	if (time_after(jiffies, spinfo->last_sample + period)) -		rate_control_pid_sample(pinfo, local, sta); - - unlock: -	rcu_read_unlock(); +		rate_control_pid_sample(pinfo, sband, sta, spinfo);  } -static void rate_control_pid_get_rate(void *priv, struct net_device *dev, -				      struct ieee80211_supported_band *sband, -				      struct sk_buff *skb, -				      struct rate_selection *sel) +static void +rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, +			  struct ieee80211_sta *sta, void *priv_sta, +			  struct sk_buff *skb, +			  struct rate_selection *sel)  { -	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);  	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -	struct ieee80211_sub_if_data *sdata; -	struct rc_pid_sta_info *spinfo; -	struct sta_info *sta; +	struct rc_pid_sta_info *spinfo = priv_sta;  	int rateidx;  	u16 fc; -	rcu_read_lock(); - -	sta = sta_info_get(local, hdr->addr1); -  	/* Send management frames and broadcast/multicast data using lowest  	 * rate. */  	fc = le16_to_cpu(hdr->frame_control); -	if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || -	    is_multicast_ether_addr(hdr->addr1) || !sta) { -		sel->rate_idx = rate_lowest_index(local, sband, sta); -		rcu_read_unlock(); +	if (!sta || !spinfo || +	    (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || +	    is_multicast_ether_addr(hdr->addr1)) { +		sel->rate_idx = rate_lowest_index(sband, sta);  		return;  	} -	/* If a forced rate is in effect, select it. */ -	sdata = IEEE80211_DEV_TO_SUB_IF(dev); -	spinfo = (struct rc_pid_sta_info *)sta->rate_ctrl_priv; -	if (sdata->force_unicast_rateidx > -1) -		spinfo->txrate_idx = sdata->force_unicast_rateidx; -  	rateidx = spinfo->txrate_idx;  	if (rateidx >= sband->n_bitrates)  		rateidx = sband->n_bitrates - 1; -	rcu_read_unlock(); -  	sel->rate_idx = rateidx;  #ifdef CONFIG_MAC80211_DEBUGFS -	rate_control_pid_event_tx_rate( -		&((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, +	rate_control_pid_event_tx_rate(&spinfo->events,  		rateidx, sband->bitrates[rateidx].bitrate);  #endif  } -static void rate_control_pid_rate_init(void *priv, void *priv_sta, -					  struct ieee80211_local *local, -					  struct sta_info *sta) +static void +rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband, +			   struct ieee80211_sta *sta, void *priv_sta)  { +	struct rc_pid_sta_info *spinfo = priv_sta; +	struct sta_info *si; +  	/* TODO: This routine should consider using RSSI from previous packets  	 * as we need to have IEEE 802.1X auth succeed immediately after assoc..  	 * Until that method is implemented, we will use the lowest supported  	 * rate as a workaround. */ -	struct ieee80211_supported_band *sband; -	struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv; -	sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; -	spinfo->txrate_idx = rate_lowest_index(local, sband, sta); -	sta->fail_avg = 0; +	spinfo->txrate_idx = rate_lowest_index(sband, sta); +	/* HACK */ +	si = container_of(sta, struct sta_info, sta); +	si->fail_avg = 0;  } -static void *rate_control_pid_alloc(struct ieee80211_local *local) +static void *rate_control_pid_alloc(struct ieee80211_hw *hw, +				    struct dentry *debugfsdir)  {  	struct rc_pid_info *pinfo;  	struct rc_pid_rateinfo *rinfo; @@ -371,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)  	struct rc_pid_debugfs_entries *de;  #endif -	sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; +	sband = hw->wiphy->bands[hw->conf.channel->band];  	pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);  	if (!pinfo) @@ -426,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)  #ifdef CONFIG_MAC80211_DEBUGFS  	de = &pinfo->dentries; -	de->dir = debugfs_create_dir("rc80211_pid", -				     local->hw.wiphy->debugfsdir);  	de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, -					de->dir, &pinfo->target); +					debugfsdir, &pinfo->target);  	de->sampling_period = debugfs_create_u32("sampling_period", -						 S_IRUSR | S_IWUSR, de->dir, +						 S_IRUSR | S_IWUSR, debugfsdir,  						 &pinfo->sampling_period);  	de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, -					 de->dir, &pinfo->coeff_p); +					 debugfsdir, &pinfo->coeff_p);  	de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, -					 de->dir, &pinfo->coeff_i); +					 debugfsdir, &pinfo->coeff_i);  	de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, -					 de->dir, &pinfo->coeff_d); +					 debugfsdir, &pinfo->coeff_d);  	de->smoothing_shift = debugfs_create_u32("smoothing_shift", -						 S_IRUSR | S_IWUSR, de->dir, +						 S_IRUSR | S_IWUSR, debugfsdir,  						 &pinfo->smoothing_shift);  	de->sharpen_factor = debugfs_create_u32("sharpen_factor", -					       S_IRUSR | S_IWUSR, de->dir, +					       S_IRUSR | S_IWUSR, debugfsdir,  					       &pinfo->sharpen_factor);  	de->sharpen_duration = debugfs_create_u32("sharpen_duration", -						  S_IRUSR | S_IWUSR, de->dir, +						  S_IRUSR | S_IWUSR, debugfsdir,  						  &pinfo->sharpen_duration);  	de->norm_offset = debugfs_create_u32("norm_offset", -					     S_IRUSR | S_IWUSR, de->dir, +					     S_IRUSR | S_IWUSR, debugfsdir,  					     &pinfo->norm_offset);  #endif @@ -471,7 +431,6 @@ static void rate_control_pid_free(void *priv)  	debugfs_remove(de->coeff_p);  	debugfs_remove(de->sampling_period);  	debugfs_remove(de->target); -	debugfs_remove(de->dir);  #endif  	kfree(pinfo->rinfo); @@ -482,7 +441,8 @@ static void rate_control_pid_clear(void *priv)  {  } -static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp) +static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta, +					gfp_t gfp)  {  	struct rc_pid_sta_info *spinfo; @@ -500,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)  	return spinfo;  } -static void rate_control_pid_free_sta(void *priv, void *priv_sta) +static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta, +				      void *priv_sta)  { -	struct rc_pid_sta_info *spinfo = priv_sta; -	kfree(spinfo); +	kfree(priv_sta);  }  static struct rate_control_ops mac80211_rcpid = {  |