aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-07-09 08:40:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:30:07 -0400
commit9d139c810a2aa17365cc548d0cd2a189d8433c65 (patch)
treeef10ca55f93689ab97368376d277102d2527c961 /net/mac80211/main.c
parentf3947e2dfa3b18f375b7acd03b7ee2877d0751fc (diff)
mac80211: revamp beacon configuration
This patch changes mac80211's beacon configuration handling to never pass skbs to the driver directly but rather always require the driver to use ieee80211_beacon_get(). Additionally, it introduces "change flags" on the config_interface() call to enable drivers to figure out what is changing. Finally, it removes the beacon_update() driver callback in favour of having IBSS beacon delivered by ieee80211_beacon_get() as well. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c59
1 files changed, 25 insertions, 34 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0759ab2ca3ff..36859e794928 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -307,7 +307,8 @@ static int ieee80211_open(struct net_device *dev)
307 if (res) 307 if (res)
308 goto err_stop; 308 goto err_stop;
309 309
310 ieee80211_if_config(dev); 310 if (ieee80211_vif_is_mesh(&sdata->vif))
311 ieee80211_start_mesh(sdata->dev);
311 changed |= ieee80211_reset_erp_info(dev); 312 changed |= ieee80211_reset_erp_info(dev);
312 ieee80211_bss_info_change_notify(sdata, changed); 313 ieee80211_bss_info_change_notify(sdata, changed);
313 ieee80211_enable_keys(sdata); 314 ieee80211_enable_keys(sdata);
@@ -985,57 +986,47 @@ void ieee80211_if_setup(struct net_device *dev)
985 986
986/* everything else */ 987/* everything else */
987 988
988static int __ieee80211_if_config(struct net_device *dev, 989int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
989 struct sk_buff *beacon)
990{ 990{
991 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 991 struct ieee80211_local *local = sdata->local;
992 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
993 struct ieee80211_if_conf conf; 992 struct ieee80211_if_conf conf;
994 993
995 if (!local->ops->config_interface || !netif_running(dev)) 994 if (WARN_ON(!netif_running(sdata->dev)))
995 return 0;
996
997 if (!local->ops->config_interface)
996 return 0; 998 return 0;
997 999
998 memset(&conf, 0, sizeof(conf)); 1000 memset(&conf, 0, sizeof(conf));
999 conf.type = sdata->vif.type; 1001 conf.changed = changed;
1002
1000 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 1003 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
1001 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 1004 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
1002 conf.bssid = sdata->u.sta.bssid; 1005 conf.bssid = sdata->u.sta.bssid;
1003 conf.ssid = sdata->u.sta.ssid; 1006 conf.ssid = sdata->u.sta.ssid;
1004 conf.ssid_len = sdata->u.sta.ssid_len; 1007 conf.ssid_len = sdata->u.sta.ssid_len;
1005 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
1006 conf.beacon = beacon;
1007 ieee80211_start_mesh(dev);
1008 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 1008 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
1009 conf.bssid = sdata->dev->dev_addr;
1009 conf.ssid = sdata->u.ap.ssid; 1010 conf.ssid = sdata->u.ap.ssid;
1010 conf.ssid_len = sdata->u.ap.ssid_len; 1011 conf.ssid_len = sdata->u.ap.ssid_len;
1011 conf.beacon = beacon; 1012 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
1013 u8 zero[ETH_ALEN] = { 0 };
1014 conf.bssid = zero;
1015 conf.ssid = zero;
1016 conf.ssid_len = 0;
1017 } else {
1018 WARN_ON(1);
1019 return -EINVAL;
1012 } 1020 }
1013 return local->ops->config_interface(local_to_hw(local),
1014 &sdata->vif, &conf);
1015}
1016 1021
1017int ieee80211_if_config(struct net_device *dev) 1022 if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
1018{ 1023 return -EINVAL;
1019 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1020 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1021 if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT &&
1022 (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
1023 return ieee80211_if_config_beacon(dev);
1024 return __ieee80211_if_config(dev, NULL);
1025}
1026 1024
1027int ieee80211_if_config_beacon(struct net_device *dev) 1025 if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID)))
1028{ 1026 return -EINVAL;
1029 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1030 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1031 struct sk_buff *skb;
1032 1027
1033 if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) 1028 return local->ops->config_interface(local_to_hw(local),
1034 return 0; 1029 &sdata->vif, &conf);
1035 skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif);
1036 if (!skb)
1037 return -ENOMEM;
1038 return __ieee80211_if_config(dev, skb);
1039} 1030}
1040 1031
1041int ieee80211_hw_config(struct ieee80211_local *local) 1032int ieee80211_hw_config(struct ieee80211_local *local)