@@ -106,6 +106,9 @@ struct reg_beacon {
static void reg_todo(struct work_struct *work);
static DECLARE_WORK(reg_work, reg_todo);
+static void reg_timeout_work(struct work_struct *work);
+static DECLARE_DELAYED_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 +1333,9 @@ static void reg_set_request_processed(void)
need_more_processing = true;
spin_unlock(®_requests_lock);
+ if (last_request->initiator == NL80211_REGDOM_SET_BY_USER)
+ cancel_delayed_work_sync(®_timeout);
+
if (need_more_processing)
schedule_work(®_work);
}
@@ -1584,6 +1590,7 @@ int regulatory_hint_user(const char *alpha2)
request->initiator = NL80211_REGDOM_SET_BY_USER;
queue_regulatory_request(request);
+ schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
return 0;
}
@@ -1787,7 +1794,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 +2131,13 @@ out:
mutex_unlock(®_mutex);
}
+static void reg_timeout_work(struct work_struct *work)
+{
+ REG_DBG_PRINT("Timeout while waiting for CRDA to reply,"
+ "restoring regulatory settings");
+ restore_regulatory_settings(true);
+}
+
int __init regulatory_init(void)
{
int err = 0;
@@ -2178,6 +2191,7 @@ void /* __init_or_exit */ regulatory_exit(void)
struct reg_beacon *reg_beacon, *btmp;
cancel_work_sync(®_work);
+ cancel_delayed_work_sync(®_timeout);
mutex_lock(&cfg80211_mutex);
mutex_lock(®_mutex);