All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luca Coelho <luca@coelho.fi>
To: kvalo@codeaurora.org
Cc: linux-wireless@vger.kernel.org
Subject: [PATCH 7/8] iwlwifi: pnvm: implement reading PNVM from UEFI
Date: Wed, 10 Feb 2021 17:23:54 +0200	[thread overview]
Message-ID: <iwlwifi.20210210172142.7ce41ca91884.Ie234805047df3be84f4235f9dafaf4cdecf0db9a@changeid> (raw)
In-Reply-To: <20210210152355.419776-1-luca@coelho.fi>

From: Luca Coelho <luciano.coelho@intel.com>

We now support fetching the PNVM data from a UEFI variable.  Add the
code to read this variable first and use it.  If it's not available,
we fall back to reading the data from the filesystem, as before.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 91 +++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
index d515af8c1686..5c2977b6364b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c
@@ -10,6 +10,7 @@
 #include "fw/api/commands.h"
 #include "fw/api/nvm-reg.h"
 #include "fw/api/alive.h"
+#include <linux/efi.h>
 
 struct iwl_pnvm_section {
 	__le32 offset;
@@ -219,6 +220,88 @@ static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
 	return -ENOENT;
 }
 
+/*
+ * This is known to be broken on v4.19 and to work on v5.4.  Until we
+ * figure out why this is the case and how to make it work, simply
+ * disable the feature in old kernels.
+ */
+#if defined(CONFIG_EFI) && LINUX_VERSION_IS_GEQ(5,4,0)
+
+#define IWL_EFI_VAR_GUID EFI_GUID(0x92daaf2f, 0xc02b, 0x455b,	\
+				  0xb2, 0xec, 0xf5, 0xa3,	\
+				  0x59, 0x4f, 0x4a, 0xea)
+
+#define IWL_UEFI_OEM_PNVM_NAME	L"UefiCnvWlanOemSignedPnvm"
+
+#define IWL_HARDCODED_PNVM_SIZE 4096
+
+struct pnvm_sku_package {
+	u8 rev;
+	u8 reserved1[3];
+	u32 total_size;
+	u8 n_skus;
+	u8 reserved2[11];
+	u8 data[];
+};
+
+static int iwl_pnvm_get_from_efi(struct iwl_trans *trans,
+				 u8 **data, size_t *len)
+{
+	struct efivar_entry *pnvm_efivar;
+	struct pnvm_sku_package *package;
+	unsigned long package_size;
+	int err;
+
+	pnvm_efivar = kzalloc(sizeof(*pnvm_efivar), GFP_KERNEL);
+	if (!pnvm_efivar)
+		return -ENOMEM;
+
+	memcpy(&pnvm_efivar->var.VariableName, IWL_UEFI_OEM_PNVM_NAME,
+	       sizeof(IWL_UEFI_OEM_PNVM_NAME));
+	pnvm_efivar->var.VendorGuid = IWL_EFI_VAR_GUID;
+
+	/*
+	 * TODO: we hardcode a maximum length here, because reading
+	 * from the UEFI is not working.  To implement this properly,
+	 * we have to call efivar_entry_size().
+	 */
+	package_size = IWL_HARDCODED_PNVM_SIZE;
+
+	package = kmalloc(package_size, GFP_KERNEL);
+	if (!package) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = efivar_entry_get(pnvm_efivar, NULL, &package_size, package);
+	if (err) {
+		IWL_DEBUG_FW(trans,
+			     "PNVM UEFI variable not found %d (len %zd)\n",
+			     err, package_size);
+		goto out;
+	}
+
+	IWL_DEBUG_FW(trans, "Read PNVM fro UEFI with size %zd\n", package_size);
+
+	*data = kmemdup(package->data, *len, GFP_KERNEL);
+	if (!*data)
+		err = -ENOMEM;
+	*len = package_size - sizeof(*package);
+
+out:
+	kfree(package);
+	kfree(pnvm_efivar);
+
+	return err;
+}
+#else /* CONFIG_EFI */
+static inline int iwl_pnvm_get_from_efi(struct iwl_trans *trans,
+					u8 **data, size_t *len)
+{
+	return -EOPNOTSUPP;
+}
+#endif /* CONFIG_EFI */
+
 static int iwl_pnvm_get_from_fs(struct iwl_trans *trans, u8 **data, size_t *len)
 {
 	const struct firmware *pnvm;
@@ -277,7 +360,12 @@ int iwl_pnvm_load(struct iwl_trans *trans,
 		goto skip_parse;
 	}
 
-	/* Try to load the PNVM from the filesystem */
+	/* First attempt to get the PNVM from BIOS */
+	ret = iwl_pnvm_get_from_efi(trans, &data, &len);
+	if (!ret)
+		goto parse;
+
+	/* If it's not available, try from the filesystem */
 	ret = iwl_pnvm_get_from_fs(trans, &data, &len);
 	if (ret) {
 		/*
@@ -290,6 +378,7 @@ int iwl_pnvm_load(struct iwl_trans *trans,
 		goto skip_parse;
 	}
 
+parse:
 	iwl_pnvm_parse(trans, data, len);
 
 	kfree(data);
-- 
2.30.0


  parent reply	other threads:[~2021-02-10 15:25 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-10 15:23 [PATCH 0/8] iwlwifi: updates intended for v5.12 2021-02-10 part 2 Luca Coelho
2021-02-10 15:23 ` [PATCH 1/8] iwlwifi: mvm: reduce the print severity of failing getting NIC temp Luca Coelho
2021-02-10 23:57   ` Luca Coelho
2021-02-10 15:23 ` [PATCH 2/8] iwlwifi: mvm: global PM mode does not reset after FW crash Luca Coelho
2021-02-10 15:23 ` [PATCH 3/8] iwlwifi: pnvm: set the PNVM again if it was already loaded Luca Coelho
2021-02-10 15:23 ` [PATCH 4/8] iwlwifi: pcie: define FW_RESET_TIMEOUT for clarity Luca Coelho
2021-02-10 15:23 ` [PATCH 5/8] iwlwifi: pnvm: increment the pointer before checking the TLV Luca Coelho
2021-02-10 15:23 ` [PATCH 6/8] iwlwifi: pnvm: move file loading code to a separate function Luca Coelho
2021-02-10 15:23 ` Luca Coelho [this message]
2021-02-10 18:01   ` [PATCH 7/8] iwlwifi: pnvm: implement reading PNVM from UEFI kernel test robot
2021-02-10 18:01     ` kernel test robot
2021-02-10 15:23 ` [PATCH 8/8] iwlwifi: bump FW API to 62 for AX devices Luca Coelho
2021-02-10 23:58   ` Luca Coelho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=iwlwifi.20210210172142.7ce41ca91884.Ie234805047df3be84f4235f9dafaf4cdecf0db9a@changeid \
    --to=luca@coelho.fi \
    --cc=kvalo@codeaurora.org \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.