On Tue, May 27, 2014 at 1:30 PM, Emmanuel Grumbach <egrumbach@xxxxxxxxx> wrote: >>> >>> It looks like your patch allows both: >>> >>> iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); >>> >>> and >>> >>> iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); >>> >>> I don't know whether that's a problem. > > I'd expect enable to be false... But I might have got lost in > mac80211's PS code... Can you check the value of enable? Thanks > Anyway - I want to call the cam one. IOW, I want to disable power save > completely. This is what is causing trouble. > We want to add a frame on the ring, and since the NIC is asleep, we > schedule a wakeup of the NIC so that it can fetch the packet when it > wakes up... But it doesn't wake up... > Now - This is firmware / hardware related... which means that there > isn't much I can do for this old device. > Bottom line, I guess we want to disable power save here. > If you can bisect this, this can be really helpful. This might allow > us to keep the feature. I doubt I can bisect -- the trigger was a new AP, not a new kernel. I can't exactly cut the AP in half :) Pre-suspend, i.e., working: [ 20.949900] enabled = 1, wowlan = 0 [ 20.950177] enabled = 1, wowlan = 0 [ 21.614016] enabled = 1, wowlan = 0 [ 21.614658] enabled = 1, wowlan = 0 [ 42.667586] enabled = 0, wowlan = 0 [ 42.672514] enabled = 1, wowlan = 0 [ 53.088165] fuse init (API version 7.23) [ 53.102082] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts [ 53.130945] SELinux: initialized (dev fusectl, type fusectl), uses genfs_contexts [ 85.627558] enabled = 0, wowlan = 0 [ 85.631686] enabled = 1, wowlan = 0 [ 134.649346] e1000e: em1 NIC Link is Down [ 137.682277] wlan0: deauthenticating from 02:c6:26:cc:b4:c7 by local choice (Reason: 3=DEAUTH_LEAVING) [ 137.682780] enabled = 0, wowlan = 0 [ 137.693889] enabled = 0, wowlan = 0 Post-suspend, i.e., not working: [ 144.406303] enabled = 1, wowlan = 0 [ 144.406496] enabled = 1, wowlan = 0 [ 145.026827] enabled = 1, wowlan = 0 [ 145.028211] enabled = 1, wowlan = 0 [ 165.688632] enabled = 0, wowlan = 0 [ 165.689960] enabled = 0, wowlan = 0 [ 165.693988] enabled = 1, wowlan = 0 [ 165.694245] enabled = 1, wowlan = 0 [ 208.641426] enabled = 0, wowlan = 0 [ 208.641786] enabled = 0, wowlan = 0 [ 208.647499] enabled = 1, wowlan = 0 [ 208.647639] enabled = 1, wowlan = 0 [ 271.435558] enabled = 0, wowlan = 0 [ 271.435767] enabled = 0, wowlan = 0 [ 271.440125] enabled = 1, wowlan = 0 [ 271.440405] enabled = 1, wowlan = 0 With even more instrumentation added, I did get a glitch before suspend/resume, but it came with more than two power setting updates. Logs and patch attached, complete with call stacks. Is it possible that part of the problem is that the firmware doesn't like being spammed with power config changes so frequently? --Andy
Attachment:
iwl_stall.txt.xz
Description: application/xz
commit 5225b6b3256c399d29de1e0db1915e07005516e7 Author: Andy Lutomirski <luto@xxxxxxxxxxxxxx> Date: Tue May 27 10:06:09 2014 -0700 iwlwifi pm hack diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index b4e6141..5d94162 100644 --- a/drivers/net/wireless/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c @@ -288,10 +288,15 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; int dtimper; + printk(KERN_INFO "enabled = %d, wowlan = %d\n", (int)enabled, (int)priv->wowlan); + dump_stack(); + dtimper = priv->hw->conf.ps_dtim_period ?: 1; if (priv->wowlan) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); + if (!enabled) + iwl_power_sleep_cam_cmd(priv, cmd); else if (!priv->lib->no_idle_support && priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); @@ -299,9 +304,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, /* in thermal throttling low power state */ iwl_static_sleep_cmd(priv, cmd, iwl_tt_current_power_mode(priv), dtimper); - } else if (!enabled) - iwl_power_sleep_cam_cmd(priv, cmd); - else if (priv->power_data.debug_sleep_level_override >= 0) + } else if (priv->power_data.debug_sleep_level_override >= 0) iwl_static_sleep_cmd(priv, cmd, priv->power_data.debug_sleep_level_override, dtimper);