Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Brugger <mbrugger@suse.com>2019-01-10 19:12:26 +0100
committerMatthias Brugger <mbrugger@suse.com>2019-01-11 11:40:42 +0100
commitab1781ad9b0e58b2f7438a491e4d290786d8edce (patch)
treef249160bf1253ff9e8b957e7d887b4ee3f8979db
parent2a639adfdb8a9d323a81c67038b3f03463cc1a57 (diff)
brcmfmac: Add support for getting nvram contents from EFI
variables (fate#326215).
-rw-r--r--patches.drivers/0007-brcmfmac-Add-support-for-getting-nvram-contents-from.patch139
-rw-r--r--series.conf1
2 files changed, 140 insertions, 0 deletions
diff --git a/patches.drivers/0007-brcmfmac-Add-support-for-getting-nvram-contents-from.patch b/patches.drivers/0007-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
new file mode 100644
index 0000000000..b013085768
--- /dev/null
+++ b/patches.drivers/0007-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
@@ -0,0 +1,139 @@
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 11 Oct 2018 11:51:06 +0200
+Subject: brcmfmac: Add support for getting nvram contents from EFI variables
+Git-commit: ce2e6db554fad444fa0b3904fc3015336e0ef765
+Patch-mainline: v5.0-rc1
+References: fate#326215
+
+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>
+Signed-off-by: Matthias Brugger <mbrugger@suse.com>
+---
+ .../broadcom/brcm80211/brcmfmac/firmware.c | 63 +++++++++++++++++--
+ 1 file changed, 57 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+index b38c4b40b235..965ae5c24c2d 100644
+--- 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(const struct firmware *fw, void *ctx)
+ {
+ 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(const struct firmware *fw, void *ctx)
+ 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(const struct firmware *fw, void *ctx)
+ 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;
+--
+2.20.1
+
diff --git a/series.conf b/series.conf
index dca2342373..8b100d7f71 100644
--- a/series.conf
+++ b/series.conf
@@ -41797,6 +41797,7 @@
patches.drivers/0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch
patches.drivers/0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch
patches.drivers/0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch
+ patches.drivers/0007-brcmfmac-Add-support-for-getting-nvram-contents-from.patch
patches.drivers/wlcore-Fix-the-return-value-in-case-of-error-in-wlco.patch
patches.drivers/rtl8xxxu-Fix-missing-break-in-switch.patch
patches.drivers/wireless-airo-potential-buffer-overflow-in-sprintf.patch