diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-07-09 08:40:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:30:06 -0400 |
commit | 3e122be089e6fb8d3f322416da4cdbb80ce12927 (patch) | |
tree | 087db56fcbe05e9a8e2caa874262c81267c27573 /net/mac80211/mlme.c | |
parent | 500c11973233437cbfd298b9d41ba942550aec76 (diff) |
mac80211: make master netdev handling sane
Currently, almost every interface type has a 'bss' pointer
pointing to BSS information. This BSS information, however,
is for a _local_ BSS, not for the BSS we joined, so having
it on a STA mode interface makes little sense, but now they
have it pointing to the master device, which is an AP mode
virtual interface. However, except for some bitrate control
data, this pointer is only used in AP/VLAN modes (for power
saving stations.)
Overall, it is not necessary to even have the master netdev
be a valid virtual interface, and it doesn't have to be on
the list of interfaces either.
This patch changes the master netdev to be special, it now
- no longer is on the list of virtual interfaces, which
lets me remove a lot of tests for that
- no longer has sub_if_data attached, since that isn't used
Additionally, this patch changes some vlan/ap mode handling
that is related to these 'bss' pointers described above (but
in the VLAN case they actually make sense because there they
point to the AP they belong to); it also adds some debugging
code to IEEE80211_DEV_TO_SUB_IF to validate it is not called
on the master netdev any more.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 56 |
1 files changed, 19 insertions, 37 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dbc8cf454bc0..64d710a88b86 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); |
@@ -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 | ||
@@ -2775,7 +2770,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2775 | */ | 2770 | */ |
2776 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 2771 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
2777 | bss->probe_resp && beacon) { | 2772 | bss->probe_resp && beacon) { |
2778 | ieee80211_rx_bss_put(dev, bss); | 2773 | ieee80211_rx_bss_put(local, bss); |
2779 | return; | 2774 | return; |
2780 | } | 2775 | } |
2781 | 2776 | ||
@@ -2918,7 +2913,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2918 | } | 2913 | } |
2919 | } | 2914 | } |
2920 | 2915 | ||
2921 | ieee80211_rx_bss_put(dev, bss); | 2916 | ieee80211_rx_bss_put(local, bss); |
2922 | } | 2917 | } |
2923 | 2918 | ||
2924 | 2919 | ||
@@ -3578,7 +3573,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3578 | selected->ssid_len); | 3573 | selected->ssid_len); |
3579 | ieee80211_sta_set_bssid(dev, selected->bssid); | 3574 | ieee80211_sta_set_bssid(dev, selected->bssid); |
3580 | ieee80211_sta_def_wmm_params(dev, selected, 0); | 3575 | ieee80211_sta_def_wmm_params(dev, selected, 0); |
3581 | ieee80211_rx_bss_put(dev, selected); | 3576 | ieee80211_rx_bss_put(local, selected); |
3582 | ifsta->state = IEEE80211_AUTHENTICATE; | 3577 | ifsta->state = IEEE80211_AUTHENTICATE; |
3583 | ieee80211_sta_reset_auth(dev, ifsta); | 3578 | ieee80211_sta_reset_auth(dev, ifsta); |
3584 | return 0; | 3579 | return 0; |
@@ -3655,7 +3650,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3655 | } | 3650 | } |
3656 | 3651 | ||
3657 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3652 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3658 | ieee80211_rx_bss_put(dev, bss); | 3653 | ieee80211_rx_bss_put(local, bss); |
3659 | return ret; | 3654 | return ret; |
3660 | } | 3655 | } |
3661 | 3656 | ||
@@ -3711,7 +3706,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
3711 | " based on configured SSID\n", | 3706 | " based on configured SSID\n", |
3712 | dev->name, print_mac(mac, bssid)); | 3707 | dev->name, print_mac(mac, bssid)); |
3713 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3708 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
3714 | ieee80211_rx_bss_put(dev, bss); | 3709 | ieee80211_rx_bss_put(local, bss); |
3715 | return ret; | 3710 | return ret; |
3716 | } | 3711 | } |
3717 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3712 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
@@ -3907,11 +3902,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
3907 | 3902 | ||
3908 | rcu_read_lock(); | 3903 | rcu_read_lock(); |
3909 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 3904 | 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 */ | 3905 | /* Tell AP we're back */ |
3916 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 3906 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
3917 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) | 3907 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) |
@@ -4077,12 +4067,6 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
4077 | 4067 | ||
4078 | rcu_read_lock(); | 4068 | rcu_read_lock(); |
4079 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4069 | 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); | 4070 | netif_stop_queue(sdata->dev); |
4087 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 4071 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
4088 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) | 4072 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) |
@@ -4473,12 +4457,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw, | |||
4473 | case IEEE80211_NOTIFY_RE_ASSOC: | 4457 | case IEEE80211_NOTIFY_RE_ASSOC: |
4474 | rcu_read_lock(); | 4458 | rcu_read_lock(); |
4475 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4459 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
4460 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | ||
4461 | continue; | ||
4476 | 4462 | ||
4477 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 4463 | ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); |
4478 | ieee80211_sta_req_auth(sdata->dev, | ||
4479 | &sdata->u.sta); | ||
4480 | } | ||
4481 | |||
4482 | } | 4464 | } |
4483 | rcu_read_unlock(); | 4465 | rcu_read_unlock(); |
4484 | break; | 4466 | break; |