shill: add scripts to set wifi regdomain when device appears

Thus far, we've handled regdomain by using the default "world"
regulatory domain, with just a few exceptions.

The exceptional cases are handled by regulatory-domain.conf, which
uses VPD to determine if a device was intended for use in a country
that has regulatory rules that are stricter than the "world" domain.
If so, regulatory-domain.conf configures cfg80211 to use the
regulatory rules for the country configured in VPD.

This approach assumes that the WiFi device driver / firmware support
the "world" regulatory domain, and/or allow the host to provide a
custom rule-set to firmware. Unfortunately, this is not true for all
WiFi chips/firmware. Instead, some firmware a) defaults to US rules,
and b) does not provide a way for the host to provide a custom
rule-set to firmware.

To use such firmware outside of the US, we want to explicitly
configure the country code from VPD data, rather than sometimes
defaulting to "world". However, for WiFi chips/firmware that either
defaults to "world" rules, or uses the rule-set provided by the host,
we want to retain existing behavior.

To solve this problem, we introduce a new script. This script is
triggered by udev, when a new network device is added to the
system. The script triggers only if the new network device uses a
driver for which we want to configuration the regulatory domain
unconditionally.

Note that, in some cases, this new script may not actually trigger any
changes in the driver or firmware. Specifically: if the regdomain has
already been set by regulatory-domain.conf, then the kernel might
realize that no change is being made. Since no change is being made,
the kernel might skip the call to the WiFi driver's
reg_notifier(). This is fine, because the driver would have been
informed of the configuration set by regulatory-domain.conf.

The reason that the driver would have been informed is that
regulatory-domain.conf waits for a device to appear, before changing
the regdomain. When the configuration change completes, the kernel
invokes the reg_notifier() that was registered by the device driver.

BUG=chrome-os-partner:38713
TEST=manual (see below)

Manual test
-----------
On minnie/speedy:
- test the first boot / after-AU case:
  - rm /var/lib/preload-network-drivers
  - reboot
  - dmesg | egrep 'Regulatory domain changed|brcmf_c_preinit_dcmds'
  - verify that 'brcmf_c_preinit_dcmds' occurs before 'Regulatory domain changed'
- test the normal case
  - [ -e /var/lib/preload-network-drivers ] || echo FAIL
  - reboot
  - dmesg | egrep 'Regulatory domain changed|brcmf_c_preinit_dcmds'
  - verify that 'brcmf_c_preinit_dcmds' occurs before 'Regulatory domain changed'
On jerry (US SKU):
- only one case to test
- mount / -oremount,rw
- mv /etc/init/regulatory-domain.conf /etc/init/regulatory-domain.conf.DISABLED
- reboot
- dmesg | grep 'Regulatory domain changed'
- verify that no matching lines are found
- mount / -oremount,rw
- mv /etc/init/regulatory-domain.conf.DISABLED /etc/init/regulatory-domain.conf
- reboot

Change-Id: I1b3bbc4fce5c5cc5563fc5e78a2025fe4dc2b19e
Reviewed-on: https://chromium-review.googlesource.com/264494
Trybot-Ready: mukesh agrawal <quiche@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Commit-Queue: mukesh agrawal <quiche@chromium.org>
(cherry picked from commit 3d7f7ce4e6b62d9a754ed6b13b5d1069c2b5fac4)
Reviewed-on: https://chromium-review.googlesource.com/264986
Reviewed-by: mukesh agrawal <quiche@chromium.org>
3 files changed