diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 172 |
1 files changed, 66 insertions, 106 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dbc8cf454bc0..8f51375317dd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -78,7 +78,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
78 | static struct ieee80211_sta_bss * | 78 | static struct ieee80211_sta_bss * |
79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, | 79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
80 | u8 *ssid, u8 ssid_len); | 80 | u8 *ssid, u8 ssid_len); |
81 | static void ieee80211_rx_bss_put(struct net_device *dev, | 81 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
82 | struct ieee80211_sta_bss *bss); | 82 | struct ieee80211_sta_bss *bss); |
83 | static int ieee80211_sta_find_ibss(struct net_device *dev, | 83 | static int ieee80211_sta_find_ibss(struct net_device *dev, |
84 | struct ieee80211_if_sta *ifsta); | 84 | struct ieee80211_if_sta *ifsta); |
@@ -345,7 +345,7 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
345 | params.aifs = pos[0] & 0x0f; | 345 | params.aifs = pos[0] & 0x0f; |
346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
347 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 347 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
348 | params.txop = pos[2] | (pos[3] << 8); | 348 | params.txop = get_unaligned_le16(pos + 2); |
349 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 349 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
351 | "cWmin=%d cWmax=%d txop=%d\n", | 351 | "cWmin=%d cWmax=%d txop=%d\n", |
@@ -554,7 +554,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
554 | 554 | ||
555 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 555 | changed |= ieee80211_handle_bss_capability(sdata, bss); |
556 | 556 | ||
557 | ieee80211_rx_bss_put(dev, bss); | 557 | ieee80211_rx_bss_put(local, bss); |
558 | } | 558 | } |
559 | 559 | ||
560 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 560 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { |
@@ -760,7 +760,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
760 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | 760 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) |
761 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 761 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
762 | 762 | ||
763 | ieee80211_rx_bss_put(dev, bss); | 763 | ieee80211_rx_bss_put(local, bss); |
764 | } else { | 764 | } else { |
765 | rates = ~0; | 765 | rates = ~0; |
766 | rates_len = sband->n_bitrates; | 766 | rates_len = sband->n_bitrates; |
@@ -992,7 +992,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
992 | wep_privacy = !!ieee80211_sta_wep_configured(dev); | 992 | wep_privacy = !!ieee80211_sta_wep_configured(dev); |
993 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); | 993 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); |
994 | 994 | ||
995 | ieee80211_rx_bss_put(dev, bss); | 995 | ieee80211_rx_bss_put(local, bss); |
996 | 996 | ||
997 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) | 997 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) |
998 | return 0; | 998 | return 0; |
@@ -2094,7 +2094,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2094 | sta->last_signal = bss->signal; | 2094 | sta->last_signal = bss->signal; |
2095 | sta->last_qual = bss->qual; | 2095 | sta->last_qual = bss->qual; |
2096 | sta->last_noise = bss->noise; | 2096 | sta->last_noise = bss->noise; |
2097 | ieee80211_rx_bss_put(dev, bss); | 2097 | ieee80211_rx_bss_put(local, bss); |
2098 | } | 2098 | } |
2099 | 2099 | ||
2100 | err = sta_info_insert(sta); | 2100 | err = sta_info_insert(sta); |
@@ -2212,10 +2212,9 @@ static void __ieee80211_rx_bss_hash_add(struct net_device *dev, | |||
2212 | 2212 | ||
2213 | 2213 | ||
2214 | /* Caller must hold local->sta_bss_lock */ | 2214 | /* Caller must hold local->sta_bss_lock */ |
2215 | static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | 2215 | static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local, |
2216 | struct ieee80211_sta_bss *bss) | 2216 | struct ieee80211_sta_bss *bss) |
2217 | { | 2217 | { |
2218 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2219 | struct ieee80211_sta_bss *b, *prev = NULL; | 2218 | struct ieee80211_sta_bss *b, *prev = NULL; |
2220 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; | 2219 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; |
2221 | while (b) { | 2220 | while (b) { |
@@ -2367,39 +2366,35 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2367 | } | 2366 | } |
2368 | 2367 | ||
2369 | 2368 | ||
2370 | static void ieee80211_rx_bss_put(struct net_device *dev, | 2369 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
2371 | struct ieee80211_sta_bss *bss) | 2370 | struct ieee80211_sta_bss *bss) |
2372 | { | 2371 | { |
2373 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2374 | |||
2375 | local_bh_disable(); | 2372 | local_bh_disable(); |
2376 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { | 2373 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { |
2377 | local_bh_enable(); | 2374 | local_bh_enable(); |
2378 | return; | 2375 | return; |
2379 | } | 2376 | } |
2380 | 2377 | ||
2381 | __ieee80211_rx_bss_hash_del(dev, bss); | 2378 | __ieee80211_rx_bss_hash_del(local, bss); |
2382 | list_del(&bss->list); | 2379 | list_del(&bss->list); |
2383 | spin_unlock_bh(&local->sta_bss_lock); | 2380 | spin_unlock_bh(&local->sta_bss_lock); |
2384 | ieee80211_rx_bss_free(bss); | 2381 | ieee80211_rx_bss_free(bss); |
2385 | } | 2382 | } |
2386 | 2383 | ||
2387 | 2384 | ||
2388 | void ieee80211_rx_bss_list_init(struct net_device *dev) | 2385 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local) |
2389 | { | 2386 | { |
2390 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2391 | spin_lock_init(&local->sta_bss_lock); | 2387 | spin_lock_init(&local->sta_bss_lock); |
2392 | INIT_LIST_HEAD(&local->sta_bss_list); | 2388 | INIT_LIST_HEAD(&local->sta_bss_list); |
2393 | } | 2389 | } |
2394 | 2390 | ||
2395 | 2391 | ||
2396 | void ieee80211_rx_bss_list_deinit(struct net_device *dev) | 2392 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local) |
2397 | { | 2393 | { |
2398 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2399 | struct ieee80211_sta_bss *bss, *tmp; | 2394 | struct ieee80211_sta_bss *bss, *tmp; |
2400 | 2395 | ||
2401 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) | 2396 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) |
2402 | ieee80211_rx_bss_put(dev, bss); | 2397 | ieee80211_rx_bss_put(local, bss); |
2403 | } | 2398 | } |
2404 | 2399 | ||
2405 | 2400 | ||
@@ -2411,8 +2406,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2411 | int res, rates, i, j; | 2406 | int res, rates, i, j; |
2412 | struct sk_buff *skb; | 2407 | struct sk_buff *skb; |
2413 | struct ieee80211_mgmt *mgmt; | 2408 | struct ieee80211_mgmt *mgmt; |
2414 | struct ieee80211_tx_info *control; | ||
2415 | struct rate_selection ratesel; | ||
2416 | u8 *pos; | 2409 | u8 *pos; |
2417 | struct ieee80211_sub_if_data *sdata; | 2410 | struct ieee80211_sub_if_data *sdata; |
2418 | struct ieee80211_supported_band *sband; | 2411 | struct ieee80211_supported_band *sband; |
@@ -2430,7 +2423,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2430 | local->ops->reset_tsf(local_to_hw(local)); | 2423 | local->ops->reset_tsf(local_to_hw(local)); |
2431 | } | 2424 | } |
2432 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); | 2425 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); |
2433 | res = ieee80211_if_config(dev); | 2426 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); |
2434 | if (res) | 2427 | if (res) |
2435 | return res; | 2428 | return res; |
2436 | 2429 | ||
@@ -2444,19 +2437,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2444 | if (res) | 2437 | if (res) |
2445 | return res; | 2438 | return res; |
2446 | 2439 | ||
2447 | /* Set beacon template */ | 2440 | /* Build IBSS probe response */ |
2448 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 2441 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
2449 | do { | 2442 | if (skb) { |
2450 | if (!skb) | ||
2451 | break; | ||
2452 | |||
2453 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2443 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2454 | 2444 | ||
2455 | mgmt = (struct ieee80211_mgmt *) | 2445 | mgmt = (struct ieee80211_mgmt *) |
2456 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 2446 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
2457 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 2447 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
2458 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 2448 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, |
2459 | IEEE80211_STYPE_BEACON); | 2449 | IEEE80211_STYPE_PROBE_RESP); |
2460 | memset(mgmt->da, 0xff, ETH_ALEN); | 2450 | memset(mgmt->da, 0xff, ETH_ALEN); |
2461 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | 2451 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); |
2462 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | 2452 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); |
@@ -2500,61 +2490,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2500 | memcpy(pos, &bss->supp_rates[8], rates); | 2490 | memcpy(pos, &bss->supp_rates[8], rates); |
2501 | } | 2491 | } |
2502 | 2492 | ||
2503 | control = IEEE80211_SKB_CB(skb); | 2493 | ifsta->probe_resp = skb; |
2504 | |||
2505 | rate_control_get_rate(dev, sband, skb, &ratesel); | ||
2506 | if (ratesel.rate_idx < 0) { | ||
2507 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | ||
2508 | "for IBSS beacon\n", dev->name); | ||
2509 | break; | ||
2510 | } | ||
2511 | control->control.vif = &sdata->vif; | ||
2512 | control->tx_rate_idx = ratesel.rate_idx; | ||
2513 | if (sdata->bss_conf.use_short_preamble && | ||
2514 | sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
2515 | control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
2516 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
2517 | control->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
2518 | control->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
2519 | control->control.retry_limit = 1; | ||
2520 | |||
2521 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | ||
2522 | if (ifsta->probe_resp) { | ||
2523 | mgmt = (struct ieee80211_mgmt *) | ||
2524 | ifsta->probe_resp->data; | ||
2525 | mgmt->frame_control = | ||
2526 | IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2527 | IEEE80211_STYPE_PROBE_RESP); | ||
2528 | } else { | ||
2529 | printk(KERN_DEBUG "%s: Could not allocate ProbeResp " | ||
2530 | "template for IBSS\n", dev->name); | ||
2531 | } | ||
2532 | 2494 | ||
2533 | if (local->ops->beacon_update && | 2495 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
2534 | local->ops->beacon_update(local_to_hw(local), skb) == 0) { | 2496 | } |
2535 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | ||
2536 | "template\n", dev->name); | ||
2537 | skb = NULL; | ||
2538 | } | ||
2539 | |||
2540 | rates = 0; | ||
2541 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2542 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
2543 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | ||
2544 | for (j = 0; j < sband->n_bitrates; j++) | ||
2545 | if (sband->bitrates[j].bitrate == bitrate) | ||
2546 | rates |= BIT(j); | ||
2547 | } | ||
2548 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
2549 | |||
2550 | ieee80211_sta_def_wmm_params(dev, bss, 1); | ||
2551 | } while (0); | ||
2552 | 2497 | ||
2553 | if (skb) { | 2498 | rates = 0; |
2554 | printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " | 2499 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
2555 | "template\n", dev->name); | 2500 | for (i = 0; i < bss->supp_rates_len; i++) { |
2556 | dev_kfree_skb(skb); | 2501 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; |
2502 | for (j = 0; j < sband->n_bitrates; j++) | ||
2503 | if (sband->bitrates[j].bitrate == bitrate) | ||
2504 | rates |= BIT(j); | ||
2557 | } | 2505 | } |
2506 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
2507 | |||
2508 | ieee80211_sta_def_wmm_params(dev, bss, 1); | ||
2558 | 2509 | ||
2559 | ifsta->state = IEEE80211_IBSS_JOINED; | 2510 | ifsta->state = IEEE80211_IBSS_JOINED; |
2560 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | 2511 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); |
@@ -2775,7 +2726,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2775 | */ | 2726 | */ |
2776 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 2727 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
2777 | bss->probe_resp && beacon) { | 2728 | bss->probe_resp && beacon) { |
2778 | ieee80211_rx_bss_put(dev, bss); | 2729 | ieee80211_rx_bss_put(local, bss); |
2779 | return; | 2730 | return; |
2780 | } | 2731 | } |
2781 | 2732 | ||
@@ -2918,7 +2869,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2918 | } | 2869 | } |
2919 | } | 2870 | } |
2920 | 2871 | ||
2921 | ieee80211_rx_bss_put(dev, bss); | 2872 | ieee80211_rx_bss_put(local, bss); |
2922 | } | 2873 | } |
2923 | 2874 | ||
2924 | 2875 | ||
@@ -3338,7 +3289,7 @@ static void ieee80211_mesh_housekeeping(struct net_device *dev, | |||
3338 | 3289 | ||
3339 | free_plinks = mesh_plink_availables(sdata); | 3290 | free_plinks = mesh_plink_availables(sdata); |
3340 | if (free_plinks != sdata->u.sta.accepting_plinks) | 3291 | if (free_plinks != sdata->u.sta.accepting_plinks) |
3341 | ieee80211_if_config_beacon(dev); | 3292 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
3342 | 3293 | ||
3343 | mod_timer(&ifsta->timer, jiffies + | 3294 | mod_timer(&ifsta->timer, jiffies + |
3344 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); | 3295 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); |
@@ -3578,7 +3529,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3578 | selected->ssid_len); | 3529 | selected->ssid_len); |
3579 | ieee80211_sta_set_bssid(dev, selected->bssid); | 3530 | ieee80211_sta_set_bssid(dev, selected->bssid); |
3580 | ieee80211_sta_def_wmm_params(dev, selected, 0); | 3531 | ieee80211_sta_def_wmm_params(dev, selected, 0); |
3581 | ieee80211_rx_bss_put(dev, selected); | 3532 | ieee80211_rx_bss_put(local, selected); |
3582 | ifsta->state = IEEE80211_AUTHENTICATE; | 3533 | ifsta->state = IEEE80211_AUTHENTICATE; |
3583 | ieee80211_sta_reset_auth(dev, ifsta); | 3534 | ieee80211_sta_reset_auth(dev, ifsta); |
3584 | return 0; | 3535 | return 0; |
@@ -3655,7 +3606,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3655 | } | 3606 | } |
3656 | 3607 | ||
3657 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3608 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3658 | ieee80211_rx_bss_put(dev, bss); | 3609 | ieee80211_rx_bss_put(local, bss); |
3659 | return ret; | 3610 | return ret; |
3660 | } | 3611 | } |
3661 | 3612 | ||
@@ -3711,7 +3662,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3711 | " based on configured SSID\n", | 3662 | " based on configured SSID\n", |
3712 | dev->name, print_mac(mac, bssid)); | 3663 | dev->name, print_mac(mac, bssid)); |
3713 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3664 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3714 | ieee80211_rx_bss_put(dev, bss); | 3665 | ieee80211_rx_bss_put(local, bss); |
3715 | return ret; | 3666 | return ret; |
3716 | } | 3667 | } |
3717 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3668 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
@@ -3762,28 +3713,45 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3762 | { | 3713 | { |
3763 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3714 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3764 | struct ieee80211_if_sta *ifsta; | 3715 | struct ieee80211_if_sta *ifsta; |
3716 | int res; | ||
3765 | 3717 | ||
3766 | if (len > IEEE80211_MAX_SSID_LEN) | 3718 | if (len > IEEE80211_MAX_SSID_LEN) |
3767 | return -EINVAL; | 3719 | return -EINVAL; |
3768 | 3720 | ||
3769 | ifsta = &sdata->u.sta; | 3721 | ifsta = &sdata->u.sta; |
3770 | 3722 | ||
3771 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3723 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) { |
3724 | memset(ifsta->ssid, 0, sizeof(ifsta->ssid)); | ||
3725 | memcpy(ifsta->ssid, ssid, len); | ||
3726 | ifsta->ssid_len = len; | ||
3772 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 3727 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
3773 | memcpy(ifsta->ssid, ssid, len); | 3728 | |
3774 | memset(ifsta->ssid + len, 0, IEEE80211_MAX_SSID_LEN - len); | 3729 | res = 0; |
3775 | ifsta->ssid_len = len; | 3730 | /* |
3731 | * Hack! MLME code needs to be cleaned up to have different | ||
3732 | * entry points for configuration and internal selection change | ||
3733 | */ | ||
3734 | if (netif_running(sdata->dev)) | ||
3735 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
3736 | if (res) { | ||
3737 | printk(KERN_DEBUG "%s: Failed to config new SSID to " | ||
3738 | "the low-level driver\n", dev->name); | ||
3739 | return res; | ||
3740 | } | ||
3741 | } | ||
3776 | 3742 | ||
3777 | if (len) | 3743 | if (len) |
3778 | ifsta->flags |= IEEE80211_STA_SSID_SET; | 3744 | ifsta->flags |= IEEE80211_STA_SSID_SET; |
3779 | else | 3745 | else |
3780 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; | 3746 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; |
3747 | |||
3781 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3748 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
3782 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { | 3749 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { |
3783 | ifsta->ibss_join_req = jiffies; | 3750 | ifsta->ibss_join_req = jiffies; |
3784 | ifsta->state = IEEE80211_IBSS_SEARCH; | 3751 | ifsta->state = IEEE80211_IBSS_SEARCH; |
3785 | return ieee80211_sta_find_ibss(dev, ifsta); | 3752 | return ieee80211_sta_find_ibss(dev, ifsta); |
3786 | } | 3753 | } |
3754 | |||
3787 | return 0; | 3755 | return 0; |
3788 | } | 3756 | } |
3789 | 3757 | ||
@@ -3809,7 +3777,12 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) | |||
3809 | 3777 | ||
3810 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 3778 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
3811 | memcpy(ifsta->bssid, bssid, ETH_ALEN); | 3779 | memcpy(ifsta->bssid, bssid, ETH_ALEN); |
3812 | res = ieee80211_if_config(dev); | 3780 | res = 0; |
3781 | /* | ||
3782 | * Hack! See also ieee80211_sta_set_ssid. | ||
3783 | */ | ||
3784 | if (netif_running(sdata->dev)) | ||
3785 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); | ||
3813 | if (res) { | 3786 | if (res) { |
3814 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " | 3787 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " |
3815 | "the low-level driver\n", dev->name); | 3788 | "the low-level driver\n", dev->name); |
@@ -3907,11 +3880,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
3907 | 3880 | ||
3908 | rcu_read_lock(); | 3881 | rcu_read_lock(); |
3909 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 3882 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
3910 | |||
3911 | /* No need to wake the master device. */ | ||
3912 | if (sdata->dev == local->mdev) | ||
3913 | continue; | ||
3914 | |||
3915 | /* Tell AP we're back */ | 3883 | /* Tell AP we're back */ |
3916 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 3884 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
3917 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) | 3885 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) |
@@ -4077,12 +4045,6 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
4077 | 4045 | ||
4078 | rcu_read_lock(); | 4046 | rcu_read_lock(); |
4079 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4047 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
4080 | |||
4081 | /* Don't stop the master interface, otherwise we can't transmit | ||
4082 | * probes! */ | ||
4083 | if (sdata->dev == local->mdev) | ||
4084 | continue; | ||
4085 | |||
4086 | netif_stop_queue(sdata->dev); | 4048 | netif_stop_queue(sdata->dev); |
4087 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 4049 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
4088 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) | 4050 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) |
@@ -4398,7 +4360,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4398 | return NULL; | 4360 | return NULL; |
4399 | } | 4361 | } |
4400 | 4362 | ||
4401 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) | 4363 | if (compare_ether_addr(bssid, sdata->u.sta.bssid)) |
4402 | return NULL; | 4364 | return NULL; |
4403 | 4365 | ||
4404 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 4366 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -4473,12 +4435,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw, | |||
4473 | case IEEE80211_NOTIFY_RE_ASSOC: | 4435 | case IEEE80211_NOTIFY_RE_ASSOC: |
4474 | rcu_read_lock(); | 4436 | rcu_read_lock(); |
4475 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4437 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
4438 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | ||
4439 | continue; | ||
4476 | 4440 | ||
4477 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 4441 | ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); |
4478 | ieee80211_sta_req_auth(sdata->dev, | ||
4479 | &sdata->u.sta); | ||
4480 | } | ||
4481 | |||
4482 | } | 4442 | } |
4483 | rcu_read_unlock(); | 4443 | rcu_read_unlock(); |
4484 | break; | 4444 | break; |