diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index c691780725a7..239c4836a946 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
173 | memcpy(skb_put(skb, ifibss->ie_len), | 173 | memcpy(skb_put(skb, ifibss->ie_len), |
174 | ifibss->ie, ifibss->ie_len); | 174 | ifibss->ie, ifibss->ie_len); |
175 | 175 | ||
176 | if (local->hw.queues >= 4) { | ||
177 | pos = skb_put(skb, 9); | ||
178 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; | ||
179 | *pos++ = 7; /* len */ | ||
180 | *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ | ||
181 | *pos++ = 0x50; | ||
182 | *pos++ = 0xf2; | ||
183 | *pos++ = 2; /* WME */ | ||
184 | *pos++ = 0; /* WME info */ | ||
185 | *pos++ = 1; /* WME ver */ | ||
186 | *pos++ = 0; /* U-APSD no in use */ | ||
187 | } | ||
188 | |||
176 | rcu_assign_pointer(ifibss->presp, skb); | 189 | rcu_assign_pointer(ifibss->presp, skb); |
177 | 190 | ||
178 | sdata->vif.bss_conf.beacon_int = beacon_int; | 191 | sdata->vif.bss_conf.beacon_int = beacon_int; |
@@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
266 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 279 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
267 | return; | 280 | return; |
268 | 281 | ||
269 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && | 282 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && |
270 | memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { | 283 | memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { |
271 | supp_rates = ieee80211_sta_get_rates(local, elems, band); | ||
272 | 284 | ||
273 | rcu_read_lock(); | 285 | rcu_read_lock(); |
274 | |||
275 | sta = sta_info_get(sdata, mgmt->sa); | 286 | sta = sta_info_get(sdata, mgmt->sa); |
276 | if (sta) { | ||
277 | u32 prev_rates; | ||
278 | 287 | ||
279 | prev_rates = sta->sta.supp_rates[band]; | 288 | if (elems->supp_rates) { |
280 | /* make sure mandatory rates are always added */ | 289 | supp_rates = ieee80211_sta_get_rates(local, elems, |
281 | sta->sta.supp_rates[band] = supp_rates | | 290 | band); |
282 | ieee80211_mandatory_rates(local, band); | 291 | if (sta) { |
292 | u32 prev_rates; | ||
293 | |||
294 | prev_rates = sta->sta.supp_rates[band]; | ||
295 | /* make sure mandatory rates are always added */ | ||
296 | sta->sta.supp_rates[band] = supp_rates | | ||
297 | ieee80211_mandatory_rates(local, band); | ||
283 | 298 | ||
284 | if (sta->sta.supp_rates[band] != prev_rates) { | 299 | if (sta->sta.supp_rates[band] != prev_rates) { |
285 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 300 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
286 | printk(KERN_DEBUG "%s: updated supp_rates set " | 301 | printk(KERN_DEBUG |
287 | "for %pM based on beacon/probe_response " | 302 | "%s: updated supp_rates set " |
288 | "(0x%x -> 0x%x)\n", | 303 | "for %pM based on beacon" |
289 | sdata->name, sta->sta.addr, | 304 | "/probe_resp (0x%x -> 0x%x)\n", |
290 | prev_rates, sta->sta.supp_rates[band]); | 305 | sdata->name, sta->sta.addr, |
306 | prev_rates, | ||
307 | sta->sta.supp_rates[band]); | ||
291 | #endif | 308 | #endif |
292 | rate_control_rate_init(sta); | 309 | rate_control_rate_init(sta); |
293 | } | 310 | } |
294 | rcu_read_unlock(); | 311 | } else |
295 | } else { | 312 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, |
296 | rcu_read_unlock(); | 313 | mgmt->sa, supp_rates, |
297 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 314 | GFP_ATOMIC); |
298 | supp_rates, GFP_KERNEL); | ||
299 | } | 315 | } |
316 | |||
317 | if (sta && elems->wmm_info) | ||
318 | set_sta_flags(sta, WLAN_STA_WME); | ||
319 | |||
320 | rcu_read_unlock(); | ||
300 | } | 321 | } |
301 | 322 | ||
302 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, | 323 | bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, |
@@ -427,14 +448,15 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
427 | return NULL; | 448 | return NULL; |
428 | 449 | ||
429 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 450 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
430 | printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", | 451 | wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n", |
431 | wiphy_name(local->hw.wiphy), addr, sdata->name); | 452 | addr, sdata->name); |
432 | #endif | 453 | #endif |
433 | 454 | ||
434 | sta = sta_info_alloc(sdata, addr, gfp); | 455 | sta = sta_info_alloc(sdata, addr, gfp); |
435 | if (!sta) | 456 | if (!sta) |
436 | return NULL; | 457 | return NULL; |
437 | 458 | ||
459 | sta->last_rx = jiffies; | ||
438 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 460 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
439 | 461 | ||
440 | /* make sure mandatory rates are always added */ | 462 | /* make sure mandatory rates are always added */ |
@@ -920,12 +942,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
920 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); | 942 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); |
921 | sdata->u.ibss.ssid_len = params->ssid_len; | 943 | sdata->u.ibss.ssid_len = params->ssid_len; |
922 | 944 | ||
945 | mutex_unlock(&sdata->u.ibss.mtx); | ||
946 | |||
947 | mutex_lock(&sdata->local->mtx); | ||
923 | ieee80211_recalc_idle(sdata->local); | 948 | ieee80211_recalc_idle(sdata->local); |
949 | mutex_unlock(&sdata->local->mtx); | ||
924 | 950 | ||
925 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 951 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
926 | 952 | ||
927 | mutex_unlock(&sdata->u.ibss.mtx); | ||
928 | |||
929 | return 0; | 953 | return 0; |
930 | } | 954 | } |
931 | 955 | ||
@@ -980,7 +1004,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
980 | 1004 | ||
981 | mutex_unlock(&sdata->u.ibss.mtx); | 1005 | mutex_unlock(&sdata->u.ibss.mtx); |
982 | 1006 | ||
1007 | mutex_lock(&local->mtx); | ||
983 | ieee80211_recalc_idle(sdata->local); | 1008 | ieee80211_recalc_idle(sdata->local); |
1009 | mutex_unlock(&local->mtx); | ||
984 | 1010 | ||
985 | return 0; | 1011 | return 0; |
986 | } | 1012 | } |