diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2018-11-07 11:06:16 +0100 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2018-11-07 11:11:08 +0100 |
commit | 3eab6b8275b2b592d5f7694b871d53ecff8d65da (patch) | |
tree | c2261bd978e820aa8d8e286353779767869a2a0a /package/kernel/mac80211/patches/brcm/321-v4.21-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch | |
parent | 5932eb690f24c25b11119a55242dac4718fe8324 (diff) | |
download | upstream-3eab6b8275b2b592d5f7694b871d53ecff8d65da.tar.gz upstream-3eab6b8275b2b592d5f7694b871d53ecff8d65da.tar.bz2 upstream-3eab6b8275b2b592d5f7694b871d53ecff8d65da.zip |
mac80211: brcmfmac: backport NVRAM loading improvements
This adds support for storing board specific NVRAM files as firmware.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
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.patch | 132 |
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; |