diff options
Diffstat (limited to 'net/mac80211/main.c')
| -rw-r--r-- | net/mac80211/main.c | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0d2d94881f1f..06c33b68d8e5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
| 18 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
| 19 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
| 20 | #include <linux/wireless.h> | ||
| 21 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
| 22 | #include <linux/bitmap.h> | 21 | #include <linux/bitmap.h> |
| 23 | #include <linux/pm_qos_params.h> | 22 | #include <linux/pm_qos_params.h> |
| @@ -32,7 +31,12 @@ | |||
| 32 | #include "led.h" | 31 | #include "led.h" |
| 33 | #include "cfg.h" | 32 | #include "cfg.h" |
| 34 | #include "debugfs.h" | 33 | #include "debugfs.h" |
| 35 | #include "debugfs_netdev.h" | 34 | |
| 35 | |||
| 36 | bool ieee80211_disable_40mhz_24ghz; | ||
| 37 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | ||
| 38 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | ||
| 39 | "Disable 40MHz support in the 2.4GHz band"); | ||
| 36 | 40 | ||
| 37 | void ieee80211_configure_filter(struct ieee80211_local *local) | 41 | void ieee80211_configure_filter(struct ieee80211_local *local) |
| 38 | { | 42 | { |
| @@ -102,6 +106,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
| 102 | if (scan_chan) { | 106 | if (scan_chan) { |
| 103 | chan = scan_chan; | 107 | chan = scan_chan; |
| 104 | channel_type = NL80211_CHAN_NO_HT; | 108 | channel_type = NL80211_CHAN_NO_HT; |
| 109 | } else if (local->tmp_channel) { | ||
| 110 | chan = scan_chan = local->tmp_channel; | ||
| 111 | channel_type = local->tmp_channel_type; | ||
| 105 | } else { | 112 | } else { |
| 106 | chan = local->oper_channel; | 113 | chan = local->oper_channel; |
| 107 | channel_type = local->oper_channel_type; | 114 | channel_type = local->oper_channel_type; |
| @@ -114,6 +121,18 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
| 114 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | 121 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; |
| 115 | } | 122 | } |
| 116 | 123 | ||
| 124 | if (!conf_is_ht(&local->hw.conf)) { | ||
| 125 | /* | ||
| 126 | * mac80211.h documents that this is only valid | ||
| 127 | * when the channel is set to an HT type, and | ||
| 128 | * that otherwise STATIC is used. | ||
| 129 | */ | ||
| 130 | local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC; | ||
| 131 | } else if (local->hw.conf.smps_mode != local->smps_mode) { | ||
| 132 | local->hw.conf.smps_mode = local->smps_mode; | ||
| 133 | changed |= IEEE80211_CONF_CHANGE_SMPS; | ||
| 134 | } | ||
| 135 | |||
| 117 | if (scan_chan) | 136 | if (scan_chan) |
| 118 | power = chan->max_power; | 137 | power = chan->max_power; |
| 119 | else | 138 | else |
| @@ -173,7 +192,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
| 173 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 192 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
| 174 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | 193 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; |
| 175 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | 194 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
| 176 | sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; | 195 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
| 177 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 196 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
| 178 | sdata->vif.bss_conf.bssid = zero; | 197 | sdata->vif.bss_conf.bssid = zero; |
| 179 | } else { | 198 | } else { |
| @@ -195,7 +214,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
| 195 | } | 214 | } |
| 196 | 215 | ||
| 197 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 216 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
| 198 | if (local->quiescing || !netif_running(sdata->dev) || | 217 | if (local->quiescing || !ieee80211_sdata_running(sdata) || |
| 199 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { | 218 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { |
| 200 | sdata->vif.bss_conf.enable_beacon = false; | 219 | sdata->vif.bss_conf.enable_beacon = false; |
| 201 | } else { | 220 | } else { |
| @@ -223,8 +242,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
| 223 | } | 242 | } |
| 224 | } | 243 | } |
| 225 | 244 | ||
| 226 | drv_bss_info_changed(local, &sdata->vif, | 245 | drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); |
| 227 | &sdata->vif.bss_conf, changed); | ||
| 228 | } | 246 | } |
| 229 | 247 | ||
| 230 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 248 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
| @@ -299,6 +317,16 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
| 299 | } | 317 | } |
| 300 | EXPORT_SYMBOL(ieee80211_restart_hw); | 318 | EXPORT_SYMBOL(ieee80211_restart_hw); |
| 301 | 319 | ||
| 320 | static void ieee80211_recalc_smps_work(struct work_struct *work) | ||
| 321 | { | ||
| 322 | struct ieee80211_local *local = | ||
| 323 | container_of(work, struct ieee80211_local, recalc_smps); | ||
| 324 | |||
| 325 | mutex_lock(&local->iflist_mtx); | ||
| 326 | ieee80211_recalc_smps(local, NULL); | ||
| 327 | mutex_unlock(&local->iflist_mtx); | ||
| 328 | } | ||
| 329 | |||
| 302 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 330 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
| 303 | const struct ieee80211_ops *ops) | 331 | const struct ieee80211_ops *ops) |
| 304 | { | 332 | { |
| @@ -333,9 +361,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
| 333 | WIPHY_FLAG_4ADDR_STATION; | 361 | WIPHY_FLAG_4ADDR_STATION; |
| 334 | wiphy->privid = mac80211_wiphy_privid; | 362 | wiphy->privid = mac80211_wiphy_privid; |
| 335 | 363 | ||
| 336 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | 364 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss); |
| 337 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - | ||
| 338 | sizeof(struct cfg80211_bss); | ||
| 339 | 365 | ||
| 340 | local = wiphy_priv(wiphy); | 366 | local = wiphy_priv(wiphy); |
| 341 | 367 | ||
| @@ -358,6 +384,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
| 358 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 384 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
| 359 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 385 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
| 360 | local->user_power_level = -1; | 386 | local->user_power_level = -1; |
| 387 | local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
| 388 | local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
| 361 | 389 | ||
| 362 | INIT_LIST_HEAD(&local->interfaces); | 390 | INIT_LIST_HEAD(&local->interfaces); |
| 363 | mutex_init(&local->iflist_mtx); | 391 | mutex_init(&local->iflist_mtx); |
| @@ -369,9 +397,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
| 369 | 397 | ||
| 370 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 398 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
| 371 | 399 | ||
| 400 | ieee80211_work_init(local); | ||
| 401 | |||
| 372 | INIT_WORK(&local->restart_work, ieee80211_restart_work); | 402 | INIT_WORK(&local->restart_work, ieee80211_restart_work); |
| 373 | 403 | ||
| 374 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); | 404 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
| 405 | INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work); | ||
| 406 | local->smps_mode = IEEE80211_SMPS_OFF; | ||
| 375 | 407 | ||
| 376 | INIT_WORK(&local->dynamic_ps_enable_work, | 408 | INIT_WORK(&local->dynamic_ps_enable_work, |
| 377 | ieee80211_dynamic_ps_enable_work); | 409 | ieee80211_dynamic_ps_enable_work); |
| @@ -461,6 +493,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 461 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 493 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
| 462 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; | 494 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; |
| 463 | 495 | ||
| 496 | WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) | ||
| 497 | && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK), | ||
| 498 | "U-APSD not supported with HW_PS_NULLFUNC_STACK\n"); | ||
| 499 | |||
| 464 | /* | 500 | /* |
| 465 | * Calculate scan IE length -- we need this to alloc | 501 | * Calculate scan IE length -- we need this to alloc |
| 466 | * memory and to subtract from the driver limit. It | 502 | * memory and to subtract from the driver limit. It |
| @@ -522,8 +558,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 522 | 558 | ||
| 523 | debugfs_hw_add(local); | 559 | debugfs_hw_add(local); |
| 524 | 560 | ||
| 561 | /* | ||
| 562 | * if the driver doesn't specify a max listen interval we | ||
| 563 | * use 5 which should be a safe default | ||
| 564 | */ | ||
| 525 | if (local->hw.max_listen_interval == 0) | 565 | if (local->hw.max_listen_interval == 0) |
| 526 | local->hw.max_listen_interval = 1; | 566 | local->hw.max_listen_interval = 5; |
| 527 | 567 | ||
| 528 | local->hw.conf.listen_interval = local->hw.max_listen_interval; | 568 | local->hw.conf.listen_interval = local->hw.max_listen_interval; |
| 529 | 569 | ||
| @@ -674,11 +714,19 @@ static int __init ieee80211_init(void) | |||
| 674 | 714 | ||
| 675 | ret = rc80211_pid_init(); | 715 | ret = rc80211_pid_init(); |
| 676 | if (ret) | 716 | if (ret) |
| 677 | return ret; | 717 | goto err_pid; |
| 678 | 718 | ||
| 679 | ieee80211_debugfs_netdev_init(); | 719 | ret = ieee80211_iface_init(); |
| 720 | if (ret) | ||
| 721 | goto err_netdev; | ||
| 680 | 722 | ||
| 681 | return 0; | 723 | return 0; |
| 724 | err_netdev: | ||
| 725 | rc80211_pid_exit(); | ||
| 726 | err_pid: | ||
| 727 | rc80211_minstrel_exit(); | ||
| 728 | |||
| 729 | return ret; | ||
| 682 | } | 730 | } |
| 683 | 731 | ||
| 684 | static void __exit ieee80211_exit(void) | 732 | static void __exit ieee80211_exit(void) |
| @@ -695,7 +743,7 @@ static void __exit ieee80211_exit(void) | |||
| 695 | if (mesh_allocated) | 743 | if (mesh_allocated) |
| 696 | ieee80211s_stop(); | 744 | ieee80211s_stop(); |
| 697 | 745 | ||
| 698 | ieee80211_debugfs_netdev_exit(); | 746 | ieee80211_iface_exit(); |
| 699 | } | 747 | } |
| 700 | 748 | ||
| 701 | 749 | ||
