diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-07-09 08:40:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:30:07 -0400 |
commit | 9d139c810a2aa17365cc548d0cd2a189d8433c65 (patch) | |
tree | ef10ca55f93689ab97368376d277102d2527c961 /net/mac80211/main.c | |
parent | f3947e2dfa3b18f375b7acd03b7ee2877d0751fc (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.c | 59 |
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 | ||
988 | static int __ieee80211_if_config(struct net_device *dev, | 989 | int 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 | ||
1017 | int 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 | ||
1027 | int 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 | ||
1041 | int ieee80211_hw_config(struct ieee80211_local *local) | 1032 | int ieee80211_hw_config(struct ieee80211_local *local) |