[wifi] CRDA Regulatory Support is broken

Bug #1126751 reported by Tony Espy
24
This bug affects 3 people
Affects Status Importance Assigned to Milestone
system-image (Ubuntu)
In Progress
High
Mathieu Trudel-Lapierre

Bug Description

Our images currently are broken with respect to Wi-Fi CRDA ( Central Regulatory Domain Agent ) / Regulatory support.

We don't include the regulatory DB package ( wireless-regdb ) nor the user agent used to load regulatory information into the kernel ( crda ). The kernel requests CRDA updates by generating a uevent, which is caught by udevd, which in turn matches a simple role that causes /sbin/crda to be invoked. As we're missing the required packages and not running udev on our images, CRDA updates fail.

If you look /var/log/syslog on a Galaxy Nexus / maguro running phablet-image >= 83, you'll see the following messages whenever the phone boots:

cfg80211: Calling CRDA to update world regulatory domain

This may be related to some of the bugs we're seeing with 802.11an ( 5GHz band ) access points we've seen including bug # 1107943 ( maguro ) and bug # 1126264 ( manta ).

Also, I went ahead an installed wireless-regdb and crda on my maguro. When I run 'sudo iw reg set US', it has no effect.

Note, for more information on the Linux regulatory framework, please refer to:

http://wireless.kernel.org/en/developers/Regulatory

or Documentation/networking/regulatory.txt in the kernel.

In order for this to be fixed, we need to do the following:

