diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 3 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 25 | ||||
-rw-r--r-- | net/mac80211/main.c | 29 | ||||
-rw-r--r-- | net/mac80211/scan.c | 12 | ||||
-rw-r--r-- | net/mac80211/util.c | 3 | ||||
-rw-r--r-- | net/mac80211/wext.c | 14 |
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 | ||
878 | int ieee80211_hw_config(struct ieee80211_local *local); | 878 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); |
879 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); | 879 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
880 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 880 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
881 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 881 | void 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 | ||
200 | int ieee80211_hw_config(struct ieee80211_local *local) | 200 | int 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 | ||
995 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | 995 | static int ieee80211_ioctl_giwpower(struct net_device *dev, |