aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-18 12:14:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-24 16:18:03 -0400
commit4b7679a561e552eeda1e3567119bef2bca99b66e (patch)
treeb5f2b45c9186eb954f9329322d07e277e669b422 /net
parent2ff6a6d4e92270283432690adf53a7e5ab186d19 (diff)
mac80211: clean up rate control API
Long awaited, hard work. This patch totally cleans up the rate control API to remove the requirement to include internal headers outside of net/mac80211/. There's one internal use in the PID algorithm left for mesh networking, we'll have to figure out a way to clean that one up and decide how to do the peer link evaluation, possibly independent of the rate control algorithm or via new API. Additionally, ath9k is left using the cross-inclusion hack for now, we will add new API where necessary to make this work properly, but right now I'm not expert enough to do it. It's still off better than before. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c4
-rw-r--r--net/mac80211/rate.c71
-rw-r--r--net/mac80211/rate.h102
-rw-r--r--net/mac80211/rc80211_pid.h2
-rw-r--r--net/mac80211/rc80211_pid_algo.c158
-rw-r--r--net/mac80211/sta_info.c17
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tx.c5
11 files changed, 159 insertions, 210 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 89a183c2327a..855126a3039d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -693,7 +693,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
693 693
694 sta_apply_parameters(local, sta, params); 694 sta_apply_parameters(local, sta, params);
695 695
696 rate_control_rate_init(sta, local); 696 rate_control_rate_init(sta);
697 697
698 rcu_read_lock(); 698 rcu_read_lock();
699 699
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0b25b0f46b1a..8025b294588b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -724,6 +724,8 @@ struct ieee80211_local {
724 724
725#ifdef CONFIG_MAC80211_DEBUGFS 725#ifdef CONFIG_MAC80211_DEBUGFS
726 struct local_debugfsdentries { 726 struct local_debugfsdentries {
727 struct dentry *rcdir;
728 struct dentry *rcname;
727 struct dentry *frequency; 729 struct dentry *frequency;
728 struct dentry *antenna_sel_tx; 730 struct dentry *antenna_sel_tx;
729 struct dentry *antenna_sel_rx; 731 struct dentry *antenna_sel_rx;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 7d2d5a041e26..d608c44047c0 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -542,6 +542,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
542 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 542 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
543 u16 frag, type; 543 u16 frag, type;
544 __le16 fc; 544 __le16 fc;
545 struct ieee80211_supported_band *sband;
545 struct ieee80211_tx_status_rtap_hdr *rthdr; 546 struct ieee80211_tx_status_rtap_hdr *rthdr;
546 struct ieee80211_sub_if_data *sdata; 547 struct ieee80211_sub_if_data *sdata;
547 struct net_device *prev_dev = NULL; 548 struct net_device *prev_dev = NULL;
@@ -588,7 +589,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
588 sta->tx_retry_count += info->status.retry_count; 589 sta->tx_retry_count += info->status.retry_count;
589 } 590 }
590 591
591 rate_control_tx_status(local->mdev, skb); 592 sband = local->hw.wiphy->bands[info->band];
593 rate_control_tx_status(local, sband, sta, skb);
592 } 594 }
593 595
594 rcu_read_unlock(); 596 rcu_read_unlock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8611a8318c9c..109c3a7e63ad 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1323,7 +1323,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1323 ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); 1323 ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
1324 } 1324 }
1325 1325
1326 rate_control_rate_init(sta, local); 1326 rate_control_rate_init(sta);
1327 1327
1328 if (elems.wmm_param) { 1328 if (elems.wmm_param) {
1329 set_sta_flags(sta, WLAN_STA_WME); 1329 set_sta_flags(sta, WLAN_STA_WME);
@@ -2342,7 +2342,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
2342 sta->sta.supp_rates[band] = supp_rates | 2342 sta->sta.supp_rates[band] = supp_rates |
2343 ieee80211_mandatory_rates(local, band); 2343 ieee80211_mandatory_rates(local, band);
2344 2344
2345 rate_control_rate_init(sta, local); 2345 rate_control_rate_init(sta);
2346 2346
2347 if (sta_info_insert(sta)) 2347 if (sta_info_insert(sta))
2348 return NULL; 2348 return NULL;
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
16struct rate_control_alg { 17struct 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
132static 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
142static const struct file_operations rcname_ops = {
143 .read = rcname_read,
144 .open = mac80211_open_file_generic,
145};
146#endif
147
130struct rate_control_ref *rate_control_alloc(const char *name, 148struct 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
165void rate_control_get_rate(struct net_device *dev, 201void 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
203struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 246struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 5f18c27eb900..eb94e584d24e 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -19,77 +19,48 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "sta_info.h" 20#include "sta_info.h"
21 21
22/**
23 * struct rate_selection - rate selection for rate control algos
24 * @rate: selected transmission rate index
25 * @nonerp: Non-ERP rate to use instead if ERP cannot be used
26 * @probe: rate for probing (or -1)
27 *
28 */
29struct rate_selection {
30 s8 rate_idx, nonerp_idx, probe_idx;
31};
32
33struct rate_control_ops {
34 struct module *module;
35 const char *name;
36 void (*tx_status)(void *priv, struct net_device *dev,
37 struct sk_buff *skb);
38 void (*get_rate)(void *priv, struct net_device *dev,
39 struct ieee80211_supported_band *band,
40 struct sk_buff *skb,
41 struct rate_selection *sel);
42 void (*rate_init)(void *priv, void *priv_sta,
43 struct ieee80211_local *local, struct sta_info *sta);
44 void (*clear)(void *priv);
45
46 void *(*alloc)(struct ieee80211_local *local);
47 void (*free)(void *priv);
48 void *(*alloc_sta)(void *priv, gfp_t gfp);
49 void (*free_sta)(void *priv, void *priv_sta);
50
51 int (*add_attrs)(void *priv, struct kobject *kobj);
52 void (*remove_attrs)(void *priv, struct kobject *kobj);
53 void (*add_sta_debugfs)(void *priv, void *priv_sta,
54 struct dentry *dir);
55 void (*remove_sta_debugfs)(void *priv, void *priv_sta);
56};
57
58struct rate_control_ref { 22struct rate_control_ref {
23 struct ieee80211_local *local;
59 struct rate_control_ops *ops; 24 struct rate_control_ops *ops;
60 void *priv; 25 void *priv;
61 struct kref kref; 26 struct kref kref;
62}; 27};
63 28
64int ieee80211_rate_control_register(struct rate_control_ops *ops);
65void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
66
67/* Get a reference to the rate control algorithm. If `name' is NULL, get the 29/* Get a reference to the rate control algorithm. If `name' is NULL, get the
68 * first available algorithm. */ 30 * first available algorithm. */
69struct rate_control_ref *rate_control_alloc(const char *name, 31struct rate_control_ref *rate_control_alloc(const char *name,
70 struct ieee80211_local *local); 32 struct ieee80211_local *local);
71void rate_control_get_rate(struct net_device *dev, 33void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
72 struct ieee80211_supported_band *sband, 34 struct ieee80211_supported_band *sband,
73 struct sk_buff *skb, 35 struct sta_info *sta, struct sk_buff *skb,
74 struct rate_selection *sel); 36 struct rate_selection *sel);
75struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); 37struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
76void rate_control_put(struct rate_control_ref *ref); 38void rate_control_put(struct rate_control_ref *ref);
77 39
78static inline void rate_control_tx_status(struct net_device *dev, 40static inline void rate_control_tx_status(struct ieee80211_local *local,
41 struct ieee80211_supported_band *sband,
42 struct sta_info *sta,
79 struct sk_buff *skb) 43 struct sk_buff *skb)
80{ 44{
81 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
82 struct rate_control_ref *ref = local->rate_ctrl; 45 struct rate_control_ref *ref = local->rate_ctrl;
46 struct ieee80211_sta *ista = &sta->sta;
47 void *priv_sta = sta->rate_ctrl_priv;
83 48
84 ref->ops->tx_status(ref->priv, dev, skb); 49 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
85} 50}
86 51
87 52
88static inline void rate_control_rate_init(struct sta_info *sta, 53static inline void rate_control_rate_init(struct sta_info *sta)
89 struct ieee80211_local *local)
90{ 54{
55 struct ieee80211_local *local = sta->sdata->local;
91 struct rate_control_ref *ref = sta->rate_ctrl; 56 struct rate_control_ref *ref = sta->rate_ctrl;
92 ref->ops->rate_init(ref->priv, sta->rate_ctrl_priv, local, sta); 57 struct ieee80211_sta *ista = &sta->sta;
58 void *priv_sta = sta->rate_ctrl_priv;
59 struct ieee80211_supported_band *sband;
60
61 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
62
63 ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
93} 64}
94 65
95 66
@@ -100,15 +71,19 @@ static inline void rate_control_clear(struct ieee80211_local *local)
100} 71}
101 72
102static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 73static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
74 struct ieee80211_sta *sta,
103 gfp_t gfp) 75 gfp_t gfp)
104{ 76{
105 return ref->ops->alloc_sta(ref->priv, gfp); 77 return ref->ops->alloc_sta(ref->priv, sta, gfp);
106} 78}
107 79
108static inline void rate_control_free_sta(struct rate_control_ref *ref, 80static inline void rate_control_free_sta(struct sta_info *sta)
109 void *priv)
110{ 81{
111 ref->ops->free_sta(ref->priv, priv); 82 struct rate_control_ref *ref = sta->rate_ctrl;
83 struct ieee80211_sta *ista = &sta->sta;
84 void *priv_sta = sta->rate_ctrl_priv;
85
86 ref->ops->free_sta(ref->priv, ista, priv_sta);
112} 87}
113 88
114static inline void rate_control_add_sta_debugfs(struct sta_info *sta) 89static inline void rate_control_add_sta_debugfs(struct sta_info *sta)
@@ -130,31 +105,6 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
130#endif 105#endif
131} 106}
132 107
133static inline int rate_supported(struct sta_info *sta,
134 enum ieee80211_band band,
135 int index)
136{
137 return (sta == NULL || sta->sta.supp_rates[band] & BIT(index));
138}
139
140static inline s8
141rate_lowest_index(struct ieee80211_local *local,
142 struct ieee80211_supported_band *sband,
143 struct sta_info *sta)
144{
145 int i;
146
147 for (i = 0; i < sband->n_bitrates; i++)
148 if (rate_supported(sta, sband->band, i))
149 return i;
150
151 /* warn when we cannot find a rate. */
152 WARN_ON(1);
153
154 return 0;
155}
156
157
158/* functions for rate control related to a device */ 108/* functions for rate control related to a device */
159int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 109int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
160 const char *name); 110 const char *name);
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
index ffafc5da572e..01d64d53f3b9 100644
--- a/net/mac80211/rc80211_pid.h
+++ b/net/mac80211/rc80211_pid.h
@@ -124,7 +124,6 @@ struct rc_pid_events_file_info {
124 * struct rc_pid_debugfs_entries - tunable parameters 124 * struct rc_pid_debugfs_entries - tunable parameters
125 * 125 *
126 * Algorithm parameters, tunable via debugfs. 126 * Algorithm parameters, tunable via debugfs.
127 * @dir: the debugfs directory for a specific phy
128 * @target: target percentage for failed frames 127 * @target: target percentage for failed frames
129 * @sampling_period: error sampling interval in milliseconds 128 * @sampling_period: error sampling interval in milliseconds
130 * @coeff_p: absolute value of the proportional coefficient 129 * @coeff_p: absolute value of the proportional coefficient
@@ -143,7 +142,6 @@ struct rc_pid_events_file_info {
143 * ordering of rates) 142 * ordering of rates)
144 */ 143 */
145struct rc_pid_debugfs_entries { 144struct rc_pid_debugfs_entries {
146 struct dentry *dir;
147 struct dentry *target; 145 struct dentry *target;
148 struct dentry *sampling_period; 146 struct dentry *sampling_period;
149 struct dentry *coeff_p; 147 struct dentry *coeff_p;
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index bc1c4569caa1..86eb374e3b87 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -68,18 +68,14 @@
68 * exhibited a worse failed frames behaviour and we'll choose the highest rate 68 * exhibited a worse failed frames behaviour and we'll choose the highest rate
69 * whose failed frames behaviour is not worse than the one of the original rate 69 * whose failed frames behaviour is not worse than the one of the original rate
70 * target. While at it, check that the new rate is valid. */ 70 * target. While at it, check that the new rate is valid. */
71static void rate_control_pid_adjust_rate(struct ieee80211_local *local, 71static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
72 struct sta_info *sta, int adj, 72 struct ieee80211_sta *sta,
73 struct rc_pid_sta_info *spinfo, int adj,
73 struct rc_pid_rateinfo *rinfo) 74 struct rc_pid_rateinfo *rinfo)
74{ 75{
75 struct ieee80211_sub_if_data *sdata;
76 struct ieee80211_supported_band *sband;
77 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; 76 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
78 struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
79 int cur = spinfo->txrate_idx; 77 int cur = spinfo->txrate_idx;
80 78
81 sdata = sta->sdata;
82 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
83 band = sband->band; 79 band = sband->band;
84 n_bitrates = sband->n_bitrates; 80 n_bitrates = sband->n_bitrates;
85 81
@@ -146,13 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
146} 142}
147 143
148static void rate_control_pid_sample(struct rc_pid_info *pinfo, 144static void rate_control_pid_sample(struct rc_pid_info *pinfo,
149 struct ieee80211_local *local, 145 struct ieee80211_supported_band *sband,
150 struct sta_info *sta) 146 struct ieee80211_sta *sta,
147 struct rc_pid_sta_info *spinfo)
151{ 148{
152 struct ieee80211_sub_if_data *sdata = sta->sdata;
153 struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
154 struct rc_pid_rateinfo *rinfo = pinfo->rinfo; 149 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
155 struct ieee80211_supported_band *sband;
156 u32 pf; 150 u32 pf;
157 s32 err_avg; 151 s32 err_avg;
158 u32 err_prop; 152 u32 err_prop;
@@ -161,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
161 int adj, i, j, tmp; 155 int adj, i, j, tmp;
162 unsigned long period; 156 unsigned long period;
163 157
164 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
165 spinfo = sta->rate_ctrl_priv;
166
167 /* In case nothing happened during the previous control interval, turn 158 /* In case nothing happened during the previous control interval, turn
168 * the sharpening factor on. */ 159 * the sharpening factor on. */
169 period = (HZ * pinfo->sampling_period + 500) / 1000; 160 period = (HZ * pinfo->sampling_period + 500) / 1000;
@@ -179,11 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
179 if (unlikely(spinfo->tx_num_xmit == 0)) 170 if (unlikely(spinfo->tx_num_xmit == 0))
180 pf = spinfo->last_pf; 171 pf = spinfo->last_pf;
181 else { 172 else {
173 /* XXX: BAD HACK!!! */
174 struct sta_info *si = container_of(sta, struct sta_info, sta);
175
182 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; 176 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
183 if (ieee80211_vif_is_mesh(&sdata->vif) && pf == 100) 177
184 mesh_plink_broken(sta); 178 if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
179 mesh_plink_broken(si);
185 pf <<= RC_PID_ARITH_SHIFT; 180 pf <<= RC_PID_ARITH_SHIFT;
186 sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) 181 si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
187 >> RC_PID_ARITH_SHIFT; 182 >> RC_PID_ARITH_SHIFT;
188 } 183 }
189 184
@@ -229,43 +224,25 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
229 224
230 /* Change rate. */ 225 /* Change rate. */
231 if (adj) 226 if (adj)
232 rate_control_pid_adjust_rate(local, sta, adj, rinfo); 227 rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
233} 228}
234 229
235static void rate_control_pid_tx_status(void *priv, struct net_device *dev, 230static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
231 struct ieee80211_sta *sta, void *priv_sta,
236 struct sk_buff *skb) 232 struct sk_buff *skb)
237{ 233{
238 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
239 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
240 struct ieee80211_sub_if_data *sdata;
241 struct rc_pid_info *pinfo = priv; 234 struct rc_pid_info *pinfo = priv;
242 struct sta_info *sta; 235 struct rc_pid_sta_info *spinfo = priv_sta;
243 struct rc_pid_sta_info *spinfo;
244 unsigned long period; 236 unsigned long period;
245 struct ieee80211_supported_band *sband;
246 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 237 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
247 238
248 rcu_read_lock(); 239 if (!spinfo)
249 240 return;
250 sta = sta_info_get(local, hdr->addr1);
251 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
252
253 if (!sta)
254 goto unlock;
255
256 spinfo = sta->rate_ctrl_priv;
257
258 /* Don't update the state if we're not controlling the rate. */
259 sdata = sta->sdata;
260 if (sdata->force_unicast_rateidx > -1) {
261 spinfo->txrate_idx = sdata->max_ratectrl_rateidx;
262 goto unlock;
263 }
264 241
265 /* Ignore all frames that were sent with a different rate than the rate 242 /* Ignore all frames that were sent with a different rate than the rate
266 * we currently advise mac80211 to use. */ 243 * we currently advise mac80211 to use. */
267 if (info->tx_rate_idx != spinfo->txrate_idx) 244 if (info->tx_rate_idx != spinfo->txrate_idx)
268 goto unlock; 245 return;
269 246
270 spinfo->tx_num_xmit++; 247 spinfo->tx_num_xmit++;
271 248
@@ -289,78 +266,63 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
289 if (!period) 266 if (!period)
290 period = 1; 267 period = 1;
291 if (time_after(jiffies, spinfo->last_sample + period)) 268 if (time_after(jiffies, spinfo->last_sample + period))
292 rate_control_pid_sample(pinfo, local, sta); 269 rate_control_pid_sample(pinfo, sband, sta, spinfo);
293
294 unlock:
295 rcu_read_unlock();
296} 270}
297 271
298static void rate_control_pid_get_rate(void *priv, struct net_device *dev, 272static void
299 struct ieee80211_supported_band *sband, 273rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
300 struct sk_buff *skb, 274 struct ieee80211_sta *sta, void *priv_sta,
301 struct rate_selection *sel) 275 struct sk_buff *skb,
276 struct rate_selection *sel)
302{ 277{
303 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
304 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 278 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
305 struct ieee80211_sub_if_data *sdata; 279 struct rc_pid_sta_info *spinfo = priv_sta;
306 struct rc_pid_sta_info *spinfo;
307 struct sta_info *sta;
308 int rateidx; 280 int rateidx;
309 u16 fc; 281 u16 fc;
310 282
311 rcu_read_lock();
312
313 sta = sta_info_get(local, hdr->addr1);
314
315 /* Send management frames and broadcast/multicast data using lowest 283 /* Send management frames and broadcast/multicast data using lowest
316 * rate. */ 284 * rate. */
317 fc = le16_to_cpu(hdr->frame_control); 285 fc = le16_to_cpu(hdr->frame_control);
318 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 286 if (!sta || !spinfo ||
319 is_multicast_ether_addr(hdr->addr1) || !sta) { 287 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
320 sel->rate_idx = rate_lowest_index(local, sband, sta); 288 is_multicast_ether_addr(hdr->addr1)) {
321 rcu_read_unlock(); 289 sel->rate_idx = rate_lowest_index(sband, sta);
322 return; 290 return;
323 } 291 }
324 292
325 /* If a forced rate is in effect, select it. */
326 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
327 spinfo = (struct rc_pid_sta_info *)sta->rate_ctrl_priv;
328 if (sdata->force_unicast_rateidx > -1)
329 spinfo->txrate_idx = sdata->force_unicast_rateidx;
330
331 rateidx = spinfo->txrate_idx; 293 rateidx = spinfo->txrate_idx;
332 294
333 if (rateidx >= sband->n_bitrates) 295 if (rateidx >= sband->n_bitrates)
334 rateidx = sband->n_bitrates - 1; 296 rateidx = sband->n_bitrates - 1;
335 297
336 rcu_read_unlock();
337
338 sel->rate_idx = rateidx; 298 sel->rate_idx = rateidx;
339 299
340#ifdef CONFIG_MAC80211_DEBUGFS 300#ifdef CONFIG_MAC80211_DEBUGFS
341 rate_control_pid_event_tx_rate( 301 rate_control_pid_event_tx_rate(&spinfo->events,
342 &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events,
343 rateidx, sband->bitrates[rateidx].bitrate); 302 rateidx, sband->bitrates[rateidx].bitrate);
344#endif 303#endif
345} 304}
346 305
347static void rate_control_pid_rate_init(void *priv, void *priv_sta, 306static void
348 struct ieee80211_local *local, 307rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
349 struct sta_info *sta) 308 struct ieee80211_sta *sta, void *priv_sta)
350{ 309{
310 struct rc_pid_sta_info *spinfo = priv_sta;
311 struct sta_info *si;
312
351 /* TODO: This routine should consider using RSSI from previous packets 313 /* TODO: This routine should consider using RSSI from previous packets
352 * as we need to have IEEE 802.1X auth succeed immediately after assoc.. 314 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
353 * Until that method is implemented, we will use the lowest supported 315 * Until that method is implemented, we will use the lowest supported
354 * rate as a workaround. */ 316 * rate as a workaround. */
355 struct ieee80211_supported_band *sband;
356 struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
357 317
358 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 318 spinfo->txrate_idx = rate_lowest_index(sband, sta);
359 spinfo->txrate_idx = rate_lowest_index(local, sband, sta); 319 /* HACK */
360 sta->fail_avg = 0; 320 si = container_of(sta, struct sta_info, sta);
321 si->fail_avg = 0;
361} 322}
362 323
363static void *rate_control_pid_alloc(struct ieee80211_local *local) 324static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
325 struct dentry *debugfsdir)
364{ 326{
365 struct rc_pid_info *pinfo; 327 struct rc_pid_info *pinfo;
366 struct rc_pid_rateinfo *rinfo; 328 struct rc_pid_rateinfo *rinfo;
@@ -371,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
371 struct rc_pid_debugfs_entries *de; 333 struct rc_pid_debugfs_entries *de;
372#endif 334#endif
373 335
374 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 336 sband = hw->wiphy->bands[hw->conf.channel->band];
375 337
376 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); 338 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
377 if (!pinfo) 339 if (!pinfo)
@@ -426,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
426 388
427#ifdef CONFIG_MAC80211_DEBUGFS 389#ifdef CONFIG_MAC80211_DEBUGFS
428 de = &pinfo->dentries; 390 de = &pinfo->dentries;
429 de->dir = debugfs_create_dir("rc80211_pid",
430 local->hw.wiphy->debugfsdir);
431 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, 391 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
432 de->dir, &pinfo->target); 392 debugfsdir, &pinfo->target);
433 de->sampling_period = debugfs_create_u32("sampling_period", 393 de->sampling_period = debugfs_create_u32("sampling_period",
434 S_IRUSR | S_IWUSR, de->dir, 394 S_IRUSR | S_IWUSR, debugfsdir,
435 &pinfo->sampling_period); 395 &pinfo->sampling_period);
436 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, 396 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
437 de->dir, &pinfo->coeff_p); 397 debugfsdir, &pinfo->coeff_p);
438 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, 398 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
439 de->dir, &pinfo->coeff_i); 399 debugfsdir, &pinfo->coeff_i);
440 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, 400 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
441 de->dir, &pinfo->coeff_d); 401 debugfsdir, &pinfo->coeff_d);
442 de->smoothing_shift = debugfs_create_u32("smoothing_shift", 402 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
443 S_IRUSR | S_IWUSR, de->dir, 403 S_IRUSR | S_IWUSR, debugfsdir,
444 &pinfo->smoothing_shift); 404 &pinfo->smoothing_shift);
445 de->sharpen_factor = debugfs_create_u32("sharpen_factor", 405 de->sharpen_factor = debugfs_create_u32("sharpen_factor",
446 S_IRUSR | S_IWUSR, de->dir, 406 S_IRUSR | S_IWUSR, debugfsdir,
447 &pinfo->sharpen_factor); 407 &pinfo->sharpen_factor);
448 de->sharpen_duration = debugfs_create_u32("sharpen_duration", 408 de->sharpen_duration = debugfs_create_u32("sharpen_duration",
449 S_IRUSR | S_IWUSR, de->dir, 409 S_IRUSR | S_IWUSR, debugfsdir,
450 &pinfo->sharpen_duration); 410 &pinfo->sharpen_duration);
451 de->norm_offset = debugfs_create_u32("norm_offset", 411 de->norm_offset = debugfs_create_u32("norm_offset",
452 S_IRUSR | S_IWUSR, de->dir, 412 S_IRUSR | S_IWUSR, debugfsdir,
453 &pinfo->norm_offset); 413 &pinfo->norm_offset);
454#endif 414#endif
455 415
@@ -471,7 +431,6 @@ static void rate_control_pid_free(void *priv)
471 debugfs_remove(de->coeff_p); 431 debugfs_remove(de->coeff_p);
472 debugfs_remove(de->sampling_period); 432 debugfs_remove(de->sampling_period);
473 debugfs_remove(de->target); 433 debugfs_remove(de->target);
474 debugfs_remove(de->dir);
475#endif 434#endif
476 435
477 kfree(pinfo->rinfo); 436 kfree(pinfo->rinfo);
@@ -482,7 +441,8 @@ static void rate_control_pid_clear(void *priv)
482{ 441{
483} 442}
484 443
485static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp) 444static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
445 gfp_t gfp)
486{ 446{
487 struct rc_pid_sta_info *spinfo; 447 struct rc_pid_sta_info *spinfo;
488 448
@@ -500,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
500 return spinfo; 460 return spinfo;
501} 461}
502 462
503static void rate_control_pid_free_sta(void *priv, void *priv_sta) 463static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
464 void *priv_sta)
504{ 465{
505 struct rc_pid_sta_info *spinfo = priv_sta; 466 kfree(priv_sta);
506 kfree(spinfo);
507} 467}
508 468
509static struct rate_control_ops mac80211_rcpid = { 469static struct rate_control_ops mac80211_rcpid = {
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d9774ac2e0f7..9b72d15bc8dc 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -93,8 +93,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
93} 93}
94 94
95/* protected by RCU */ 95/* protected by RCU */
96static struct sta_info *__sta_info_find(struct ieee80211_local *local, 96struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr)
97 const u8 *addr)
98{ 97{
99 struct sta_info *sta; 98 struct sta_info *sta;
100 99
@@ -107,12 +106,6 @@ static struct sta_info *__sta_info_find(struct ieee80211_local *local,
107 return sta; 106 return sta;
108} 107}
109 108
110struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr)
111{
112 return __sta_info_find(local, addr);
113}
114EXPORT_SYMBOL(sta_info_get);
115
116struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, 109struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
117 struct net_device *dev) 110 struct net_device *dev)
118{ 111{
@@ -146,7 +139,7 @@ static void __sta_info_free(struct ieee80211_local *local,
146{ 139{
147 DECLARE_MAC_BUF(mbuf); 140 DECLARE_MAC_BUF(mbuf);
148 141
149 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 142 rate_control_free_sta(sta);
150 rate_control_put(sta->rate_ctrl); 143 rate_control_put(sta->rate_ctrl);
151 144
152#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 145#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -244,7 +237,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
244 237
245 sta->rate_ctrl = rate_control_get(local->rate_ctrl); 238 sta->rate_ctrl = rate_control_get(local->rate_ctrl);
246 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 239 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
247 gfp); 240 &sta->sta, gfp);
248 if (!sta->rate_ctrl_priv) { 241 if (!sta->rate_ctrl_priv) {
249 rate_control_put(sta->rate_ctrl); 242 rate_control_put(sta->rate_ctrl);
250 kfree(sta); 243 kfree(sta);
@@ -308,7 +301,7 @@ int sta_info_insert(struct sta_info *sta)
308 301
309 spin_lock_irqsave(&local->sta_lock, flags); 302 spin_lock_irqsave(&local->sta_lock, flags);
310 /* check if STA exists already */ 303 /* check if STA exists already */
311 if (__sta_info_find(local, sta->sta.addr)) { 304 if (sta_info_get(local, sta->sta.addr)) {
312 spin_unlock_irqrestore(&local->sta_lock, flags); 305 spin_unlock_irqrestore(&local->sta_lock, flags);
313 err = -EEXIST; 306 err = -EEXIST;
314 goto out_free; 307 goto out_free;
@@ -834,7 +827,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
834struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, 827struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
835 const u8 *addr) 828 const u8 *addr)
836{ 829{
837 struct sta_info *sta = __sta_info_find(hw_to_local(hw), addr); 830 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);
838 831
839 if (!sta) 832 if (!sta)
840 return NULL; 833 return NULL;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index daedfa9e1c63..c3f436964621 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -416,7 +416,7 @@ static inline u32 get_sta_flags(struct sta_info *sta)
416/* 416/*
417 * Get a STA info, must have be under RCU read lock. 417 * Get a STA info, must have be under RCU read lock.
418 */ 418 */
419struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr); 419struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr);
420/* 420/*
421 * Get STA info by index, BROKEN! 421 * Get STA info by index, BROKEN!
422 */ 422 */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 00d96e63dce9..0cc2e23f082c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -446,7 +446,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
446 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 446 sband = tx->local->hw.wiphy->bands[tx->channel->band];
447 447
448 if (likely(tx->rate_idx < 0)) { 448 if (likely(tx->rate_idx < 0)) {
449 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); 449 rate_control_get_rate(tx->sdata, sband, tx->sta,
450 tx->skb, &rsel);
450 if (tx->sta) 451 if (tx->sta)
451 tx->sta->last_txrate_idx = rsel.rate_idx; 452 tx->sta->last_txrate_idx = rsel.rate_idx;
452 tx->rate_idx = rsel.rate_idx; 453 tx->rate_idx = rsel.rate_idx;
@@ -1955,7 +1956,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1955 skb->do_not_encrypt = 1; 1956 skb->do_not_encrypt = 1;
1956 1957
1957 info->band = band; 1958 info->band = band;
1958 rate_control_get_rate(local->mdev, sband, skb, &rsel); 1959 rate_control_get_rate(sdata, sband, NULL, skb, &rsel);
1959 1960
1960 if (unlikely(rsel.rate_idx < 0)) { 1961 if (unlikely(rsel.rate_idx < 0)) {
1961 if (net_ratelimit()) { 1962 if (net_ratelimit()) {