diff options
Diffstat (limited to 'net/mac80211/rate.c')
| -rw-r--r-- | net/mac80211/rate.c | 61 | 
1 files changed, 28 insertions, 33 deletions
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index e126605cec6..8fdadfd94ba 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -10,15 +10,15 @@  #include <linux/kernel.h>  #include <linux/rtnetlink.h> -#include <linux/slab.h>  #include <linux/module.h> +#include <linux/slab.h>  #include "rate.h"  #include "ieee80211_i.h"  #include "debugfs.h"  struct rate_control_alg {  	struct list_head list; -	struct rate_control_ops *ops; +	const struct rate_control_ops *ops;  };  static LIST_HEAD(rate_ctrl_algs); @@ -29,7 +29,7 @@ module_param(ieee80211_default_rc_algo, charp, 0644);  MODULE_PARM_DESC(ieee80211_default_rc_algo,  		 "Default rate control algorithm for mac80211 to use"); -int ieee80211_rate_control_register(struct rate_control_ops *ops) +int ieee80211_rate_control_register(const struct rate_control_ops *ops)  {  	struct rate_control_alg *alg; @@ -60,7 +60,7 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops)  }  EXPORT_SYMBOL(ieee80211_rate_control_register); -void ieee80211_rate_control_unregister(struct rate_control_ops *ops) +void ieee80211_rate_control_unregister(const struct rate_control_ops *ops)  {  	struct rate_control_alg *alg; @@ -76,32 +76,31 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops)  }  EXPORT_SYMBOL(ieee80211_rate_control_unregister); -static struct rate_control_ops * +static const struct rate_control_ops *  ieee80211_try_rate_control_ops_get(const char *name)  {  	struct rate_control_alg *alg; -	struct rate_control_ops *ops = NULL; +	const struct rate_control_ops *ops = NULL;  	if (!name)  		return NULL;  	mutex_lock(&rate_ctrl_mutex);  	list_for_each_entry(alg, &rate_ctrl_algs, list) { -		if (!strcmp(alg->ops->name, name)) -			if (try_module_get(alg->ops->module)) { -				ops = alg->ops; -				break; -			} +		if (!strcmp(alg->ops->name, name)) { +			ops = alg->ops; +			break; +		}  	}  	mutex_unlock(&rate_ctrl_mutex);  	return ops;  }  /* Get the rate control algorithm. */ -static struct rate_control_ops * +static const struct rate_control_ops *  ieee80211_rate_control_ops_get(const char *name)  { -	struct rate_control_ops *ops; +	const struct rate_control_ops *ops;  	const char *alg_name;  	kparam_block_sysfs_write(ieee80211_default_rc_algo); @@ -111,10 +110,6 @@ ieee80211_rate_control_ops_get(const char *name)  		alg_name = name;  	ops = ieee80211_try_rate_control_ops_get(alg_name); -	if (!ops) { -		request_module("rc80211_%s", alg_name); -		ops = ieee80211_try_rate_control_ops_get(alg_name); -	}  	if (!ops && name)  		/* try default if specific alg requested but not found */  		ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo); @@ -127,11 +122,6 @@ ieee80211_rate_control_ops_get(const char *name)  	return ops;  } -static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops) -{ -	module_put(ops->module); -} -  #ifdef CONFIG_MAC80211_DEBUGFS  static ssize_t rcname_read(struct file *file, char __user *userbuf,  			   size_t count, loff_t *ppos) @@ -158,11 +148,11 @@ static struct rate_control_ref *rate_control_alloc(const char *name,  	ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);  	if (!ref) -		goto fail_ref; +		return NULL;  	ref->local = local;  	ref->ops = ieee80211_rate_control_ops_get(name);  	if (!ref->ops) -		goto fail_ops; +		goto free;  #ifdef CONFIG_MAC80211_DEBUGFS  	debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir); @@ -172,14 +162,11 @@ static struct rate_control_ref *rate_control_alloc(const char *name,  	ref->priv = ref->ops->alloc(&local->hw, debugfsdir);  	if (!ref->priv) -		goto fail_priv; +		goto free;  	return ref; -fail_priv: -	ieee80211_rate_control_ops_put(ref->ops); -fail_ops: +free:  	kfree(ref); -fail_ref:  	return NULL;  } @@ -192,7 +179,6 @@ static void rate_control_free(struct rate_control_ref *ctrl_ref)  	ctrl_ref->local->debugfs.rcdir = NULL;  #endif -	ieee80211_rate_control_ops_put(ctrl_ref->ops);  	kfree(ctrl_ref);  } @@ -235,7 +221,8 @@ static void rc_send_low_basicrate(s8 *idx, u32 basic_rates,  static void __rate_control_send_low(struct ieee80211_hw *hw,  				    struct ieee80211_supported_band *sband,  				    struct ieee80211_sta *sta, -				    struct ieee80211_tx_info *info) +				    struct ieee80211_tx_info *info, +				    u32 rate_mask)  {  	int i;  	u32 rate_flags = @@ -247,6 +234,12 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,  	info->control.rates[0].idx = 0;  	for (i = 0; i < sband->n_bitrates; i++) { +		if (!(rate_mask & BIT(i))) +			continue; + +		if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +			continue; +  		if (!rate_supported(sta, sband->band, i))  			continue; @@ -274,7 +267,8 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,  	bool use_basicrate = false;  	if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { -		__rate_control_send_low(txrc->hw, sband, pubsta, info); +		__rate_control_send_low(txrc->hw, sband, pubsta, info, +					txrc->rate_idx_mask);  		if (!pubsta && txrc->bss) {  			mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; @@ -656,7 +650,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,  		rate_control_apply_mask(sdata, sta, sband, info, dest, max_rates);  	if (dest[0].idx < 0) -		__rate_control_send_low(&sdata->local->hw, sband, sta, info); +		__rate_control_send_low(&sdata->local->hw, sband, sta, info, +					sdata->rc_rateidx_mask[info->band]);  	if (sta)  		rate_fixup_ratelist(vif, sband, info, dest, max_rates);  | 
