3 Helper functions used by at least two Simple Network Protocol methods.
5 Copyright (C) 2013, Red Hat, Inc.
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/MemoryAllocationLib.h>
19 #include "VirtioNet.h"
22 // The user structure for the ordered collection that will track the mapping
23 // info of the packets queued in TxRing
27 EFI_PHYSICAL_ADDRESS DeviceAddress
; // lookup key for reverse mapping
32 Release RX and TX resources on the boundary of the
33 EfiSimpleNetworkInitialized state.
35 These functions contribute to rolling back a partial, failed initialization
36 of the virtio-net SNP driver instance, or to shutting down a fully
37 initialized, running instance.
39 They are only callable by the VirtioNetInitialize() and the
40 VirtioNetShutdown() SNP methods. See the state diagram in "VirtioNet.h".
42 @param[in,out] Dev The VNET_DEV driver instance being shut down, or whose
43 partial, failed initialization is being rolled back.
52 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->RxBufMap
);
53 Dev
->VirtIo
->FreeSharedPages (
67 ORDERED_COLLECTION_ENTRY
*Entry
, *Entry2
;
68 TX_BUF_MAP_INFO
*TxBufMapInfo
;
71 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Dev
->TxSharedReqMap
);
72 Dev
->VirtIo
->FreeSharedPages (
74 EFI_SIZE_TO_PAGES (sizeof *(Dev
->TxSharedReq
)),
78 for (Entry
= OrderedCollectionMin (Dev
->TxBufCollection
);
81 Entry2
= OrderedCollectionNext (Entry
);
82 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
83 TxBufMapInfo
= UserStruct
;
84 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
85 FreePool (TxBufMapInfo
);
87 OrderedCollectionUninit (Dev
->TxBufCollection
);
89 FreePool (Dev
->TxFreeStack
);
93 Release TX and RX VRING resources.
95 @param[in,out] Dev The VNET_DEV driver instance which was using
97 @param[in,out] Ring The virtio ring to clean up.
98 @param[in] RingMap A token return from the VirtioRingMap()
102 VirtioNetUninitRing (
103 IN OUT VNET_DEV
*Dev
,
108 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, RingMap
);
109 VirtioRingUninit (Dev
->VirtIo
, Ring
);
114 Map Caller-supplied TxBuf buffer to the device-mapped address
116 @param[in] Dev The VNET_DEV driver instance which wants to
118 @param[in] Buffer The system physical address of TxBuf
119 @param[in] NumberOfBytes Number of bytes to map
120 @param[out] DeviceAddress The resulting device address for the bus
123 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to
125 @return Status codes from
126 VirtioMapAllBytesInSharedBuffer()
127 @retval EFI_SUCCESS Caller-supplied buffer is succesfully mapped.
134 IN UINTN NumberOfBytes
,
135 OUT EFI_PHYSICAL_ADDRESS
*DeviceAddress
139 TX_BUF_MAP_INFO
*TxBufMapInfo
;
140 EFI_PHYSICAL_ADDRESS Address
;
143 TxBufMapInfo
= AllocatePool (sizeof (*TxBufMapInfo
));
144 if (TxBufMapInfo
== NULL
) {
145 return EFI_OUT_OF_RESOURCES
;
148 Status
= VirtioMapAllBytesInSharedBuffer (
150 VirtioOperationBusMasterRead
,
156 if (EFI_ERROR (Status
)) {
157 goto FreeTxBufMapInfo
;
160 TxBufMapInfo
->Buffer
= Buffer
;
161 TxBufMapInfo
->DeviceAddress
= Address
;
162 TxBufMapInfo
->BufMap
= Mapping
;
164 Status
= OrderedCollectionInsert (
165 Dev
->TxBufCollection
,
170 case EFI_OUT_OF_RESOURCES
:
172 case EFI_ALREADY_STARTED
:
174 // This should never happen: it implies
176 // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
177 // implementation -- which is fine,
179 // - and an SNP client that queues multiple instances of the exact same
180 // buffer address with SNP.Transmit() -- which is undefined behavior,
181 // based on the TxBuf language in UEFI-2.7,
182 // EFI_SIMPLE_NETWORK.GetStatus().
185 Status
= EFI_INVALID_PARAMETER
;
188 ASSERT_EFI_ERROR (Status
);
192 *DeviceAddress
= Address
;
196 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, Mapping
);
199 FreePool (TxBufMapInfo
);
204 Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
207 @param[in] Dev The VNET_DEV driver instance which wants to
208 reverse- and unmap the Tx packet.
209 @param[out] Buffer The system physical address of TxBuf
210 @param[in] DeviceAddress The device address for the TxBuf
212 @retval EFI_INVALID_PARAMETER The DeviceAddress is not mapped
213 @retval EFI_SUCCESS The TxBuf at DeviceAddress has been unmapped,
214 and Buffer has been set to TxBuf's system
220 VirtioNetUnmapTxBuf (
223 IN EFI_PHYSICAL_ADDRESS DeviceAddress
226 ORDERED_COLLECTION_ENTRY
*Entry
;
227 TX_BUF_MAP_INFO
*TxBufMapInfo
;
230 Entry
= OrderedCollectionFind (Dev
->TxBufCollection
, &DeviceAddress
);
232 return EFI_INVALID_PARAMETER
;
235 OrderedCollectionDelete (Dev
->TxBufCollection
, Entry
, &UserStruct
);
237 TxBufMapInfo
= UserStruct
;
239 *Buffer
= TxBufMapInfo
->Buffer
;
240 Dev
->VirtIo
->UnmapSharedBuffer (Dev
->VirtIo
, TxBufMapInfo
->BufMap
);
241 FreePool (TxBufMapInfo
);
247 Comparator function for two TX_BUF_MAP_INFO objects.
249 @param[in] UserStruct1 Pointer to the first TX_BUF_MAP_INFO object.
251 @param[in] UserStruct2 Pointer to the second TX_BUF_MAP_INFO object.
253 @retval <0 If UserStruct1 compares less than UserStruct2.
255 @retval 0 If UserStruct1 compares equal to UserStruct2.
257 @retval >0 If UserStruct1 compares greater than UserStruct2.
261 VirtioNetTxBufMapInfoCompare (
262 IN CONST VOID
*UserStruct1
,
263 IN CONST VOID
*UserStruct2
266 CONST TX_BUF_MAP_INFO
*MapInfo1
;
267 CONST TX_BUF_MAP_INFO
*MapInfo2
;
269 MapInfo1
= UserStruct1
;
270 MapInfo2
= UserStruct2
;
272 return MapInfo1
->DeviceAddress
< MapInfo2
->DeviceAddress
? -1 :
273 MapInfo1
->DeviceAddress
> MapInfo2
->DeviceAddress
? 1 :
278 Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
279 containing an embedded DeviceAddress.
281 @param[in] StandaloneKey Pointer to DeviceAddress, which has type
282 EFI_PHYSICAL_ADDRESS.
284 @param[in] UserStruct Pointer to the TX_BUF_MAP_INFO object with the
285 embedded DeviceAddress.
287 @retval <0 If StandaloneKey compares less than UserStruct's key.
289 @retval 0 If StandaloneKey compares equal to UserStruct's key.
291 @retval >0 If StandaloneKey compares greater than UserStruct's key.
295 VirtioNetTxBufDeviceAddressCompare (
296 IN CONST VOID
*StandaloneKey
,
297 IN CONST VOID
*UserStruct
300 CONST EFI_PHYSICAL_ADDRESS
*DeviceAddress
;
301 CONST TX_BUF_MAP_INFO
*MapInfo
;
303 DeviceAddress
= StandaloneKey
;
304 MapInfo
= UserStruct
;
306 return *DeviceAddress
< MapInfo
->DeviceAddress
? -1 :
307 *DeviceAddress
> MapInfo
->DeviceAddress
? 1 :