1. Add wireless-regdb and crda to our builds
2. Figure out someway to properly set the REGDOMAIN in /etc/default/crda
( distro plans to fix by modifying the post-install script of crda, but I'm not sure this will work for us )
3. Fix one or more Wi-Fi drivers, if so required

== Drivers ==

=== Galaxy Nexus (maguro) ===

The Galaxy Nexus uses the bcmdhd Wi-Fi driver. Which it turns out has code to set a custom world regdomain by default ( see /drivers/net/wireless/bcmdhd/wl_cfg80211.c ), and also appears not to play well with the kernel wireless regulatory framework.

This causes problems for wpa_supplicant, which actually queries the regdomain info from the kernel/driver, and uses this information to govern it's behavior.

This means it's probably time to revisit the delta between Android's version of wpa_supplicant, and the latest version in Ubuntu.

Also note, while doing some investigation on the bcmdhd driver, I ran into a reference of a private Broadcom-specific wpa_supplicant library.

== Nexus 4 (mako) ==

The Nexus 4 uses the wcnss_wlan driver ( aka prima ). The upstream git tree can be found at git://codeaurora.org/external/wlan/prima.git.

This driver also apparently doesn't react to 'iw reg set' either. It also doesn't appear to be integrated with cfg80211 either.

Note, from the codearora.org site, it appears the Prima driver is for a Qualcomm MSM WLAN module ( which may use an Atheros chip internally ).

Tony Espy (awe)
Changed in manhattan:
status: New → Confirmed
importance: Undecided → Medium
importance: Medium → High
assignee: nobody → Tony Espy (awe)
Revision history for this message
Tony Espy (awe) wrote :

Debug logging for libnl can be enabled by setting the following two environment variables:

NLCB=debug
NLDBG=4

From the log ( see attached ), I can see that the kernel is NAK'ing one of the netlink messages sent by CRDA. I have to dig a bit into the trace as the function/identity of the message isn't output. The kernel is returning an error of -22 "Invalid Argument" to the message. For some unfortunate reason, crda turns this into a -7 ( E2BIG ) return code which is mis-leading.

Revision history for this message
Tony Espy (awe) wrote :

This is the debug output from running crda on phablet-image #95 on a Galaxy Nexus / maguro.

To test, I ssh'd into the phone, installed crda and wireless-reg, became root, then exported COUNTRY=US, the two NL env vars referenced in the previous comment, then ran /sbin/crda.

Changed in manhattan:
status: Confirmed → In Progress
Revision history for this message
Ricardo Salveti (rsalveti) wrote :

crda output with mako.

Linux localhost.localdomain 3.4.0-perf-g97f8032 #1 SMP PREEMPT Sat Feb 23 07:45:17 UTC 2013 armv7l armv7l armv7l GNU/Linux

Revision history for this message
Tony Espy (awe) wrote :

So it turns out that the error returned from crda isn't as important, as I get the same thing on my laptop if I run it.

That said, even with crda and wireless-regdb installed on our image, CRDA is still broken.

On my laptop ( as root ) I can run "iw reg set US" and then run "iw reg set 00" and see the update take hold by querying the regdomain using "iw reg get". You can also see this in the kernel:

Feb 26 09:55:19 alien kernel: [16106.288980] cfg80211: Regulatory domain changed to country: US
Feb 26 09:55:19 alien kernel: [16106.288983] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
Feb 26 09:55:19 alien kernel: [16106.288988] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2700 mBm)
Feb 26 09:55:19 alien kernel: [16106.288993] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 1700 mBm)
Feb 26 09:55:19 alien kernel: [16106.288998] cfg80211: (5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
Feb 26 09:55:19 alien kernel: [16106.289003] cfg80211: (5490000 KHz - 5600000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
Feb 26 09:55:19 alien kernel: [16106.289007] cfg80211: (5650000 KHz - 5710000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
Feb 26 09:55:19 alien kernel: [16106.289011] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 mBm)

Whereas on the phone, I only see the initial set:

Feb 26 14:02:44 localhost kernel: [ 0.693359] cfg80211: Calling CRDA to update world regulatory domain

Note I also discovered that CRDA is broken on our Desktop installs ( 12.04+ ) as a default regdomain is not ever set. I've discussed this with cyphermox, and he's going to patch crda to set the default regdomain ( /etc/default/crda ) in the post-install script, based on the timezone set at install time. Long term, there's also discussion to have geoclue set regdomain.

I tried this on the phone ( setting the default in /etc/default/regdomain ) and it has no effect.

Tony Espy (awe)
description: updated
Tony Espy (awe)
description: updated
Tony Espy (awe)
description: updated
description: updated
Revision history for this message
Seth Forshee (sforshee) wrote :

A few points.

First, even if the error returned from crda isn't important the fact that the netlink message gets back a error of EINVAL probably is. Presumably this netlink message is providing the regulatory information requested by the kernel, and thus would be handled by nl80211_set_reg(). Unfortunately there are a lot of reasons this might return EINVAL.

Second, when drivers supply a custom domain this overrides the default user domain for any devices using that driver. bcmdhd _does_ supply a custom domain, so what you see from 'iw reg get' is irrelevant. The custom domain in bcmdhd does encompass all the legal frequencies in the US and EU for both 2.4 and 5 GHz. On my nexus 7 at least the hw doesn't appear to support 5 GHz however. Also, Tony discovered that running 'iw list' gives a better, per-device list of channels available to the devices and their associated flags (also, 'iw phyX info' gives the same information for the specified device).

Third, user hints (the kind given for 'iw wlanX reg set') may be rejected by the kernel for a number of reasons. However, if they are getting as far as calling crda and crda is getting an error when it tries to supply the requested regulatory information, that would also result in the user hint not being applied.

Finally, I'd question whether we really want to set /etc/default/crda. Most of the wireless drivers in the kernel that work well at all are using custom domains that should make them behave appropriately throughout the world. If the value of /etc/default/crda is set incorrectly at boot, or when the machine is used in a country other than that where the original install happened, this could result in transmitting on restricted or disallowed channels.

Oh, one more thing.

> To test, I ssh'd into the phone, installed crda and wireless-reg, became root,
> then exported COUNTRY=US, the two NL env vars referenced in the
> previous comment, then ran /sbin/crda.

This won't work. The kernel is going to reject any information from crda that it didn't request. Which explains the EINVAL in this case at least. Are you getting EINVAL from the kernel in other cases?

Revision history for this message
Seth Forshee (sforshee) wrote :

I did a little bit of experimenting today with the desktop image on the nexus 7. If I disable network-manager and set up the interface manually I can change the regulatory domain without problem, whether the interface is up or down and whether or not it is associated with an AP.

I also noticed that if I set the domain while network-manager has the interface up that the new domain seems to get applied after it stops managing the interface.

Tony Espy (awe)
information type: Proprietary → Public
affects: manhattan → touch-preview-images
Changed in touch-preview-images:
assignee: Tony Espy (awe) → Mathieu Trudel-Lapierre (mathieu-tl)
affects: touch-preview-images → system-image (Ubuntu)
tags: added: touch-preview-images
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.