aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-07-09 08:40:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:30:06 -0400
commit3e122be089e6fb8d3f322416da4cdbb80ce12927 (patch)
tree087db56fcbe05e9a8e2caa874262c81267c27573 /net/mac80211/mlme.c
parent500c11973233437cbfd298b9d41ba942550aec76 (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.c56
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,
78static struct ieee80211_sta_bss * 78static struct ieee80211_sta_bss *
79ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, 79ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq,
80 u8 *ssid, u8 ssid_len); 80 u8 *ssid, u8 ssid_len);
81static void ieee80211_rx_bss_put(struct net_device *dev, 81static void ieee80211_rx_bss_put(struct ieee80211_local *local,
82 struct ieee80211_sta_bss *bss); 82 struct ieee80211_sta_bss *bss);
83static int ieee80211_sta_find_ibss(struct net_device *dev, 83static 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 */
2215static void __ieee80211_rx_bss_hash_del(struct net_device *dev, 2215static 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
2370static void ieee80211_rx_bss_put(struct net_device *dev, 2369static 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
2388void ieee80211_rx_bss_list_init(struct net_device *dev) 2385void 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
2396void ieee80211_rx_bss_list_deinit(struct net_device *dev) 2392void 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;