mac80211: implement hardware offload for remain-on-channel

This allows drivers to support remain-on-channel
offload if they implement smarter timing or need
to use a device implementation like iwlwifi.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b6db237..8acba45 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1264,7 +1264,7 @@
 {
 	struct ieee80211_sub_if_data *sdata;
 	int count = 0;
-	bool working = false, scanning = false;
+	bool working = false, scanning = false, hw_roc = false;
 	struct ieee80211_work *wk;
 	unsigned int led_trig_start = 0, led_trig_stop = 0;
 
@@ -1308,6 +1308,9 @@
 		local->scan_sdata->vif.bss_conf.idle = false;
 	}
 
+	if (local->hw_roc_channel)
+		hw_roc = true;
+
 	list_for_each_entry(sdata, &local->interfaces, list) {
 		if (sdata->old_idle == sdata->vif.bss_conf.idle)
 			continue;
@@ -1316,7 +1319,7 @@
 		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE);
 	}
 
-	if (working || scanning)
+	if (working || scanning || hw_roc)
 		led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK;
 	else
 		led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK;
@@ -1328,6 +1331,8 @@
 
 	ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop);
 
+	if (hw_roc)
+		return ieee80211_idle_off(local, "hw remain-on-channel");
 	if (working)
 		return ieee80211_idle_off(local, "working");
 	if (scanning)