VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/E1kNetDxe/SnpSharedHelpers.c@ 99476

最後變更 在這個檔案從99476是 89503,由 vboxsync 提交於 4 年 前

EFI/E1kNetDxe: Updates, the basic receive and transmit operations are functional and PXE booting seems to work with the limited testing done, include the driver in our image

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.8 KB
 
1/** @file
2
3 Helper functions used by at least two Simple Network Protocol methods.
4
5 Copyright (c) 2021, Oracle and/or its affiliates.
6 Copyright (C) 2013, Red Hat, Inc.<BR>
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Library/MemoryAllocationLib.h>
13
14#include "E1kNet.h"
15
16//
17// The user structure for the ordered collection that will track the mapping
18// info of the packets queued in TxRing
19//
20typedef struct {
21 VOID *Buffer;
22 EFI_PHYSICAL_ADDRESS DeviceAddress; // lookup key for reverse mapping
23 VOID *BufMap;
24} TX_BUF_MAP_INFO;
25
26/**
27 Release RX and TX resources on the boundary of the
28 EfiSimpleNetworkInitialized state.
29
30 These functions contribute to rolling back a partial, failed initialization
31 of the e1000 SNP driver instance, or to shutting down a fully
32 initialized, running instance.
33
34 They are only callable by the E1kNetInitialize() and the
35 E1kNetShutdown() SNP methods. See the state diagram in "E1kNet.h".
36
37 @param[in,out] Dev The E1K_NET_DEV driver instance being shut down, or whose
38 partial, failed initialization is being rolled back.
39*/
40
41VOID
42EFIAPI
43E1kNetShutdownRx (
44 IN OUT E1K_NET_DEV *Dev
45 )
46{
47 Dev->PciIo->Unmap (Dev->PciIo, Dev->RxMap);
48 Dev->PciIo->FreeBuffer (
49 Dev->PciIo,
50 Dev->RxBufNrPages,
51 Dev->RxRing
52 );
53}
54
55
56VOID
57EFIAPI
58E1kNetShutdownTx (
59 IN OUT E1K_NET_DEV *Dev
60 )
61{
62 ORDERED_COLLECTION_ENTRY *Entry, *Entry2;
63 TX_BUF_MAP_INFO *TxBufMapInfo;
64 VOID *UserStruct;
65
66 Dev->PciIo->Unmap (Dev->PciIo, Dev->TxRingMap);
67 Dev->PciIo->FreeBuffer (
68 Dev->PciIo,
69 EFI_SIZE_TO_PAGES (Dev->TxMaxPending * sizeof (*Dev->TxRing)),
70 Dev->TxRing
71 );
72
73 for (Entry = OrderedCollectionMin (Dev->TxBufCollection);
74 Entry != NULL;
75 Entry = Entry2) {
76 Entry2 = OrderedCollectionNext (Entry);
77 OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
78 TxBufMapInfo = UserStruct;
79 Dev->PciIo->Unmap (Dev->PciIo, TxBufMapInfo->BufMap);
80 FreePool (TxBufMapInfo);
81 }
82 OrderedCollectionUninit (Dev->TxBufCollection);
83}
84
85/**
86 Map Caller-supplied TxBuf buffer to the device-mapped address
87
88 @param[in] Dev The E1K_NET_DEV driver instance which wants to
89 map the Tx packet.
90 @param[in] Buffer The system physical address of TxBuf
91 @param[in] NumberOfBytes Number of bytes to map
92 @param[out] DeviceAddress The resulting device address for the bus
93 master access.
94
95 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to
96 a lack of resources.
97 @return Status codes from
98 VirtioMapAllBytesInSharedBuffer()
99 @retval EFI_SUCCESS Caller-supplied buffer is successfully mapped.
100*/
101EFI_STATUS
102EFIAPI
103E1kNetMapTxBuf (
104 IN E1K_NET_DEV *Dev,
105 IN VOID *Buffer,
106 IN UINTN NumberOfBytes,
107 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress
108 )
109{
110 EFI_STATUS Status;
111 TX_BUF_MAP_INFO *TxBufMapInfo;
112 EFI_PHYSICAL_ADDRESS Address;
113 VOID *Mapping;
114
115 TxBufMapInfo = AllocatePool (sizeof (*TxBufMapInfo));
116 if (TxBufMapInfo == NULL) {
117 return EFI_OUT_OF_RESOURCES;
118 }
119
120 Status = Dev->PciIo->Map (
121 Dev->PciIo,
122 EfiPciIoOperationBusMasterRead,
123 Buffer,
124 &NumberOfBytes,
125 &Address,
126 &Mapping
127 );
128 if (EFI_ERROR (Status)) {
129 goto FreeTxBufMapInfo;
130 }
131
132 TxBufMapInfo->Buffer = Buffer;
133 TxBufMapInfo->DeviceAddress = Address;
134 TxBufMapInfo->BufMap = Mapping;
135
136 Status = OrderedCollectionInsert (
137 Dev->TxBufCollection,
138 NULL,
139 TxBufMapInfo
140 );
141 switch (Status) {
142 case EFI_OUT_OF_RESOURCES:
143 goto UnmapTxBuf;
144 case EFI_ALREADY_STARTED:
145 //
146 // This should never happen: it implies
147 //
148 // - an identity-mapping VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
149 // implementation -- which is fine,
150 //
151 // - and an SNP client that queues multiple instances of the exact same
152 // buffer address with SNP.Transmit() -- which is undefined behavior,
153 // based on the TxBuf language in UEFI-2.7,
154 // EFI_SIMPLE_NETWORK.GetStatus().
155 //
156 ASSERT (FALSE);
157 Status = EFI_INVALID_PARAMETER;
158 goto UnmapTxBuf;
159 default:
160 ASSERT_EFI_ERROR (Status);
161 break;
162 }
163
164 *DeviceAddress = Address;
165 return EFI_SUCCESS;
166
167UnmapTxBuf:
168 Dev->PciIo->Unmap (Dev->PciIo, Mapping);
169
170FreeTxBufMapInfo:
171 FreePool (TxBufMapInfo);
172 return Status;
173}
174
175/**
176 Unmap (aka reverse mapping) device mapped TxBuf buffer to the system
177 physical address
178
179 @param[in] Dev The E1K_NET_DEV driver instance which wants to
180 reverse- and unmap the Tx packet.
181 @param[out] Buffer The system physical address of TxBuf
182 @param[in] DeviceAddress The device address for the TxBuf
183
184 @retval EFI_INVALID_PARAMETER The DeviceAddress is not mapped
185 @retval EFI_SUCCESS The TxBuf at DeviceAddress has been unmapped,
186 and Buffer has been set to TxBuf's system
187 physical address.
188
189*/
190EFI_STATUS
191EFIAPI
192E1kNetUnmapTxBuf (
193 IN E1K_NET_DEV *Dev,
194 OUT VOID **Buffer,
195 IN EFI_PHYSICAL_ADDRESS DeviceAddress
196 )
197{
198 ORDERED_COLLECTION_ENTRY *Entry;
199 TX_BUF_MAP_INFO *TxBufMapInfo;
200 VOID *UserStruct;
201
202 Entry = OrderedCollectionFind (Dev->TxBufCollection, &DeviceAddress);
203 if (Entry == NULL) {
204 return EFI_INVALID_PARAMETER;
205 }
206
207 OrderedCollectionDelete (Dev->TxBufCollection, Entry, &UserStruct);
208
209 TxBufMapInfo = UserStruct;
210
211 *Buffer = TxBufMapInfo->Buffer;
212 Dev->PciIo->Unmap (Dev->PciIo, TxBufMapInfo->BufMap);
213 FreePool (TxBufMapInfo);
214
215 return EFI_SUCCESS;
216}
217
218/**
219 Comparator function for two TX_BUF_MAP_INFO objects.
220
221 @param[in] UserStruct1 Pointer to the first TX_BUF_MAP_INFO object.
222
223 @param[in] UserStruct2 Pointer to the second TX_BUF_MAP_INFO object.
224
225 @retval <0 If UserStruct1 compares less than UserStruct2.
226
227 @retval 0 If UserStruct1 compares equal to UserStruct2.
228
229 @retval >0 If UserStruct1 compares greater than UserStruct2.
230*/
231INTN
232EFIAPI
233E1kNetTxBufMapInfoCompare (
234 IN CONST VOID *UserStruct1,
235 IN CONST VOID *UserStruct2
236 )
237{
238 CONST TX_BUF_MAP_INFO *MapInfo1;
239 CONST TX_BUF_MAP_INFO *MapInfo2;
240
241 MapInfo1 = UserStruct1;
242 MapInfo2 = UserStruct2;
243
244 return MapInfo1->DeviceAddress < MapInfo2->DeviceAddress ? -1 :
245 MapInfo1->DeviceAddress > MapInfo2->DeviceAddress ? 1 :
246 0;
247}
248
249/**
250 Compare a standalone DeviceAddress against a TX_BUF_MAP_INFO object
251 containing an embedded DeviceAddress.
252
253 @param[in] StandaloneKey Pointer to DeviceAddress, which has type
254 EFI_PHYSICAL_ADDRESS.
255
256 @param[in] UserStruct Pointer to the TX_BUF_MAP_INFO object with the
257 embedded DeviceAddress.
258
259 @retval <0 If StandaloneKey compares less than UserStruct's key.
260
261 @retval 0 If StandaloneKey compares equal to UserStruct's key.
262
263 @retval >0 If StandaloneKey compares greater than UserStruct's key.
264**/
265INTN
266EFIAPI
267E1kNetTxBufDeviceAddressCompare (
268 IN CONST VOID *StandaloneKey,
269 IN CONST VOID *UserStruct
270 )
271{
272 CONST EFI_PHYSICAL_ADDRESS *DeviceAddress;
273 CONST TX_BUF_MAP_INFO *MapInfo;
274
275 DeviceAddress = StandaloneKey;
276 MapInfo = UserStruct;
277
278 return *DeviceAddress < MapInfo->DeviceAddress ? -1 :
279 *DeviceAddress > MapInfo->DeviceAddress ? 1 :
280 0;
281}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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