aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-02-28 13:42:54 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-28 13:42:54 -0500
commitb95eddbb907538d5501d4d659056e987de64d978 (patch)
tree85e9385bc476992ce21bf3b4a34bcd627cc2e534 /net
parent5e038890b60c34267c99528f3cb0fc4d6c75d89d (diff)
parentcb664981607a6b5b3d670ad57bbda893b2528d96 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c23
-rw-r--r--net/wireless/reg.c10
2 files changed, 32 insertions, 1 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 57d5482b10fa..245dce969b31 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -222,6 +222,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
222 switch (vht_oper->chan_width) { 222 switch (vht_oper->chan_width) {
223 case IEEE80211_VHT_CHANWIDTH_USE_HT: 223 case IEEE80211_VHT_CHANWIDTH_USE_HT:
224 vht_chandef.width = chandef->width; 224 vht_chandef.width = chandef->width;
225 vht_chandef.center_freq1 = chandef->center_freq1;
225 break; 226 break;
226 case IEEE80211_VHT_CHANWIDTH_80MHZ: 227 case IEEE80211_VHT_CHANWIDTH_80MHZ:
227 vht_chandef.width = NL80211_CHAN_WIDTH_80; 228 vht_chandef.width = NL80211_CHAN_WIDTH_80;
@@ -271,6 +272,28 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
271 ret = 0; 272 ret = 0;
272 273
273out: 274out:
275 /*
276 * When tracking the current AP, don't do any further checks if the
277 * new chandef is identical to the one we're currently using for the
278 * connection. This keeps us from playing ping-pong with regulatory,
279 * without it the following can happen (for example):
280 * - connect to an AP with 80 MHz, world regdom allows 80 MHz
281 * - AP advertises regdom US
282 * - CRDA loads regdom US with 80 MHz prohibited (old database)
283 * - the code below detects an unsupported channel, downgrades, and
284 * we disconnect from the AP in the caller
285 * - disconnect causes CRDA to reload world regdomain and the game
286 * starts anew.
287 * (see https://bugzilla.kernel.org/show_bug.cgi?id=70881)
288 *
289 * It seems possible that there are still scenarios with CSA or real
290 * bandwidth changes where a this could happen, but those cases are
291 * less common and wouldn't completely prevent using the AP.
292 */
293 if (tracking &&
294 cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef))
295 return ret;
296
274 /* don't print the message below for VHT mismatch if VHT is disabled */ 297 /* don't print the message below for VHT mismatch if VHT is disabled */
275 if (ret & IEEE80211_STA_DISABLE_VHT) 298 if (ret & IEEE80211_STA_DISABLE_VHT)
276 vht_chandef = *chandef; 299 vht_chandef = *chandef;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4c50c21d6f52..f0541370e68e 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2373,6 +2373,7 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
2373int set_regdom(const struct ieee80211_regdomain *rd) 2373int set_regdom(const struct ieee80211_regdomain *rd)
2374{ 2374{
2375 struct regulatory_request *lr; 2375 struct regulatory_request *lr;
2376 bool user_reset = false;
2376 int r; 2377 int r;
2377 2378
2378 if (!reg_is_valid_request(rd->alpha2)) { 2379 if (!reg_is_valid_request(rd->alpha2)) {
@@ -2389,6 +2390,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2389 break; 2390 break;
2390 case NL80211_REGDOM_SET_BY_USER: 2391 case NL80211_REGDOM_SET_BY_USER:
2391 r = reg_set_rd_user(rd, lr); 2392 r = reg_set_rd_user(rd, lr);
2393 user_reset = true;
2392 break; 2394 break;
2393 case NL80211_REGDOM_SET_BY_DRIVER: 2395 case NL80211_REGDOM_SET_BY_DRIVER:
2394 r = reg_set_rd_driver(rd, lr); 2396 r = reg_set_rd_driver(rd, lr);
@@ -2402,8 +2404,14 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2402 } 2404 }
2403 2405
2404 if (r) { 2406 if (r) {
2405 if (r == -EALREADY) 2407 switch (r) {
2408 case -EALREADY:
2406 reg_set_request_processed(); 2409 reg_set_request_processed();
2410 break;
2411 default:
2412 /* Back to world regulatory in case of errors */
2413 restore_regulatory_settings(user_reset);
2414 }
2407 2415
2408 kfree(rd); 2416 kfree(rd);
2409 return r; 2417 return r;