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;
 | 
						|
}
 |