123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /** @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;
- }
|