VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c@ 99396

Last change on this file since 99396 was 85718, checked in by vboxsync, 4 years ago

Devices/EFI: Merge edk-stable202005 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1/** @file
2
3 Helper functions used by at least two Simple Network Protocol methods.
4
5 Copyright (C) 2013, Red Hat, Inc.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include <Library/MemoryAllocationLib.h>
12
13#include "VirtioNet.h"
14
15//
16// The user structure for the ordered collection that will track the mapping
17// info of the packets queued in TxRing
18//
19typedef struct {
20 VOID *Buffer;
21 EFI_PHYSICAL_ADDRESS DeviceAddress; // lookup key for reverse mapping
22 VOID *BufMap;
23} TX_BUF_MAP_INFO;
24
25/**
26 Release RX and TX resources on the boundary of the
27 EfiSimpleNetworkInitialized state.
28
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.
32
33 They are only callable by the VirtioNetInitialize() and the
34 VirtioNetShutdown() SNP methods. See the state diagram in "VirtioNet.h".
35
36 @param[in,out] Dev The VNET_DEV driver instance being shut down, or whose
37 partial, failed initialization is being rolled back.
38*/
39
40VOID
41EFIAPI
42VirtioNetShutdownRx (
43 IN OUT VNET_DEV *Dev
44 )
45{
46 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RxBufMap);
47 Dev->VirtIo->FreeSharedPages (
48 Dev->VirtIo,
49 Dev->RxBufNrPages,
50 Dev->RxBuf
51 );
52}
53
54
55VOID
56EFIAPI
57VirtioNetShutdownTx (
58 IN OUT VNET_DEV *Dev
59 )
60{
61 ORDERED_COLLECTION_ENTRY *Entry, *Entry2;
62 TX_BUF_MAP_INFO *TxBufMapInfo;
63 VOID *UserStruct;
64
65 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->TxSharedReqMap);
66 Dev->VirtIo->FreeSharedPages (
67 Dev->VirtIo,
68 EFI_SIZE_TO_PAGES (sizeof *(Dev->TxSharedReq)),
69 Dev->TxSharedReq
70 );
71
72 for (Entry = OrderedCollectionMin (Dev->TxBufCollection);
73 Entry != NULL;
74 Entry = Entry2) {
75 Entry2 = OrderedCollectionNext (Entry);
76 OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
77 TxBufMapInfo = UserStruct;
78 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, TxBufMapInfo->BufMap);
79 FreePool (TxBufMapInfo);
80 }
81 OrderedCollectionUninit (Dev->TxBufCollection);
82
83 FreePool (Dev->TxFreeStack);
84}
85
86/**
87 Release TX and RX VRING resources.
88
89 @param[in,out] Dev The VNET_DEV driver instance which was using
90 the ring.
91 @param[in,out] Ring The virtio ring to clean up.
92 @param[in] RingMap A token return from the VirtioRingMap()
93*/
94VOID
95EFIAPI
96VirtioNetUninitRing (
97 IN OUT VNET_DEV *Dev,
98 IN OUT VRING *Ring,
99 IN VOID *RingMap
100 )
101{
102 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, RingMap);
103 VirtioRingUninit (Dev->VirtIo, Ring);
104}
105
106
107/**
108 Map Caller-supplied TxBuf buffer to the device-mapped address
109
110 @param[in] Dev The VNET_DEV driver instance which wants to
111 map the Tx packet.
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
115 master access.
116
117 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to
118 a lack of resources.
119 @return Status codes from
120 VirtioMapAllBytesInSharedBuffer()
121 @retval EFI_SUCCESS Caller-supplied buffer is successfully mapped.
122*/
123EFI_STATUS
124EFIAPI
125VirtioNetMapTxBuf (
126 IN VNET_DEV *Dev,
127 IN VOID *Buffer,
128 IN UINTN NumberOfBytes,
129 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress
130 )
131{
132 EFI_STATUS Status;
133 TX_BUF_MAP_INFO *TxBufMapInfo;
134 EFI_PHYSICAL_ADDRESS Address;
135 VOID *Mapping;
136
137 TxBufMapInfo = AllocatePool (sizeof (*TxBufMapInfo));
138 if (TxBufMapInfo == NULL) {
139 return EFI_OUT_OF_RESOURCES;
140 }
141
142 Status = VirtioMapAllBytesInSharedBuffer (
143 Dev->VirtIo,
144 VirtioOperationBusMasterRead,
145 Buffer,
146 NumberOfBytes,
147 &Address,
148 &Mapping
149 );
150 if (EFI_ERROR (Status)) {
151 goto FreeTxBufMapInfo;
152 }
153
154 TxBufMapInfo->Buffer = Buffer;
155 TxBufMapInfo->DeviceAddress = Address;
156 TxBufMapInfo->BufMap = Mapping;
157
158 Status = OrderedCollectionInsert (
159 Dev->TxBufCollection,
160 NULL,
161 TxBufMapInfo
162 );
163 switch (Status) {
164 case EFI_OUT_OF_RESOURCES:
165 goto UnmapTxBuf;
166 case EFI_ALREADY_STARTED:
167 //
168 // This should never happen: it implies
169 //
170 // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
171 // implementation -- which is fine,
172 //
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().
177 //
178 ASSERT (FALSE);
179 Status = EFI_INVALID_PARAMETER;
180 goto UnmapTxBuf;
181 default:
182 ASSERT_EFI_ERROR (Status);
183 break;
184 }
185
186 *DeviceAddress = Address;
187 return EFI_SUCCESS;
188
189UnmapTxBuf:
190 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
191
192FreeTxBufMapInfo:
193 FreePool (TxBufMapInfo);
194 return Status;
195}
196
197/**
198 Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
199 physical address
200
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
205
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
209 physical address.
210
211*/
212EFI_STATUS
213EFIAPI
214VirtioNetUnmapTxBuf (
215 IN VNET_DEV *Dev,
216 OUT VOID **Buffer,
217 IN EFI_PHYSICAL_ADDRESS DeviceAddress
218 )
219{
220 ORDERED_COLLECTION_ENTRY *Entry;
221 TX_BUF_MAP_INFO *TxBufMapInfo;
222 VOID *UserStruct;
223
224 Entry = OrderedCollectionFind (Dev->TxBufCollection, &DeviceAddress);
225 if (Entry == NULL) {
226 return EFI_INVALID_PARAMETER;
227 }
228
229 OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
230
231 TxBufMapInfo = UserStruct;
232
233 *Buffer = TxBufMapInfo->Buffer;
234 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, TxBufMapInfo->BufMap);
235 FreePool (TxBufMapInfo);
236
237 return EFI_SUCCESS;
238}
239
240/**
241 Comparator function for two TX_BUF_MAP_INFO objects.
242
243 @param[in] UserStruct1 Pointer to the first TX_BUF_MAP_INFO object.
244
245 @param[in] UserStruct2 Pointer to the second TX_BUF_MAP_INFO object.
246
247 @retval <0 If UserStruct1 compares less than UserStruct2.
248
249 @retval 0 If UserStruct1 compares equal to UserStruct2.
250
251 @retval >0 If UserStruct1 compares greater than UserStruct2.
252*/
253INTN
254EFIAPI
255VirtioNetTxBufMapInfoCompare (
256 IN CONST VOID *UserStruct1,
257 IN CONST VOID *UserStruct2
258 )
259{
260 CONST TX_BUF_MAP_INFO *MapInfo1;
261 CONST TX_BUF_MAP_INFO *MapInfo2;
262
263 MapInfo1 = UserStruct1;
264 MapInfo2 = UserStruct2;
265
266 return MapInfo1->DeviceAddress < MapInfo2->DeviceAddress ? -1 :
267 MapInfo1->DeviceAddress > MapInfo2->DeviceAddress ? 1 :
268 0;
269}
270
271/**
272 Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
273 containing an embedded DeviceAddress.
274
275 @param[in] StandaloneKey Pointer to DeviceAddress, which has type
276 EFI_PHYSICAL_ADDRESS.
277
278 @param[in] UserStruct Pointer to the TX_BUF_MAP_INFO object with the
279 embedded DeviceAddress.
280
281 @retval <0 If StandaloneKey compares less than UserStruct's key.
282
283 @retval 0 If StandaloneKey compares equal to UserStruct's key.
284
285 @retval >0 If StandaloneKey compares greater than UserStruct's key.
286**/
287INTN
288EFIAPI
289VirtioNetTxBufDeviceAddressCompare (
290 IN CONST VOID *StandaloneKey,
291 IN CONST VOID *UserStruct
292 )
293{
294 CONST EFI_PHYSICAL_ADDRESS *DeviceAddress;
295 CONST TX_BUF_MAP_INFO *MapInfo;
296
297 DeviceAddress = StandaloneKey;
298 MapInfo = UserStruct;
299
300 return *DeviceAddress < MapInfo->DeviceAddress ? -1 :
301 *DeviceAddress > MapInfo->DeviceAddress ? 1 :
302 0;
303}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette