diff mbox

cfg80211: add a timer for invalid user reg hints

Message ID 1301610698-3688-1-git-send-email-lrodriguez@atheros.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Luis Rodriguez March 31, 2011, 10:31 p.m. UTC
None
diff mbox

Patch

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 3332d5b..62d9ea1 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -42,6 +42,7 @@ 
 #include <linux/ctype.h>
 #include <linux/nl80211.h>
 #include <linux/platform_device.h>
+#include <linux/timer.h>
 #include <net/cfg80211.h>
 #include "core.h"
 #include "reg.h"
@@ -106,6 +107,10 @@  struct reg_beacon {
 static void reg_todo(struct work_struct *work);
 static DECLARE_WORK(reg_work, reg_todo);
 
+static struct timer_list reg_timer;
+static void reg_timeout_work(struct work_struct *work);
+static DECLARE_WORK(reg_timeout, reg_timeout_work);
+
 /* We keep a static world regulatory domain in case of the absence of CRDA */
 static const struct ieee80211_regdomain world_regdom = {
 	.n_reg_rules = 5,
@@ -1330,6 +1335,9 @@  static void reg_set_request_processed(void)
 		need_more_processing = true;
 	spin_unlock(&reg_requests_lock);
 
+	if (last_request->initiator == NL80211_REGDOM_SET_BY_USER)
+		del_timer_sync(&reg_timer);
+
 	if (need_more_processing)
 		schedule_work(&reg_work);
 }
@@ -1584,6 +1592,7 @@  int regulatory_hint_user(const char *alpha2)
 	request->initiator = NL80211_REGDOM_SET_BY_USER;
 
 	queue_regulatory_request(request);
+	mod_timer(&reg_timer, jiffies + msecs_to_jiffies(3142));
 
 	return 0;
 }
@@ -1787,7 +1796,6 @@  static void restore_regulatory_settings(bool reset_user)
 		regulatory_hint_user(user_alpha2);
 }
 
-
 void regulatory_hint_disconnect(void)
 {
 	REG_DBG_PRINT("All devices are disconnected, going to "
@@ -2125,6 +2133,18 @@  out:
 	mutex_unlock(&reg_mutex);
 }
 
+static void reg_timeout_work(struct work_struct *work)
+{
+	restore_regulatory_settings(true);
+}
+
+static void reg_set_failed_timer(unsigned long data)
+{
+	REG_DBG_PRINT("Timeout while waiting for CRDA to reply,"
+		      "restoring regulatory settings");
+	schedule_work(&reg_timeout);
+}
+
 int __init regulatory_init(void)
 {
 	int err = 0;
@@ -2137,6 +2157,7 @@  int __init regulatory_init(void)
 
 	spin_lock_init(&reg_requests_lock);
 	spin_lock_init(&reg_pending_beacons_lock);
+	setup_timer(&reg_timer, reg_set_failed_timer, (unsigned long) NULL);
 
 	cfg80211_regdomain = cfg80211_world_regdom;
 
@@ -2178,6 +2199,8 @@  void /* __init_or_exit */ regulatory_exit(void)
 	struct reg_beacon *reg_beacon, *btmp;
 
 	cancel_work_sync(&reg_work);
+	cancel_work_sync(&reg_timeout);
+	del_timer_sync(&reg_timer);
 
 	mutex_lock(&cfg80211_mutex);
 	mutex_lock(&reg_mutex);