aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rate.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rate.c')
-rw-r--r--net/mac80211/rate.c46
1 files changed, 16 insertions, 30 deletions
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 22b223f13c9f..8fdadfd94ba8 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -10,15 +10,15 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/rtnetlink.h> 12#include <linux/rtnetlink.h>
13#include <linux/slab.h>
14#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
15#include "rate.h" 15#include "rate.h"
16#include "ieee80211_i.h" 16#include "ieee80211_i.h"
17#include "debugfs.h" 17#include "debugfs.h"
18 18
19struct rate_control_alg { 19struct rate_control_alg {
20 struct list_head list; 20 struct list_head list;
21 struct rate_control_ops *ops; 21 const struct rate_control_ops *ops;
22}; 22};
23 23
24static LIST_HEAD(rate_ctrl_algs); 24static LIST_HEAD(rate_ctrl_algs);
@@ -29,7 +29,7 @@ module_param(ieee80211_default_rc_algo, charp, 0644);
29MODULE_PARM_DESC(ieee80211_default_rc_algo, 29MODULE_PARM_DESC(ieee80211_default_rc_algo,
30 "Default rate control algorithm for mac80211 to use"); 30 "Default rate control algorithm for mac80211 to use");
31 31
32int ieee80211_rate_control_register(struct rate_control_ops *ops) 32int ieee80211_rate_control_register(const struct rate_control_ops *ops)
33{ 33{
34 struct rate_control_alg *alg; 34 struct rate_control_alg *alg;
35 35
@@ -60,7 +60,7 @@ int ieee80211_rate_control_register(struct rate_control_ops *ops)
60} 60}
61EXPORT_SYMBOL(ieee80211_rate_control_register); 61EXPORT_SYMBOL(ieee80211_rate_control_register);
62 62
63void ieee80211_rate_control_unregister(struct rate_control_ops *ops) 63void ieee80211_rate_control_unregister(const struct rate_control_ops *ops)
64{ 64{
65 struct rate_control_alg *alg; 65 struct rate_control_alg *alg;
66 66
@@ -76,32 +76,31 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops)
76} 76}
77EXPORT_SYMBOL(ieee80211_rate_control_unregister); 77EXPORT_SYMBOL(ieee80211_rate_control_unregister);
78 78
79static struct rate_control_ops * 79static const struct rate_control_ops *
80ieee80211_try_rate_control_ops_get(const char *name) 80ieee80211_try_rate_control_ops_get(const char *name)
81{ 81{
82 struct rate_control_alg *alg; 82 struct rate_control_alg *alg;
83 struct rate_control_ops *ops = NULL; 83 const struct rate_control_ops *ops = NULL;
84 84
85 if (!name) 85 if (!name)
86 return NULL; 86 return NULL;
87 87
88 mutex_lock(&rate_ctrl_mutex); 88 mutex_lock(&rate_ctrl_mutex);
89 list_for_each_entry(alg, &rate_ctrl_algs, list) { 89 list_for_each_entry(alg, &rate_ctrl_algs, list) {
90 if (!strcmp(alg->ops->name, name)) 90 if (!strcmp(alg->ops->name, name)) {
91 if (try_module_get(alg->ops->module)) { 91 ops = alg->ops;
92 ops = alg->ops; 92 break;
93 break; 93 }
94 }
95 } 94 }
96 mutex_unlock(&rate_ctrl_mutex); 95 mutex_unlock(&rate_ctrl_mutex);
97 return ops; 96 return ops;
98} 97}
99 98
100/* Get the rate control algorithm. */ 99/* Get the rate control algorithm. */
101static struct rate_control_ops * 100static const struct rate_control_ops *
102ieee80211_rate_control_ops_get(const char *name) 101ieee80211_rate_control_ops_get(const char *name)
103{ 102{
104 struct rate_control_ops *ops; 103 const struct rate_control_ops *ops;
105 const char *alg_name; 104 const char *alg_name;
106 105
107 kparam_block_sysfs_write(ieee80211_default_rc_algo); 106 kparam_block_sysfs_write(ieee80211_default_rc_algo);
@@ -111,10 +110,6 @@ ieee80211_rate_control_ops_get(const char *name)
111 alg_name = name; 110 alg_name = name;
112 111
113 ops = ieee80211_try_rate_control_ops_get(alg_name); 112 ops = ieee80211_try_rate_control_ops_get(alg_name);
114 if (!ops) {
115 request_module("rc80211_%s", alg_name);
116 ops = ieee80211_try_rate_control_ops_get(alg_name);
117 }
118 if (!ops && name) 113 if (!ops && name)
119 /* try default if specific alg requested but not found */ 114 /* try default if specific alg requested but not found */
120 ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo); 115 ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
@@ -127,11 +122,6 @@ ieee80211_rate_control_ops_get(const char *name)
127 return ops; 122 return ops;
128} 123}
129 124
130static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
131{
132 module_put(ops->module);
133}
134
135#ifdef CONFIG_MAC80211_DEBUGFS 125#ifdef CONFIG_MAC80211_DEBUGFS
136static ssize_t rcname_read(struct file *file, char __user *userbuf, 126static ssize_t rcname_read(struct file *file, char __user *userbuf,
137 size_t count, loff_t *ppos) 127 size_t count, loff_t *ppos)
@@ -158,11 +148,11 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
158 148
159 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); 149 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
160 if (!ref) 150 if (!ref)
161 goto fail_ref; 151 return NULL;
162 ref->local = local; 152 ref->local = local;
163 ref->ops = ieee80211_rate_control_ops_get(name); 153 ref->ops = ieee80211_rate_control_ops_get(name);
164 if (!ref->ops) 154 if (!ref->ops)
165 goto fail_ops; 155 goto free;
166 156
167#ifdef CONFIG_MAC80211_DEBUGFS 157#ifdef CONFIG_MAC80211_DEBUGFS
168 debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir); 158 debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
@@ -172,14 +162,11 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
172 162
173 ref->priv = ref->ops->alloc(&local->hw, debugfsdir); 163 ref->priv = ref->ops->alloc(&local->hw, debugfsdir);
174 if (!ref->priv) 164 if (!ref->priv)
175 goto fail_priv; 165 goto free;
176 return ref; 166 return ref;
177 167
178fail_priv: 168free:
179 ieee80211_rate_control_ops_put(ref->ops);
180fail_ops:
181 kfree(ref); 169 kfree(ref);
182fail_ref:
183 return NULL; 170 return NULL;
184} 171}
185 172
@@ -192,7 +179,6 @@ static void rate_control_free(struct rate_control_ref *ctrl_ref)
192 ctrl_ref->local->debugfs.rcdir = NULL; 179 ctrl_ref->local->debugfs.rcdir = NULL;
193#endif 180#endif
194 181
195 ieee80211_rate_control_ops_put(ctrl_ref->ops);
196 kfree(ctrl_ref); 182 kfree(ctrl_ref);
197} 183}
198 184