aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c78
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}