[ltp] Re: spotty wireless with t520 w/Intel wifi and xubuntu 13.04

Michael Livshin linux-thinkpad@linux-thinkpad.org
Sat, 26 Oct 2013 08:06:47 +0300

Content-Type: text/plain

According to my experience, it's NetworkManager.  OK, it's the
combination of NetworkManager and the wireless driver.  Even though
Intel wireless cards are supposed to be well-supported in Linux.  Go
figure.  Then again, I have an RTL8192CE card in my T420 -- now _that_
one's driver is utter shit.  Believe you me, you have it relatively

Where was I?  Ah, yes, NetworkManager.  See, that fine piece of software
is periodically (as in every fscking two minutes) issuing AP scans.
_While_ you are connected.  The idea, as I understand it, is to support
WiFi roaming transparently -- I mean, who cares for those sedentary
idiots like your truly who just want to sit at the table, or on the
couch, and work on their laptop?  This cool portable device, which has
WiFi?  While _seated_?  Really, who the hell would want to do that,

Now, it looks like many Linux wireless drivers (or perhaps it's a deeper
kernel WiFi infrastructure problem?  Apparently nobody has a real clue!)
have trouble keeping a connection up and scanning at the same time,
which trouble manifests itself by disconnection from the active AP and,
in many cases (like with this here RTL8192CE), ceasing to see that AP
for some time (usually, but not always, cured by reloading the driver
module).  The problem is greatly exacerbated by poor (60% or less)
signal in the first place.

The NetworkManager maintainers are refusing to introduce a configuration
knob to turn those moronic periodic scans off, because they figure that
any problem caused by scanning is always the driver's fault.  So
everyone should just fix their drivers (sound familiar?  Yes, all the
NetworkManager maintainers work at RedHat).

The proper solution, obviously, is to nuke the NetworkManager maintainer
office (if such a place exists) from orbit.  A passable workaround
(which has been making using my T420 on the home network bearable for a
month now) is to patch the NetworkManager source and build your own deb
for it (but make sure to tweak the version in debian/changelog, or
apt-get will bring back the official package at the first opportinity).

See the attached patch.

(You'd expect some nice individual to maintain a PPA and The Community
(whatever that is) to plaster the internets with friendly links to said
PPA, right?  Or perhaps (*gasp*) you'd expect sane distributors to just
fix the stupid problem in their packaged versions, right?  Right.)

Content-Type: text/x-diff
Content-Disposition: inline; filename=p.diff
Content-Description: disable scanning while connected

--- a/src/nm-device-wifi.c	2013-02-20 22:56:16.000000000 +0200
+++ b/src/nm-device-wifi.c	2013-10-18 16:51:20.266374157 +0300
@@ -1807,14 +1757,17 @@
 	if (!priv->pending_scan_id) {
 		guint factor = 2, next_scan = priv->scan_interval;
+		int is_activated = (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED);
 		if (    nm_device_is_activating (NM_DEVICE (self))
 		    || (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED))
 			factor = 1;
-		priv->pending_scan_id = g_timeout_add_seconds (next_scan,
-		                                               request_wireless_scan,
-		                                               self);
+		if (!is_activated) {
+			priv->pending_scan_id = g_timeout_add_seconds (next_scan,
+														   request_wireless_scan,
+														   self);
+		}
 		priv->scheduled_scan_time = now + priv->scan_interval;
 		if (backoff && (priv->scan_interval < (SCAN_INTERVAL_MAX / factor))) {
@@ -1830,10 +1783,12 @@
 			priv->scan_interval = 5;
-		nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scheduled scan in %d seconds (interval now %d seconds)",
-		            nm_device_get_iface (NM_DEVICE (self)),
-		            next_scan,
-		            priv->scan_interval);
+		if (!is_activated) {
+			nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scheduled scan in %d seconds (interval now %d seconds)",
+						nm_device_get_iface (NM_DEVICE (self)),
+						next_scan,
+						priv->scan_interval);
+		}