* [PATCH v3] brcmfmac: Add support for getting nvram contents from EFI variables
@ 2018-10-10 7:16 Hans de Goede
2018-10-10 17:43 ` kbuild test robot
0 siblings, 1 reply; 2+ messages in thread
From: Hans de Goede @ 2018-10-10 7:16 UTC (permalink / raw)
To: Arend van Spriel, Franky Lin, Hante Meuleman, Kalle Valo,
Chi-Hsien Lin, Wright Feng
Cc: Hans de Goede, linux-wireless, brcm80211-dev-list.pdl
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>
---
Changes in v3:
-Drop ccode fixup code (to be re-added in a separate commit), so that we
can get the main EFI nvram support merged while we figure out the ccode
handling
Changes in v2:
-Stop testing for asus in the dmi sys_vendor string at least the Toshiba
Encore uses the nvram efivar variable too
-Use a table mapping the firmare name to the correct ccode value (XV / X2) to
use for the worldwide regulatory domain for that firmware, assuming the
firmware from linux-firmware is used. This fixes the T200TA and T100HA not
seeing 5GHz networks
-Not only fixup ccode=ALL, but also ccode=XV, this is necessary since the
T100HA nvram efivar containts ccode=XV, but the firmware from Linux firmware
needs ccode=X2 for proper operation
---
.../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..a1dfe75c835f 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(const char *path, 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(cur->path, &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.19.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] brcmfmac: Add support for getting nvram contents from EFI variables
2018-10-10 7:16 [PATCH v3] brcmfmac: Add support for getting nvram contents from EFI variables Hans de Goede
@ 2018-10-10 17:43 ` kbuild test robot
0 siblings, 0 replies; 2+ messages in thread
From: kbuild test robot @ 2018-10-10 17:43 UTC (permalink / raw)
To: Hans de Goede
Cc: kbuild-all, Arend van Spriel, Franky Lin, Hante Meuleman,
Kalle Valo, Chi-Hsien Lin, Wright Feng, Hans de Goede,
linux-wireless, brcm80211-dev-list.pdl
[-- Attachment #1: Type: text/plain, Size: 3742 bytes --]
Hi Hans,
I love your patch! Yet something to improve:
[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on v4.19-rc7 next-20181010]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Hans-de-Goede/brcmfmac-Add-support-for-getting-nvram-contents-from-EFI-variables/20181010-211419
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: i386-randconfig-c0-10102322 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c: In function 'brcmf_fw_request_nvram_done':
>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c:529:44: error: passing argument 1 of 'brcmf_fw_nvram_from_efi' from incompatible pointer type [-Werror=incompatible-pointer-types]
else if ((data = brcmf_fw_nvram_from_efi(cur->path, &data_len)))
^~~
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c:491:12: note: expected 'size_t * {aka unsigned int *}' but argument is of type 'const char *'
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c:529:20: error: too many arguments to function 'brcmf_fw_nvram_from_efi'
else if ((data = brcmf_fw_nvram_from_efi(cur->path, &data_len)))
^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c:491:12: note: declared here
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
^~~~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/brcmf_fw_nvram_from_efi +529 drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
507
508 static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
509 {
510 struct brcmf_fw *fwctx = ctx;
511 struct brcmf_fw_item *cur;
512 bool free_bcm47xx_nvram = false;
513 bool kfree_nvram = false;
514 u32 nvram_length = 0;
515 void *nvram = NULL;
516 u8 *data = NULL;
517 size_t data_len;
518
519 brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
520
521 cur = &fwctx->req->items[fwctx->curpos];
522
523 if (fw && fw->data) {
524 data = (u8 *)fw->data;
525 data_len = fw->size;
526 } else {
527 if ((data = bcm47xx_nvram_get_contents(&data_len)))
528 free_bcm47xx_nvram = true;
> 529 else if ((data = brcmf_fw_nvram_from_efi(cur->path, &data_len)))
530 kfree_nvram = true;
531 else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL))
532 goto fail;
533 }
534
535 if (data)
536 nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
537 fwctx->req->domain_nr,
538 fwctx->req->bus_nr);
539
540 if (free_bcm47xx_nvram)
541 bcm47xx_nvram_release_contents(data);
542 if (kfree_nvram)
543 kfree(data);
544
545 release_firmware(fw);
546 if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
547 goto fail;
548
549 brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
550 cur->nv_data.data = nvram;
551 cur->nv_data.len = nvram_length;
552 return 0;
553
554 fail:
555 return -ENOENT;
556 }
557
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32539 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-10-10 17:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-10 7:16 [PATCH v3] brcmfmac: Add support for getting nvram contents from EFI variables Hans de Goede
2018-10-10 17:43 ` kbuild test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.