aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-05-12 15:18:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-13 15:44:49 -0400
commitb59066a291ca7c12a1e5b58f3ada5ab6e32cb6bd (patch)
tree6653f502fcae42a288b5beab4a5684e31f84a501 /net/mac80211/ibss.c
parente0d61887c2ee19bb63f6a8c0e2c149184e879501 (diff)
mac80211: IBSS supported rate fixes
Currently mac80211 announces a rate set with no basic rates, this fixes it to use 1/2 or 6/9 Mbit as basic rates by default. Additionally, mac80211 will currently adopt the peer's entire rate set, rather than just the basic rate set; fix that too. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index c94a695d8488..c236079ed38a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -63,19 +63,18 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
64 const u8 *bssid, const int beacon_int, 64 const u8 *bssid, const int beacon_int,
65 struct ieee80211_channel *chan, 65 struct ieee80211_channel *chan,
66 const size_t supp_rates_len, 66 const u32 basic_rates,
67 const u8 *supp_rates,
68 const u16 capability, u64 tsf) 67 const u16 capability, u64 tsf)
69{ 68{
70 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
71 struct ieee80211_local *local = sdata->local; 70 struct ieee80211_local *local = sdata->local;
72 int rates, i, j; 71 int rates, i;
73 struct sk_buff *skb; 72 struct sk_buff *skb;
74 struct ieee80211_mgmt *mgmt; 73 struct ieee80211_mgmt *mgmt;
75 u8 *pos; 74 u8 *pos;
76 struct ieee80211_supported_band *sband; 75 struct ieee80211_supported_band *sband;
77 u32 bss_change; 76 u32 bss_change;
78 77 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
79 78
80 /* Reset own TSF to allow time synchronization work. */ 79 /* Reset own TSF to allow time synchronization work. */
81 drv_reset_tsf(local); 80 drv_reset_tsf(local);
@@ -101,6 +100,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
101 100
102 sband = local->hw.wiphy->bands[chan->band]; 101 sband = local->hw.wiphy->bands[chan->band];
103 102
103 /* build supported rates array */
104 pos = supp_rates;
105 for (i = 0; i < sband->n_bitrates; i++) {
106 int rate = sband->bitrates[i].bitrate;
107 u8 basic = 0;
108 if (basic_rates & BIT(i))
109 basic = 0x80;
110 *pos++ = basic | (u8) (rate / 5);
111 }
112
104 /* Build IBSS probe response */ 113 /* Build IBSS probe response */
105 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 114 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
106 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 115 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
@@ -118,7 +127,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
118 *pos++ = ifibss->ssid_len; 127 *pos++ = ifibss->ssid_len;
119 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 128 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
120 129
121 rates = supp_rates_len; 130 rates = sband->n_bitrates;
122 if (rates > 8) 131 if (rates > 8)
123 rates = 8; 132 rates = 8;
124 pos = skb_put(skb, 2 + rates); 133 pos = skb_put(skb, 2 + rates);
@@ -140,8 +149,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
140 *pos++ = 0; 149 *pos++ = 0;
141 *pos++ = 0; 150 *pos++ = 0;
142 151
143 if (supp_rates_len > 8) { 152 if (sband->n_bitrates > 8) {
144 rates = supp_rates_len - 8; 153 rates = sband->n_bitrates - 8;
145 pos = skb_put(skb, 2 + rates); 154 pos = skb_put(skb, 2 + rates);
146 *pos++ = WLAN_EID_EXT_SUPP_RATES; 155 *pos++ = WLAN_EID_EXT_SUPP_RATES;
147 *pos++ = rates; 156 *pos++ = rates;
@@ -162,15 +171,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
162 bss_change |= BSS_CHANGED_BEACON_ENABLED; 171 bss_change |= BSS_CHANGED_BEACON_ENABLED;
163 ieee80211_bss_info_change_notify(sdata, bss_change); 172 ieee80211_bss_info_change_notify(sdata, bss_change);
164 173
165 rates = 0; 174 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
166 for (i = 0; i < supp_rates_len; i++) {
167 int bitrate = (supp_rates[i] & 0x7f) * 5;
168 for (j = 0; j < sband->n_bitrates; j++)
169 if (sband->bitrates[j].bitrate == bitrate)
170 rates |= BIT(j);
171 }
172
173 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
174 175
175 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 176 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
176 mod_timer(&ifibss->timer, 177 mod_timer(&ifibss->timer,
@@ -184,15 +185,35 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
184static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 185static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
185 struct ieee80211_bss *bss) 186 struct ieee80211_bss *bss)
186{ 187{
188 struct ieee80211_supported_band *sband;
189 u32 basic_rates;
190 int i, j;
187 u16 beacon_int = bss->cbss.beacon_interval; 191 u16 beacon_int = bss->cbss.beacon_interval;
188 192
189 if (beacon_int < 10) 193 if (beacon_int < 10)
190 beacon_int = 10; 194 beacon_int = 10;
191 195
196 sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
197
198 basic_rates = 0;
199
200 for (i = 0; i < bss->supp_rates_len; i++) {
201 int rate = (bss->supp_rates[i] & 0x7f) * 5;
202 bool is_basic = !!(bss->supp_rates[i] & 0x80);
203
204 for (j = 0; j < sband->n_bitrates; j++) {
205 if (sband->bitrates[j].bitrate == rate) {
206 if (is_basic)
207 basic_rates |= BIT(j);
208 break;
209 }
210 }
211 }
212
192 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, 213 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
193 beacon_int, 214 beacon_int,
194 bss->cbss.channel, 215 bss->cbss.channel,
195 bss->supp_rates_len, bss->supp_rates, 216 basic_rates,
196 bss->cbss.capability, 217 bss->cbss.capability,
197 bss->cbss.tsf); 218 bss->cbss.tsf);
198} 219}
@@ -449,9 +470,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
449 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 470 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
450 struct ieee80211_local *local = sdata->local; 471 struct ieee80211_local *local = sdata->local;
451 struct ieee80211_supported_band *sband; 472 struct ieee80211_supported_band *sband;
452 u8 *pos;
453 u8 bssid[ETH_ALEN]; 473 u8 bssid[ETH_ALEN];
454 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
455 u16 capability; 474 u16 capability;
456 int i; 475 int i;
457 476
@@ -480,15 +499,9 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
480 else 499 else
481 sdata->drop_unencrypted = 0; 500 sdata->drop_unencrypted = 0;
482 501
483 pos = supp_rates;
484 for (i = 0; i < sband->n_bitrates; i++) {
485 int rate = sband->bitrates[i].bitrate;
486 *pos++ = (u8) (rate / 5);
487 }
488
489 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, 502 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
490 ifibss->channel, sband->n_bitrates, 503 ifibss->channel, 3, /* first two are basic */
491 supp_rates, capability, 0); 504 capability, 0);
492} 505}
493 506
494static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 507static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)