diff options
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/reg.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 7b1a89b20ebf..2714379ce2d6 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -106,6 +106,9 @@ struct reg_beacon { | |||
106 | static void reg_todo(struct work_struct *work); | 106 | static void reg_todo(struct work_struct *work); |
107 | static DECLARE_WORK(reg_work, reg_todo); | 107 | static DECLARE_WORK(reg_work, reg_todo); |
108 | 108 | ||
109 | static void reg_timeout_work(struct work_struct *work); | ||
110 | static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work); | ||
111 | |||
109 | /* We keep a static world regulatory domain in case of the absence of CRDA */ | 112 | /* We keep a static world regulatory domain in case of the absence of CRDA */ |
110 | static const struct ieee80211_regdomain world_regdom = { | 113 | static const struct ieee80211_regdomain world_regdom = { |
111 | .n_reg_rules = 5, | 114 | .n_reg_rules = 5, |
@@ -1330,6 +1333,9 @@ static void reg_set_request_processed(void) | |||
1330 | need_more_processing = true; | 1333 | need_more_processing = true; |
1331 | spin_unlock(®_requests_lock); | 1334 | spin_unlock(®_requests_lock); |
1332 | 1335 | ||
1336 | if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) | ||
1337 | cancel_delayed_work_sync(®_timeout); | ||
1338 | |||
1333 | if (need_more_processing) | 1339 | if (need_more_processing) |
1334 | schedule_work(®_work); | 1340 | schedule_work(®_work); |
1335 | } | 1341 | } |
@@ -1440,8 +1446,17 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
1440 | r = __regulatory_hint(wiphy, reg_request); | 1446 | r = __regulatory_hint(wiphy, reg_request); |
1441 | /* This is required so that the orig_* parameters are saved */ | 1447 | /* This is required so that the orig_* parameters are saved */ |
1442 | if (r == -EALREADY && wiphy && | 1448 | if (r == -EALREADY && wiphy && |
1443 | wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) | 1449 | wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { |
1444 | wiphy_update_regulatory(wiphy, initiator); | 1450 | wiphy_update_regulatory(wiphy, initiator); |
1451 | return; | ||
1452 | } | ||
1453 | |||
1454 | /* | ||
1455 | * We only time out user hints, given that they should be the only | ||
1456 | * source of bogus requests. | ||
1457 | */ | ||
1458 | if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER) | ||
1459 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); | ||
1445 | } | 1460 | } |
1446 | 1461 | ||
1447 | /* | 1462 | /* |
@@ -2169,6 +2184,13 @@ out: | |||
2169 | mutex_unlock(®_mutex); | 2184 | mutex_unlock(®_mutex); |
2170 | } | 2185 | } |
2171 | 2186 | ||
2187 | static void reg_timeout_work(struct work_struct *work) | ||
2188 | { | ||
2189 | REG_DBG_PRINT("Timeout while waiting for CRDA to reply, " | ||
2190 | "restoring regulatory settings"); | ||
2191 | restore_regulatory_settings(true); | ||
2192 | } | ||
2193 | |||
2172 | int __init regulatory_init(void) | 2194 | int __init regulatory_init(void) |
2173 | { | 2195 | { |
2174 | int err = 0; | 2196 | int err = 0; |
@@ -2222,6 +2244,7 @@ void /* __init_or_exit */ regulatory_exit(void) | |||
2222 | struct reg_beacon *reg_beacon, *btmp; | 2244 | struct reg_beacon *reg_beacon, *btmp; |
2223 | 2245 | ||
2224 | cancel_work_sync(®_work); | 2246 | cancel_work_sync(®_work); |
2247 | cancel_delayed_work_sync(®_timeout); | ||
2225 | 2248 | ||
2226 | mutex_lock(&cfg80211_mutex); | 2249 | mutex_lock(&cfg80211_mutex); |
2227 | mutex_lock(®_mutex); | 2250 | mutex_lock(®_mutex); |