/** @file | |
Implementation of reading and writing operations on the NVRAM device | |
attached to a network interface. | |
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "Snp.h" | |
/** | |
This routine calls Undi to read the desired number of eeprom bytes. | |
@param Snp pointer to the snp driver structure | |
@param Offset eeprom register value relative to the base address | |
@param BufferSize number of bytes to read | |
@param Buffer pointer where to read into | |
@retval EFI_SUCCESS The NVRAM access was performed. | |
@retval EFI_INVALID_PARAMETER Invalid UNDI command. | |
@retval EFI_UNSUPPORTED Command is not supported by UNDI. | |
@retval EFI_DEVICE_ERROR Fail to execute UNDI command. | |
**/ | |
EFI_STATUS | |
PxeNvDataRead ( | |
IN SNP_DRIVER *Snp, | |
IN UINTN Offset, | |
IN UINTN BufferSize, | |
IN OUT VOID *Buffer | |
) | |
{ | |
PXE_DB_NVDATA *Db; | |
Db = Snp->Db; | |
Snp->Cdb.OpCode = PXE_OPCODE_NVDATA; | |
Snp->Cdb.OpFlags = PXE_OPFLAGS_NVDATA_READ; | |
Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED; | |
Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED; | |
Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_NVDATA); | |
Snp->Cdb.DBaddr = (UINT64)(UINTN)Db; | |
Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE; | |
Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE; | |
Snp->Cdb.IFnum = Snp->IfNum; | |
Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST; | |
// | |
// Issue UNDI command and check result. | |
// | |
DEBUG ((DEBUG_NET, "\nsnp->undi.nvdata () ")); | |
(*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb); | |
switch (Snp->Cdb.StatCode) { | |
case PXE_STATCODE_SUCCESS: | |
break; | |
case PXE_STATCODE_UNSUPPORTED: | |
DEBUG ( | |
(DEBUG_NET, | |
"\nsnp->undi.nvdata() %xh:%xh\n", | |
Snp->Cdb.StatFlags, | |
Snp->Cdb.StatCode) | |
); | |
return EFI_UNSUPPORTED; | |
default: | |
DEBUG ( | |
(DEBUG_NET, | |
"\nsnp->undi.nvdata() %xh:%xh\n", | |
Snp->Cdb.StatFlags, | |
Snp->Cdb.StatCode) | |
); | |
return EFI_DEVICE_ERROR; | |
} | |
ASSERT (Offset < sizeof (Db->Data)); | |
CopyMem (Buffer, &Db->Data.Byte[Offset], BufferSize); | |
return EFI_SUCCESS; | |
} | |
/** | |
Performs read and write operations on the NVRAM device attached to a network | |
interface. | |
This function performs read and write operations on the NVRAM device attached | |
to a network interface. If ReadWrite is TRUE, a read operation is performed. | |
If ReadWrite is FALSE, a write operation is performed. Offset specifies the | |
byte offset at which to start either operation. Offset must be a multiple of | |
NvRamAccessSize , and it must have a value between zero and NvRamSize. | |
BufferSize specifies the length of the read or write operation. BufferSize must | |
also be a multiple of NvRamAccessSize, and Offset + BufferSize must not exceed | |
NvRamSize. | |
If any of the above conditions is not met, then EFI_INVALID_PARAMETER will be | |
returned. | |
If all the conditions are met and the operation is "read," the NVRAM device | |
attached to the network interface will be read into Buffer and EFI_SUCCESS | |
will be returned. If this is a write operation, the contents of Buffer will be | |
used to update the contents of the NVRAM device attached to the network | |
interface and EFI_SUCCESS will be returned. | |
It does the basic checking on the input parameters and retrieves snp structure | |
and then calls the read_nvdata() call which does the actual reading | |
@param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance. | |
@param ReadWrite TRUE for read operations, FALSE for write operations. | |
@param Offset Byte offset in the NVRAM device at which to start the read or | |
write operation. This must be a multiple of NvRamAccessSize | |
and less than NvRamSize. (See EFI_SIMPLE_NETWORK_MODE) | |
@param BufferSize The number of bytes to read or write from the NVRAM device. | |
This must also be a multiple of NvramAccessSize. | |
@param Buffer A pointer to the data buffer. | |
@retval EFI_SUCCESS The NVRAM access was performed. | |
@retval EFI_NOT_STARTED The network interface has not been started. | |
@retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: | |
* The This parameter is NULL | |
* The This parameter does not point to a valid | |
EFI_SIMPLE_NETWORK_PROTOCOL structure | |
* The Offset parameter is not a multiple of | |
EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize | |
* The Offset parameter is not less than | |
EFI_SIMPLE_NETWORK_MODE.NvRamSize | |
* The BufferSize parameter is not a multiple of | |
EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize | |
* The Buffer parameter is NULL | |
@retval EFI_DEVICE_ERROR The command could not be sent to the network | |
interface. | |
@retval EFI_UNSUPPORTED This function is not supported by the network | |
interface. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
SnpUndi32NvData ( | |
IN EFI_SIMPLE_NETWORK_PROTOCOL *This, | |
IN BOOLEAN ReadWrite, | |
IN UINTN Offset, | |
IN UINTN BufferSize, | |
IN OUT VOID *Buffer | |
) | |
{ | |
SNP_DRIVER *Snp; | |
EFI_TPL OldTpl; | |
EFI_STATUS Status; | |
// | |
// Get pointer to SNP driver instance for *this. | |
// | |
if (This == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This); | |
OldTpl = gBS->RaiseTPL (TPL_CALLBACK); | |
// | |
// Return error if the SNP is not initialized. | |
// | |
switch (Snp->Mode.State) { | |
case EfiSimpleNetworkInitialized: | |
break; | |
case EfiSimpleNetworkStopped: | |
Status = EFI_NOT_STARTED; | |
goto ON_EXIT; | |
default: | |
Status = EFI_DEVICE_ERROR; | |
goto ON_EXIT; | |
} | |
// | |
// Return error if non-volatile memory variables are not valid. | |
// | |
if ((Snp->Mode.NvRamSize == 0) || (Snp->Mode.NvRamAccessSize == 0)) { | |
Status = EFI_UNSUPPORTED; | |
goto ON_EXIT; | |
} | |
// | |
// Check for invalid parameter combinations. | |
// | |
if ((BufferSize == 0) || | |
(Buffer == NULL) || | |
(Offset >= Snp->Mode.NvRamSize) || | |
(Offset + BufferSize > Snp->Mode.NvRamSize) || | |
(BufferSize % Snp->Mode.NvRamAccessSize != 0) || | |
(Offset % Snp->Mode.NvRamAccessSize != 0) | |
) | |
{ | |
Status = EFI_INVALID_PARAMETER; | |
goto ON_EXIT; | |
} | |
// | |
// check the implementation flags of undi if we can write the nvdata! | |
// | |
if (!ReadWrite) { | |
Status = EFI_UNSUPPORTED; | |
} else { | |
Status = PxeNvDataRead (Snp, Offset, BufferSize, Buffer); | |
} | |
ON_EXIT: | |
gBS->RestoreTPL (OldTpl); | |
return Status; | |
} |