3 Helper functions used by at least two Simple Network Protocol methods.
5 Copyright (C) 2013, Red Hat, Inc.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/MemoryAllocationLib.h>
13 #include "VirtioNet.h"
16 // The user structure for the ordered collection that will track the mapping
17 // info of the packets queued in TxRing
21 EFI_PHYSICAL_ADDRESS DeviceAddress
; // lookup key for reverse mapping
26 Release RX and TX resources on the boundary of the
27 EfiSimpleNetworkInitialized state.
29 These functions contribute to rolling back a partial, failed initialization
30 of the virtio-net SNP driver instance, or to shutting down a fully
31 initialized, running instance.
33 They are only callable by the VirtioNetInitialize() and the
34 VirtioNetShutdown() SNP methods. See the state diagram in "VirtioNet.h".
36 @param[in,out] Dev The VNET_DEV driver instance being shut down, or whose
37 partial, failed initialization is being rolled back.
45 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->RxBufMap
);
46 Dev
->VirtIo
->FreeSharedPages (
59 ORDERED_COLLECTION_ENTRY
*Entry
, *Entry2
;
60 TX_BUF_MAP_INFO
*TxBufMapInfo
;
63 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->TxSharedReqMap
);
64 Dev
->VirtIo
->FreeSharedPages (
66 EFI_SIZE_TO_PAGES (sizeof *(Dev
->TxSharedReq
)),
70 for (Entry
= OrderedCollectionMin (Dev
->TxBufCollection
);
74 Entry2
= OrderedCollectionNext (Entry
);
75 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
76 TxBufMapInfo
= UserStruct
;
77 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
78 FreePool (TxBufMapInfo
);
81 OrderedCollectionUninit (Dev
->TxBufCollection
);
83 FreePool (Dev
->TxFreeStack
);
87 Release TX and RX VRING resources.
89 @param[in,out] Dev The VNET_DEV driver instance which was using
91 @param[in,out] Ring The virtio ring to clean up.
92 @param[in] RingMap A token return from the VirtioRingMap()
102 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, RingMap
);
103 VirtioRingUninit (Dev
->VirtIo
, Ring
);
107 Map Caller-supplied TxBuf buffer to the device-mapped address
109 @param[in] Dev The VNET_DEV driver instance which wants to
111 @param[in] Buffer The system physical address of TxBuf
112 @param[in] NumberOfBytes Number of bytes to map
113 @param[out] DeviceAddress The resulting device address for the bus
116 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to
118 @return Status codes from
119 VirtioMapAllBytesInSharedBuffer()
120 @retval EFI_SUCCESS Caller-supplied buffer is successfully mapped.
127 IN UINTN NumberOfBytes
,
128 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
132 TX_BUF_MAP_INFO
*TxBufMapInfo
;
133 EFI_PHYSICAL_ADDRESS Address
;
136 TxBufMapInfo
= AllocatePool (sizeof (*TxBufMapInfo
));
137 if (TxBufMapInfo
== NULL
) {
138 return EFI_OUT_OF_RESOURCES
;
141 Status
= VirtioMapAllBytesInSharedBuffer (
143 VirtioOperationBusMasterRead
,
149 if (EFI_ERROR (Status
)) {
150 goto FreeTxBufMapInfo
;
153 TxBufMapInfo
->Buffer
= Buffer
;
154 TxBufMapInfo
->DeviceAddress
= Address
;
155 TxBufMapInfo
->BufMap
= Mapping
;
157 Status
= OrderedCollectionInsert (
158 Dev
->TxBufCollection
,
163 case EFI_OUT_OF_RESOURCES
:
165 case EFI_ALREADY_STARTED
:
167 // This should never happen: it implies
169 // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
170 // implementation -- which is fine,
172 // - and an SNP client that queues multiple instances of the exact same
173 // buffer address with SNP.Transmit() -- which is undefined behavior,
174 // based on the TxBuf language in UEFI-2.7,
175 // EFI_SIMPLE_NETWORK.GetStatus().
178 Status
= EFI_INVALID_PARAMETER
;
181 ASSERT_EFI_ERROR (Status
);
185 *DeviceAddress
= Address
;
189 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Mapping
);
192 FreePool (TxBufMapInfo
);
197 Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
200 @param[in] Dev The VNET_DEV driver instance which wants to
201 reverse- and unmap the Tx packet.
202 @param[out] Buffer The system physical address of TxBuf
203 @param[in] DeviceAddress The device address for the TxBuf
205 @retval EFI_INVALID_PARAMETER The DeviceAddress is not mapped
206 @retval EFI_SUCCESS The TxBuf at DeviceAddress has been unmapped,
207 and Buffer has been set to TxBuf's system
213 VirtioNetUnmapTxBuf (
216 IN EFI_PHYSICAL_ADDRESS DeviceAddress
219 ORDERED_COLLECTION_ENTRY
*Entry
;
220 TX_BUF_MAP_INFO
*TxBufMapInfo
;
223 Entry
= OrderedCollectionFind (Dev
->TxBufCollection
, &DeviceAddress
);
225 return EFI_INVALID_PARAMETER
;
228 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
230 TxBufMapInfo
= UserStruct
;
232 *Buffer
= TxBufMapInfo
->Buffer
;
233 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
234 FreePool (TxBufMapInfo
);
240 Comparator function for two TX_BUF_MAP_INFO objects.
242 @param[in] UserStruct1 Pointer to the first TX_BUF_MAP_INFO object.
244 @param[in] UserStruct2 Pointer to the second TX_BUF_MAP_INFO object.
246 @retval <0 If UserStruct1 compares less than UserStruct2.
248 @retval 0 If UserStruct1 compares equal to UserStruct2.
250 @retval >0 If UserStruct1 compares greater than UserStruct2.
254 VirtioNetTxBufMapInfoCompare (
255 IN CONST VOID
*UserStruct1
,
256 IN CONST VOID
*UserStruct2
259 CONST TX_BUF_MAP_INFO
*MapInfo1
;
260 CONST TX_BUF_MAP_INFO
*MapInfo2
;
262 MapInfo1
= UserStruct1
;
263 MapInfo2
= UserStruct2
;
265 return MapInfo1
->DeviceAddress
< MapInfo2
->DeviceAddress
? -1 :
266 MapInfo1
->DeviceAddress
> MapInfo2
->DeviceAddress
? 1 :
271 Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
272 containing an embedded DeviceAddress.
274 @param[in] StandaloneKey Pointer to DeviceAddress, which has type
275 EFI_PHYSICAL_ADDRESS.
277 @param[in] UserStruct Pointer to the TX_BUF_MAP_INFO object with the
278 embedded DeviceAddress.
280 @retval <0 If StandaloneKey compares less than UserStruct's key.
282 @retval 0 If StandaloneKey compares equal to UserStruct's key.
284 @retval >0 If StandaloneKey compares greater than UserStruct's key.
288 VirtioNetTxBufDeviceAddressCompare (
289 IN CONST VOID
*StandaloneKey
,
290 IN CONST VOID
*UserStruct
293 CONST EFI_PHYSICAL_ADDRESS
*DeviceAddress
;
294 CONST TX_BUF_MAP_INFO
*MapInfo
;
296 DeviceAddress
= StandaloneKey
;
297 MapInfo
= UserStruct
;
299 return *DeviceAddress
< MapInfo
->DeviceAddress
? -1 :
300 *DeviceAddress
> MapInfo
->DeviceAddress
? 1 :