Fix few typos in comments and documentation. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Antoine Coeur <coeur@gmx.fr> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com> Message-Id: <20200207010831.9046-59-philmd@redhat.com>
		
			
				
	
	
		
			304 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   Helper functions used by at least two Simple Network Protocol methods.
 | |
| 
 | |
|   Copyright (C) 2013, Red Hat, Inc.
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| 
 | |
| #include "VirtioNet.h"
 | |
| 
 | |
| //
 | |
| // The user structure for the ordered collection that will track the mapping
 | |
| // info of the packets queued in TxRing
 | |
| //
 | |
| typedef struct {
 | |
|   VOID                  *Buffer;
 | |
|   EFI_PHYSICAL_ADDRESS  DeviceAddress;  // lookup key for reverse mapping
 | |
|   VOID                  *BufMap;
 | |
| } TX_BUF_MAP_INFO;
 | |
| 
 | |
| /**
 | |
|   Release RX and TX resources on the boundary of the
 | |
|   EfiSimpleNetworkInitialized state.
 | |
| 
 | |
|   These functions contribute to rolling back a partial, failed initialization
 | |
|   of the virtio-net SNP driver instance, or to shutting down a fully
 | |
|   initialized, running instance.
 | |
| 
 | |
|   They are only callable by the VirtioNetInitialize() and the
 | |
|   VirtioNetShutdown() SNP methods. See the state diagram in "VirtioNet.h".
 | |
| 
 | |
|   @param[in,out] Dev  The VNET_DEV driver instance being shut down, or whose
 | |
|                       partial, failed initialization is being rolled back.
 | |
| */
 | |
| 
 | |
| VOID
 | |
| EFIAPI
 | |
| VirtioNetShutdownRx (
 | |
|   IN OUT VNET_DEV *Dev
 | |
|   )
 | |
| {
 | |
|   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
 | |
|   Dev->VirtIo->FreeSharedPages (
 | |
|                  Dev->VirtIo,
 | |
|                  Dev->RxBufNrPages,
 | |
|                  Dev->RxBuf
 | |
|                  );
 | |
| }
 | |
| 
 | |
| 
 | |
| VOID
 | |
| EFIAPI
 | |
| VirtioNetShutdownTx (
 | |
|   IN OUT VNET_DEV *Dev
 | |
|   )
 | |
| {
 | |
|   ORDERED_COLLECTION_ENTRY *Entry, *Entry2;
 | |
|   TX_BUF_MAP_INFO          *TxBufMapInfo;
 | |
|   VOID                     *UserStruct;
 | |
| 
 | |
|   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxSharedReqMap);
 | |
|   Dev->VirtIo->FreeSharedPages (
 | |
|                  Dev->VirtIo,
 | |
|                  EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
 | |
|                  Dev->TxSharedReq
 | |
|                  );
 | |
| 
 | |
|   for (Entry = OrderedCollectionMin (Dev->TxBufCollection);
 | |
|        Entry != NULL;
 | |
|        Entry = Entry2) {
 | |
|     Entry2 = OrderedCollectionNext (Entry);
 | |
|     OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
 | |
|     TxBufMapInfo = UserStruct;
 | |
|     Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, TxBufMapInfo->BufMap);
 | |
|     FreePool (TxBufMapInfo);
 | |
|   }
 | |
|   OrderedCollectionUninit (Dev->TxBufCollection);
 | |
| 
 | |
|   FreePool (Dev->TxFreeStack);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Release TX and RX VRING resources.
 | |
| 
 | |
|   @param[in,out] Dev       The VNET_DEV driver instance which was using
 | |
|                            the ring.
 | |
|   @param[in,out] Ring      The virtio ring to clean up.
 | |
|   @param[in]     RingMap   A token return from the VirtioRingMap()
 | |
| */
 | |
| VOID
 | |
| EFIAPI
 | |
| VirtioNetUninitRing (
 | |
|   IN OUT VNET_DEV *Dev,
 | |
|   IN OUT VRING    *Ring,
 | |
|   IN     VOID     *RingMap
 | |
|   )
 | |
