diff options
Diffstat (limited to 'net/mac80211/rate.c')
-rw-r--r-- | net/mac80211/rate.c | 46 |
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 | ||
19 | struct rate_control_alg { | 19 | struct 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 | ||
24 | static LIST_HEAD(rate_ctrl_algs); | 24 | static LIST_HEAD(rate_ctrl_algs); |
@@ -29,7 +29,7 @@ module_param(ieee80211_default_rc_algo, charp, 0644); | |||
29 | MODULE_PARM_DESC(ieee80211_default_rc_algo, | 29 | MODULE_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 | ||
32 | int ieee80211_rate_control_register(struct rate_control_ops *ops) | 32 | int 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 | } |
61 | EXPORT_SYMBOL(ieee80211_rate_control_register); | 61 | EXPORT_SYMBOL(ieee80211_rate_control_register); |
62 | 62 | ||
63 | void ieee80211_rate_control_unregister(struct rate_control_ops *ops) | 63 | void 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 | } |
77 | EXPORT_SYMBOL(ieee80211_rate_control_unregister); | 77 | EXPORT_SYMBOL(ieee80211_rate_control_unregister); |
78 | 78 | ||
79 | static struct rate_control_ops * | 79 | static const struct rate_control_ops * |
80 | ieee80211_try_rate_control_ops_get(const char *name) | 80 | ieee80211_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. */ |
101 | static struct rate_control_ops * | 100 | static const struct rate_control_ops * |
102 | ieee80211_rate_control_ops_get(const char *name) | 101 | ieee80211_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 | ||
130 | static 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 |
136 | static ssize_t rcname_read(struct file *file, char __user *userbuf, | 126 | static 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 | ||
178 | fail_priv: | 168 | free: |
179 | ieee80211_rate_control_ops_put(ref->ops); | ||
180 | fail_ops: | ||
181 | kfree(ref); | 169 | kfree(ref); |
182 | fail_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 | ||