aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-07 18:41:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:13:50 -0400
commite312c24cf8229f9b6e76dbfd5d99eefe21f4ac0a (patch)
tree79e3b967f3905716baef4bc73b4510543b38ceb5 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentd91b1ba37744bc7fb7524516be855c9fa81142e2 (diff)
iwlwifi: automatically adjust sleep level
Depending on required latency requested by pm_qos (via mac80211) we can automatically adjust the sleep state. Also, mac80211 has a user-visible dynamic sleep feature where we are supposed to stay awake after sending/receiving frames to better receive response frames to our packets, this can be integrated into the sleep command. Currently, and this patch doesn't change that yet, we default to using sleep level 1 if PS is enabled. With a module parameter to iwlcore, automatic adjustment to changing network latency requirements can be enabled -- this isn't yet the default due to requiring more testing. The goal is to enable automatic adjustment and then go into the deepest possible sleep state possible depending on the networking latency requirements. This patch does, however, enable IEEE80211_HW_SUPPORTS_DYNAMIC_PS to avoid the double-timer (one in software and one in the device) when transmitting -- the exact timeout may be ignored but that is not of big concern. Note also that we keep the hard-coded power indices around for thermal throttling -- the specification of that calls for using the specified power levels. Those can also be selected in debugfs to allow easier testing of such parameters. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c46
1 files changed, 2 insertions, 44 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 319df4ab7f1..2232b1794e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1606,7 +1606,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1606 set_bit(STATUS_READY, &priv->status); 1606 set_bit(STATUS_READY, &priv->status);
1607 wake_up_interruptible(&priv->wait_command_queue); 1607 wake_up_interruptible(&priv->wait_command_queue);
1608 1608
1609 iwl_power_update_mode(priv, 1); 1609 iwl_power_update_mode(priv, true);
1610 1610
1611 /* reassociate for ADHOC mode */ 1611 /* reassociate for ADHOC mode */
1612 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { 1612 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
@@ -2075,7 +2075,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2075 * If chain noise has already been run, then we need to enable 2075 * If chain noise has already been run, then we need to enable
2076 * power management here */ 2076 * power management here */
2077 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) 2077 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2078 iwl_power_update_mode(priv, 0); 2078 iwl_power_update_mode(priv, false);
2079 2079
2080 /* Enable Rx differential gain and sensitivity calibrations */ 2080 /* Enable Rx differential gain and sensitivity calibrations */
2081 iwl_chain_noise_reset(priv); 2081 iwl_chain_noise_reset(priv);
@@ -2565,47 +2565,6 @@ static ssize_t store_filter_flags(struct device *d,
2565static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 2565static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
2566 store_filter_flags); 2566 store_filter_flags);
2567 2567
2568static ssize_t store_power_level(struct device *d,
2569 struct device_attribute *attr,
2570 const char *buf, size_t count)
2571{
2572 struct iwl_priv *priv = dev_get_drvdata(d);
2573 int ret;
2574 unsigned long mode;
2575
2576
2577 mutex_lock(&priv->mutex);
2578
2579 ret = strict_strtoul(buf, 10, &mode);
2580 if (ret)
2581 goto out;
2582
2583 ret = iwl_power_set_user_mode(priv, mode);
2584 if (ret) {
2585 IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
2586 goto out;
2587 }
2588 ret = count;
2589
2590 out:
2591 mutex_unlock(&priv->mutex);
2592 return ret;
2593}
2594
2595static ssize_t show_power_level(struct device *d,
2596 struct device_attribute *attr, char *buf)
2597{
2598 struct iwl_priv *priv = dev_get_drvdata(d);
2599 int level = priv->power_data.power_mode;
2600 char *p = buf;
2601
2602 p += sprintf(p, "%d\n", level);
2603 return p - buf + 1;
2604}
2605
2606static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
2607 store_power_level);
2608
2609 2568
2610static ssize_t show_statistics(struct device *d, 2569static ssize_t show_statistics(struct device *d,
2611 struct device_attribute *attr, char *buf) 2570 struct device_attribute *attr, char *buf)
@@ -2698,7 +2657,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
2698static struct attribute *iwl_sysfs_entries[] = { 2657static struct attribute *iwl_sysfs_entries[] = {
2699 &dev_attr_flags.attr, 2658 &dev_attr_flags.attr,
2700 &dev_attr_filter_flags.attr, 2659 &dev_attr_filter_flags.attr,
2701 &dev_attr_power_level.attr,
2702 &dev_attr_statistics.attr, 2660 &dev_attr_statistics.attr,
2703 &dev_attr_temperature.attr, 2661 &dev_attr_temperature.attr,
2704 &dev_attr_tx_power.attr, 2662 &dev_attr_tx_power.attr,