aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/adm8211.c3
-rw-r--r--drivers/net/wireless/ath5k/base.c7
-rw-r--r--drivers/net/wireless/ath9k/main.c4
-rw-r--r--drivers/net/wireless/b43/main.c3
-rw-r--r--drivers/net/wireless/b43legacy/main.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c7
-rw-r--r--drivers/net/wireless/libertas_tf/main.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--drivers/net/wireless/p54/p54common.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c3
-rw-r--r--drivers/net/wireless/rtl8180_dev.c3
-rw-r--r--drivers/net/wireless/rtl8187_dev.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c4
-rw-r--r--include/net/mac80211.h30
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/iface.c25
-rw-r--r--net/mac80211/main.c29
-rw-r--r--net/mac80211/scan.c12
-rw-r--r--net/mac80211/util.c3
-rw-r--r--net/mac80211/wext.c14
24 files changed, 116 insertions, 60 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 6e18c9d36787..9a1e0c514c08 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1314,9 +1314,10 @@ static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len)
1314 return 0; 1314 return 0;
1315} 1315}
1316 1316
1317static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 1317static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
1318{ 1318{
1319 struct adm8211_priv *priv = dev->priv; 1319 struct adm8211_priv *priv = dev->priv;
1320 struct ieee80211_conf *conf = &dev->conf;
1320 int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 1321 int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
1321 1322
1322 if (channel != priv->channel) { 1323 if (channel != priv->channel) {
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 9e47d727e220..fcd688765d04 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -219,8 +219,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
219 struct ieee80211_if_init_conf *conf); 219 struct ieee80211_if_init_conf *conf);
220static void ath5k_remove_interface(struct ieee80211_hw *hw, 220static void ath5k_remove_interface(struct ieee80211_hw *hw,
221 struct ieee80211_if_init_conf *conf); 221 struct ieee80211_if_init_conf *conf);
222static int ath5k_config(struct ieee80211_hw *hw, 222static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
223 struct ieee80211_conf *conf);
224static int ath5k_config_interface(struct ieee80211_hw *hw, 223static int ath5k_config_interface(struct ieee80211_hw *hw,
225 struct ieee80211_vif *vif, 224 struct ieee80211_vif *vif,
226 struct ieee80211_if_conf *conf); 225 struct ieee80211_if_conf *conf);
@@ -2780,10 +2779,10 @@ end:
2780 * TODO: Phy disable/diversity etc 2779 * TODO: Phy disable/diversity etc
2781 */ 2780 */
2782static int 2781static int
2783ath5k_config(struct ieee80211_hw *hw, 2782ath5k_config(struct ieee80211_hw *hw, u32 changed)
2784 struct ieee80211_conf *conf)
2785{ 2783{
2786 struct ath5k_softc *sc = hw->priv; 2784 struct ath5k_softc *sc = hw->priv;
2785 struct ieee80211_conf *conf = &hw->conf;
2787 2786
2788 sc->bintval = conf->beacon_int; 2787 sc->bintval = conf->beacon_int;
2789 sc->power_level = conf->power_level; 2788 sc->power_level = conf->power_level;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 5e087c92a6d9..f49910799ede 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1230,11 +1230,11 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1230 __func__, error); 1230 __func__, error);
1231} 1231}
1232 1232
1233static int ath9k_config(struct ieee80211_hw *hw, 1233static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1234 struct ieee80211_conf *conf)
1235{ 1234{
1236 struct ath_softc *sc = hw->priv; 1235 struct ath_softc *sc = hw->priv;
1237 struct ieee80211_channel *curchan = hw->conf.channel; 1236 struct ieee80211_channel *curchan = hw->conf.channel;
1237 struct ieee80211_conf *conf = &hw->conf;
1238 int pos; 1238 int pos;
1239 1239
1240 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n", 1240 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 6b85428b0e1d..2e81af1022e4 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3320,11 +3320,12 @@ init_failure:
3320 return err; 3320 return err;
3321} 3321}
3322 3322
3323static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 3323static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3324{ 3324{
3325 struct b43_wl *wl = hw_to_b43_wl(hw); 3325 struct b43_wl *wl = hw_to_b43_wl(hw);
3326 struct b43_wldev *dev; 3326 struct b43_wldev *dev;
3327 struct b43_phy *phy; 3327 struct b43_phy *phy;
3328 struct ieee80211_conf *conf = &hw->conf;
3328 unsigned long flags; 3329 unsigned long flags;
3329 int antenna; 3330 int antenna;
3330 int err = 0; 3331 int err = 0;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 867f01ce45c7..793cc396562f 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2557,11 +2557,12 @@ init_failure:
2557} 2557}
2558 2558
2559static int b43legacy_op_dev_config(struct ieee80211_hw *hw, 2559static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2560 struct ieee80211_conf *conf) 2560 u32 changed)
2561{ 2561{
2562 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 2562 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2563 struct b43legacy_wldev *dev; 2563 struct b43legacy_wldev *dev;
2564 struct b43legacy_phy *phy; 2564 struct b43legacy_phy *phy;
2565 struct ieee80211_conf *conf = &hw->conf;
2565 unsigned long flags; 2566 unsigned long flags;
2566 unsigned int new_phymode = 0xFFFF; 2567 unsigned int new_phymode = 0xFFFF;
2567 int antenna_tx; 2568 int antenna_tx;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e6695e80fb53..79a24410dd0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2734,10 +2734,11 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
2734 * be set inappropriately and the driver currently sets the hardware up to 2734 * be set inappropriately and the driver currently sets the hardware up to
2735 * use it whenever needed. 2735 * use it whenever needed.
2736 */ 2736 */
2737static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 2737static int iwl4965_mac_config(struct ieee80211_hw *hw, u32 changed)
2738{ 2738{
2739 struct iwl_priv *priv = hw->priv; 2739 struct iwl_priv *priv = hw->priv;
2740 const struct iwl_channel_info *ch_info; 2740 const struct iwl_channel_info *ch_info;
2741 struct ieee80211_conf *conf = &hw->conf;
2741 unsigned long flags; 2742 unsigned long flags;
2742 int ret = 0; 2743 int ret = 0;
2743 u16 channel; 2744 u16 channel;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d3a2966d9181..b1464c71ea0a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6415,7 +6415,7 @@ static void iwl3945_bg_abort_scan(struct work_struct *work)
6415 mutex_unlock(&priv->mutex); 6415 mutex_unlock(&priv->mutex);
6416} 6416}
6417 6417
6418static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); 6418static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
6419 6419
6420static void iwl3945_bg_scan_completed(struct work_struct *work) 6420static void iwl3945_bg_scan_completed(struct work_struct *work)
6421{ 6421{
@@ -6428,7 +6428,7 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
6428 return; 6428 return;
6429 6429
6430 if (test_bit(STATUS_CONF_PENDING, &priv->status)) 6430 if (test_bit(STATUS_CONF_PENDING, &priv->status))
6431 iwl3945_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw)); 6431 iwl3945_mac_config(priv->hw, 0);
6432 6432
6433 ieee80211_scan_completed(priv->hw); 6433 ieee80211_scan_completed(priv->hw);
6434 6434
@@ -6616,10 +6616,11 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
6616 * be set inappropriately and the driver currently sets the hardware up to 6616 * be set inappropriately and the driver currently sets the hardware up to
6617 * use it whenever needed. 6617 * use it whenever needed.
6618 */ 6618 */
6619static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 6619static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
6620{ 6620{
6621 struct iwl3945_priv *priv = hw->priv; 6621 struct iwl3945_priv *priv = hw->priv;
6622 const struct iwl3945_channel_info *ch_info; 6622 const struct iwl3945_channel_info *ch_info;
6623 struct ieee80211_conf *conf = &hw->conf;
6623 unsigned long flags; 6624 unsigned long flags;
6624 int ret = 0; 6625 int ret = 0;
6625 6626
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index feff945ad856..241ddcfa352e 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -354,9 +354,11 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
354 priv->vif = NULL; 354 priv->vif = NULL;
355} 355}
356 356
357static int lbtf_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 357static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
358{ 358{
359 struct lbtf_private *priv = hw->priv; 359 struct lbtf_private *priv = hw->priv;
360 struct ieee80211_conf *conf = &hw->conf;
361
360 if (conf->channel->center_freq != priv->cur_freq) { 362 if (conf->channel->center_freq != priv->cur_freq) {
361 priv->cur_freq = conf->channel->center_freq; 363 priv->cur_freq = conf->channel->center_freq;
362 lbtf_set_channel(priv, conf->channel->hw_value); 364 lbtf_set_channel(priv, conf->channel->hw_value);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 3f236b546683..e2aeef8de707 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -359,10 +359,10 @@ static void mac80211_hwsim_beacon(unsigned long arg)
359} 359}
360 360
361 361
362static int mac80211_hwsim_config(struct ieee80211_hw *hw, 362static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
363 struct ieee80211_conf *conf)
364{ 363{
365 struct mac80211_hwsim_data *data = hw->priv; 364 struct mac80211_hwsim_data *data = hw->priv;
365 struct ieee80211_conf *conf = &hw->conf;
366 366
367 printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n", 367 printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
368 wiphy_name(hw->wiphy), __func__, 368 wiphy_name(hw->wiphy), __func__,
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index b3e75eb4d5ba..b3c297ed00cd 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -1192,10 +1192,11 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
1192 p54_set_filter(dev, 0, NULL); 1192 p54_set_filter(dev, 0, NULL);
1193} 1193}
1194 1194
1195static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 1195static int p54_config(struct ieee80211_hw *dev, u32 changed)
1196{ 1196{
1197 int ret; 1197 int ret;
1198 struct p54_common *priv = dev->priv; 1198 struct p54_common *priv = dev->priv;
1199 struct ieee80211_conf *conf = &dev->conf;
1199 1200
1200 mutex_lock(&priv->conf_mutex); 1201 mutex_lock(&priv->conf_mutex);
1201 priv->rx_antenna = 2; /* automatic */ 1202 priv->rx_antenna = 2; /* automatic */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 1359a3768404..8ec8f7e9ec64 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -997,7 +997,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
997 struct ieee80211_if_init_conf *conf); 997 struct ieee80211_if_init_conf *conf);
998void rt2x00mac_remove_interface(struct ieee80211_hw *hw, 998void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
999 struct ieee80211_if_init_conf *conf); 999 struct ieee80211_if_init_conf *conf);
1000int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); 1000int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
1001int rt2x00mac_config_interface(struct ieee80211_hw *hw, 1001int rt2x00mac_config_interface(struct ieee80211_hw *hw,
1002 struct ieee80211_vif *vif, 1002 struct ieee80211_vif *vif,
1003 struct ieee80211_if_conf *conf); 1003 struct ieee80211_if_conf *conf);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9e0472bd1edf..697806cf94e2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1245,7 +1245,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
1245 /* 1245 /*
1246 * Reconfigure device. 1246 * Reconfigure device.
1247 */ 1247 */
1248 retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf); 1248 retval = rt2x00mac_config(rt2x00dev->hw, ~0);
1249 if (retval) 1249 if (retval)
1250 goto exit; 1250 goto exit;
1251 1251
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 2c6cc5c374ff..da7b49a364ff 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -335,9 +335,10 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
335} 335}
336EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); 336EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
337 337
338int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 338int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
339{ 339{
340 struct rt2x00_dev *rt2x00dev = hw->priv; 340 struct rt2x00_dev *rt2x00dev = hw->priv;
341 struct ieee80211_conf *conf = &hw->conf;
341 int radio_on; 342 int radio_on;
342 int status; 343 int status;
343 344
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 9de8f57486df..e8d22393797f 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -692,9 +692,10 @@ static void rtl8180_remove_interface(struct ieee80211_hw *dev,
692 priv->vif = NULL; 692 priv->vif = NULL;
693} 693}
694 694
695static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 695static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
696{ 696{
697 struct rtl8180_priv *priv = dev->priv; 697 struct rtl8180_priv *priv = dev->priv;
698 struct ieee80211_conf *conf = &dev->conf;
698 699
699 priv->rf->set_chan(dev, conf); 700 priv->rf->set_chan(dev, conf);
700 701
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 9ceae9017f86..2c69ab37c650 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -873,9 +873,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
873 mutex_unlock(&priv->conf_mutex); 873 mutex_unlock(&priv->conf_mutex);
874} 874}
875 875
876static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 876static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
877{ 877{
878 struct rtl8187_priv *priv = dev->priv; 878 struct rtl8187_priv *priv = dev->priv;
879 struct ieee80211_conf *conf = &dev->conf;
879 u32 reg; 880 u32 reg;
880 881
881 mutex_lock(&priv->conf_mutex); 882 mutex_lock(&priv->conf_mutex);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index de45509d757e..6c3e21887fc8 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -743,9 +743,11 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
743 zd_write_mac_addr(&mac->chip, NULL); 743 zd_write_mac_addr(&mac->chip, NULL);
744} 744}
745 745
746static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) 746static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
747{ 747{
748 struct zd_mac *mac = zd_hw_mac(hw); 748 struct zd_mac *mac = zd_hw_mac(hw);
749 struct ieee80211_conf *conf = &hw->conf;
750
749 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); 751 return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
750} 752}
751 753
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5f28b7f89887..34e8569b59bb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -464,12 +464,32 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
464#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME()) 464#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
465 465
466/** 466/**
467 * enum ieee80211_conf_changed - denotes which configuration changed
468 *
469 * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed
470 * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed
471 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
472 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
473 * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
474 * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
475 * @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed
476 */
477enum ieee80211_conf_changed {
478 IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
479 IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),
480 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
481 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),
482 IEEE80211_CONF_CHANGE_PS = BIT(4),
483 IEEE80211_CONF_CHANGE_POWER = BIT(5),
484 IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
485};
486
487/**
467 * struct ieee80211_conf - configuration of the device 488 * struct ieee80211_conf - configuration of the device
468 * 489 *
469 * This struct indicates how the driver shall configure the hardware. 490 * This struct indicates how the driver shall configure the hardware.
470 * 491 *
471 * @radio_enabled: when zero, driver is required to switch off the radio. 492 * @radio_enabled: when zero, driver is required to switch off the radio.
472 * TODO make a flag
473 * @beacon_int: beacon interval (TODO make interface config) 493 * @beacon_int: beacon interval (TODO make interface config)
474 * @listen_interval: listen interval in units of beacon interval 494 * @listen_interval: listen interval in units of beacon interval
475 * @flags: configuration flags defined above 495 * @flags: configuration flags defined above
@@ -479,13 +499,13 @@ static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
479 * @channel: the channel to tune to 499 * @channel: the channel to tune to
480 */ 500 */
481struct ieee80211_conf { 501struct ieee80211_conf {
482 int radio_enabled;
483
484 int beacon_int; 502 int beacon_int;
485 u16 listen_interval;
486 u32 flags; 503 u32 flags;
487 int power_level; 504 int power_level;
488 505
506 u16 listen_interval;
507 bool radio_enabled;
508
489 struct ieee80211_channel *channel; 509 struct ieee80211_channel *channel;
490 510
491 struct ieee80211_sta_ht_cap ht_cap; 511 struct ieee80211_sta_ht_cap ht_cap;
@@ -1214,7 +1234,7 @@ struct ieee80211_ops {
1214 struct ieee80211_if_init_conf *conf); 1234 struct ieee80211_if_init_conf *conf);
1215 void (*remove_interface)(struct ieee80211_hw *hw, 1235 void (*remove_interface)(struct ieee80211_hw *hw,
1216 struct ieee80211_if_init_conf *conf); 1236 struct ieee80211_if_init_conf *conf);
1217 int (*config)(struct ieee80211_hw *hw, struct ieee80211_conf *conf); 1237 int (*config)(struct ieee80211_hw *hw, u32 changed);
1218 int (*config_interface)(struct ieee80211_hw *hw, 1238 int (*config_interface)(struct ieee80211_hw *hw,
1219 struct ieee80211_vif *vif, 1239 struct ieee80211_vif *vif,
1220 struct ieee80211_if_conf *conf); 1240 struct ieee80211_if_conf *conf);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a5dea617aab3..8ea30902d5db 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -394,7 +394,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
394 */ 394 */
395 if (params->interval) { 395 if (params->interval) {
396 sdata->local->hw.conf.beacon_int = params->interval; 396 sdata->local->hw.conf.beacon_int = params->interval;
397 ieee80211_hw_config(sdata->local); 397 ieee80211_hw_config(sdata->local,
398 IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
398 /* 399 /*
399 * We updated some parameter so if below bails out 400 * We updated some parameter so if below bails out
400 * it's not an error. 401 * it's not an error.
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 88015838a63c..1deb787ff8dc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -875,7 +875,7 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
875} 875}
876 876
877 877
878int ieee80211_hw_config(struct ieee80211_local *local); 878int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
879int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); 879int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
880void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 880void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
881void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 881void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8336fee68d3e..df28c5f7c9c0 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -65,7 +65,7 @@ static int ieee80211_open(struct net_device *dev)
65 struct ieee80211_if_init_conf conf; 65 struct ieee80211_if_init_conf conf;
66 u32 changed = 0; 66 u32 changed = 0;
67 int res; 67 int res;
68 bool need_hw_reconfig = 0; 68 u32 hw_reconf_flags = 0;
69 u8 null_addr[ETH_ALEN] = {0}; 69 u8 null_addr[ETH_ALEN] = {0};
70 70
71 /* fail early if user set an invalid address */ 71 /* fail early if user set an invalid address */
@@ -152,7 +152,8 @@ static int ieee80211_open(struct net_device *dev)
152 res = local->ops->start(local_to_hw(local)); 152 res = local->ops->start(local_to_hw(local));
153 if (res) 153 if (res)
154 goto err_del_bss; 154 goto err_del_bss;
155 need_hw_reconfig = 1; 155 /* we're brought up, everything changes */
156 hw_reconf_flags = ~0;
156 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 157 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
157 } 158 }
158 159
@@ -198,8 +199,10 @@ static int ieee80211_open(struct net_device *dev)
198 199
199 /* must be before the call to ieee80211_configure_filter */ 200 /* must be before the call to ieee80211_configure_filter */
200 local->monitors++; 201 local->monitors++;
201 if (local->monitors == 1) 202 if (local->monitors == 1) {
202 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; 203 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
204 hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
205 }
203 206
204 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 207 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
205 local->fif_fcsfail++; 208 local->fif_fcsfail++;
@@ -279,8 +282,8 @@ static int ieee80211_open(struct net_device *dev)
279 atomic_inc(&local->iff_promiscs); 282 atomic_inc(&local->iff_promiscs);
280 283
281 local->open_count++; 284 local->open_count++;
282 if (need_hw_reconfig) { 285 if (hw_reconf_flags) {
283 ieee80211_hw_config(local); 286 ieee80211_hw_config(local, hw_reconf_flags);
284 /* 287 /*
285 * set default queue parameters so drivers don't 288 * set default queue parameters so drivers don't
286 * need to initialise the hardware if the hardware 289 * need to initialise the hardware if the hardware
@@ -322,6 +325,7 @@ static int ieee80211_stop(struct net_device *dev)
322 struct ieee80211_local *local = sdata->local; 325 struct ieee80211_local *local = sdata->local;
323 struct ieee80211_if_init_conf conf; 326 struct ieee80211_if_init_conf conf;
324 struct sta_info *sta; 327 struct sta_info *sta;
328 u32 hw_reconf_flags = 0;
325 329
326 /* 330 /*
327 * Stop TX on this interface first. 331 * Stop TX on this interface first.
@@ -405,8 +409,10 @@ static int ieee80211_stop(struct net_device *dev)
405 } 409 }
406 410
407 local->monitors--; 411 local->monitors--;
408 if (local->monitors == 0) 412 if (local->monitors == 0) {
409 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; 413 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
414 hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
415 }
410 416
411 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) 417 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
412 local->fif_fcsfail--; 418 local->fif_fcsfail--;
@@ -504,8 +510,15 @@ static int ieee80211_stop(struct net_device *dev)
504 510
505 tasklet_disable(&local->tx_pending_tasklet); 511 tasklet_disable(&local->tx_pending_tasklet);
506 tasklet_disable(&local->tasklet); 512 tasklet_disable(&local->tasklet);
513
514 /* no reconfiguring after stop! */
515 hw_reconf_flags = 0;
507 } 516 }
508 517
518 /* do after stop to avoid reconfiguring when we stop anyway */
519 if (hw_reconf_flags)
520 ieee80211_hw_config(local, hw_reconf_flags);
521
509 return 0; 522 return 0;
510} 523}
511 524
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 07f812755e55..c936017f6d48 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -197,31 +197,34 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
197 &sdata->vif, &conf); 197 &sdata->vif, &conf);
198} 198}
199 199
200int ieee80211_hw_config(struct ieee80211_local *local) 200int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
201{ 201{
202 struct ieee80211_channel *chan; 202 struct ieee80211_channel *chan;
203 int ret = 0; 203 int ret = 0;
204 int power;
204 205
205 if (local->sw_scanning) 206 if (local->sw_scanning)
206 chan = local->scan_channel; 207 chan = local->scan_channel;
207 else 208 else
208 chan = local->oper_channel; 209 chan = local->oper_channel;
209 210
210 local->hw.conf.channel = chan; 211 if (chan != local->hw.conf.channel) {
212 local->hw.conf.channel = chan;
213 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
214 }
215
211 216
212 if (!local->hw.conf.power_level) 217 if (!local->hw.conf.power_level)
213 local->hw.conf.power_level = chan->max_power; 218 power = chan->max_power;
214 else 219 else
215 local->hw.conf.power_level = min(chan->max_power, 220 power = min(chan->max_power, local->hw.conf.power_level);
216 local->hw.conf.power_level); 221 if (local->hw.conf.power_level != power) {
217 222 changed |= IEEE80211_CONF_CHANGE_POWER;
218#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 223 local->hw.conf.power_level = power;
219 printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", 224 }
220 wiphy_name(local->hw.wiphy), chan->center_freq);
221#endif
222 225
223 if (local->open_count) { 226 if (changed && local->open_count) {
224 ret = local->ops->config(local_to_hw(local), &local->hw.conf); 227 ret = local->ops->config(local_to_hw(local), changed);
225 /* 228 /*
226 * HW reconfiguration should never fail, the driver has told 229 * HW reconfiguration should never fail, the driver has told
227 * us what it can support so it should live up to that promise. 230 * us what it can support so it should live up to that promise.
@@ -672,7 +675,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
672 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 675 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
673 local->short_retry_limit = 7; 676 local->short_retry_limit = 7;
674 local->long_retry_limit = 4; 677 local->long_retry_limit = 4;
675 local->hw.conf.radio_enabled = 1; 678 local->hw.conf.radio_enabled = true;
676 679
677 INIT_LIST_HEAD(&local->interfaces); 680 INIT_LIST_HEAD(&local->interfaces);
678 681
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 0989b1c062e3..7372d7abb8c0 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -448,12 +448,17 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
448 448
449 if (local->hw_scanning) { 449 if (local->hw_scanning) {
450 local->hw_scanning = false; 450 local->hw_scanning = false;
451 ieee80211_hw_config(local); 451 /*
452 * Somebody might have requested channel change during scan
453 * that we won't have acted upon, try now. ieee80211_hw_config
454 * will set the flag based on actual changes.
455 */
456 ieee80211_hw_config(local, 0);
452 goto done; 457 goto done;
453 } 458 }
454 459
455 local->sw_scanning = false; 460 local->sw_scanning = false;
456 ieee80211_hw_config(local); 461 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
457 462
458 netif_tx_lock_bh(local->mdev); 463 netif_tx_lock_bh(local->mdev);
459 netif_addr_lock(local->mdev); 464 netif_addr_lock(local->mdev);
@@ -540,7 +545,8 @@ void ieee80211_scan_work(struct work_struct *work)
540 545
541 if (!skip) { 546 if (!skip) {
542 local->scan_channel = chan; 547 local->scan_channel = chan;
543 if (ieee80211_hw_config(local)) 548 if (ieee80211_hw_config(local,
549 IEEE80211_CONF_CHANGE_CHANNEL))
544 skip = 1; 550 skip = 1;
545 } 551 }
546 552
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9941a60a2327..3288c3de67ca 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -645,7 +645,8 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
645 if (local->sw_scanning || local->hw_scanning) 645 if (local->sw_scanning || local->hw_scanning)
646 ret = 0; 646 ret = 0;
647 else 647 else
648 ret = ieee80211_hw_config(local); 648 ret = ieee80211_hw_config(
649 local, IEEE80211_CONF_CHANGE_CHANNEL);
649 650
650 rate_control_clear(local); 651 rate_control_clear(local);
651 } 652 }
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index a3af15141244..94c4b35eeb14 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -656,7 +656,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
656 union iwreq_data *data, char *extra) 656 union iwreq_data *data, char *extra)
657{ 657{
658 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 658 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
659 bool need_reconfig = 0; 659 u32 reconf_flags = 0;
660 int new_power_level; 660 int new_power_level;
661 661
662 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) 662 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
@@ -680,17 +680,17 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
680 680
681 if (local->hw.conf.power_level != new_power_level) { 681 if (local->hw.conf.power_level != new_power_level) {
682 local->hw.conf.power_level = new_power_level; 682 local->hw.conf.power_level = new_power_level;
683 need_reconfig = 1; 683 reconf_flags |= IEEE80211_CONF_CHANGE_POWER;
684 } 684 }
685 685
686 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { 686 if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
687 local->hw.conf.radio_enabled = !(data->txpower.disabled); 687 local->hw.conf.radio_enabled = !(data->txpower.disabled);
688 need_reconfig = 1; 688 reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
689 ieee80211_led_radio(local, local->hw.conf.radio_enabled); 689 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
690 } 690 }
691 691
692 if (need_reconfig) 692 if (reconf_flags)
693 ieee80211_hw_config(local); 693 ieee80211_hw_config(local, reconf_flags);
694 694
695 return 0; 695 return 0;
696} 696}
@@ -976,7 +976,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
976 976
977 if (wrq->disabled) { 977 if (wrq->disabled) {
978 conf->flags &= ~IEEE80211_CONF_PS; 978 conf->flags &= ~IEEE80211_CONF_PS;
979 return ieee80211_hw_config(local); 979 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
980 } 980 }
981 981
982 switch (wrq->flags & IW_POWER_MODE) { 982 switch (wrq->flags & IW_POWER_MODE) {
@@ -989,7 +989,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
989 return -EINVAL; 989 return -EINVAL;
990 } 990 }
991 991
992 return ieee80211_hw_config(local); 992 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
993} 993}
994 994
995static int ieee80211_ioctl_giwpower(struct net_device *dev, 995static int ieee80211_ioctl_giwpower(struct net_device *dev,