| {
 | |
|   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RingMap);
 | |
|   VirtioRingUninit (Dev->VirtIo, Ring);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Map Caller-supplied TxBuf buffer to the device-mapped address
 | |
| 
 | |
|   @param[in]    Dev               The VNET_DEV driver instance which wants to
 | |
|                                   map the Tx packet.
 | |
|   @param[in]    Buffer            The system physical address of TxBuf
 | |
|   @param[in]    NumberOfBytes     Number of bytes to map
 | |
|   @param[out]   DeviceAddress     The resulting device address for the bus
 | |
|                                   master access.
 | |
| 
 | |
|   @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to
 | |
|                                   a lack of resources.
 | |
|   @return                         Status codes from
 | |
|                                   VirtioMapAllBytesInSharedBuffer()
 | |
|   @retval EFI_SUCCESS             Caller-supplied buffer is successfully mapped.
 | |
| */
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| VirtioNetMapTxBuf (
 | |
|   IN  VNET_DEV              *Dev,
 | |
|   IN  VOID                  *Buffer,
 | |
|   IN  UINTN                 NumberOfBytes,
 | |
|   OUT EFI_PHYSICAL_ADDRESS  *DeviceAddress
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                Status;
 | |
|   TX_BUF_MAP_INFO           *TxBufMapInfo;
 | |
|   EFI_PHYSICAL_ADDRESS      Address;
 | |
|   VOID                      *Mapping;
 | |
| 
 | |
|   TxBufMapInfo = AllocatePool (sizeof (*TxBufMapInfo));
 | |
|   if (TxBufMapInfo == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   Status = VirtioMapAllBytesInSharedBuffer (
 | |
|              Dev->VirtIo,
 | |
|              VirtioOperationBusMasterRead,
 | |
|              Buffer,
 | |
|              NumberOfBytes,
 | |
|              &Address,
 | |
|              &Mapping
 | |
|             );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto FreeTxBufMapInfo;
 | |
|   }
 | |
| 
 | |
|   TxBufMapInfo->Buffer = Buffer;
 | |
|   TxBufMapInfo->DeviceAddress = Address;
 | |
|   TxBufMapInfo->BufMap = Mapping;
 | |
| 
 | |
|   Status = OrderedCollectionInsert (
 | |
|              Dev->TxBufCollection,
 | |
|              NULL,
 | |
|              TxBufMapInfo
 | |
|              );
 | |
|   switch (Status) {
 | |
|   case EFI_OUT_OF_RESOURCES:
 | |
|     goto UnmapTxBuf;
 | |
|   case EFI_ALREADY_STARTED:
 | |
|     //
 | |
|     // This should never happen: it implies
 | |
|     //
 | |
|     // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
 | |
|     //   implementation -- which is fine,
 | |
|     //
 | |
|     // - and an SNP client that queues multiple instances of the exact same
 | |
|     //   buffer address with SNP.Transmit() -- which is undefined behavior,
 | |
|     //   based on the TxBuf language in UEFI-2.7,
 | |
|     //   EFI_SIMPLE_NETWORK.GetStatus().
 | |
|     //
 | |
|     ASSERT (FALSE);
 | |
|     Status = EFI_INVALID_PARAMETER;
 | |
|     goto UnmapTxBuf;
 | |
|   default:
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   *DeviceAddress = Address;
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| UnmapTxBuf:
 | |
|   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
 | |
| 
 | |
| FreeTxBufMapInfo:
 | |
|   FreePool (TxBufMapInfo);
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
 | |
|   physical address
 | |
| 
 | |
|   @param[in]    Dev               The VNET_DEV driver instance which wants to
 | |
|                                   reverse- and unmap the Tx packet.
 | |
|   @param[out]   Buffer            The system physical address of TxBuf
 | |
|   @param[in]    DeviceAddress     The device address for the TxBuf
 | |
| 
 | |
|   @retval EFI_INVALID_PARAMETER   The DeviceAddress is not mapped
 | |
|   @retval EFI_SUCCESS             The TxBuf at DeviceAddress has been unmapped,
 | |
|                                   and Buffer has been set to TxBuf's system
 | |
|                                   physical address.
 | |
| 
 | |
| */
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| VirtioNetUnmapTxBuf (
 | |
|   IN  VNET_DEV              *Dev,
 | |
|   OUT VOID                  **Buffer,
 | |
|   IN  EFI_PHYSICAL_ADDRESS  DeviceAddress
 | |
|   )
 | |
| {
 | |
|   ORDERED_COLLECTION_ENTRY  *Entry;
 | |
|   TX_BUF_MAP_INFO           *TxBufMapInfo;
 | |
|   VOID                      *UserStruct;
 | |
| 
 | |
|   Entry = OrderedCollectionFind (Dev->TxBufCollection, &DeviceAddress);
 | |
|   if (Entry == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
 | |
| 
 | |
|   TxBufMapInfo = UserStruct;
 | |
| 
 | |
|   *Buffer = TxBufMapInfo->Buffer;
 | |
|   Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, TxBufMapInfo->BufMap);
 | |
|   FreePool (TxBufMapInfo);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Comparator function for two TX_BUF_MAP_INFO objects.
 | |
| 
 | |
|   @param[in] UserStruct1  Pointer to the first TX_BUF_MAP_INFO object.
 | |
| 
 | |
|   @param[in] UserStruct2  Pointer to the second TX_BUF_MAP_INFO object.
 | |
| 
 | |
|   @retval <0  If UserStruct1 compares less than UserStruct2.
 | |
| 
 | |
|   @retval  0  If UserStruct1 compares equal to UserStruct2.
 | |
| 
 | |
|   @retval >0  If UserStruct1 compares greater than UserStruct2.
 | |
| */
 | |
| INTN
 | |
| EFIAPI
 | |
| VirtioNetTxBufMapInfoCompare (
 | |
|   IN CONST VOID *UserStruct1,
 | |
|   IN CONST VOID *UserStruct2
 | |
|   )
 | |
| {
 | |
|   CONST TX_BUF_MAP_INFO *MapInfo1;
 | |
|   CONST TX_BUF_MAP_INFO *MapInfo2;
 | |
| 
 | |
|   MapInfo1 = UserStruct1;
 | |
|   MapInfo2 = UserStruct2;
 | |
| 
 | |
|   return MapInfo1->DeviceAddress < MapInfo2->DeviceAddress ? -1 :
 | |
|          MapInfo1->DeviceAddress > MapInfo2->DeviceAddress ?  1 :
 | |
|          0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
 | |
|   containing an embedded DeviceAddress.
 | |
| 
 | |
|   @param[in] StandaloneKey  Pointer to DeviceAddress, which has type
 | |
|                             EFI_PHYSICAL_ADDRESS.
 | |
| 
 | |
|   @param[in] UserStruct     Pointer to the TX_BUF_MAP_INFO object with the
 | |
|                             embedded DeviceAddress.
 | |
| 
 | |
|   @retval <0  If StandaloneKey compares less than UserStruct's key.
 | |
| 
 | |
|   @retval  0  If StandaloneKey compares equal to UserStruct's key.
 | |
| 
 | |
|   @retval >0  If StandaloneKey compares greater than UserStruct's key.
 | |
| **/
 | |
| INTN
 | |
| EFIAPI
 | |
| VirtioNetTxBufDeviceAddressCompare (
 | |
|   IN CONST VOID *StandaloneKey,
 | |
|   IN CONST VOID *UserStruct
 | |
|   )
 | |
| {
 | |
|   CONST EFI_PHYSICAL_ADDRESS *DeviceAddress;
 | |
|   CONST TX_BUF_MAP_INFO      *MapInfo;
 | |
| 
 | |
|   DeviceAddress = StandaloneKey;
 | |
|   MapInfo = UserStruct;
 | |
| 
 | |
|   return *DeviceAddress < MapInfo->DeviceAddress ? -1 :
 | |
|          *DeviceAddress > MapInfo->DeviceAddress ?  1 :
 | |
|          0;
 | |
| }
 |