On Thursday 28 July 2011 00:23:00 you wrote: > Does the following work? It has been applied upstream and will > probably be part of v3.1-rc1.
Short version: Yes it works, but the patch did not apply to the curren linux-source package. Long Version: I tried to apply the patch, but it seemed to be for a different version than that of linux-source-3.0.0 version 3.0.0-1, so I had to apply it by hand (not using git that is). See below for my diff (). Then I configured and compiled the kernel with make localmodconfig make clean make -j 3 KDEB_PKGVERSION=3.0.0-mac80211.1 deb-pkg and installed it with dpkg -i linux-image-3.0.0_3.0.0-mac80211.1_amd64.deb. (It looks like I choose a wrong name for the version here because the installation didn't do what I hoped -- to have a separate entry in the boot loader -- and I had to remove linux-image-3.0.0-1-amd64 for it to work out.) Then I rebooted into runlevel 1 and tried to suspend a few times by writing "mem\n" to /sys/power/state. It never failed. BTW: Here is a workaround, for those with the same problem and installed pm-utils package. Add the following line to a file in /etc/pm/config.d (e.g. iwlagn): SUSPEND_MODULES="iwlagn" Kind regards, Florian.
diff -Ntaur linux-source-3.0.0-orig//net/mac80211/pm.c linux-source-3.0.0/net/mac80211/pm.c --- linux-source-3.0.0-orig//net/mac80211/pm.c 2011-07-22 04:17:23.000000000 +0200 +++ linux-source-3.0.0/net/mac80211/pm.c 2011-07-28 09:12:00.303443535 +0200 @@ -12,6 +12,9 @@ struct ieee80211_sub_if_data *sdata; struct sta_info *sta; + if (!local->open_count) + goto suspend; + ieee80211_scan_cancel(local); if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { diff -Ntaur linux-source-3.0.0-orig//net/mac80211/util.c linux-source-3.0.0/net/mac80211/util.c --- linux-source-3.0.0-orig//net/mac80211/util.c 2011-07-22 04:17:23.000000000 +0200 +++ linux-source-3.0.0/net/mac80211/util.c 2011-07-28 09:23:56.442994666 +0200 @@ -1146,26 +1146,36 @@ } #endif - /* restart hardware */ - if (local->open_count) { - /* - * Upon resume hardware can sometimes be goofy due to - * various platform / driver / bus issues, so restarting - * the device may at times not work immediately. Propagate - * the error. - */ - res = drv_start(local); - if (res) { - WARN(local->suspended, "Hardware became unavailable " - "upon resume. This could be a software issue " - "prior to suspend or a hardware issue.\n"); - return res; - } + /* setup fragmentation threshold */ + drv_set_frag_threshold(local, hw->wiphy->frag_threshold); + + /* setup RTS threshold */ + drv_set_rts_threshold(local, hw->wiphy->rts_threshold); + + /* reset coverage class */ + drv_set_coverage_class(local, hw->wiphy->coverage_class); - ieee80211_led_radio(local, true); - ieee80211_mod_tpt_led_trig(local, - IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); + /* everything else happens only if HW was up & running */ + if (!local->open_count) + goto wake_up; + + /* + * Upon resume hardware can sometimes be goofy due to + * various platform / driver / bus issues, so restarting + * the device may at times not work immediately. Propagate + * the error. + */ + res = drv_start(local); + if (res) { + WARN(local->suspended, "Hardware became unavailable " + "upon resume. This could be a software issue " + "prior to suspend or a hardware issue.\n"); + return res; } + + ieee80211_led_radio(local, true); + ieee80211_mod_tpt_led_trig(local, + IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); /* add interfaces */ list_for_each_entry(sdata, &local->interfaces, list) { @@ -1190,12 +1200,6 @@ } mutex_unlock(&local->sta_mtx); - /* setup fragmentation threshold */ - drv_set_frag_threshold(local, hw->wiphy->frag_threshold); - - /* setup RTS threshold */ - drv_set_rts_threshold(local, hw->wiphy->rts_threshold); - /* reconfigure hardware */ ieee80211_hw_config(local, ~0);