aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch')
-rw-r--r--package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch132
1 files changed, 132 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch b/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
new file mode 100644
index 0000000000..88e5c67735
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
@@ -0,0 +1,132 @@
+From ce2e6db554fad444fa0b3904fc3015336e0ef765 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 11 Oct 2018 11:51:06 +0200
+Subject: [PATCH] brcmfmac: Add support for getting nvram contents from EFI
+ variables
+
+Various X86 laptops with a SDIO attached brcmfmac wifi chip, store the
+nvram contents in a special EFI variable. This commit adds support for
+getting nvram directly from this EFI variable, without the user needing
+to manually copy it.
+
+This makes Wifi / Bluetooth work out of the box on these devices instead of
+requiring manual setup.
+
+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.
+
+Tested-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/firmware.c | 63 +++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -14,6 +14,7 @@
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
++#include <linux/efi.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/device.h>
+@@ -445,6 +446,51 @@ struct brcmf_fw {
+
+ static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
+
++#ifdef CONFIG_EFI
++static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
++{
++ const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
++ struct efivar_entry *nvram_efivar;
++ unsigned long data_len = 0;
++ u8 *data = NULL;
++ int err;
++
++ nvram_efivar = kzalloc(sizeof(*nvram_efivar), GFP_KERNEL);
++ if (!nvram_efivar)
++ return NULL;
++
++ memcpy(&nvram_efivar->var.VariableName, name, sizeof(name));
++ nvram_efivar->var.VendorGuid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61,
++ 0xb5, 0x1f, 0x43, 0x26,
++ 0x81, 0x23, 0xd1, 0x13);
++
++ err = efivar_entry_size(nvram_efivar, &data_len);
++ if (err)
++ goto fail;
++
++ data = kmalloc(data_len, GFP_KERNEL);
++ if (!data)
++ goto fail;
++
++ err = efivar_entry_get(nvram_efivar, NULL, &data_len, data);
++ if (err)
++ goto fail;
++
++ brcmf_info("Using nvram EFI variable\n");
++
++ kfree(nvram_efivar);
++ *data_len_ret = data_len;
++ return data;
++
++fail:
++ kfree(data);
++ kfree(nvram_efivar);
++ return NULL;
++}
++#else
++static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
++#endif
++
+ static void brcmf_fw_free_request(struct brcmf_fw_request *req)
+ {
+ struct brcmf_fw_item *item;
+@@ -463,11 +509,12 @@ static int brcmf_fw_request_nvram_done(c
+ {
+ struct brcmf_fw *fwctx = ctx;
+ struct brcmf_fw_item *cur;
++ bool free_bcm47xx_nvram = false;
++ bool kfree_nvram = false;
+ u32 nvram_length = 0;
+ void *nvram = NULL;
+ u8 *data = NULL;
+ size_t data_len;
+- bool raw_nvram;
+
+ brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
+
+@@ -476,12 +523,13 @@ static int brcmf_fw_request_nvram_done(c
+ if (fw && fw->data) {
+ data = (u8 *)fw->data;
+ data_len = fw->size;
+- raw_nvram = false;
+ } else {
+- data = bcm47xx_nvram_get_contents(&data_len);
+- if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
++ if ((data = bcm47xx_nvram_get_contents(&data_len)))
++ free_bcm47xx_nvram = true;
++ else if ((data = brcmf_fw_nvram_from_efi(&data_len)))
++ kfree_nvram = true;
++ else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL))
+ goto fail;
+- raw_nvram = true;
+ }
+
+ if (data)
+@@ -489,8 +537,11 @@ static int brcmf_fw_request_nvram_done(c
+ fwctx->req->domain_nr,
+ fwctx->req->bus_nr);
+
+- if (raw_nvram)
++ if (free_bcm47xx_nvram)
+ bcm47xx_nvram_release_contents(data);
++ if (kfree_nvram)
++ kfree(data);
++
+ release_firmware(fw);
+ if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
+ goto fail;