aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211.c6
-rw-r--r--net/mac80211/ieee80211_rate.c47
-rw-r--r--net/mac80211/ieee80211_rate.h73
-rw-r--r--net/mac80211/ieee80211_sta.c13
-rw-r--r--net/mac80211/rc80211_simple.c64
-rw-r--r--net/mac80211/tx.c42
6 files changed, 129 insertions, 116 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index d6a97a68a62e..5bf7a5bebfc9 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -859,10 +859,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
859 sta_info_put(sta); 859 sta_info_put(sta);
860 return; 860 return;
861 } 861 }
862 } else { 862 } else
863 /* FIXME: STUPID to call this with both local and local->mdev */ 863 rate_control_tx_status(local->mdev, skb, status);
864 rate_control_tx_status(local, local->mdev, skb, status);
865 }
866 864
867 ieee80211_led_tx(local, 0); 865 ieee80211_led_tx(local, 0);
868 866
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c
index c3f278393741..e495b0998b4d 100644
--- a/net/mac80211/ieee80211_rate.c
+++ b/net/mac80211/ieee80211_rate.c
@@ -147,6 +147,53 @@ static void rate_control_release(struct kref *kref)
147 kfree(ctrl_ref); 147 kfree(ctrl_ref);
148} 148}
149 149
150void rate_control_get_rate(struct net_device *dev,
151 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
152 struct rate_selection *sel)
153{
154 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
155 struct rate_control_ref *ref = local->rate_ctrl;
156 struct ieee80211_sub_if_data *sdata;
157 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
158 struct sta_info *sta = sta_info_get(local, hdr->addr1);
159 int i;
160 u16 fc;
161
162 memset(sel, 0, sizeof(struct rate_selection));
163
164 /* Send management frames and broadcast/multicast data using lowest
165 * rate. */
166 fc = le16_to_cpu(hdr->frame_control);
167 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
168 is_multicast_ether_addr(hdr->addr1))
169 sel->rate = rate_lowest(local, mode, sta);
170
171 /* If a forced rate is in effect, select it. */
172 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
173 if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
174 sel->rate = &mode->rates[sdata->bss->force_unicast_rateidx];
175
176 /* If we haven't found the rate yet, ask the rate control algo. */
177 if (!sel->rate)
178 ref->ops->get_rate(ref->priv, dev, mode, skb, sel);
179
180 /* Select a non-ERP backup rate. */
181 if (!sel->nonerp) {
182 for (i = 0; i < mode->num_rates - 1; i++) {
183 struct ieee80211_rate *rate = &mode->rates[i];
184 if (sel->rate->rate < rate->rate)
185 break;
186
187 if (rate_supported(sta, mode, i) &&
188 !(rate->flags & IEEE80211_RATE_ERP))
189 sel->nonerp = rate;
190 }
191 }
192
193 if (sta)
194 sta_info_put(sta);
195}
196
150struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 197struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
151{ 198{
152 kref_get(&ref->kref); 199 kref_get(&ref->kref);
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h
index 23688139ffb3..787134bd6abf 100644
--- a/net/mac80211/ieee80211_rate.h
+++ b/net/mac80211/ieee80211_rate.h
@@ -18,31 +18,24 @@
18#include "ieee80211_i.h" 18#include "ieee80211_i.h"
19#include "sta_info.h" 19#include "sta_info.h"
20 20
21#define RATE_CONTROL_NUM_DOWN 20 21struct rate_selection {
22#define RATE_CONTROL_NUM_UP 15 22 /* Selected transmission rate */
23 23 struct ieee80211_rate *rate;
24 24 /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
25struct rate_control_extra {
26 /* values from rate_control_get_rate() to the caller: */
27 struct ieee80211_rate *probe; /* probe with this rate, or NULL for no
28 * probing */
29 struct ieee80211_rate *nonerp; 25 struct ieee80211_rate *nonerp;
30 26 /* probe with this rate, or NULL for no probing */
31 /* parameters from the caller to rate_control_get_rate(): */ 27 struct ieee80211_rate *probe;
32 struct ieee80211_hw_mode *mode;
33 u16 ethertype;
34}; 28};
35 29
36
37struct rate_control_ops { 30struct rate_control_ops {
38 struct module *module; 31 struct module *module;
39 const char *name; 32 const char *name;
40 void (*tx_status)(void *priv, struct net_device *dev, 33 void (*tx_status)(void *priv, struct net_device *dev,
41 struct sk_buff *skb, 34 struct sk_buff *skb,
42 struct ieee80211_tx_status *status); 35 struct ieee80211_tx_status *status);
43 struct ieee80211_rate *(*get_rate)(void *priv, struct net_device *dev, 36 void (*get_rate)(void *priv, struct net_device *dev,
44 struct sk_buff *skb, 37 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
45 struct rate_control_extra *extra); 38 struct rate_selection *sel);
46 void (*rate_init)(void *priv, void *priv_sta, 39 void (*rate_init)(void *priv, void *priv_sta,
47 struct ieee80211_local *local, struct sta_info *sta); 40 struct ieee80211_local *local, struct sta_info *sta);
48 void (*clear)(void *priv); 41 void (*clear)(void *priv);
@@ -75,25 +68,20 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
75 * first available algorithm. */ 68 * first available algorithm. */
76struct rate_control_ref *rate_control_alloc(const char *name, 69struct rate_control_ref *rate_control_alloc(const char *name,
77 struct ieee80211_local *local); 70 struct ieee80211_local *local);
71void rate_control_get_rate(struct net_device *dev,
72 struct ieee80211_hw_mode *mode, struct sk_buff *skb,
73 struct rate_selection *sel);
78struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); 74struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
79void rate_control_put(struct rate_control_ref *ref); 75void rate_control_put(struct rate_control_ref *ref);
80 76
81static inline void rate_control_tx_status(struct ieee80211_local *local, 77static inline void rate_control_tx_status(struct net_device *dev,
82 struct net_device *dev,
83 struct sk_buff *skb, 78 struct sk_buff *skb,
84 struct ieee80211_tx_status *status) 79 struct ieee80211_tx_status *status)
85{ 80{
81 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
86 struct rate_control_ref *ref = local->rate_ctrl; 82 struct rate_control_ref *ref = local->rate_ctrl;
87 ref->ops->tx_status(ref->priv, dev, skb, status);
88}
89 83
90 84 ref->ops->tx_status(ref->priv, dev, skb, status);
91static inline struct ieee80211_rate *
92rate_control_get_rate(struct ieee80211_local *local, struct net_device *dev,
93 struct sk_buff *skb, struct rate_control_extra *extra)
94{
95 struct rate_control_ref *ref = local->rate_ctrl;
96 return ref->ops->get_rate(ref->priv, dev, skb, extra);
97} 85}
98 86
99 87
@@ -142,6 +130,37 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
142#endif 130#endif
143} 131}
144 132
133static inline int
134rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index)
135{
136 return (sta == NULL || sta->supp_rates & BIT(index)) &&
137 (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED);
138}
139
140static inline int
141rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
142 struct sta_info *sta)
143{
144 int i;
145
146 for (i = 0; i < mode->num_rates; i++) {
147 if (rate_supported(sta, mode, i))
148 return i;
149 }
150
151 /* warn when we cannot find a rate. */
152 WARN_ON(1);
153
154 return 0;
155}
156
157static inline struct ieee80211_rate *
158rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
159 struct sta_info *sta)
160{
161 return &mode->rates[rate_lowest_index(local, mode, sta)];
162}
163
145 164
146/* functions for rate control related to a device */ 165/* functions for rate control related to a device */
147int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 166int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 3c552fed2af5..3978ad606b5c 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2463,9 +2463,8 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2463 struct sk_buff *skb; 2463 struct sk_buff *skb;
2464 struct ieee80211_mgmt *mgmt; 2464 struct ieee80211_mgmt *mgmt;
2465 struct ieee80211_tx_control control; 2465 struct ieee80211_tx_control control;
2466 struct ieee80211_rate *rate;
2467 struct ieee80211_hw_mode *mode; 2466 struct ieee80211_hw_mode *mode;
2468 struct rate_control_extra extra; 2467 struct rate_selection ratesel;
2469 u8 *pos; 2468 u8 *pos;
2470 struct ieee80211_sub_if_data *sdata; 2469 struct ieee80211_sub_if_data *sdata;
2471 2470
@@ -2550,18 +2549,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2550 } 2549 }
2551 2550
2552 memset(&control, 0, sizeof(control)); 2551 memset(&control, 0, sizeof(control));
2553 memset(&extra, 0, sizeof(extra)); 2552 rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel);
2554 extra.mode = local->oper_hw_mode; 2553 if (!ratesel.rate) {
2555 rate = rate_control_get_rate(local, dev, skb, &extra);
2556 if (!rate) {
2557 printk(KERN_DEBUG "%s: Failed to determine TX rate " 2554 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2558 "for IBSS beacon\n", dev->name); 2555 "for IBSS beacon\n", dev->name);
2559 break; 2556 break;
2560 } 2557 }
2561 control.tx_rate = 2558 control.tx_rate =
2562 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && 2559 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
2563 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 2560 (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2564 rate->val2 : rate->val; 2561 ratesel.rate->val2 : ratesel.rate->val;
2565 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; 2562 control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2566 control.power_level = local->hw.conf.power_level; 2563 control.power_level = local->hw.conf.power_level;
2567 control.flags |= IEEE80211_TXCTL_NO_ACK; 2564 control.flags |= IEEE80211_TXCTL_NO_ACK;
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index da72737364e4..c1c8b76a56af 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -23,6 +23,8 @@
23/* This is a minimal implementation of TX rate controlling that can be used 23/* This is a minimal implementation of TX rate controlling that can be used
24 * as the default when no improved mechanisms are available. */ 24 * as the default when no improved mechanisms are available. */
25 25
26#define RATE_CONTROL_NUM_DOWN 20
27#define RATE_CONTROL_NUM_UP 15
26 28
27#define RATE_CONTROL_EMERG_DEC 2 29#define RATE_CONTROL_EMERG_DEC 2
28#define RATE_CONTROL_INTERVAL (HZ / 20) 30#define RATE_CONTROL_INTERVAL (HZ / 20)
@@ -87,26 +89,6 @@ static void rate_control_rate_dec(struct ieee80211_local *local,
87 } 89 }
88} 90}
89 91
90
91static struct ieee80211_rate *
92rate_control_lowest_rate(struct ieee80211_local *local,
93 struct ieee80211_hw_mode *mode)
94{
95 int i;
96
97 for (i = 0; i < mode->num_rates; i++) {
98 struct ieee80211_rate *rate = &mode->rates[i];
99
100 if (rate->flags & IEEE80211_RATE_SUPPORTED)
101 return rate;
102 }
103
104 printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
105 "found\n");
106 return &mode->rates[0];
107}
108
109
110struct global_rate_control { 92struct global_rate_control {
111 int dummy; 93 int dummy;
112}; 94};
@@ -216,56 +198,32 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
216} 198}
217 199
218 200
219static struct ieee80211_rate * 201static void
220rate_control_simple_get_rate(void *priv, struct net_device *dev, 202rate_control_simple_get_rate(void *priv, struct net_device *dev,
203 struct ieee80211_hw_mode *mode,
221 struct sk_buff *skb, 204 struct sk_buff *skb,
222 struct rate_control_extra *extra) 205 struct rate_selection *sel)
223{ 206{
224 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 207 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
225 struct ieee80211_sub_if_data *sdata;
226 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
227 struct ieee80211_hw_mode *mode = extra->mode;
228 struct sta_info *sta; 209 struct sta_info *sta;
229 int rateidx, nonerp_idx; 210 int rateidx;
230 u16 fc;
231
232 memset(extra, 0, sizeof(*extra));
233
234 fc = le16_to_cpu(hdr->frame_control);
235 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
236 (hdr->addr1[0] & 0x01)) {
237 /* Send management frames and broadcast/multicast data using
238 * lowest rate. */
239 /* TODO: this could probably be improved.. */
240 return rate_control_lowest_rate(local, mode);
241 }
242 211
243 sta = sta_info_get(local, hdr->addr1); 212 sta = sta_info_get(local, hdr->addr1);
244 213
245 if (!sta) 214 if (!sta) {
246 return rate_control_lowest_rate(local, mode); 215 sel->rate = rate_lowest(local, mode, NULL);
247 216 return;
248 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 217 }
249 if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
250 sta->txrate = sdata->bss->force_unicast_rateidx;
251 218
252 rateidx = sta->txrate; 219 rateidx = sta->txrate;
253 220
254 if (rateidx >= mode->num_rates) 221 if (rateidx >= mode->num_rates)
255 rateidx = mode->num_rates - 1; 222 rateidx = mode->num_rates - 1;
256 223
257 sta->last_txrate = rateidx;
258 nonerp_idx = rateidx;
259 while (nonerp_idx > 0 &&
260 ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
261 !(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
262 !(sta->supp_rates & BIT(nonerp_idx))))
263 nonerp_idx--;
264 extra->nonerp = &mode->rates[nonerp_idx];
265
266 sta_info_put(sta); 224 sta_info_put(sta);
267 225
268 return &mode->rates[rateidx]; 226 sel->rate = &mode->rates[rateidx];
269} 227}
270 228
271 229
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 12c15588af68..4655e3038658 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -569,21 +569,17 @@ ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
569static ieee80211_txrx_result 569static ieee80211_txrx_result
570ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) 570ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
571{ 571{
572 struct rate_control_extra extra; 572 struct rate_selection rsel;
573 573
574 if (likely(!tx->u.tx.rate)) { 574 if (likely(!tx->u.tx.rate)) {
575 memset(&extra, 0, sizeof(extra)); 575 rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel);
576 extra.mode = tx->u.tx.mode; 576 tx->u.tx.rate = rsel.rate;
577 extra.ethertype = tx->ethertype; 577 if (unlikely(rsel.probe != NULL)) {
578
579 tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
580 tx->skb, &extra);
581 if (unlikely(extra.probe != NULL)) {
582 tx->u.tx.control->flags |= 578 tx->u.tx.control->flags |=
583 IEEE80211_TXCTL_RATE_CTRL_PROBE; 579 IEEE80211_TXCTL_RATE_CTRL_PROBE;
584 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 580 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
585 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; 581 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
586 tx->u.tx.rate = extra.probe; 582 tx->u.tx.rate = rsel.probe;
587 } else 583 } else
588 tx->u.tx.control->alt_retry_rate = -1; 584 tx->u.tx.control->alt_retry_rate = -1;
589 585
@@ -594,14 +590,14 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
594 590
595 if (tx->u.tx.mode->mode == MODE_IEEE80211G && 591 if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
596 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) && 592 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
597 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) { 593 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) {
598 tx->u.tx.last_frag_rate = tx->u.tx.rate; 594 tx->u.tx.last_frag_rate = tx->u.tx.rate;
599 if (extra.probe) 595 if (rsel.probe)
600 tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 596 tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
601 else 597 else
602 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 598 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
603 tx->u.tx.rate = extra.nonerp; 599 tx->u.tx.rate = rsel.nonerp;
604 tx->u.tx.control->rate = extra.nonerp; 600 tx->u.tx.control->rate = rsel.nonerp;
605 tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; 601 tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
606 } else { 602 } else {
607 tx->u.tx.last_frag_rate = tx->u.tx.rate; 603 tx->u.tx.last_frag_rate = tx->u.tx.rate;
@@ -1667,8 +1663,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1667 struct net_device *bdev; 1663 struct net_device *bdev;
1668 struct ieee80211_sub_if_data *sdata = NULL; 1664 struct ieee80211_sub_if_data *sdata = NULL;
1669 struct ieee80211_if_ap *ap = NULL; 1665 struct ieee80211_if_ap *ap = NULL;
1670 struct ieee80211_rate *rate; 1666 struct rate_selection rsel;
1671 struct rate_control_extra extra;
1672 u8 *b_head, *b_tail; 1667 u8 *b_head, *b_tail;
1673 int bh_len, bt_len; 1668 int bh_len, bt_len;
1674 1669
@@ -1712,14 +1707,13 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1712 } 1707 }
1713 1708
1714 if (control) { 1709 if (control) {
1715 memset(&extra, 0, sizeof(extra)); 1710 rate_control_get_rate(local->mdev, local->oper_hw_mode, skb,
1716 extra.mode = local->oper_hw_mode; 1711 &rsel);
1717 1712 if (!rsel.rate) {
1718 rate = rate_control_get_rate(local, local->mdev, skb, &extra);
1719 if (!rate) {
1720 if (net_ratelimit()) { 1713 if (net_ratelimit()) {
1721 printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate " 1714 printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
1722 "found\n", wiphy_name(local->hw.wiphy)); 1715 "no rate found\n",
1716 wiphy_name(local->hw.wiphy));
1723 } 1717 }
1724 dev_kfree_skb(skb); 1718 dev_kfree_skb(skb);
1725 return NULL; 1719 return NULL;
@@ -1727,8 +1721,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
1727 1721
1728 control->tx_rate = 1722 control->tx_rate =
1729 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) && 1723 ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
1730 (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? 1724 (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
1731 rate->val2 : rate->val; 1725 rsel.rate->val2 : rsel.rate->val;
1732 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1726 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1733 control->power_level = local->hw.conf.power_level; 1727 control->power_level = local->hw.conf.power_level;
1734 control->flags |= IEEE80211_TXCTL_NO_ACK; 1728 control->flags |= IEEE80211_TXCTL_NO_ACK;