Skip to content

Commit 1abbe49

Browse files
saittamdavem330
authored andcommitted
mac80211: clean up rate selection
Move some code out of rc80211_simple since it's probably needed for all rate selection algorithms, and fix iwlwifi accordingly. While at it, clean up the rate_control_get_rate() interface. Signed-off-by: Stefano Brivio <[email protected]> Signed-off-by: John W. Linville <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 98f0b0a commit 1abbe49

File tree

8 files changed

+146
-189
lines changed

8 files changed

+146
-189
lines changed

drivers/net/wireless/iwlwifi/iwl-3945-rs.c

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -562,22 +562,6 @@ static void rs_tx_status(void *priv_rate,
562562
return;
563563
}
564564

565-
static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local
566-
*local)
567-
{
568-
struct ieee80211_hw_mode *mode = local->oper_hw_mode;
569-
int i;
570-
571-
for (i = 0; i < mode->num_rates; i++) {
572-
struct ieee80211_rate *rate = &mode->rates[i];
573-
574-
if (rate->flags & IEEE80211_RATE_SUPPORTED)
575-
return rate;
576-
}
577-
578-
return &mode->rates[0];
579-
}
580-
581565
static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
582566
u8 index, u16 rate_mask, int phymode)
583567
{
@@ -656,10 +640,9 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
656640
* rate table and must reference the driver allocated rate table
657641
*
658642
*/
659-
static struct ieee80211_rate *rs_get_rate(void *priv_rate,
660-
struct net_device *dev,
661-
struct sk_buff *skb,
662-
struct rate_control_extra *extra)
643+
static void rs_get_rate(void *priv_rate, struct net_device *dev,
644+
struct ieee80211_hw_mode *mode, struct sk_buff *skb,
645+
struct rate_selection *sel)
663646
{
664647
u8 low = IWL_RATE_INVALID;
665648
u8 high = IWL_RATE_INVALID;
@@ -676,32 +659,19 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
676659
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
677660
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
678661
struct sta_info *sta;
679-
u16 fc, rate_mask;
662+
u16 rate_mask;
680663
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
681664
DECLARE_MAC_BUF(mac);
682665

683666
IWL_DEBUG_RATE("enter\n");
684667

685-
memset(extra, 0, sizeof(*extra));
686-
687-
fc = le16_to_cpu(hdr->frame_control);
688-
if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
689-
(is_multicast_ether_addr(hdr->addr1))) {
690-
/* Send management frames and broadcast/multicast data using
691-
* lowest rate. */
692-
/* TODO: this could probably be improved.. */
693-
IWL_DEBUG_RATE("leave: lowest rate (not data or is "
694-
"multicast)\n");
695-
696-
return iwl_get_lowest_rate(local);
697-
}
698-
699668
sta = sta_info_get(local, hdr->addr1);
700669
if (!sta || !sta->rate_ctrl_priv) {
701670
IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
671+
sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
702672
if (sta)
703673
sta_info_put(sta);
704-
return NULL;
674+
return;
705675
}
706676

707677
rate_mask = sta->supp_rates;
@@ -846,7 +816,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
846816

847817
IWL_DEBUG_RATE("leave: %d\n", index);
848818

849-
return &priv->ieee_rates[index];
819+
sel->rate = &priv->ieee_rates[index];
850820
}
851821

852822
static struct rate_control_ops rs_ops = {

drivers/net/wireless/iwlwifi/iwl-4965-rs.c

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,55 +1693,27 @@ static void rs_initialize_lq(struct iwl_priv *priv,
16931693
return;
16941694
}
16951695

1696-
static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local
1697-
*local)
1698-
{
1699-
struct ieee80211_hw_mode *mode = local->oper_hw_mode;
1700-
int i;
1701-
1702-
for (i = 0; i < mode->num_rates; i++) {
1703-
struct ieee80211_rate *rate = &mode->rates[i];
1704-
1705-
if (rate->flags & IEEE80211_RATE_SUPPORTED)
1706-
return rate;
1707-
}
1708-
1709-
return &mode->rates[0];
1710-
}
1711-
1712-
static struct ieee80211_rate *rs_get_rate(void *priv_rate,
1713-
struct net_device *dev,
1714-
struct sk_buff *skb,
1715-
struct rate_control_extra
1716-
*extra)
1696+
static void rs_get_rate(void *priv_rate, struct net_device *dev,
1697+
struct ieee80211_hw_mode *mode, struct sk_buff *skb,
1698+
struct rate_selection *sel)
17171699
{
17181700

17191701
int i;
17201702
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
17211703
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
17221704
struct sta_info *sta;
1723-
u16 fc;
17241705
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
17251706
struct iwl_rate_scale_priv *lq;
17261707

17271708
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
17281709

1729-
memset(extra, 0, sizeof(*extra));
1730-
1731-
fc = le16_to_cpu(hdr->frame_control);
1732-
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
1733-
/* Send management frames and broadcast/multicast data using
1734-
* lowest rate. */
1735-
/* TODO: this could probably be improved.. */
1736-
return rs_get_lowest_rate(local);
1737-
}
1738-
17391710
sta = sta_info_get(local, hdr->addr1);
17401711

17411712
if (!sta || !sta->rate_ctrl_priv) {
1713+
sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
17421714
if (sta)
17431715
sta_info_put(sta);
1744-
return rs_get_lowest_rate(local);
1716+
return;
17451717
}
17461718

17471719
lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
@@ -1768,11 +1740,13 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
17681740
}
17691741

