summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@redhat.com>2013-08-01 08:49:55 -0400
committerJosh Boyer <jwboyer@redhat.com>2013-08-01 08:50:16 -0400
commit5481645f3ccf95c1c6f22c844a541e7a970bfa7f (patch)
treed2d71b387846e54f2454fa10c1c715e1cbe43f5b
parentc35d85bd25d1673fa355e99055352b0141a3c1ef (diff)
downloadkernel-5481645f3ccf95c1c6f22c844a541e7a970bfa7f.tar.gz
kernel-5481645f3ccf95c1c6f22c844a541e7a970bfa7f.tar.xz
kernel-5481645f3ccf95c1c6f22c844a541e7a970bfa7f.zip
Fix mac80211 connection issues (rhbz 981445)
-rw-r--r--kernel.spec11
-rw-r--r--mac80211-continue-using-disabled-channels-while-connected.patch43
-rw-r--r--mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch32
-rw-r--r--mac80211-ignore-HT-primary-channel-while-connected.patch121
4 files changed, 207 insertions, 0 deletions
diff --git a/kernel.spec b/kernel.spec
index 2fdf118a3..51bb6e7d0 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -757,6 +757,11 @@ Patch25072: HID-Revert-Revert-HID-Fix-logitech-dj-missing-Unifying-device-issue.
#rhbz 977053
Patch25073: iwl4965-reset-firmware-after-rfkill-off.patch
+#rhbz 981445
+Patch25074: mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch
+Patch25075: mac80211-ignore-HT-primary-channel-while-connected.patch
+Patch25076: mac80211-continue-using-disabled-channels-while-connected.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1466,6 +1471,11 @@ ApplyPatch HID-Revert-Revert-HID-Fix-logitech-dj-missing-Unifying-device-issue.p
#rhbz 977053
ApplyPatch iwl4965-reset-firmware-after-rfkill-off.patch
+#rhbz 981445
+ApplyPatch mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch
+ApplyPatch mac80211-ignore-HT-primary-channel-while-connected.patch
+ApplyPatch mac80211-continue-using-disabled-channels-while-connected.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2263,6 +2273,7 @@ fi
# || ||
%changelog
* Thu Aug 01 2013 Josh Boyer <jwboyer@redhat.com>
+- Fix mac80211 connection issues (rhbz 981445)
- Fix firmware issues with iwl4965 and rfkill (rhbz 977053)
- Drop hid-logitech-dj patch that was breaking enumeration (rhbz 989138)
diff --git a/mac80211-continue-using-disabled-channels-while-connected.patch b/mac80211-continue-using-disabled-channels-while-connected.patch
new file mode 100644
index 000000000..91dd1d7db
--- /dev/null
+++ b/mac80211-continue-using-disabled-channels-while-connected.patch
@@ -0,0 +1,43 @@
+From ddfe49b42d8ad4bfdf92d63d4a74f162660d878d Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 31 Jul 2013 18:52:03 +0000
+Subject: mac80211: continue using disabled channels while connected
+
+In case the AP has different regulatory information than we do,
+it can happen that we connect to an AP based on e.g. the world
+roaming regulatory data, and then update our database with the
+AP's country information disables the channel the AP is using.
+If this happens on an HT AP, the bandwidth tracking code will
+hit the WARN_ON() and disconnect. Since that's not very useful,
+ignore the channel-disable flag in bandwidth tracking.
+
+Cc: stable@vger.kernel.org
+Reported-by: Chris Wright <chrisw@sous-sol.org>
+Tested-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 077a953..cc9e02d 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -335,8 +335,17 @@ out:
+ if (ret & IEEE80211_STA_DISABLE_VHT)
+ vht_chandef = *chandef;
+
++ /*
++ * Ignore the DISABLED flag when we're already connected and only
++ * tracking the APs beacon for bandwidth changes - otherwise we
++ * might get disconnected here if we connect to an AP, update our
++ * regulatory information based on the AP's country IE and the
++ * information we have is wrong/outdated and disables the channel
++ * that we're actually using for the connection to the AP.
++ */
+ while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
+- IEEE80211_CHAN_DISABLED)) {
++ tracking ? 0 :
++ IEEE80211_CHAN_DISABLED)) {
+ if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
+ ret = IEEE80211_STA_DISABLE_HT |
+ IEEE80211_STA_DISABLE_VHT;
+--
+cgit v0.9.2
diff --git a/mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch b/mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch
new file mode 100644
index 000000000..49115f969
--- /dev/null
+++ b/mac80211-fix-infinite-loop-in-ieee80211_determine_chantype.patch
@@ -0,0 +1,32 @@
+From b56e4b857c5210e848bfb80e074e5756a36cd523 Mon Sep 17 00:00:00 2001
+From: Chris Wright <chrisw@sous-sol.org>
+Date: Wed, 31 Jul 2013 19:12:24 +0000
+Subject: mac80211: fix infinite loop in ieee80211_determine_chantype
+
+Commit "3d9646d mac80211: fix channel selection bug" introduced a possible
+infinite loop by moving the out target above the chandef_downgrade
+while loop. When we downgrade to NL80211_CHAN_WIDTH_20_NOHT, we jump
+back up to re-run the while loop...indefinitely. Replace goto with
+break and carry on. This may not be sufficient to connect to the AP,
+but will at least keep the cpu from livelocking. Thanks to Derek Atkins
+as an extra pair of debugging eyes.
+
+Cc: stable@kernel.org
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index ae31968..e3e7d2b 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -338,7 +338,7 @@ out:
+ if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
+ ret = IEEE80211_STA_DISABLE_HT |
+ IEEE80211_STA_DISABLE_VHT;
+- goto out;
++ break;
+ }
+
+ ret |= chandef_downgrade(chandef);
+--
+cgit v0.9.2
diff --git a/mac80211-ignore-HT-primary-channel-while-connected.patch b/mac80211-ignore-HT-primary-channel-while-connected.patch
new file mode 100644
index 000000000..ba5d2a478
--- /dev/null
+++ b/mac80211-ignore-HT-primary-channel-while-connected.patch
@@ -0,0 +1,121 @@
+From 5cdaed1e878d723d56d04ae0be1738124acf9f46 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Wed, 31 Jul 2013 09:23:06 +0000
+Subject: mac80211: ignore HT primary channel while connected
+
+While we're connected, the AP shouldn't change the primary channel
+in the HT information. We checked this, and dropped the connection
+if it did change it.
+
+Unfortunately, this is causing problems on some APs, e.g. on the
+Netgear WRT610NL: the beacons seem to always contain a bad channel
+and if we made a connection using a probe response (correct data)
+we drop the connection immediately and can basically not connect
+properly at all.
+
+Work around this by ignoring the HT primary channel information in
+beacons if we're already connected.
+
+Also print out more verbose messages in the other situations to
+help diagnose similar bugs quicker in the future.
+
+Cc: stable@vger.kernel.org [3.10]
+Acked-by: Andy Isaacson <adi@hexapodia.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index e5c3cf4..077a953 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -211,8 +211,9 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_channel *channel,
+ const struct ieee80211_ht_operation *ht_oper,
+ const struct ieee80211_vht_operation *vht_oper,
+- struct cfg80211_chan_def *chandef, bool verbose)
++ struct cfg80211_chan_def *chandef, bool tracking)
+ {
++ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+ struct cfg80211_chan_def vht_chandef;
+ u32 ht_cfreq, ret;
+
+@@ -231,7 +232,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
+ channel->band);
+ /* check that channel matches the right operating channel */
+- if (channel->center_freq != ht_cfreq) {
++ if (!tracking && channel->center_freq != ht_cfreq) {
+ /*
+ * It's possible that some APs are confused here;
+ * Netgear WNDR3700 sometimes reports 4 higher than
+@@ -239,11 +240,10 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ * since we look at probe response/beacon data here
+ * it should be OK.
+ */
+- if (verbose)
+- sdata_info(sdata,
+- "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
+- channel->center_freq, ht_cfreq,
+- ht_oper->primary_chan, channel->band);
++ sdata_info(sdata,
++ "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
++ channel->center_freq, ht_cfreq,
++ ht_oper->primary_chan, channel->band);
+ ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
+ goto out;
+ }
+@@ -297,7 +297,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ channel->band);
+ break;
+ default:
+- if (verbose)
++ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+ sdata_info(sdata,
+ "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
+ vht_oper->chan_width);
+@@ -306,7 +306,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ }
+
+ if (!cfg80211_chandef_valid(&vht_chandef)) {
+- if (verbose)
++ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+ sdata_info(sdata,
+ "AP VHT information is invalid, disable VHT\n");
+ ret = IEEE80211_STA_DISABLE_VHT;
+@@ -319,7 +319,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
+ }
+
+ if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
+- if (verbose)
++ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
+ sdata_info(sdata,
+ "AP VHT information doesn't match HT, disable VHT\n");
+ ret = IEEE80211_STA_DISABLE_VHT;
+@@ -346,7 +346,7 @@ out:
+ ret |= chandef_downgrade(chandef);
+ }
+
+- if (chandef->width != vht_chandef.width && verbose)
++ if (chandef->width != vht_chandef.width && !tracking)
+ sdata_info(sdata,
+ "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
+
+@@ -386,7 +386,7 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
+
+ /* calculate new channel (type) based on HT/VHT operation IEs */
+ flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper,
+- vht_oper, &chandef, false);
++ vht_oper, &chandef, true);
+
+ /*
+ * Downgrade the new channel if we associated with restricted
+@@ -3838,7 +3838,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
+ ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
+ cbss->channel,
+ ht_oper, vht_oper,
+- &chandef, true);
++ &chandef, false);
+
+ sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
+ local->rx_chains);
+--
+cgit v0.9.2