1*84c3c995SLuca Coelho // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2*84c3c995SLuca Coelho /* 3*84c3c995SLuca Coelho * Copyright(c) 2021 Intel Corporation 4*84c3c995SLuca Coelho */ 5*84c3c995SLuca Coelho 6*84c3c995SLuca Coelho #include "iwl-drv.h" 7*84c3c995SLuca Coelho #include "pnvm.h" 8*84c3c995SLuca Coelho #include "iwl-prph.h" 9*84c3c995SLuca Coelho #include "iwl-io.h" 10*84c3c995SLuca Coelho 11*84c3c995SLuca Coelho #include "fw/uefi.h" 12*84c3c995SLuca Coelho #include <linux/efi.h> 13*84c3c995SLuca Coelho 14*84c3c995SLuca Coelho #define IWL_EFI_VAR_GUID EFI_GUID(0x92daaf2f, 0xc02b, 0x455b, \ 15*84c3c995SLuca Coelho 0xb2, 0xec, 0xf5, 0xa3, \ 16*84c3c995SLuca Coelho 0x59, 0x4f, 0x4a, 0xea) 17*84c3c995SLuca Coelho 18*84c3c995SLuca Coelho void *iwl_uefi_get_pnvm(struct iwl_trans *trans, size_t *len) 19*84c3c995SLuca Coelho { 20*84c3c995SLuca Coelho struct efivar_entry *pnvm_efivar; 21*84c3c995SLuca Coelho void *data; 22*84c3c995SLuca Coelho unsigned long package_size; 23*84c3c995SLuca Coelho int err; 24*84c3c995SLuca Coelho 25*84c3c995SLuca Coelho pnvm_efivar = kzalloc(sizeof(*pnvm_efivar), GFP_KERNEL); 26*84c3c995SLuca Coelho if (!pnvm_efivar) 27*84c3c995SLuca Coelho return ERR_PTR(-ENOMEM); 28*84c3c995SLuca Coelho 29*84c3c995SLuca Coelho memcpy(&pnvm_efivar->var.VariableName, IWL_UEFI_OEM_PNVM_NAME, 30*84c3c995SLuca Coelho sizeof(IWL_UEFI_OEM_PNVM_NAME)); 31*84c3c995SLuca Coelho pnvm_efivar->var.VendorGuid = IWL_EFI_VAR_GUID; 32*84c3c995SLuca Coelho 33*84c3c995SLuca Coelho /* 34*84c3c995SLuca Coelho * TODO: we hardcode a maximum length here, because reading 35*84c3c995SLuca Coelho * from the UEFI is not working. To implement this properly, 36*84c3c995SLuca Coelho * we have to call efivar_entry_size(). 37*84c3c995SLuca Coelho */ 38*84c3c995SLuca Coelho package_size = IWL_HARDCODED_PNVM_SIZE; 39*84c3c995SLuca Coelho 40*84c3c995SLuca Coelho data = kmalloc(package_size, GFP_KERNEL); 41*84c3c995SLuca Coelho if (!data) { 42*84c3c995SLuca Coelho data = ERR_PTR(-ENOMEM); 43*84c3c995SLuca Coelho *len = 0; 44*84c3c995SLuca Coelho goto out; 45*84c3c995SLuca Coelho } 46*84c3c995SLuca Coelho 47*84c3c995SLuca Coelho err = efivar_entry_get(pnvm_efivar, NULL, &package_size, data); 48*84c3c995SLuca Coelho if (err) { 49*84c3c995SLuca Coelho IWL_DEBUG_FW(trans, 50*84c3c995SLuca Coelho "PNVM UEFI variable not found %d (len %zd)\n", 51*84c3c995SLuca Coelho err, package_size); 52*84c3c995SLuca Coelho kfree(data); 53*84c3c995SLuca Coelho data = ERR_PTR(err); 54*84c3c995SLuca Coelho goto out; 55*84c3c995SLuca Coelho } 56*84c3c995SLuca Coelho 57*84c3c995SLuca Coelho IWL_DEBUG_FW(trans, "Read PNVM from UEFI with size %zd\n", package_size); 58*84c3c995SLuca Coelho *len = package_size; 59*84c3c995SLuca Coelho 60*84c3c995SLuca Coelho out: 61*84c3c995SLuca Coelho kfree(pnvm_efivar); 62*84c3c995SLuca Coelho 63*84c3c995SLuca Coelho return data; 64*84c3c995SLuca Coelho } 65