17701742
done:
1743+
if ((i < 0) || (i > IWL_RATE_COUNT)) {
1744+
sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
1745+
return;
1746+
}
17711747
sta_info_put(sta);
1772-
if ((i < 0) || (i > IWL_RATE_COUNT))
1773-
return rs_get_lowest_rate(local);
17741748

1775-
return &priv->ieee_rates[i];
1749+
sel->rate = &priv->ieee_rates[i];
17761750
}
17771751

17781752
static void *rs_alloc_sta(void *priv, gfp_t gfp)

net/mac80211/ieee80211.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -859,10 +859,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
859859
sta_info_put(sta);
860860
return;
861861
}
862-
} else {
863-
/* FIXME: STUPID to call this with both local and local->mdev */
864-
rate_control_tx_status(local, local->mdev, skb, status);
865-
}
862+
} else
863+
rate_control_tx_status(local->mdev, skb, status);
866864

867865
ieee80211_led_tx(local, 0);
868866

net/mac80211/ieee80211_rate.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,53 @@ static void rate_control_release(struct kref *kref)
147147
kfree(ctrl_ref);
148148
}
149149

150+
void 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+
150197
struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
151198
{
152199
kref_get(&ref->kref);

net/mac80211/ieee80211_rate.h

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,24 @@
1818
#include "ieee80211_i.h"
1919
#include "sta_info.h"
2020

21-
#define RATE_CONTROL_NUM_DOWN 20
22-
#define RATE_CONTROL_NUM_UP 15
23-
24-
25-
struct 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 */
21+
struct rate_selection {
22+
/* Selected transmission rate */
23+
struct ieee80211_rate *rate;
24+
/* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
2925
struct ieee80211_rate *nonerp;
30-
31-
/* parameters from the caller to rate_control_get_rate(): */
32-
struct ieee80211_hw_mode *mode;
33-
u16 ethertype;
26+
/* probe with this rate, or NULL for no probing */
27+
struct ieee80211_rate *probe;
3428
};
3529

36-
3730
struct rate_control_ops {
3831
struct module *module;
3932
const char *name;
4033
void (*tx_status)(void *priv, struct net_device *dev,
4134
struct sk_buff *skb,
4235
struct ieee80211_tx_status *status);
43-
struct ieee80211_rate *(*get_rate)(void *priv, struct net_device *dev,
44-
struct sk_buff *skb,
45-
struct rate_control_extra *extra);
36+
void (*get_rate)(void *priv, struct net_device *dev,
37+
struct ieee80211_hw_mode *mode, struct sk_buff *skb,
38+
struct rate_selection *sel);
4639
void (*rate_init)(void *priv, void *priv_sta,
4740
struct ieee80211_local *local, struct sta_info *sta);
4841
void (*clear)(void *priv);
@@ -75,25 +68,20 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
7568
* first available algorithm. */
7669
struct rate_control_ref *rate_control_alloc(const char *name,
7770
struct ieee80211_local *local);
71+
void rate_control_get_rate(struct net_device *dev,
72+
struct ieee80211_hw_mode *mode, struct sk_buff *skb,
73+
struct rate_selection *sel);
7874
struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
7975
void rate_control_put(struct rate_control_ref *ref);
8076

81-
static inline void rate_control_tx_status(struct ieee80211_local *local,
82-
struct net_device *dev,
77+
static inline void rate_control_tx_status(struct net_device *dev,
8378
struct sk_buff *skb,
8479
struct ieee80211_tx_status *status)
8580
{
81+
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
8682
struct rate_control_ref *ref = local->rate_ctrl;
87-
ref->ops->tx_status(ref->priv, dev, skb, status);
88-
}
8983

90-
91-
static inline struct ieee80211_rate *
92-
rate_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);
84+
ref->ops->tx_status(ref->priv, dev, skb, status);
9785
}
9886

9987

@@ -142,6 +130,37 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
142130
#endif
143131
}
144132

133+
static inline int
134+
rate_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+
140+
static inline int
141+
rate_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+
157+
static inline struct ieee80211_rate *
158+
rate_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+
145164

146165
/* functions for rate control related to a device */
147166
int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,

net/mac80211/ieee80211_sta.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2463,9 +2463,8 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
24632463
struct sk_buff *skb;
24642464
struct ieee80211_mgmt *mgmt;
24652465
struct ieee80211_tx_control control;
2466-
struct ieee80211_rate *rate;
24672466
struct ieee80211_hw_mode *mode;
2468-
struct rate_control_extra extra;
2467+
struct rate_selection ratesel;
24692468
u8 *pos;
24702469
struct ieee80211_sub_if_data *sdata;
24712470

@@ -2550,18 +2549,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
25502549
}
25512550

25522551
memset(&control, 0, sizeof(control));
2553-
memset(&extra, 0, sizeof(extra));
2554-
extra.mode = local->oper_hw_mode;
2555-
rate = rate_control_get_rate(local, dev, skb, &extra);
2556-
if (!rate) {
2552+
rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel);
2553+
if (!ratesel.rate) {
25572554
printk(KERN_DEBUG "%s: Failed to determine TX rate "
25582555
"for IBSS beacon\n", dev->name);
25592556
break;
25602557
}
25612558
control.tx_rate =
25622559
((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
2563-
(rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2564-
rate->val2 : rate->val;
2560+
(ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2561+
ratesel.rate->val2 : ratesel.rate->val;
25652562
control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
25662563
control.power_level = local->hw.conf.power_level;
25672564
control.flags |= IEEE80211_TXCTL_NO_ACK;

0 commit comments

Comments
 (0)