| /** @file | |
| Implementation of reading and writing operations on the NVRAM device | |
| attached to a network interface. | |
| Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials are licensed | |
| and made available under the terms and conditions of the BSD License which | |
| accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #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 ((EFI_D_NET, "\nsnp->undi.nvdata () ")); | |
| (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb); | |
| switch (Snp->Cdb.StatCode) { | |
| case PXE_STATCODE_SUCCESS: | |
| break; | |
| case PXE_STATCODE_UNSUPPORTED: | |
| DEBUG ( | |
| (EFI_D_NET, | |
| "\nsnp->undi.nvdata() %xh:%xh\n", | |
| Snp->Cdb.StatFlags, | |
| Snp->Cdb.StatCode) | |
| ); | |
| return EFI_UNSUPPORTED; | |
| default: | |
| DEBUG ( | |
| (EFI_D_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; | |
| } |