321-v5.0-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch 4.1 KB

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