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.
46 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->RxBufMap
);
47 Dev
->VirtIo
->FreeSharedPages (
61 ORDERED_COLLECTION_ENTRY
*Entry
, *Entry2
;
62 TX_BUF_MAP_INFO
*TxBufMapInfo
;
65 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->TxSharedReqMap
);
66 Dev
->VirtIo
->FreeSharedPages (
68 EFI_SIZE_TO_PAGES (sizeof *(Dev
->TxSharedReq
)),
72 for (Entry
= OrderedCollectionMin (Dev
->TxBufCollection
);
75 Entry2
= OrderedCollectionNext (Entry
);
76 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
77 TxBufMapInfo
= UserStruct
;
78 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
79 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
);
108 Map Caller-supplied TxBuf buffer to the device-mapped address
110 @param[in] Dev The VNET_DEV driver instance which wants to
112 @param[in] Buffer The system physical address of TxBuf
113 @param[in] NumberOfBytes Number of bytes to map
114 @param[out] DeviceAddress The resulting device address for the bus
117 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to
119 @return Status codes from
120 VirtioMapAllBytesInSharedBuffer()
121 @retval EFI_SUCCESS Caller-supplied buffer is successfully mapped.
128 IN UINTN NumberOfBytes
,
129 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
133 TX_BUF_MAP_INFO
*TxBufMapInfo
;
134 EFI_PHYSICAL_ADDRESS Address
;
137 TxBufMapInfo
= AllocatePool (sizeof (*TxBufMapInfo
));
138 if (TxBufMapInfo
== NULL
) {
139 return EFI_OUT_OF_RESOURCES
;
142 Status
= VirtioMapAllBytesInSharedBuffer (
144 VirtioOperationBusMasterRead
,
150 if (EFI_ERROR (Status
)) {
151 goto FreeTxBufMapInfo
;
154 TxBufMapInfo
->Buffer
= Buffer
;
155 TxBufMapInfo
->DeviceAddress
= Address
;
156 TxBufMapInfo
->BufMap
= Mapping
;
158 Status
= OrderedCollectionInsert (
159 Dev
->TxBufCollection
,
164 case EFI_OUT_OF_RESOURCES
:
166 case EFI_ALREADY_STARTED
:
168 // This should never happen: it implies
170 // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
171 // implementation -- which is fine,
173 // - and an SNP client that queues multiple instances of the exact same
174 // buffer address with SNP.Transmit() -- which is undefined behavior,
175 // based on the TxBuf language in UEFI-2.7,
176 // EFI_SIMPLE_NETWORK.GetStatus().
179 Status
= EFI_INVALID_PARAMETER
;
182 ASSERT_EFI_ERROR (Status
);
186 *DeviceAddress
= Address
;
190 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Mapping
);
193 FreePool (TxBufMapInfo
);
198 Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
201 @param[in] Dev The VNET_DEV driver instance which wants to
202 reverse- and unmap the Tx packet.
203 @param[out] Buffer The system physical address of TxBuf
204 @param[in] DeviceAddress The device address for the TxBuf
206 @retval EFI_INVALID_PARAMETER The DeviceAddress is not mapped
207 @retval EFI_SUCCESS The TxBuf at DeviceAddress has been unmapped,
208 and Buffer has been set to TxBuf's system
214 VirtioNetUnmapTxBuf (
217 IN EFI_PHYSICAL_ADDRESS DeviceAddress
220 ORDERED_COLLECTION_ENTRY
*Entry
;
221 TX_BUF_MAP_INFO
*TxBufMapInfo
;
224 Entry
= OrderedCollectionFind (Dev
->TxBufCollection
, &DeviceAddress
);
226 return EFI_INVALID_PARAMETER
;
229 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
231 TxBufMapInfo
= UserStruct
;
233 *Buffer
= TxBufMapInfo
->Buffer
;
234 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
235 FreePool (TxBufMapInfo
);
241 Comparator function for two TX_BUF_MAP_INFO objects.
243 @param[in] UserStruct1 Pointer to the first TX_BUF_MAP_INFO object.
245 @param[in] UserStruct2 Pointer to the second TX_BUF_MAP_INFO object.
247 @retval <0 If UserStruct1 compares less than UserStruct2.
249 @retval 0 If UserStruct1 compares equal to UserStruct2.
251 @retval >0 If UserStruct1 compares greater than UserStruct2.
255 VirtioNetTxBufMapInfoCompare (
256 IN CONST VOID
*UserStruct1
,
257 IN CONST VOID
*UserStruct2
260 CONST TX_BUF_MAP_INFO
*MapInfo1
;
261 CONST TX_BUF_MAP_INFO
*MapInfo2
;
263 MapInfo1
= UserStruct1
;
264 MapInfo2
= UserStruct2
;
266 return MapInfo1
->DeviceAddress
< MapInfo2
->DeviceAddress
? -1 :
267 MapInfo1
->DeviceAddress
> MapInfo2
->DeviceAddress
? 1 :
272 Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
273 containing an embedded DeviceAddress.
275 @param[in] StandaloneKey Pointer to DeviceAddress, which has type
276 EFI_PHYSICAL_ADDRESS.
278 @param[in] UserStruct Pointer to the TX_BUF_MAP_INFO object with the
279 embedded DeviceAddress.
281 @retval <0 If StandaloneKey compares less than UserStruct's key.
283 @retval 0 If StandaloneKey compares equal to UserStruct's key.
285 @retval >0 If StandaloneKey compares greater than UserStruct's key.
289 VirtioNetTxBufDeviceAddressCompare (
290 IN CONST VOID
*StandaloneKey
,
291 IN CONST VOID
*UserStruct
294 CONST EFI_PHYSICAL_ADDRESS
*DeviceAddress
;
295 CONST TX_BUF_MAP_INFO
*MapInfo
;
297 DeviceAddress
= StandaloneKey
;
298 MapInfo
= UserStruct
;
300 return *DeviceAddress
< MapInfo
->DeviceAddress
? -1 :
301 *DeviceAddress
> MapInfo
->DeviceAddress
? 1 :