aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-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
7 files changed, 56 insertions, 32 deletions
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,