aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath5k/base.c13
-rw-r--r--drivers/net/wireless/b43/main.c48
-rw-r--r--drivers/net/wireless/b43legacy/main.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c22
-rw-r--r--include/net/mac80211.h49
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c59
-rw-r--r--net/mac80211/mlme.c112
-rw-r--r--net/mac80211/tx.c36
-rw-r--r--net/mac80211/wext.c2
21 files changed, 226 insertions, 248 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index a43e9b25169b..217d506527a9 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -207,7 +207,6 @@ static struct ieee80211_ops ath5k_hw_ops = {
207 .get_tx_stats = ath5k_get_tx_stats, 207 .get_tx_stats = ath5k_get_tx_stats,
208 .get_tsf = ath5k_get_tsf, 208 .get_tsf = ath5k_get_tsf,
209 .reset_tsf = ath5k_reset_tsf, 209 .reset_tsf = ath5k_reset_tsf,
210 .beacon_update = ath5k_beacon_update,
211}; 210};
212 211
213/* 212/*
@@ -2785,6 +2784,18 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2785 * a clean way of letting us retrieve this yet. */ 2784 * a clean way of letting us retrieve this yet. */
2786 ath5k_hw_set_associd(ah, ah->ah_bssid, 0); 2785 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
2787 } 2786 }
2787
2788 if (conf->changed & IEEE80211_IFCC_BEACON &&
2789 vif->type == IEEE80211_IF_TYPE_IBSS) {
2790 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2791 if (!beacon) {
2792 ret = -ENOMEM;
2793 goto unlock;
2794 }
2795 /* call old handler for now */
2796 ath5k_beacon_update(hw, beacon);
2797 }
2798
2788 mutex_unlock(&sc->lock); 2799 mutex_unlock(&sc->lock);
2789 2800
2790 return ath5k_reset(hw); 2801 return ath5k_reset(hw);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9d2eb273b726..381dbd33dfc2 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1675,14 +1675,24 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1675 1675
1676/* Asynchronously update the packet templates in template RAM. 1676/* Asynchronously update the packet templates in template RAM.
1677 * Locking: Requires wl->irq_lock to be locked. */ 1677 * Locking: Requires wl->irq_lock to be locked. */
1678static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon) 1678static void b43_update_templates(struct b43_wl *wl)
1679{ 1679{
1680 struct sk_buff *beacon;
1681
1680 /* This is the top half of the ansynchronous beacon update. 1682 /* This is the top half of the ansynchronous beacon update.
1681 * The bottom half is the beacon IRQ. 1683 * The bottom half is the beacon IRQ.
1682 * Beacon update must be asynchronous to avoid sending an 1684 * Beacon update must be asynchronous to avoid sending an
1683 * invalid beacon. This can happen for example, if the firmware 1685 * invalid beacon. This can happen for example, if the firmware
1684 * transmits a beacon while we are updating it. */ 1686 * transmits a beacon while we are updating it. */
1685 1687
1688 /* We could modify the existing beacon and set the aid bit in
1689 * the TIM field, but that would probably require resizing and
1690 * moving of data within the beacon template.
1691 * Simply request a new beacon and let mac80211 do the hard work. */
1692 beacon = ieee80211_beacon_get(wl->hw, wl->vif);
1693 if (unlikely(!beacon))
1694 return;
1695
1686 if (wl->current_beacon) 1696 if (wl->current_beacon)
1687 dev_kfree_skb_any(wl->current_beacon); 1697 dev_kfree_skb_any(wl->current_beacon);
1688 wl->current_beacon = beacon; 1698 wl->current_beacon = beacon;
@@ -3645,10 +3655,14 @@ static int b43_op_config_interface(struct ieee80211_hw *hw,
3645 if (b43_status(dev) >= B43_STAT_INITIALIZED) { 3655 if (b43_status(dev) >= B43_STAT_INITIALIZED) {
3646 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) || 3656 if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
3647 b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) { 3657 b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) {
3648 B43_WARN_ON(conf->type != wl->if_type); 3658 B43_WARN_ON(vif->type != wl->if_type);
3649 b43_set_ssid(dev, conf->ssid, conf->ssid_len); 3659 if (conf->changed & IEEE80211_IFCC_SSID)
3650 if (conf->beacon) 3660 b43_set_ssid(dev, conf->ssid, conf->ssid_len);
3651 b43_update_templates(wl, conf->beacon); 3661 if (conf->changed & IEEE80211_IFCC_BEACON)
3662 b43_update_templates(wl);
3663 } else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) {
3664 if (conf->changed & IEEE80211_IFCC_BEACON)
3665 b43_update_templates(wl);
3652 } 3666 }
3653 b43_write_mac_bssid_templates(dev); 3667 b43_write_mac_bssid_templates(dev);
3654 } 3668 }
@@ -4336,31 +4350,10 @@ out_unlock:
4336static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set) 4350static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set)
4337{ 4351{
4338 struct b43_wl *wl = hw_to_b43_wl(hw); 4352 struct b43_wl *wl = hw_to_b43_wl(hw);
4339 struct sk_buff *beacon;
4340 unsigned long flags;
4341
4342 /* We could modify the existing beacon and set the aid bit in
4343 * the TIM field, but that would probably require resizing and
4344 * moving of data within the beacon template.
4345 * Simply request a new beacon and let mac80211 do the hard work. */
4346 beacon = ieee80211_beacon_get(hw, wl->vif);
4347 if (unlikely(!beacon))
4348 return -ENOMEM;
4349 spin_lock_irqsave(&wl->irq_lock, flags);
4350 b43_update_templates(wl, beacon);
4351 spin_unlock_irqrestore(&wl->irq_lock, flags);
4352
4353 return 0;
4354}
4355
4356static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
4357 struct sk_buff *beacon)
4358{
4359 struct b43_wl *wl = hw_to_b43_wl(hw);
4360 unsigned long flags; 4353 unsigned long flags;
4361 4354
4362 spin_lock_irqsave(&wl->irq_lock, flags); 4355 spin_lock_irqsave(&wl->irq_lock, flags);
4363 b43_update_templates(wl, beacon); 4356 b43_update_templates(wl);
4364 spin_unlock_irqrestore(&wl->irq_lock, flags); 4357 spin_unlock_irqrestore(&wl->irq_lock, flags);
4365 4358
4366 return 0; 4359 return 0;
@@ -4391,7 +4384,6 @@ static const struct ieee80211_ops b43_hw_ops = {
4391 .stop = b43_op_stop, 4384 .stop = b43_op_stop,
4392 .set_retry_limit = b43_op_set_retry_limit, 4385 .set_retry_limit = b43_op_set_retry_limit,
4393 .set_tim = b43_op_beacon_set_tim, 4386 .set_tim = b43_op_beacon_set_tim,
4394 .beacon_update = b43_op_ibss_beacon_update,
4395 .sta_notify = b43_op_sta_notify, 4387 .sta_notify = b43_op_sta_notify,
4396}; 4388};
4397 4389
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 069157eea05c..a1b8bf3ee732 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1138,14 +1138,22 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
1138 1138
1139/* Asynchronously update the packet templates in template RAM. 1139/* Asynchronously update the packet templates in template RAM.
1140 * Locking: Requires wl->irq_lock to be locked. */ 1140 * Locking: Requires wl->irq_lock to be locked. */
1141static void b43legacy_update_templates(struct b43legacy_wl *wl, 1141static void b43legacy_update_templates(struct b43legacy_wl *wl)
1142 struct sk_buff *beacon)
1143{ 1142{
1143 struct sk_buff *beacon;
1144 /* This is the top half of the ansynchronous beacon update. The bottom 1144 /* This is the top half of the ansynchronous beacon update. The bottom
1145 * half is the beacon IRQ. Beacon update must be asynchronous to avoid 1145 * half is the beacon IRQ. Beacon update must be asynchronous to avoid
1146 * sending an invalid beacon. This can happen for example, if the 1146 * sending an invalid beacon. This can happen for example, if the
1147 * firmware transmits a beacon while we are updating it. */ 1147 * firmware transmits a beacon while we are updating it. */
1148 1148
1149 /* We could modify the existing beacon and set the aid bit in the TIM
1150 * field, but that would probably require resizing and moving of data
1151 * within the beacon template. Simply request a new beacon and let
1152 * mac80211 do the hard work. */
1153 beacon = ieee80211_beacon_get(wl->hw, wl->vif);
1154 if (unlikely(!beacon))
1155 return;
1156
1149 if (wl->current_beacon) 1157 if (wl->current_beacon)
1150 dev_kfree_skb_any(wl->current_beacon); 1158 dev_kfree_skb_any(wl->current_beacon);
1151 wl->current_beacon = beacon; 1159 wl->current_beacon = beacon;
@@ -2727,10 +2735,13 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
2727 memset(wl->bssid, 0, ETH_ALEN); 2735 memset(wl->bssid, 0, ETH_ALEN);
2728 if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) { 2736 if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
2729 if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) { 2737 if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
2730 B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); 2738 B43legacy_WARN_ON(vif->type != IEEE80211_IF_TYPE_AP);
2731 b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); 2739 b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len);
2732 if (conf->beacon) 2740 if (conf->changed & IEEE80211_IFCC_BEACON)
2733 b43legacy_update_templates(wl, conf->beacon); 2741 b43legacy_update_templates(wl);
2742 } else if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) {
2743 if (conf->changed & IEEE80211_IFCC_BEACON)
2744 b43legacy_update_templates(wl);
2734 } 2745 }
2735 b43legacy_write_mac_bssid_templates(dev); 2746 b43legacy_write_mac_bssid_templates(dev);
2736 } 2747 }
@@ -3396,31 +3407,10 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
3396 int aid, int set) 3407 int aid, int set)
3397{ 3408{
3398 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 3409 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3399 struct sk_buff *beacon;
3400 unsigned long flags;
3401
3402 /* We could modify the existing beacon and set the aid bit in the TIM
3403 * field, but that would probably require resizing and moving of data
3404 * within the beacon template. Simply request a new beacon and let
3405 * mac80211 do the hard work. */
3406 beacon = ieee80211_beacon_get(hw, wl->vif);
3407 if (unlikely(!beacon))
3408 return -ENOMEM;
3409 spin_lock_irqsave(&wl->irq_lock, flags);
3410 b43legacy_update_templates(wl, beacon);
3411 spin_unlock_irqrestore(&wl->irq_lock, flags);
3412
3413 return 0;
3414}
3415
3416static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw,
3417 struct sk_buff *beacon)
3418{
3419 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3420 unsigned long flags; 3410 unsigned long flags;
3421 3411
3422 spin_lock_irqsave(&wl->irq_lock, flags); 3412 spin_lock_irqsave(&wl->irq_lock, flags);
3423 b43legacy_update_templates(wl, beacon); 3413 b43legacy_update_templates(wl);
3424 spin_unlock_irqrestore(&wl->irq_lock, flags); 3414 spin_unlock_irqrestore(&wl->irq_lock, flags);
3425 3415
3426 return 0; 3416 return 0;
@@ -3440,7 +3430,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3440 .stop = b43legacy_op_stop, 3430 .stop = b43legacy_op_stop,
3441 .set_retry_limit = b43legacy_op_set_retry_limit, 3431 .set_retry_limit = b43legacy_op_set_retry_limit,
3442 .set_tim = b43legacy_op_beacon_set_tim, 3432 .set_tim = b43legacy_op_beacon_set_tim,
3443 .beacon_update = b43legacy_op_ibss_beacon_update,
3444}; 3433};
3445 3434
3446/* Hard-reset the chip. Do not call this directly. 3435/* Hard-reset the chip. Do not call this directly.
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1a7d18fea89d..7d015f86ee8c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6907,6 +6907,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
6907 * clear sta table, add BCAST sta... */ 6907 * clear sta table, add BCAST sta... */
6908} 6908}
6909 6909
6910/* temporary */
6911static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
6912
6910static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, 6913static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
6911 struct ieee80211_vif *vif, 6914 struct ieee80211_vif *vif,
6912 struct ieee80211_if_conf *conf) 6915 struct ieee80211_if_conf *conf)
@@ -6924,10 +6927,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
6924 return 0; 6927 return 0;
6925 } 6928 }
6926 6929
6930 /* handle this temporarily here */
6931 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
6932 conf->changed & IEEE80211_IFCC_BEACON) {
6933 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
6934 if (!beacon)
6935 return -ENOMEM;
6936 rc = iwl3945_mac_beacon_update(hw, beacon);
6937 if (rc)
6938 return rc;
6939 }
6940
6927 /* XXX: this MUST use conf->mac_addr */ 6941 /* XXX: this MUST use conf->mac_addr */
6928 6942
6929 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && 6943 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
6930 (!conf->beacon || !conf->ssid_len)) { 6944 (!conf->ssid_len)) {
6931 IWL_DEBUG_MAC80211 6945 IWL_DEBUG_MAC80211
6932 ("Leaving in AP mode because HostAPD is not ready.\n"); 6946 ("Leaving in AP mode because HostAPD is not ready.\n");
6933 return 0; 6947 return 0;
@@ -6959,7 +6973,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
6959 if (priv->ibss_beacon) 6973 if (priv->ibss_beacon)
6960 dev_kfree_skb(priv->ibss_beacon); 6974 dev_kfree_skb(priv->ibss_beacon);
6961 6975
6962 priv->ibss_beacon = conf->beacon; 6976 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
6963 } 6977 }
6964 6978
6965 if (iwl3945_is_rfkill(priv)) 6979 if (iwl3945_is_rfkill(priv))
@@ -7940,7 +7954,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
7940 .conf_tx = iwl3945_mac_conf_tx, 7954 .conf_tx = iwl3945_mac_conf_tx,
7941 .get_tsf = iwl3945_mac_get_tsf, 7955 .get_tsf = iwl3945_mac_get_tsf,
7942 .reset_tsf = iwl3945_mac_reset_tsf, 7956 .reset_tsf = iwl3945_mac_reset_tsf,
7943 .beacon_update = iwl3945_mac_beacon_update,
7944 .hw_scan = iwl3945_mac_hw_scan 7957 .hw_scan = iwl3945_mac_hw_scan
7945}; 7958};
7946 7959
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 7f65d9123b2a..d6fe0ded59d7 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2912,6 +2912,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
2912 * clear sta table, add BCAST sta... */ 2912 * clear sta table, add BCAST sta... */
2913} 2913}
2914 2914
2915/* temporary */
2916static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
2917
2915static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, 2918static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
2916 struct ieee80211_vif *vif, 2919 struct ieee80211_vif *vif,
2917 struct ieee80211_if_conf *conf) 2920 struct ieee80211_if_conf *conf)
@@ -2929,8 +2932,18 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
2929 return 0; 2932 return 0;
2930 } 2933 }
2931 2934
2935 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
2936 conf->changed & IEEE80211_IFCC_BEACON) {
2937 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2938 if (!beacon)
2939 return -ENOMEM;
2940 rc = iwl4965_mac_beacon_update(hw, beacon);
2941 if (rc)
2942 return rc;
2943 }
2944
2932 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && 2945 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
2933 (!conf->beacon || !conf->ssid_len)) { 2946 (!conf->ssid_len)) {
2934 IWL_DEBUG_MAC80211 2947 IWL_DEBUG_MAC80211
2935 ("Leaving in AP mode because HostAPD is not ready.\n"); 2948 ("Leaving in AP mode because HostAPD is not ready.\n");
2936 return 0; 2949 return 0;
@@ -2962,7 +2975,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
2962 if (priv->ibss_beacon) 2975 if (priv->ibss_beacon)
2963 dev_kfree_skb(priv->ibss_beacon); 2976 dev_kfree_skb(priv->ibss_beacon);
2964 2977
2965 priv->ibss_beacon = conf->beacon; 2978 priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
2966 } 2979 }
2967 2980
2968 if (iwl_is_rfkill(priv)) 2981 if (iwl_is_rfkill(priv))
@@ -4090,7 +4103,6 @@ static struct ieee80211_ops iwl4965_hw_ops = {
4090 .get_tx_stats = iwl4965_mac_get_tx_stats, 4103 .get_tx_stats = iwl4965_mac_get_tx_stats,
4091 .conf_tx = iwl4965_mac_conf_tx, 4104 .conf_tx = iwl4965_mac_conf_tx,
4092 .reset_tsf = iwl4965_mac_reset_tsf, 4105 .reset_tsf = iwl4965_mac_reset_tsf,
4093 .beacon_update = iwl4965_mac_beacon_update,
4094 .bss_info_changed = iwl4965_bss_info_changed, 4106 .bss_info_changed = iwl4965_bss_info_changed,
4095 .ampdu_action = iwl4965_mac_ampdu_action, 4107 .ampdu_action = iwl4965_mac_ampdu_action,
4096 .hw_scan = iwl4965_mac_hw_scan 4108 .hw_scan = iwl4965_mac_hw_scan
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index ee953ca0c6a3..89b874ca6107 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1581,7 +1581,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1581 .conf_tx = rt2400pci_conf_tx, 1581 .conf_tx = rt2400pci_conf_tx,
1582 .get_tx_stats = rt2x00mac_get_tx_stats, 1582 .get_tx_stats = rt2x00mac_get_tx_stats,
1583 .get_tsf = rt2400pci_get_tsf, 1583 .get_tsf = rt2400pci_get_tsf,
1584 .beacon_update = rt2400pci_beacon_update,
1585 .tx_last_beacon = rt2400pci_tx_last_beacon, 1584 .tx_last_beacon = rt2400pci_tx_last_beacon,
1586}; 1585};
1587 1586
@@ -1601,6 +1600,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1601 .write_tx_data = rt2x00pci_write_tx_data, 1600 .write_tx_data = rt2x00pci_write_tx_data,
1602 .kick_tx_queue = rt2400pci_kick_tx_queue, 1601 .kick_tx_queue = rt2400pci_kick_tx_queue,
1603 .fill_rxdone = rt2400pci_fill_rxdone, 1602 .fill_rxdone = rt2400pci_fill_rxdone,
1603 .beacon_update = rt2400pci_beacon_update,
1604 .config_filter = rt2400pci_config_filter, 1604 .config_filter = rt2400pci_config_filter,
1605 .config_intf = rt2400pci_config_intf, 1605 .config_intf = rt2400pci_config_intf,
1606 .config_erp = rt2400pci_config_erp, 1606 .config_erp = rt2400pci_config_erp,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 0423c251c78e..a64bb18322e9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1875,7 +1875,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1875 .conf_tx = rt2x00mac_conf_tx, 1875 .conf_tx = rt2x00mac_conf_tx,
1876 .get_tx_stats = rt2x00mac_get_tx_stats, 1876 .get_tx_stats = rt2x00mac_get_tx_stats,
1877 .get_tsf = rt2500pci_get_tsf, 1877 .get_tsf = rt2500pci_get_tsf,
1878 .beacon_update = rt2500pci_beacon_update,
1879 .tx_last_beacon = rt2500pci_tx_last_beacon, 1878 .tx_last_beacon = rt2500pci_tx_last_beacon,
1880}; 1879};
1881 1880
@@ -1895,6 +1894,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1895 .write_tx_data = rt2x00pci_write_tx_data, 1894 .write_tx_data = rt2x00pci_write_tx_data,
1896 .kick_tx_queue = rt2500pci_kick_tx_queue, 1895 .kick_tx_queue = rt2500pci_kick_tx_queue,
1897 .fill_rxdone = rt2500pci_fill_rxdone, 1896 .fill_rxdone = rt2500pci_fill_rxdone,
1897 .beacon_update = rt2500pci_beacon_update,
1898 .config_filter = rt2500pci_config_filter, 1898 .config_filter = rt2500pci_config_filter,
1899 .config_intf = rt2500pci_config_intf, 1899 .config_intf = rt2500pci_config_intf,
1900 .config_erp = rt2500pci_config_erp, 1900 .config_erp = rt2500pci_config_erp,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 0dd1cb537b92..8ce1726d7508 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1775,7 +1775,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1775 .bss_info_changed = rt2x00mac_bss_info_changed, 1775 .bss_info_changed = rt2x00mac_bss_info_changed,
1776 .conf_tx = rt2x00mac_conf_tx, 1776 .conf_tx = rt2x00mac_conf_tx,
1777 .get_tx_stats = rt2x00mac_get_tx_stats, 1777 .get_tx_stats = rt2x00mac_get_tx_stats,
1778 .beacon_update = rt2500usb_beacon_update,
1779}; 1778};
1780 1779
1781static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { 1780static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1793,6 +1792,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1793 .get_tx_data_len = rt2500usb_get_tx_data_len, 1792 .get_tx_data_len = rt2500usb_get_tx_data_len,
1794 .kick_tx_queue = rt2500usb_kick_tx_queue, 1793 .kick_tx_queue = rt2500usb_kick_tx_queue,
1795 .fill_rxdone = rt2500usb_fill_rxdone, 1794 .fill_rxdone = rt2500usb_fill_rxdone,
1795 .beacon_update = rt2500usb_beacon_update,
1796 .config_filter = rt2500usb_config_filter, 1796 .config_filter = rt2500usb_config_filter,
1797 .config_intf = rt2500usb_config_intf, 1797 .config_intf = rt2500usb_config_intf,
1798 .config_erp = rt2500usb_config_erp, 1798 .config_erp = rt2500usb_config_erp,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c07d9ef383f0..9ad3ce43e6cd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -534,6 +534,8 @@ struct rt2x00lib_ops {
534 /* 534 /*
535 * Configuration handlers. 535 * Configuration handlers.
536 */ 536 */
537 int (*beacon_update) (struct ieee80211_hw *hw, struct sk_buff *bcn);
538
537 void (*config_filter) (struct rt2x00_dev *rt2x00dev, 539 void (*config_filter) (struct rt2x00_dev *rt2x00dev,
538 const unsigned int filter_flags); 540 const unsigned int filter_flags);
539 void (*config_intf) (struct rt2x00_dev *rt2x00dev, 541 void (*config_intf) (struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b48c04e80a38..1b7f87799a7e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -409,7 +409,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
409{ 409{
410 struct rt2x00_dev *rt2x00dev = data; 410 struct rt2x00_dev *rt2x00dev = data;
411 struct rt2x00_intf *intf = vif_to_intf(vif); 411 struct rt2x00_intf *intf = vif_to_intf(vif);
412 struct sk_buff *skb;
413 struct ieee80211_bss_conf conf; 412 struct ieee80211_bss_conf conf;
414 int delayed_flags; 413 int delayed_flags;
415 414
@@ -436,10 +435,11 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
436 return; 435 return;
437 436
438 if (delayed_flags & DELAYED_UPDATE_BEACON) { 437 if (delayed_flags & DELAYED_UPDATE_BEACON) {
439 skb = ieee80211_beacon_get(rt2x00dev->hw, vif); 438 struct ieee80211_if_conf conf;
440 if (skb && 439 conf.bssid = conf.ssid = NULL;
441 rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb)) 440 conf.ssid_len = 0;
442 dev_kfree_skb(skb); 441 conf.changed = IEEE80211_IFCC_BEACON;
442 rt2x00dev->ops->hw->config_interface(rt2x00dev->hw, vif, &conf);
443 } 443 }
444 444
445 if (delayed_flags & DELAYED_CONFIG_ERP) 445 if (delayed_flags & DELAYED_CONFIG_ERP)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 3a1fb6d47e5d..84b51f49175e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -348,6 +348,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
348{ 348{
349 struct rt2x00_dev *rt2x00dev = hw->priv; 349 struct rt2x00_dev *rt2x00dev = hw->priv;
350 struct rt2x00_intf *intf = vif_to_intf(vif); 350 struct rt2x00_intf *intf = vif_to_intf(vif);
351 struct sk_buff *beacon;
351 int status; 352 int status;
352 353
353 /* 354 /*
@@ -363,8 +364,11 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
363 * If the interface does not work in master mode, 364 * If the interface does not work in master mode,
364 * then the bssid value in the interface structure 365 * then the bssid value in the interface structure
365 * should now be set. 366 * should now be set.
367 *
368 * conf->bssid can be NULL if coming from the internal
369 * beacon update routine.
366 */ 370 */
367 if (conf->type != IEEE80211_IF_TYPE_AP) 371 if (conf->bssid && vif->type != IEEE80211_IF_TYPE_AP)
368 memcpy(&intf->bssid, conf->bssid, ETH_ALEN); 372 memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
369 373
370 spin_unlock(&intf->lock); 374 spin_unlock(&intf->lock);
@@ -375,17 +379,23 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
375 * values as arguments we make keep access to rt2x00_intf thread safe 379 * values as arguments we make keep access to rt2x00_intf thread safe
376 * even without the lock. 380 * even without the lock.
377 */ 381 */
378 rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); 382 rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, conf->bssid);
379 383
380 /* 384 /*
381 * We only need to initialize the beacon when master mode is enabled. 385 * We only need to initialize the beacon when in master/ibss mode.
382 */ 386 */
383 if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon) 387 if ((vif->type != IEEE80211_IF_TYPE_AP &&
388 vif->type != IEEE80211_IF_TYPE_IBSS) ||
389 !(conf->changed & IEEE80211_IFCC_BEACON))
384 return 0; 390 return 0;
385 391
386 status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, conf->beacon); 392 beacon = ieee80211_beacon_get(rt2x00dev->hw, vif);
393 if (!beacon)
394 return -ENOMEM;
395
396 status = rt2x00dev->ops->lib->beacon_update(rt2x00dev->hw, beacon);
387 if (status) 397 if (status)
388 dev_kfree_skb(conf->beacon); 398 dev_kfree_skb(beacon);
389 399
390 return status; 400 return status;
391} 401}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index bbf1048f6400..852d193a11a9 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2427,7 +2427,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2427 .conf_tx = rt2x00mac_conf_tx, 2427 .conf_tx = rt2x00mac_conf_tx,
2428 .get_tx_stats = rt2x00mac_get_tx_stats, 2428 .get_tx_stats = rt2x00mac_get_tx_stats,
2429 .get_tsf = rt61pci_get_tsf, 2429 .get_tsf = rt61pci_get_tsf,
2430 .beacon_update = rt61pci_beacon_update,
2431}; 2430};
2432 2431
2433static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { 2432static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -2449,6 +2448,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2449 .write_tx_data = rt2x00pci_write_tx_data, 2448 .write_tx_data = rt2x00pci_write_tx_data,
2450 .kick_tx_queue = rt61pci_kick_tx_queue, 2449 .kick_tx_queue = rt61pci_kick_tx_queue,
2451 .fill_rxdone = rt61pci_fill_rxdone, 2450 .fill_rxdone = rt61pci_fill_rxdone,
2451 .beacon_update = rt61pci_beacon_update,
2452 .config_filter = rt61pci_config_filter, 2452 .config_filter = rt61pci_config_filter,
2453 .config_intf = rt61pci_config_intf, 2453 .config_intf = rt61pci_config_intf,
2454 .config_erp = rt61pci_config_erp, 2454 .config_erp = rt61pci_config_erp,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 3ef318e098e7..657200972424 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2031,7 +2031,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2031 .conf_tx = rt2x00mac_conf_tx, 2031 .conf_tx = rt2x00mac_conf_tx,
2032 .get_tx_stats = rt2x00mac_get_tx_stats, 2032 .get_tx_stats = rt2x00mac_get_tx_stats,
2033 .get_tsf = rt73usb_get_tsf, 2033 .get_tsf = rt73usb_get_tsf,
2034 .beacon_update = rt73usb_beacon_update,
2035}; 2034};
2036 2035
2037static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { 2036static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2052,6 +2051,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2052 .get_tx_data_len = rt73usb_get_tx_data_len, 2051 .get_tx_data_len = rt73usb_get_tx_data_len,
2053 .kick_tx_queue = rt73usb_kick_tx_queue, 2052 .kick_tx_queue = rt73usb_kick_tx_queue,
2054 .fill_rxdone = rt73usb_fill_rxdone, 2053 .fill_rxdone = rt73usb_fill_rxdone,
2054 .beacon_update = rt73usb_beacon_update,
2055 .config_filter = rt73usb_config_filter, 2055 .config_filter = rt73usb_config_filter,
2056 .config_intf = rt73usb_config_intf, 2056 .config_intf = rt73usb_config_intf,
2057 .config_erp = rt73usb_config_erp, 2057 .config_erp = rt73usb_config_erp,
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 665f76af2fec..68e2749b2ce8 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -727,15 +727,19 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
727 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || 727 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT ||
728 mac->type == IEEE80211_IF_TYPE_IBSS) { 728 mac->type == IEEE80211_IF_TYPE_IBSS) {
729 associated = true; 729 associated = true;
730 if (conf->beacon) { 730 if (conf->changed & IEEE80211_IFCC_BEACON) {
731 r = zd_mac_config_beacon(hw, conf->beacon); 731 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
732
733 if (!beacon)
734 return -ENOMEM;
735 r = zd_mac_config_beacon(hw, beacon);
732 if (r < 0) 736 if (r < 0)
733 return r; 737 return r;
734 r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | 738 r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
735 hw->conf.beacon_int); 739 hw->conf.beacon_int);
736 if (r < 0) 740 if (r < 0)
737 return r; 741 return r;
738 kfree_skb(conf->beacon); 742 kfree_skb(beacon);
739 } 743 }
740 } else 744 } else
741 associated = is_valid_ether_addr(conf->bssid); 745 associated = is_valid_ether_addr(conf->bssid);
@@ -889,17 +893,6 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
889 } 893 }
890} 894}
891 895
892static int zd_op_beacon_update(struct ieee80211_hw *hw,
893 struct sk_buff *skb)
894{
895 struct zd_mac *mac = zd_hw_mac(hw);
896 zd_mac_config_beacon(hw, skb);
897 kfree_skb(skb);
898 zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
899 hw->conf.beacon_int);
900 return 0;
901}
902
903static const struct ieee80211_ops zd_ops = { 896static const struct ieee80211_ops zd_ops = {
904 .tx = zd_op_tx, 897 .tx = zd_op_tx,
905 .start = zd_op_start, 898 .start = zd_op_start,
@@ -910,7 +903,6 @@ static const struct ieee80211_ops zd_ops = {
910 .config_interface = zd_op_config_interface, 903 .config_interface = zd_op_config_interface,
911 .configure_filter = zd_op_configure_filter, 904 .configure_filter = zd_op_configure_filter,
912 .bss_info_changed = zd_op_bss_info_changed, 905 .bss_info_changed = zd_op_bss_info_changed,
913 .beacon_update = zd_op_beacon_update,
914}; 906};
915 907
916struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) 908struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9672a04c4f7b..47c072eab42c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -529,33 +529,38 @@ struct ieee80211_if_init_conf {
529}; 529};
530 530
531/** 531/**
532 * enum ieee80211_if_conf_change - interface config change flags
533 *
534 * @IEEE80211_IFCC_BSSID: The BSSID changed.
535 * @IEEE80211_IFCC_SSID: The SSID changed.
536 * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
537 * (currently AP and MESH only), use ieee80211_beacon_get().
538 */
539enum ieee80211_if_conf_change {
540 IEEE80211_IFCC_BSSID = BIT(0),
541 IEEE80211_IFCC_SSID = BIT(1),
542 IEEE80211_IFCC_BEACON = BIT(2),
543};
544
545/**
532 * struct ieee80211_if_conf - configuration of an interface 546 * struct ieee80211_if_conf - configuration of an interface
533 * 547 *
534 * @type: type of the interface. This is always the same as was specified in 548 * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
535 * &struct ieee80211_if_init_conf. The type of an interface never changes
536 * during the life of the interface; this field is present only for
537 * convenience.
538 * @bssid: BSSID of the network we are associated to/creating. 549 * @bssid: BSSID of the network we are associated to/creating.
539 * @ssid: used (together with @ssid_len) by drivers for hardware that 550 * @ssid: used (together with @ssid_len) by drivers for hardware that
540 * generate beacons independently. The pointer is valid only during the 551 * generate beacons independently. The pointer is valid only during the
541 * config_interface() call, so copy the value somewhere if you need 552 * config_interface() call, so copy the value somewhere if you need
542 * it. 553 * it.
543 * @ssid_len: length of the @ssid field. 554 * @ssid_len: length of the @ssid field.
544 * @beacon: beacon template. Valid only if @host_gen_beacon_template in
545 * &struct ieee80211_hw is set. The driver is responsible of freeing
546 * the sk_buff.
547 * @beacon_control: tx_control for the beacon template, this field is only
548 * valid when the @beacon field was set.
549 * 555 *
550 * This structure is passed to the config_interface() callback of 556 * This structure is passed to the config_interface() callback of
551 * &struct ieee80211_hw. 557 * &struct ieee80211_hw.
552 */ 558 */
553struct ieee80211_if_conf { 559struct ieee80211_if_conf {
554 int type; 560 u32 changed;
555 u8 *bssid; 561 u8 *bssid;
556 u8 *ssid; 562 u8 *ssid;
557 size_t ssid_len; 563 size_t ssid_len;
558 struct sk_buff *beacon;
559}; 564};
560 565
561/** 566/**
@@ -683,15 +688,6 @@ enum ieee80211_tkip_key_type {
683 * any particular flags. There are some exceptions to this rule, 688 * any particular flags. There are some exceptions to this rule,
684 * however, so you are advised to review these flags carefully. 689 * however, so you are advised to review these flags carefully.
685 * 690 *
686 * @IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE:
687 * The device only needs to be supplied with a beacon template.
688 * If you need the host to generate each beacon then don't use
689 * this flag and call ieee80211_beacon_get() when you need the
690 * next beacon frame. Note that if you set this flag, you must
691 * implement the set_tim() callback for powersave mode to work
692 * properly.
693 * This flag is only relevant for access-point mode.
694 *
695 * @IEEE80211_HW_RX_INCLUDES_FCS: 691 * @IEEE80211_HW_RX_INCLUDES_FCS:
696 * Indicates that received frames passed to the stack include 692 * Indicates that received frames passed to the stack include
697 * the FCS at the end. 693 * the FCS at the end.
@@ -1151,17 +1147,6 @@ enum ieee80211_ampdu_mlme_action {
1151 * function is optional if the firmware/hardware takes full care of 1147 * function is optional if the firmware/hardware takes full care of
1152 * TSF synchronization. 1148 * TSF synchronization.
1153 * 1149 *
1154 * @beacon_update: Setup beacon data for IBSS beacons. Unlike access point,
1155 * IBSS uses a fixed beacon frame which is configured using this
1156 * function.
1157 * If the driver returns success (0) from this callback, it owns
1158 * the skb. That means the driver is responsible to kfree_skb() it.
1159 * The control structure is not dynamically allocated. That means the
1160 * driver does not own the pointer and if it needs it somewhere
1161 * outside of the context of this function, it must copy it
1162 * somewhere else.
1163 * This handler is required only for IBSS mode.
1164 *
1165 * @tx_last_beacon: Determine whether the last IBSS beacon was sent by us. 1150 * @tx_last_beacon: Determine whether the last IBSS beacon was sent by us.
1166 * This is needed only for IBSS mode and the result of this function is 1151 * This is needed only for IBSS mode and the result of this function is
1167 * used to determine whether to reply to Probe Requests. 1152 * used to determine whether to reply to Probe Requests.
@@ -1219,8 +1204,6 @@ struct ieee80211_ops {
1219 struct ieee80211_tx_queue_stats *stats); 1204 struct ieee80211_tx_queue_stats *stats);
1220 u64 (*get_tsf)(struct ieee80211_hw *hw); 1205 u64 (*get_tsf)(struct ieee80211_hw *hw);
1221 void (*reset_tsf)(struct ieee80211_hw *hw); 1206 void (*reset_tsf)(struct ieee80211_hw *hw);
1222 int (*beacon_update)(struct ieee80211_hw *hw,
1223 struct sk_buff *skb);
1224 int (*tx_last_beacon)(struct ieee80211_hw *hw); 1207 int (*tx_last_beacon)(struct ieee80211_hw *hw);
1225 int (*ampdu_action)(struct ieee80211_hw *hw, 1208 int (*ampdu_action)(struct ieee80211_hw *hw,
1226 enum ieee80211_ampdu_mlme_action action, 1209 enum ieee80211_ampdu_mlme_action action,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ea0301025c15..8e7ba0e62cf5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -469,7 +469,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
469 469
470 kfree(old); 470 kfree(old);
471 471
472 return ieee80211_if_config_beacon(sdata->dev); 472 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
473} 473}
474 474
475static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 475static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -523,7 +523,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
523 synchronize_rcu(); 523 synchronize_rcu();
524 kfree(old); 524 kfree(old);
525 525
526 return ieee80211_if_config_beacon(dev); 526 return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
527} 527}
528 528
529/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ 529/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 2146c0c436d2..934c3ef4f0bc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -854,8 +854,7 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
854 854
855/* ieee80211.c */ 855/* ieee80211.c */
856int ieee80211_hw_config(struct ieee80211_local *local); 856int ieee80211_hw_config(struct ieee80211_local *local);
857int ieee80211_if_config(struct net_device *dev); 857int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
858int ieee80211_if_config_beacon(struct net_device *dev);
859void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 858void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
860u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, 859u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
861 struct ieee80211_ht_info *req_ht_cap, 860 struct ieee80211_ht_info *req_ht_cap,
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)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 64d710a88b86..61d7f81bf45e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2406,8 +2406,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2406 int res, rates, i, j; 2406 int res, rates, i, j;
2407 struct sk_buff *skb; 2407 struct sk_buff *skb;
2408 struct ieee80211_mgmt *mgmt; 2408 struct ieee80211_mgmt *mgmt;
2409 struct ieee80211_tx_info *control;
2410 struct rate_selection ratesel;
2411 u8 *pos; 2409 u8 *pos;
2412 struct ieee80211_sub_if_data *sdata; 2410 struct ieee80211_sub_if_data *sdata;
2413 struct ieee80211_supported_band *sband; 2411 struct ieee80211_supported_band *sband;
@@ -2425,7 +2423,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2425 local->ops->reset_tsf(local_to_hw(local)); 2423 local->ops->reset_tsf(local_to_hw(local));
2426 } 2424 }
2427 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); 2425 memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
2428 res = ieee80211_if_config(dev); 2426 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
2429 if (res) 2427 if (res)
2430 return res; 2428 return res;
2431 2429
@@ -2439,19 +2437,16 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2439 if (res) 2437 if (res)
2440 return res; 2438 return res;
2441 2439
2442 /* Set beacon template */ 2440 /* Build IBSS probe response */
2443 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 2441 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
2444 do { 2442 if (skb) {
2445 if (!skb)
2446 break;
2447
2448 skb_reserve(skb, local->hw.extra_tx_headroom); 2443 skb_reserve(skb, local->hw.extra_tx_headroom);
2449 2444
2450 mgmt = (struct ieee80211_mgmt *) 2445 mgmt = (struct ieee80211_mgmt *)
2451 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 2446 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
2452 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 2447 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2453 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 2448 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
2454 IEEE80211_STYPE_BEACON); 2449 IEEE80211_STYPE_PROBE_RESP);
2455 memset(mgmt->da, 0xff, ETH_ALEN); 2450 memset(mgmt->da, 0xff, ETH_ALEN);
2456 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 2451 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
2457 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 2452 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
@@ -2495,61 +2490,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2495 memcpy(pos, &bss->supp_rates[8], rates); 2490 memcpy(pos, &bss->supp_rates[8], rates);
2496 } 2491 }
2497 2492
2498 control = IEEE80211_SKB_CB(skb); 2493 ifsta->probe_resp = skb;
2499
2500 rate_control_get_rate(dev, sband, skb, &ratesel);
2501 if (ratesel.rate_idx < 0) {
2502 printk(KERN_DEBUG "%s: Failed to determine TX rate "
2503 "for IBSS beacon\n", dev->name);
2504 break;
2505 }
2506 control->control.vif = &sdata->vif;
2507 control->tx_rate_idx = ratesel.rate_idx;
2508 if (sdata->bss_conf.use_short_preamble &&
2509 sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
2510 control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
2511 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
2512 control->flags |= IEEE80211_TX_CTL_NO_ACK;
2513 control->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
2514 control->control.retry_limit = 1;
2515
2516 ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC);
2517 if (ifsta->probe_resp) {
2518 mgmt = (struct ieee80211_mgmt *)
2519 ifsta->probe_resp->data;
2520 mgmt->frame_control =
2521 IEEE80211_FC(IEEE80211_FTYPE_MGMT,
2522 IEEE80211_STYPE_PROBE_RESP);
2523 } else {
2524 printk(KERN_DEBUG "%s: Could not allocate ProbeResp "
2525 "template for IBSS\n", dev->name);
2526 }
2527
2528 if (local->ops->beacon_update &&
2529 local->ops->beacon_update(local_to_hw(local), skb) == 0) {
2530 printk(KERN_DEBUG "%s: Configured IBSS beacon "
2531 "template\n", dev->name);
2532 skb = NULL;
2533 }
2534
2535 rates = 0;
2536 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2537 for (i = 0; i < bss->supp_rates_len; i++) {
2538 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
2539 for (j = 0; j < sband->n_bitrates; j++)
2540 if (sband->bitrates[j].bitrate == bitrate)
2541 rates |= BIT(j);
2542 }
2543 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2544 2494
2545 ieee80211_sta_def_wmm_params(dev, bss, 1); 2495 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
2546 } while (0); 2496 }
2547 2497
2548 if (skb) { 2498 rates = 0;
2549 printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " 2499 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2550 "template\n", dev->name); 2500 for (i = 0; i < bss->supp_rates_len; i++) {
2551 dev_kfree_skb(skb); 2501 int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
2502 for (j = 0; j < sband->n_bitrates; j++)
2503 if (sband->bitrates[j].bitrate == bitrate)
2504 rates |= BIT(j);
2552 } 2505 }
2506 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2507
2508 ieee80211_sta_def_wmm_params(dev, bss, 1);
2553 2509
2554 ifsta->state = IEEE80211_IBSS_JOINED; 2510 ifsta->state = IEEE80211_IBSS_JOINED;
2555 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 2511 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
@@ -3333,7 +3289,7 @@ static void ieee80211_mesh_housekeeping(struct net_device *dev,
3333 3289
3334 free_plinks = mesh_plink_availables(sdata); 3290 free_plinks = mesh_plink_availables(sdata);
3335 if (free_plinks != sdata->u.sta.accepting_plinks) 3291 if (free_plinks != sdata->u.sta.accepting_plinks)
3336 ieee80211_if_config_beacon(dev); 3292 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3337 3293
3338 mod_timer(&ifsta->timer, jiffies + 3294 mod_timer(&ifsta->timer, jiffies +
3339 IEEE80211_MESH_HOUSEKEEPING_INTERVAL); 3295 IEEE80211_MESH_HOUSEKEEPING_INTERVAL);
@@ -3757,28 +3713,45 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len)
3757{ 3713{
3758 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3714 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3759 struct ieee80211_if_sta *ifsta; 3715 struct ieee80211_if_sta *ifsta;
3716 int res;
3760 3717
3761 if (len > IEEE80211_MAX_SSID_LEN) 3718 if (len > IEEE80211_MAX_SSID_LEN)
3762 return -EINVAL; 3719 return -EINVAL;
3763 3720
3764 ifsta = &sdata->u.sta; 3721 ifsta = &sdata->u.sta;
3765 3722
3766 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) 3723 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) {
3724 memset(ifsta->ssid, 0, sizeof(ifsta->ssid));
3725 memcpy(ifsta->ssid, ssid, len);
3726 ifsta->ssid_len = len;
3767 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; 3727 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3768 memcpy(ifsta->ssid, ssid, len); 3728
3769 memset(ifsta->ssid + len, 0, IEEE80211_MAX_SSID_LEN - len); 3729 res = 0;
3770 ifsta->ssid_len = len; 3730 /*
3731 * Hack! MLME code needs to be cleaned up to have different
3732 * entry points for configuration and internal selection change
3733 */
3734 if (netif_running(sdata->dev))
3735 res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
3736 if (res) {
3737 printk(KERN_DEBUG "%s: Failed to config new SSID to "
3738 "the low-level driver\n", dev->name);
3739 return res;
3740 }
3741 }
3771 3742
3772 if (len) 3743 if (len)
3773 ifsta->flags |= IEEE80211_STA_SSID_SET; 3744 ifsta->flags |= IEEE80211_STA_SSID_SET;
3774 else 3745 else
3775 ifsta->flags &= ~IEEE80211_STA_SSID_SET; 3746 ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3747
3776 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && 3748 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3777 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { 3749 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
3778 ifsta->ibss_join_req = jiffies; 3750 ifsta->ibss_join_req = jiffies;
3779 ifsta->state = IEEE80211_IBSS_SEARCH; 3751 ifsta->state = IEEE80211_IBSS_SEARCH;
3780 return ieee80211_sta_find_ibss(dev, ifsta); 3752 return ieee80211_sta_find_ibss(dev, ifsta);
3781 } 3753 }
3754
3782 return 0; 3755 return 0;
3783} 3756}
3784 3757
@@ -3804,7 +3777,12 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid)
3804 3777
3805 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { 3778 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
3806 memcpy(ifsta->bssid, bssid, ETH_ALEN); 3779 memcpy(ifsta->bssid, bssid, ETH_ALEN);
3807 res = ieee80211_if_config(dev); 3780 res = 0;
3781 /*
3782 * Hack! See also ieee80211_sta_set_ssid.
3783 */
3784 if (netif_running(sdata->dev))
3785 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3808 if (res) { 3786 if (res) {
3809 printk(KERN_DEBUG "%s: Failed to config new BSSID to " 3787 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3810 "the low-level driver\n", dev->name); 3788 "the low-level driver\n", dev->name);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a757dcc1208d..8843416e1460 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1788,17 +1788,17 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1788 struct ieee80211_vif *vif) 1788 struct ieee80211_vif *vif)
1789{ 1789{
1790 struct ieee80211_local *local = hw_to_local(hw); 1790 struct ieee80211_local *local = hw_to_local(hw);
1791 struct sk_buff *skb; 1791 struct sk_buff *skb = NULL;
1792 struct ieee80211_tx_info *info; 1792 struct ieee80211_tx_info *info;
1793 struct net_device *bdev; 1793 struct net_device *bdev;
1794 struct ieee80211_sub_if_data *sdata = NULL; 1794 struct ieee80211_sub_if_data *sdata = NULL;
1795 struct ieee80211_if_ap *ap = NULL; 1795 struct ieee80211_if_ap *ap = NULL;
1796 struct ieee80211_if_sta *ifsta = NULL;
1796 struct rate_selection rsel; 1797 struct rate_selection rsel;
1797 struct beacon_data *beacon; 1798 struct beacon_data *beacon;
1798 struct ieee80211_supported_band *sband; 1799 struct ieee80211_supported_band *sband;
1799 struct ieee80211_mgmt *mgmt; 1800 struct ieee80211_mgmt *mgmt;
1800 int *num_beacons; 1801 int *num_beacons;
1801 bool err = true;
1802 enum ieee80211_band band = local->hw.conf.channel->band; 1802 enum ieee80211_band band = local->hw.conf.channel->band;
1803 u8 *pos; 1803 u8 *pos;
1804 1804
@@ -1852,9 +1852,24 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1852 beacon->tail, beacon->tail_len); 1852 beacon->tail, beacon->tail_len);
1853 1853
1854 num_beacons = &ap->num_beacons; 1854 num_beacons = &ap->num_beacons;
1855 } else
1856 goto out;
1857 } else if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
1858 struct ieee80211_hdr *hdr;
1859 ifsta = &sdata->u.sta;
1855 1860
1856 err = false; 1861 if (!ifsta->probe_resp)
1857 } 1862 goto out;
1863
1864 skb = skb_copy(ifsta->probe_resp, GFP_ATOMIC);
1865 if (!skb)
1866 goto out;
1867
1868 hdr = (struct ieee80211_hdr *) skb->data;
1869 hdr->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1870 IEEE80211_STYPE_BEACON);
1871
1872 num_beacons = &ifsta->num_beacons;
1858 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 1873 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
1859 /* headroom, head length, tail length and maximum TIM length */ 1874 /* headroom, head length, tail length and maximum TIM length */
1860 skb = dev_alloc_skb(local->tx_headroom + 400); 1875 skb = dev_alloc_skb(local->tx_headroom + 400);
@@ -1881,17 +1896,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1881 mesh_mgmt_ies_add(skb, sdata->dev); 1896 mesh_mgmt_ies_add(skb, sdata->dev);
1882 1897
1883 num_beacons = &sdata->u.sta.num_beacons; 1898 num_beacons = &sdata->u.sta.num_beacons;
1884 1899 } else {
1885 err = false; 1900 WARN_ON(1);
1886 }
1887
1888 if (err) {
1889#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1890 if (net_ratelimit())
1891 printk(KERN_DEBUG "no beacon data avail for %s\n",
1892 bdev->name);
1893#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
1894 skb = NULL;
1895 goto out; 1901 goto out;
1896 } 1902 }
1897 1903
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index c041db9556c7..34fa8ed1e784 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -444,7 +444,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
444 memset(sdata->u.ap.ssid + len, 0, 444 memset(sdata->u.ap.ssid + len, 0,
445 IEEE80211_MAX_SSID_LEN - len); 445 IEEE80211_MAX_SSID_LEN - len);
446 sdata->u.ap.ssid_len = len; 446 sdata->u.ap.ssid_len = len;
447 return ieee80211_if_config(dev); 447 return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
448 } 448 }
449 return -EOPNOTSUPP; 449 return -EOPNOTSUPP;
450} 450}