aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1ff83532120f..b361e2acfce9 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -28,6 +28,7 @@
28#include "rate.h" 28#include "rate.h"
29#include "mesh.h" 29#include "mesh.h"
30#include "wme.h" 30#include "wme.h"
31#include "led.h"
31 32
32/* privid for wiphys to determine whether they belong to us or not */ 33/* privid for wiphys to determine whether they belong to us or not */
33void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 34void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -966,3 +967,120 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
966 } 967 }
967 return supp_rates; 968 return supp_rates;
968} 969}
970
971int ieee80211_reconfig(struct ieee80211_local *local)
972{
973 struct ieee80211_hw *hw = &local->hw;
974 struct ieee80211_sub_if_data *sdata;
975 struct ieee80211_if_init_conf conf;
976 struct sta_info *sta;
977 unsigned long flags;
978 int res;
979
980 /* restart hardware */
981 if (local->open_count) {
982 res = local->ops->start(hw);
983
984 ieee80211_led_radio(local, hw->conf.radio_enabled);
985 }
986
987 /* add interfaces */
988 list_for_each_entry(sdata, &local->interfaces, list) {
989 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
990 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
991 netif_running(sdata->dev)) {
992 conf.vif = &sdata->vif;
993 conf.type = sdata->vif.type;
994 conf.mac_addr = sdata->dev->dev_addr;
995 res = local->ops->add_interface(hw, &conf);
996 }
997 }
998
999 /* add STAs back */
1000 if (local->ops->sta_notify) {
1001 spin_lock_irqsave(&local->sta_lock, flags);
1002 list_for_each_entry(sta, &local->sta_list, list) {
1003 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1004 sdata = container_of(sdata->bss,
1005 struct ieee80211_sub_if_data,
1006 u.ap);
1007
1008 local->ops->sta_notify(hw, &sdata->vif,
1009 STA_NOTIFY_ADD, &sta->sta);
1010 }
1011 spin_unlock_irqrestore(&local->sta_lock, flags);
1012 }
1013
1014 /* Clear Suspend state so that ADDBA requests can be processed */
1015
1016 rcu_read_lock();
1017
1018 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1019 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1020 clear_sta_flags(sta, WLAN_STA_SUSPEND);
1021 }
1022 }
1023
1024 rcu_read_unlock();
1025
1026 /* setup RTS threshold */
1027 if (local->ops->set_rts_threshold)
1028 local->ops->set_rts_threshold(hw, local->rts_threshold);
1029
1030 /* reconfigure hardware */
1031 ieee80211_hw_config(local, ~0);
1032
1033 netif_addr_lock_bh(local->mdev);
1034 ieee80211_configure_filter(local);
1035 netif_addr_unlock_bh(local->mdev);
1036
1037 /* Finally also reconfigure all the BSS information */
1038 list_for_each_entry(sdata, &local->interfaces, list) {
1039 u32 changed = ~0;
1040 if (!netif_running(sdata->dev))
1041 continue;
1042 switch (sdata->vif.type) {
1043 case NL80211_IFTYPE_STATION:
1044 /* disable beacon change bits */
1045 changed &= ~IEEE80211_IFCC_BEACON;
1046 /* fall through */
1047 case NL80211_IFTYPE_ADHOC:
1048 case NL80211_IFTYPE_AP:
1049 case NL80211_IFTYPE_MESH_POINT:
1050 /*
1051 * Driver's config_interface can fail if rfkill is
1052 * enabled. Accommodate this return code.
1053 * FIXME: When mac80211 has knowledge of rfkill
1054 * state the code below can change back to:
1055 * WARN(ieee80211_if_config(sdata, changed));
1056 * ieee80211_bss_info_change_notify(sdata, ~0);
1057 */
1058 if (ieee80211_if_config(sdata, changed))
1059 printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
1060 sdata->dev->name);
1061 else
1062 ieee80211_bss_info_change_notify(sdata, ~0);
1063 break;
1064 case NL80211_IFTYPE_WDS:
1065 break;
1066 case NL80211_IFTYPE_AP_VLAN:
1067 case NL80211_IFTYPE_MONITOR:
1068 /* ignore virtual */
1069 break;
1070 case NL80211_IFTYPE_UNSPECIFIED:
1071 case __NL80211_IFTYPE_AFTER_LAST:
1072 WARN_ON(1);
1073 break;
1074 }
1075 }
1076
1077 /* add back keys */
1078 list_for_each_entry(sdata, &local->interfaces, list)
1079 if (netif_running(sdata->dev))
1080 ieee80211_enable_keys(sdata);
1081
1082 ieee80211_wake_queues_by_reason(hw,
1083 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1084
1085 return 0;
1086}