aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-02-03 07:59:58 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-02-08 16:50:53 -0500
commit34e895075e21be3e21e71d6317440d1ee7969ad0 (patch)
tree217fe70e32e54ef0134f477510472f3992655d79 /net/mac80211/cfg.c
parent070bb5477fb4029131aad4941d7aaf0093db0c38 (diff)
mac80211: allow station add/remove to sleep
Many drivers would like to sleep during station addition and removal, and currently have a high complexity there from not being able to. This introduces two new callbacks sta_add() and sta_remove() that drivers can implement instead of using sta_notify() and that can sleep, and the new sta_add() callback is also allowed to fail. The reason we didn't do this previously is that the IBSS code wants to insert stations from the RX path, which is a tasklet, so cannot sleep. This patch will keep the station allocation in that path, but moves adding the station to the driver out of line. Since the addition can now fail, we can have IBSS peer structs the driver rejected -- in that case we still talk to the station but never tell the driver about it in the control.sta pointer. If there will ever be a driver that has a low limit on the number of stations and that cannot talk to any stations that are not known to it, we need to do come up with a new strategy of handling larger IBSSs, maybe quicker expiry or rejecting peers. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c23
1 files changed, 4 insertions, 19 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index facf233843e0..a362523d8eb7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -747,9 +747,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
747 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 747 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
748 sdata->vif.type == NL80211_IFTYPE_AP; 748 sdata->vif.type == NL80211_IFTYPE_AP;
749 749
750 rcu_read_lock(); 750 err = sta_info_insert_rcu(sta);
751
752 err = sta_info_insert(sta);
753 if (err) { 751 if (err) {
754 rcu_read_unlock(); 752 rcu_read_unlock();
755 return err; 753 return err;
@@ -768,26 +766,13 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
768{ 766{
769 struct ieee80211_local *local = wiphy_priv(wiphy); 767 struct ieee80211_local *local = wiphy_priv(wiphy);
770 struct ieee80211_sub_if_data *sdata; 768 struct ieee80211_sub_if_data *sdata;
771 struct sta_info *sta;
772 769
773 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 770 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
774 771
775 if (mac) { 772 if (mac)
776 rcu_read_lock(); 773 return sta_info_destroy_addr_bss(sdata, mac);
777
778 sta = sta_info_get_bss(sdata, mac);
779 if (!sta) {
780 rcu_read_unlock();
781 return -ENOENT;
782 }
783
784 sta_info_unlink(&sta);
785 rcu_read_unlock();
786
787 sta_info_destroy(sta);
788 } else
789 sta_info_flush(local, sdata);
790 774
775 sta_info_flush(local, sdata);
791 return 0; 776 return 0;
792} 777}
793 778