diff options
Diffstat (limited to 'net/mac80211/rate.c')
-rw-r--r-- | net/mac80211/rate.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 0388c090dfe9..5d786720d935 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/rtnetlink.h> | 12 | #include <linux/rtnetlink.h> |
13 | #include "rate.h" | 13 | #include "rate.h" |
14 | #include "ieee80211_i.h" | 14 | #include "ieee80211_i.h" |
15 | #include "debugfs.h" | ||
15 | 16 | ||
16 | struct rate_control_alg { | 17 | struct rate_control_alg { |
17 | struct list_head list; | 18 | struct list_head list; |
@@ -127,19 +128,46 @@ static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops) | |||
127 | module_put(ops->module); | 128 | module_put(ops->module); |
128 | } | 129 | } |
129 | 130 | ||
131 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
132 | static ssize_t rcname_read(struct file *file, char __user *userbuf, | ||
133 | size_t count, loff_t *ppos) | ||
134 | { | ||
135 | struct rate_control_ref *ref = file->private_data; | ||
136 | int len = strlen(ref->ops->name); | ||
137 | |||
138 | return simple_read_from_buffer(userbuf, count, ppos, | ||
139 | ref->ops->name, len); | ||
140 | } | ||
141 | |||
142 | static const struct file_operations rcname_ops = { | ||
143 | .read = rcname_read, | ||
144 | .open = mac80211_open_file_generic, | ||
145 | }; | ||
146 | #endif | ||
147 | |||
130 | struct rate_control_ref *rate_control_alloc(const char *name, | 148 | struct rate_control_ref *rate_control_alloc(const char *name, |
131 | struct ieee80211_local *local) | 149 | struct ieee80211_local *local) |
132 | { | 150 | { |
151 | struct dentry *debugfsdir = NULL; | ||
133 | struct rate_control_ref *ref; | 152 | struct rate_control_ref *ref; |
134 | 153 | ||
135 | ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); | 154 | ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); |
136 | if (!ref) | 155 | if (!ref) |
137 | goto fail_ref; | 156 | goto fail_ref; |
138 | kref_init(&ref->kref); | 157 | kref_init(&ref->kref); |
158 | ref->local = local; | ||
139 | ref->ops = ieee80211_rate_control_ops_get(name); | 159 | ref->ops = ieee80211_rate_control_ops_get(name); |
140 | if (!ref->ops) | 160 | if (!ref->ops) |
141 | goto fail_ops; | 161 | goto fail_ops; |
142 | ref->priv = ref->ops->alloc(local); | 162 | |
163 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
164 | debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir); | ||
165 | local->debugfs.rcdir = debugfsdir; | ||
166 | local->debugfs.rcname = debugfs_create_file("name", 0400, debugfsdir, | ||
167 | ref, &rcname_ops); | ||
168 | #endif | ||
169 | |||
170 | ref->priv = ref->ops->alloc(&local->hw, debugfsdir); | ||
143 | if (!ref->priv) | 171 | if (!ref->priv) |
144 | goto fail_priv; | 172 | goto fail_priv; |
145 | return ref; | 173 | return ref; |
@@ -158,29 +186,46 @@ static void rate_control_release(struct kref *kref) | |||
158 | 186 | ||
159 | ctrl_ref = container_of(kref, struct rate_control_ref, kref); | 187 | ctrl_ref = container_of(kref, struct rate_control_ref, kref); |
160 | ctrl_ref->ops->free(ctrl_ref->priv); | 188 | ctrl_ref->ops->free(ctrl_ref->priv); |
189 | |||
190 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
191 | debugfs_remove(ctrl_ref->local->debugfs.rcname); | ||
192 | ctrl_ref->local->debugfs.rcname = NULL; | ||
193 | debugfs_remove(ctrl_ref->local->debugfs.rcdir); | ||
194 | ctrl_ref->local->debugfs.rcdir = NULL; | ||
195 | #endif | ||
196 | |||
161 | ieee80211_rate_control_ops_put(ctrl_ref->ops); | 197 | ieee80211_rate_control_ops_put(ctrl_ref->ops); |
162 | kfree(ctrl_ref); | 198 | kfree(ctrl_ref); |
163 | } | 199 | } |
164 | 200 | ||
165 | void rate_control_get_rate(struct net_device *dev, | 201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
166 | struct ieee80211_supported_band *sband, | 202 | struct ieee80211_supported_band *sband, |
167 | struct sk_buff *skb, | 203 | struct sta_info *sta, struct sk_buff *skb, |
168 | struct rate_selection *sel) | 204 | struct rate_selection *sel) |
169 | { | 205 | { |
170 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 206 | struct rate_control_ref *ref = sdata->local->rate_ctrl; |
171 | struct rate_control_ref *ref = local->rate_ctrl; | 207 | void *priv_sta = NULL; |
172 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 208 | struct ieee80211_sta *ista = NULL; |
173 | struct sta_info *sta; | ||
174 | int i; | 209 | int i; |
175 | 210 | ||
176 | rcu_read_lock(); | ||
177 | sta = sta_info_get(local, hdr->addr1); | ||
178 | |||
179 | sel->rate_idx = -1; | 211 | sel->rate_idx = -1; |
180 | sel->nonerp_idx = -1; | 212 | sel->nonerp_idx = -1; |
181 | sel->probe_idx = -1; | 213 | sel->probe_idx = -1; |
214 | sel->max_rate_idx = sdata->max_ratectrl_rateidx; | ||
215 | |||
216 | if (sta) { | ||
217 | ista = &sta->sta; | ||
218 | priv_sta = sta->rate_ctrl_priv; | ||
219 | } | ||
220 | |||
221 | if (sta && sdata->force_unicast_rateidx > -1) | ||
222 | sel->rate_idx = sdata->force_unicast_rateidx; | ||
223 | else | ||
224 | ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel); | ||
182 | 225 | ||
183 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); | 226 | if (sdata->max_ratectrl_rateidx > -1 && |
227 | sel->rate_idx > sdata->max_ratectrl_rateidx) | ||
228 | sel->rate_idx = sdata->max_ratectrl_rateidx; | ||
184 | 229 | ||
185 | BUG_ON(sel->rate_idx < 0); | 230 | BUG_ON(sel->rate_idx < 0); |
186 | 231 | ||
@@ -191,13 +236,11 @@ void rate_control_get_rate(struct net_device *dev, | |||
191 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) | 236 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) |
192 | break; | 237 | break; |
193 | 238 | ||
194 | if (rate_supported(sta, sband->band, i) && | 239 | if (rate_supported(ista, sband->band, i) && |
195 | !(rate->flags & IEEE80211_RATE_ERP_G)) | 240 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
196 | sel->nonerp_idx = i; | 241 | sel->nonerp_idx = i; |
197 | } | 242 | } |
198 | } | 243 | } |
199 | |||
200 | rcu_read_unlock(); | ||
201 | } | 244 | } |
202 | 245 | ||
203 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) | 246 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) |