12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- From 29ec3394f0bd85c22674ab6693d92da5e2324610 Mon Sep 17 00:00:00 2001
- From: Hans de Goede <[email protected]>
- Date: Thu, 11 Oct 2018 11:51:07 +0200
- Subject: [PATCH] brcmfmac: Fix ccode from EFI nvram when necessary
- In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
- to specify "worldwide" compatible settings, but these 2 ccode-s do not work
- properly.
- I've tested the different known "worldwide" ccode-s used in various nvram
- sources with the latest firmwares from linux-firmware for various brcmfmac
- models, here is a simplified (*) table with what each setting results in:
- ALL: 12-14 disab, U-NII-1, U-NII-2 no-IR/radar, U-NII-3
- XV: 12-14 no-IR, disables all 5G channels
- XY: 12-13 enab, 14 disab, U-NII-1 enab, U-NII-2 no-IR/radar, U-NII-3 disab
- X2: 12-13 no-IR, 14 dis, U-NII-1 no-IR, U-NII-2 no-IR/radar, U-NII-3 no-IR
- Where 12,13,14 are 2.4G channels 12-14 and U-NII-1/2/3 are the 3 different
- 5G channel groups. no-IR is no-Initiate-Radiation, we will never send on
- these channels without first having received valid wifi traffic there.
- This immediately shows that both ALL and XV are not as worldwide as we want
- them to be. ALL causes channels 12 and 13 to not be available and XV causes
- all 5GHz channels to not be available. Also ALL unconditionally enables the
- U-NII-1 and U-NII-3 5G groups, while we really should be using no-IR for
- these.
- This commit replace XV and ALL with X2, which allows usage of chan 12-13
- and 5G channels, but only after receiving valid wifi traffic there first.
- Note that this configure the firmware's channel limits, the kernels own
- regulatory restrictions based on e.g. regulatory info received from the
- access-point, will be applied on top of this.
- This fixes channels 12+13 not working on the Asus T200TA and the Lenovo
- Mixx 2 8 and 5G channels not working on the Asus T100HA.
- This has been tested on the following models: Acer Iconia Tab8 w1-810,
- Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a
- Lenovo Mixx 2 8.
- *) There are some exceptions to this table:
- 1) On really old firmware e.g. linux-firmware's 2011 brcmfmac4330-sdio.bin
- ALL really means all, unconditionally enabling everything
- 2) The exact meaning might be influenced by setting the regrev nvram var.
- Specifically using ccode=XV + regrev=1 on brcmfmac43241b4 leads to:
- 12-14 no-ir, U-NII-1 no-ir, U-NII-2 no-ir/radar, U-NII-3 no-ir
- But only on the brcmfmac43241b4 and not on e.g. the brcmfmac43340
- Tested-by: Hans de Goede <[email protected]>
- Signed-off-by: Hans de Goede <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- .../broadcom/brcm80211/brcmfmac/firmware.c | 24 ++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
- @@ -447,6 +447,29 @@ struct brcmf_fw {
- static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
-
- #ifdef CONFIG_EFI
- +/* In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
- + * to specify "worldwide" compatible settings, but these 2 ccode-s do not work
- + * properly. "ccode=ALL" causes channels 12 and 13 to not be available,
- + * "ccode=XV" causes all 5GHz channels to not be available. So we replace both
- + * with "ccode=X2" which allows channels 12+13 and 5Ghz channels in
- + * no-Initiate-Radiation mode. This means that we will never send on these
- + * channels without first having received valid wifi traffic on the channel.
- + */
- +static void brcmf_fw_fix_efi_nvram_ccode(char *data, unsigned long data_len)
- +{
- + char *ccode;
- +
- + ccode = strnstr((char *)data, "ccode=ALL", data_len);
- + if (!ccode)
- + ccode = strnstr((char *)data, "ccode=XV\r", data_len);
- + if (!ccode)
- + return;
- +
- + ccode[6] = 'X';
- + ccode[7] = '2';
- + ccode[8] = '\r';
- +}
- +
- static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
- {
- const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
- @@ -476,6 +499,7 @@ static u8 *brcmf_fw_nvram_from_efi(size_
- if (err)
- goto fail;
-
- + brcmf_fw_fix_efi_nvram_ccode(data, data_len);
- brcmf_info("Using nvram EFI variable\n");
-
- kfree(nvram_efivar);
|