]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Win/Host/WinPacketFilter.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmulatorPkg / Win / Host / WinPacketFilter.c
CommitLineData
bb78cfbe
NW
1/**@file\r
2 Windows Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the\r
3 emulator to get on real networks.\r
4\r
5Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>\r
6Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
7(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
8\r
9SPDX-License-Identifier: BSD-2-Clause-Patent\r
10\r
11**/\r
12#include "WinHost.h"\r
13\r
14#define NETWORK_LIBRARY_NAME_U L"SnpNt32Io.dll"\r
15#define NETWORK_LIBRARY_INITIALIZE "SnpInitialize"\r
16#define NETWORK_LIBRARY_FINALIZE "SnpFinalize"\r
17#define NETWORK_LIBRARY_SET_RCV_FILTER "SnpSetReceiveFilter"\r
18#define NETWORK_LIBRARY_RECEIVE "SnpReceive"\r
19#define NETWORK_LIBRARY_TRANSMIT "SnpTransmit"\r
20\r
21#pragma pack(1)\r
22typedef struct _NT_NET_INTERFACE_INFO {\r
a550d468
MK
23 UINT32 InterfaceIndex;\r
24 EFI_MAC_ADDRESS MacAddr;\r
bb78cfbe
NW
25} NT_NET_INTERFACE_INFO;\r
26#pragma pack()\r
27\r
a550d468
MK
28#define NET_ETHER_HEADER_SIZE 14\r
29#define MAX_INTERFACE_INFO_NUMBER 16\r
30#define SNP_MAX_TX_BUFFER_NUM 65536\r
31#define SNP_TX_BUFFER_INCREASEMENT 32\r
32#define DEFAULT_SELECTED_NIC_INDEX 0\r
bb78cfbe
NW
33\r
34//\r
35// Functions in Net Library\r
36//\r
37typedef\r
38INT32\r
39(*NT_NET_INITIALIZE) (\r
a550d468
MK
40 IN OUT UINT32 *InterfaceCount,\r
41 IN OUT NT_NET_INTERFACE_INFO *InterfaceInfoBuffer\r
bb78cfbe
NW
42 );\r
43\r
44typedef\r
45INT32\r
46(*NT_NET_FINALIZE) (\r
47 VOID\r
48 );\r
49\r
50typedef\r
51INT32\r
52(*NT_NET_SET_RECEIVE_FILTER) (\r
a550d468
MK
53 IN UINT32 Index,\r
54 IN UINT32 EnableFilter,\r
55 IN UINT32 MCastFilterCnt,\r
56 IN EFI_MAC_ADDRESS *MCastFilter\r
bb78cfbe
NW
57 );\r
58\r
59typedef\r
60INT32\r
61(*NT_NET_RECEIVE) (\r
a550d468
MK
62 IN UINT32 Index,\r
63 IN OUT UINT32 *BufferSize,\r
64 OUT VOID *Buffer\r
bb78cfbe
NW
65 );\r
66\r
67typedef\r
68INT32\r
69(*NT_NET_TRANSMIT) (\r
a550d468
MK
70 IN UINT32 Index,\r
71 IN UINT32 HeaderSize,\r
72 IN UINT32 BufferSize,\r
73 IN VOID *Buffer,\r
74 IN EFI_MAC_ADDRESS *SrcAddr,\r
75 IN EFI_MAC_ADDRESS *DestAddr,\r
76 IN UINT16 *Protocol\r
bb78cfbe
NW
77 );\r
78\r
79typedef struct _NT_NET_UTILITY_TABLE {\r
a550d468
MK
80 NT_NET_INITIALIZE Initialize;\r
81 NT_NET_FINALIZE Finalize;\r
82 NT_NET_SET_RECEIVE_FILTER SetReceiveFilter;\r
83 NT_NET_RECEIVE Receive;\r
84 NT_NET_TRANSMIT Transmit;\r
bb78cfbe
NW
85} NT_NET_UTILITY_TABLE;\r
86\r
87//\r
88// Instance data for each fake SNP instance\r
89//\r
a550d468 90#define WIN_NT_INSTANCE_SIGNATURE SIGNATURE_32 ('N', 'T', 'I', 'S')\r
bb78cfbe
NW
91\r
92typedef struct {\r
a550d468 93 UINT32 Signature;\r
bb78cfbe
NW
94\r
95 //\r
96 // Array of the recycled transmit buffer address.\r
97 //\r
a550d468 98 UINT64 *RecycledTxBuf;\r
bb78cfbe
NW
99\r
100 //\r
101 // Current number of recycled buffer pointers in RecycledTxBuf.\r
102 //\r
a550d468 103 UINT32 RecycledTxBufCount;\r
bb78cfbe
NW
104\r
105 //\r
106 // The maximum number of recycled buffer pointers in RecycledTxBuf.\r
107 //\r
a550d468
MK
108 UINT32 MaxRecycledTxBuf;\r
109 EFI_SIMPLE_NETWORK_MODE Mode;\r
110 NT_NET_INTERFACE_INFO InterfaceInfo;\r
bb78cfbe
NW
111} WIN_NT_INSTANCE_DATA;\r
112\r
113//\r
114// Instance data for each SNP private instance\r
115//\r
a550d468 116#define WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 's', 'n')\r
bb78cfbe
NW
117\r
118typedef struct {\r
a550d468
MK
119 UINTN Signature;\r
120 EMU_IO_THUNK_PROTOCOL *Thunk;\r
121 EMU_SNP_PROTOCOL EmuSnp;\r
122 EFI_SIMPLE_NETWORK_MODE *Mode;\r
123 HMODULE NetworkLibraryHandle;\r
124 NT_NET_UTILITY_TABLE NtNetUtilityTable;\r
125 WIN_NT_INSTANCE_DATA Instance;\r
bb78cfbe
NW
126} WIN_NT_SNP_PRIVATE;\r
127\r
128#define WIN_NT_SNP_PRIVATE_DATA_FROM_THIS(a) \\r
129 CR(a, WIN_NT_SNP_PRIVATE, EmuSnp, WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE)\r
130\r
bb78cfbe
NW
131/**\r
132 Register storage for SNP Mode.\r
133\r
134 @param This Protocol instance pointer.\r
135 @param Mode SimpleNetworkProtocol Mode structure passed into driver.\r
136\r
137 @retval EFI_SUCCESS The network interface was started.\r
138 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
139\r
140**/\r
141EFI_STATUS\r
142WinNtSnpCreateMapping (\r
143 IN EMU_SNP_PROTOCOL *This,\r
144 IN EFI_SIMPLE_NETWORK_MODE *Mode\r
145 )\r
146{\r
a550d468 147 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
148\r
149 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
150\r
151 Private->Mode = Mode;\r
152\r
153 //\r
154 // Set the broadcast address.\r
155 //\r
156 CopyMem (&Mode->BroadcastAddress, &Private->Instance.Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS));\r
157 //\r
158 // Set the MAC address.\r
159 //\r
160 CopyMem (&Mode->CurrentAddress, &Private->Instance.Mode.CurrentAddress, sizeof (EFI_MAC_ADDRESS));\r
161 CopyMem (&Mode->PermanentAddress, &Private->Instance.Mode.PermanentAddress, sizeof (EFI_MAC_ADDRESS));\r
162\r
163 return EFI_SUCCESS;\r
164}\r
165\r
166/**\r
167 Changes the state of a network interface from "stopped" to "started".\r
168\r
169 @param This Protocol instance pointer.\r
170\r
171 @retval EFI_SUCCESS The network interface was started.\r
172 @retval EFI_ALREADY_STARTED The network interface is already in the started state.\r
173 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
174 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
175 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
176\r
177**/\r
178EFI_STATUS\r
179WinNtSnpStart (\r
180 IN EMU_SNP_PROTOCOL *This\r
181 )\r
182{\r
a550d468 183 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
184\r
185 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
186\r
187 switch (Private->Mode->State) {\r
188 case EfiSimpleNetworkStopped:\r
189 break;\r
190\r
191 case EfiSimpleNetworkStarted:\r
192 case EfiSimpleNetworkInitialized:\r
193 return EFI_ALREADY_STARTED;\r
194 break;\r
195\r
196 default:\r
197 return EFI_DEVICE_ERROR;\r
198 break;\r
199 }\r
200\r
201 Private->Mode->State = EfiSimpleNetworkStarted;\r
202\r
203 return EFI_SUCCESS;\r
204}\r
205\r
206/**\r
207 Changes the state of a network interface from "started" to "stopped".\r
208\r
209 @param This Protocol instance pointer.\r
210\r
211 @retval EFI_SUCCESS The network interface was stopped.\r
212 @retval EFI_ALREADY_STARTED The network interface is already in the stopped state.\r
213 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
214 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
215 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
216\r
217**/\r
218EFI_STATUS\r
219WinNtSnpStop (\r
220 IN EMU_SNP_PROTOCOL *This\r
221 )\r
222{\r
a550d468 223 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
224\r
225 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
226\r
227 switch ( Private->Mode->State ) {\r
228 case EfiSimpleNetworkStarted:\r
229 break;\r
230\r
231 case EfiSimpleNetworkStopped:\r
232 return EFI_NOT_STARTED;\r
233 break;\r
234\r
235 default:\r
236 return EFI_DEVICE_ERROR;\r
237 break;\r
238 }\r
239\r
240 Private->Mode->State = EfiSimpleNetworkStopped;\r
241\r
242 return EFI_SUCCESS;\r
243}\r
244\r
245/**\r
246 Resets a network adapter and allocates the transmit and receive buffers\r
247 required by the network interface; optionally, also requests allocation\r
248 of additional transmit and receive buffers.\r
249\r
250 @param This The protocol instance pointer.\r
251 @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r
252 that the driver should allocate for the network interface.\r
253 Some network interfaces will not be able to use the extra\r
254 buffer, and the caller will not know if it is actually\r
255 being used.\r
256 @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r
257 that the driver should allocate for the network interface.\r
258 Some network interfaces will not be able to use the extra\r
259 buffer, and the caller will not know if it is actually\r
260 being used.\r
261\r
262 @retval EFI_SUCCESS The network interface was initialized.\r
263 @retval EFI_NOT_STARTED The network interface has not been started.\r
264 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and\r
265 receive buffers.\r
266 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
267 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
268 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
269\r
270**/\r
271EFI_STATUS\r
272WinNtSnpInitialize (\r
a550d468
MK
273 IN EMU_SNP_PROTOCOL *This,\r
274 IN UINTN ExtraRxBufferSize OPTIONAL,\r
275 IN UINTN ExtraTxBufferSize OPTIONAL\r
bb78cfbe
NW
276 )\r
277{\r
a550d468 278 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
279\r
280 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
281\r
282 switch ( Private->Mode->State ) {\r
283 case EfiSimpleNetworkStarted:\r
284 break;\r
285\r
286 case EfiSimpleNetworkStopped:\r
287 return EFI_NOT_STARTED;\r
288 break;\r
289\r
290 default:\r
291 return EFI_DEVICE_ERROR;\r
292 break;\r
293 }\r
294\r
a550d468 295 Private->Mode->MCastFilterCount = 0;\r
bb78cfbe
NW
296 Private->Mode->ReceiveFilterSetting = 0;\r
297 ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter));\r
298\r
299 Private->Mode->State = EfiSimpleNetworkInitialized;\r
300\r
301 return EFI_SUCCESS;\r
302}\r
303\r
304/**\r
305 Resets a network adapter and re-initializes it with the parameters that were\r
306 provided in the previous call to Initialize().\r
307\r
308 @param This The protocol instance pointer.\r
309 @param ExtendedVerification Indicates that the driver may perform a more\r
310 exhaustive verification operation of the device\r
311 during reset.\r
312\r
313 @retval EFI_SUCCESS The network interface was reset.\r
314 @retval EFI_NOT_STARTED The network interface has not been started.\r
315 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
316 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
317 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
318\r
319**/\r
320EFI_STATUS\r
321WinNtSnpReset (\r
a550d468
MK
322 IN EMU_SNP_PROTOCOL *This,\r
323 IN BOOLEAN ExtendedVerification\r
bb78cfbe
NW
324 )\r
325{\r
a550d468 326 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
327\r
328 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
329\r
330 switch ( Private->Mode->State ) {\r
331 case EfiSimpleNetworkInitialized:\r
332 break;\r
333\r
334 case EfiSimpleNetworkStopped:\r
335 return EFI_NOT_STARTED;\r
336 break;\r
337\r
338 default:\r
339 return EFI_DEVICE_ERROR;\r
340 break;\r
341 }\r
342\r
343 return EFI_SUCCESS;\r
344}\r
345\r
346/**\r
347 Resets a network adapter and leaves it in a state that is safe for\r
348 another driver to initialize.\r
349\r
350 @param This Protocol instance pointer.\r
351\r
352 @retval EFI_SUCCESS The network interface was shutdown.\r
353 @retval EFI_NOT_STARTED The network interface has not been started.\r
354 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
355 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
356 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
357\r
358**/\r
359EFI_STATUS\r
360WinNtSnpShutdown (\r
361 IN EMU_SNP_PROTOCOL *This\r
362 )\r
363{\r
a550d468 364 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
365\r
366 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
367\r
368 switch ( Private->Mode->State ) {\r
369 case EfiSimpleNetworkInitialized:\r
370 break;\r
371\r
372 case EfiSimpleNetworkStopped:\r
373 return EFI_NOT_STARTED;\r
374 break;\r
375\r
376 default:\r
377 return EFI_DEVICE_ERROR;\r
378 break;\r
379 }\r
380\r
381 Private->Mode->State = EfiSimpleNetworkStarted;\r
382\r
383 Private->Mode->ReceiveFilterSetting = 0;\r
a550d468 384 Private->Mode->MCastFilterCount = 0;\r
bb78cfbe
NW
385 ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter));\r
386\r
387 return EFI_SUCCESS;\r
388}\r
389\r
390/**\r
391 Manages the multicast receive filters of a network interface.\r
392\r
393 @param This The protocol instance pointer.\r
394 @param Enable A bit mask of receive filters to enable on the network interface.\r
395 @param Disable A bit mask of receive filters to disable on the network interface.\r
396 @param ResetMCastFilter Set to TRUE to reset the contents of the multicast receive\r
397 filters on the network interface to their default values.\r
398 @param McastFilterCnt Number of multicast HW MAC addresses in the new\r
399 MCastFilter list. This value must be less than or equal to\r
400 the MCastFilterCnt field of EMU_SNP_MODE. This\r
401 field is optional if ResetMCastFilter is TRUE.\r
402 @param MCastFilter A pointer to a list of new multicast receive filter HW MAC\r
403 addresses. This list will replace any existing multicast\r
404 HW MAC address list. This field is optional if\r
405 ResetMCastFilter is TRUE.\r
406\r
407 @retval EFI_SUCCESS The multicast receive filter list was updated.\r
408 @retval EFI_NOT_STARTED The network interface has not been started.\r
409 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
410 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
411 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
412\r
413**/\r
414EFI_STATUS\r
415WinNtSnpReceiveFilters (\r
a550d468
MK
416 IN EMU_SNP_PROTOCOL *This,\r
417 IN UINT32 Enable,\r
418 IN UINT32 Disable,\r
419 IN BOOLEAN ResetMCastFilter,\r
420 IN UINTN MCastFilterCnt OPTIONAL,\r
421 IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL\r
bb78cfbe
NW
422 )\r
423{\r
a550d468
MK
424 WIN_NT_SNP_PRIVATE *Private;\r
425 INT32 ReturnValue;\r
bb78cfbe
NW
426\r
427 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
428\r
429 ReturnValue = Private->NtNetUtilityTable.SetReceiveFilter (\r
a550d468
MK
430 Private->Instance.InterfaceInfo.InterfaceIndex,\r
431 Enable,\r
432 (UINT32)MCastFilterCnt,\r
433 MCastFilter\r
434 );\r
bb78cfbe
NW
435\r
436 if (ReturnValue <= 0) {\r
437 return EFI_DEVICE_ERROR;\r
438 }\r
439\r
440 return EFI_SUCCESS;\r
441}\r
442\r
443/**\r
444 Modifies or resets the current station address, if supported.\r
445\r
446 @param This The protocol instance pointer.\r
447 @param Reset Flag used to reset the station address to the network interfaces\r
448 permanent address.\r
449 @param New The new station address to be used for the network interface.\r
450\r
451 @retval EFI_SUCCESS The network interfaces station address was updated.\r
452 @retval EFI_NOT_STARTED The network interface has not been started.\r
453 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
454 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
455 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
456\r
457**/\r
458EFI_STATUS\r
459WinNtSnpStationAddress (\r
a550d468
MK
460 IN EMU_SNP_PROTOCOL *This,\r
461 IN BOOLEAN Reset,\r
462 IN EFI_MAC_ADDRESS *New OPTIONAL\r
bb78cfbe
NW
463 )\r
464{\r
a550d468 465 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
466\r
467 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
468\r
469 return EFI_UNSUPPORTED;\r
470}\r
471\r
472/**\r
473 Resets or collects the statistics on a network interface.\r
474\r
475 @param This Protocol instance pointer.\r
476 @param Reset Set to TRUE to reset the statistics for the network interface.\r
477 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r
478 output the size, in bytes, of the resulting table of\r
479 statistics.\r
480 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
481 contains the statistics.\r
482\r
483 @retval EFI_SUCCESS The statistics were collected from the network interface.\r
484 @retval EFI_NOT_STARTED The network interface has not been started.\r
485 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
486 size needed to hold the statistics is returned in\r
487 StatisticsSize.\r
488 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
489 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
490 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
491\r
492**/\r
493EFI_STATUS\r
494WinNtSnpStatistics (\r
a550d468
MK
495 IN EMU_SNP_PROTOCOL *This,\r
496 IN BOOLEAN Reset,\r
497 IN OUT UINTN *StatisticsSize OPTIONAL,\r
498 OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL\r
bb78cfbe
NW
499 )\r
500{\r
a550d468 501 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
502\r
503 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
504\r
505 return EFI_UNSUPPORTED;\r
506}\r
507\r
508/**\r
509 Converts a multicast IP address to a multicast HW MAC address.\r
510\r
511 @param This The protocol instance pointer.\r
512 @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r
513 to FALSE if the multicast IP address is IPv4 [RFC 791].\r
514 @param IP The multicast IP address that is to be converted to a multicast\r
515 HW MAC address.\r
516 @param MAC The multicast HW MAC address that is to be generated from IP.\r
517\r
518 @retval EFI_SUCCESS The multicast IP address was mapped to the multicast\r
519 HW MAC address.\r
520 @retval EFI_NOT_STARTED The network interface has not been started.\r
521 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
522 size needed to hold the statistics is returned in\r
523 StatisticsSize.\r
524 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
525 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
526 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
527\r
528**/\r
529EFI_STATUS\r
530WinNtSnpMCastIpToMac (\r
a550d468
MK
531 IN EMU_SNP_PROTOCOL *This,\r
532 IN BOOLEAN IPv6,\r
533 IN EFI_IP_ADDRESS *IP,\r
534 OUT EFI_MAC_ADDRESS *MAC\r
bb78cfbe
NW
535 )\r
536{\r
a550d468 537 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
538\r
539 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
540\r
541 return EFI_UNSUPPORTED;\r
542}\r
543\r
544/**\r
545 Performs read and write operations on the NVRAM device attached to a\r
546 network interface.\r
547\r
548 @param This The protocol instance pointer.\r
549 @param ReadWrite TRUE for read operations, FALSE for write operations.\r
550 @param Offset Byte offset in the NVRAM device at which to start the read or\r
551 write operation. This must be a multiple of NvRamAccessSize and\r
552 less than NvRamSize.\r
553 @param BufferSize The number of bytes to read or write from the NVRAM device.\r
554 This must also be a multiple of NvramAccessSize.\r
555 @param Buffer A pointer to the data buffer.\r
556\r
557 @retval EFI_SUCCESS The NVRAM access was performed.\r
558 @retval EFI_NOT_STARTED The network interface has not been started.\r
559 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
560 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
561 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
562\r
563**/\r
564EFI_STATUS\r
565WinNtSnpNvData (\r
a550d468
MK
566 IN EMU_SNP_PROTOCOL *This,\r
567 IN BOOLEAN ReadWrite,\r
568 IN UINTN Offset,\r
569 IN UINTN BufferSize,\r
570 IN OUT VOID *Buffer\r
bb78cfbe
NW
571 )\r
572{\r
a550d468 573 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
574\r
575 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
576\r
577 return EFI_UNSUPPORTED;\r
578}\r
579\r
580/**\r
581 Reads the current interrupt status and recycled transmit buffer status from\r
582 a network interface.\r
583\r
584 @param This The protocol instance pointer.\r
585 @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r
586 If this is NULL, the interrupt status will not be read from\r
587 the device. If this is not NULL, the interrupt status will\r
588 be read from the device. When the interrupt status is read,\r
589 it will also be cleared. Clearing the transmit interrupt\r
590 does not empty the recycled transmit buffer array.\r
591 @param TxBuf Recycled transmit buffer address. The network interface will\r
592 not transmit if its internal recycled transmit buffer array\r
593 is full. Reading the transmit buffer does not clear the\r
594 transmit interrupt. If this is NULL, then the transmit buffer\r
595 status will not be read. If there are no transmit buffers to\r
596 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r
597\r
598 @retval EFI_SUCCESS The status of the network interface was retrieved.\r
599 @retval EFI_NOT_STARTED The network interface has not been started.\r
600 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
601 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
602 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
603\r
604**/\r
605EFI_STATUS\r
606WinNtSnpGetStatus (\r
a550d468
MK
607 IN EMU_SNP_PROTOCOL *This,\r
608 OUT UINT32 *InterruptStatus OPTIONAL,\r
609 OUT VOID **TxBuf OPTIONAL\r
bb78cfbe
NW
610 )\r
611{\r
a550d468 612 WIN_NT_SNP_PRIVATE *Private;\r
bb78cfbe
NW
613\r
614 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
615\r
616 if (TxBuf != NULL) {\r
617 if (Private->Instance.RecycledTxBufCount != 0) {\r
a550d468
MK
618 Private->Instance.RecycledTxBufCount--;\r
619 *((UINT8 **)TxBuf) = (UINT8 *)(UINTN)Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount];\r
bb78cfbe 620 } else {\r
a550d468 621 *((UINT8 **)TxBuf) = NULL;\r
bb78cfbe
NW
622 }\r
623 }\r
624\r
625 if (InterruptStatus != NULL) {\r
626 *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
627 }\r
628\r
629 return EFI_SUCCESS;\r
630}\r
631\r
632/**\r
633 Places a packet in the transmit queue of a network interface.\r
634\r
635 @param This The protocol instance pointer.\r
636 @param HeaderSize The size, in bytes, of the media header to be filled in by\r
637 the Transmit() function. If HeaderSize is non-zero, then it\r
638 must be equal to This->Mode->MediaHeaderSize and the DestAddr\r
639 and Protocol parameters must not be NULL.\r
640 @param BufferSize The size, in bytes, of the entire packet (media header and\r
641 data) to be transmitted through the network interface.\r
642 @param Buffer A pointer to the packet (media header followed by data) to be\r
643 transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r
644 then the media header in Buffer must already be filled in by the\r
645 caller. If HeaderSize is non-zero, then the media header will be\r
646 filled in by the Transmit() function.\r
647 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r
648 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r
649 This->Mode->CurrentAddress is used for the source HW MAC address.\r
650 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r
651 parameter is ignored.\r
652 @param Protocol The type of header to build. If HeaderSize is zero, then this\r
653 parameter is ignored. See RFC 1700, section "Ether Types", for\r
654 examples.\r
655\r
656 @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
657 @retval EFI_NOT_STARTED The network interface has not been started.\r
658 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.\r
659 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
660 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
661 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
662 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
663\r
664**/\r
665EFI_STATUS\r
666WinNtSnpTransmit (\r
a550d468
MK
667 IN EMU_SNP_PROTOCOL *This,\r
668 IN UINTN HeaderSize,\r
669 IN UINTN BufferSize,\r
670 IN VOID *Buffer,\r
671 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
672 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
673 IN UINT16 *Protocol OPTIONAL\r
bb78cfbe
NW
674 )\r
675{\r
a550d468
MK
676 WIN_NT_SNP_PRIVATE *Private;\r
677 INT32 ReturnValue;\r
678 UINT64 *Tmp;\r
bb78cfbe
NW
679\r
680 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
681\r
682 if ((HeaderSize != 0) && (SrcAddr == NULL)) {\r
683 SrcAddr = &Private->Instance.Mode.CurrentAddress;\r
684 }\r
685\r
686 ReturnValue = Private->NtNetUtilityTable.Transmit (\r
a550d468
MK
687 Private->Instance.InterfaceInfo.InterfaceIndex,\r
688 (UINT32)HeaderSize,\r
689 (UINT32)BufferSize,\r
690 Buffer,\r
691 SrcAddr,\r
692 DestAddr,\r
693 Protocol\r
694 );\r
bb78cfbe
NW
695\r
696 if (ReturnValue < 0) {\r
697 return EFI_DEVICE_ERROR;\r
698 } else {\r
699 if ((Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >= SNP_MAX_TX_BUFFER_NUM) {\r
700 return EFI_NOT_READY;\r
701 }\r
702\r
703 if (Private->Instance.RecycledTxBufCount < Private->Instance.MaxRecycledTxBuf) {\r
a550d468
MK
704 Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount] = (UINT64)Buffer;\r
705 Private->Instance.RecycledTxBufCount++;\r
bb78cfbe
NW
706 } else {\r
707 Tmp = malloc (sizeof (UINT64) * (Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT));\r
708 if (Tmp == NULL) {\r
709 return EFI_DEVICE_ERROR;\r
710 }\r
a550d468 711\r
bb78cfbe
NW
712 CopyMem (Tmp, Private->Instance.RecycledTxBuf, sizeof (UINT64) * Private->Instance.RecycledTxBufCount);\r
713 free (Private->Instance.RecycledTxBuf);\r
a550d468 714 Private->Instance.RecycledTxBuf = Tmp;\r
bb78cfbe
NW
715 Private->Instance.MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASEMENT;\r
716 }\r
717 }\r
718\r
719 return EFI_SUCCESS;\r
720}\r
721\r
722/**\r
723 Receives a packet from a network interface.\r
724\r
725 @param This The protocol instance pointer.\r
726 @param HeaderSize The size, in bytes, of the media header received on the network\r
727 interface. If this parameter is NULL, then the media header size\r
728 will not be returned.\r
729 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
730 bytes, of the packet that was received on the network interface.\r
731 @param Buffer A pointer to the data buffer to receive both the media header and\r
732 the data.\r
733 @param SrcAddr The source HW MAC address. If this parameter is NULL, the\r
734 HW MAC source address will not be extracted from the media\r
735 header.\r
736 @param DestAddr The destination HW MAC address. If this parameter is NULL,\r
737 the HW MAC destination address will not be extracted from the\r
738 media header.\r
739 @param Protocol The media header type. If this parameter is NULL, then the\r
740 protocol will not be extracted from the media header. See\r
741 RFC 1700 section "Ether Types" for examples.\r
742\r
743 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r
744 been updated to the number of bytes received.\r
745 @retval EFI_NOT_STARTED The network interface has not been started.\r
746 @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
747 request.\r
748 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
749 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
750 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
751 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
752\r
753**/\r
754EFI_STATUS\r
755WinNtSnpReceive (\r
a550d468
MK
756 IN EMU_SNP_PROTOCOL *This,\r
757 OUT UINTN *HeaderSize OPTIONAL,\r
758 IN OUT UINTN *BufferSize,\r
759 OUT VOID *Buffer,\r
760 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
761 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
762 OUT UINT16 *Protocol OPTIONAL\r
bb78cfbe
NW
763 )\r
764{\r
a550d468
MK
765 WIN_NT_SNP_PRIVATE *Private;\r
766 INT32 ReturnValue;\r
767 UINTN BufSize;\r
bb78cfbe
NW
768\r
769 Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This);\r
770\r
a550d468 771 BufSize = *BufferSize;\r
bb78cfbe
NW
772\r
773 ASSERT (Private->NtNetUtilityTable.Receive != NULL);\r
774\r
775 ReturnValue = Private->NtNetUtilityTable.Receive (\r
a550d468
MK
776 Private->Instance.InterfaceInfo.InterfaceIndex,\r
777 BufferSize,\r
778 Buffer\r
779 );\r
bb78cfbe
NW
780\r
781 if (ReturnValue < 0) {\r
782 if (ReturnValue == -100) {\r
783 return EFI_BUFFER_TOO_SMALL;\r
784 }\r
785\r
786 return EFI_DEVICE_ERROR;\r
787 } else if (ReturnValue == 0) {\r
788 return EFI_NOT_READY;\r
789 }\r
790\r
791 if (HeaderSize != NULL) {\r
792 *HeaderSize = 14;\r
793 }\r
794\r
795 if (SrcAddr != NULL) {\r
796 ZeroMem (SrcAddr, sizeof (EFI_MAC_ADDRESS));\r
a550d468 797 CopyMem (SrcAddr, ((UINT8 *)Buffer) + 6, 6);\r
bb78cfbe
NW
798 }\r
799\r
800 if (DestAddr != NULL) {\r
801 ZeroMem (DestAddr, sizeof (EFI_MAC_ADDRESS));\r
a550d468 802 CopyMem (DestAddr, ((UINT8 *)Buffer), 6);\r
bb78cfbe
NW
803 }\r
804\r
805 if (Protocol != NULL) {\r
a550d468 806 *Protocol = NTOHS (*((UINT16 *)(((UINT8 *)Buffer) + 12)));\r
bb78cfbe
NW
807 }\r
808\r
809 return (*BufferSize <= BufSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
810}\r
811\r
812/**\r
813 Initialize the snpnt32 driver instance.\r
814\r
815 @param Instance Pointer to the instance context data.\r
816 @param NetInfo Pointer to the interface info.\r
817\r
818 @retval EFI_SUCCESS The driver instance is initialized.\r
819 @retval other Initialization errors.\r
820\r
821**/\r
822EFI_STATUS\r
823WinNtInitializeInstanceData (\r
a550d468
MK
824 IN OUT WIN_NT_INSTANCE_DATA *Instance,\r
825 IN NT_NET_INTERFACE_INFO *NetInfo\r
bb78cfbe
NW
826 )\r
827{\r
a550d468 828 if ((Instance == NULL) || (NetInfo == NULL)) {\r
bb78cfbe
NW
829 return EFI_INVALID_PARAMETER;\r
830 }\r
831\r
832 ZeroMem (Instance, sizeof (WIN_NT_INSTANCE_DATA));\r
833\r
a550d468
MK
834 Instance->Signature = WIN_NT_INSTANCE_SIGNATURE;\r
835 Instance->RecycledTxBufCount = 0;\r
836 Instance->MaxRecycledTxBuf = 32;\r
837 Instance->Mode.State = EfiSimpleNetworkInitialized;\r
838 Instance->Mode.HwAddressSize = NET_ETHER_ADDR_LEN;\r
839 Instance->Mode.MediaHeaderSize = NET_ETHER_HEADER_SIZE;\r
840 Instance->Mode.MaxPacketSize = 1500;\r
841 Instance->Mode.MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;\r
842 Instance->Mode.IfType = NET_IFTYPE_ETHERNET;\r
bb78cfbe 843 Instance->Mode.MediaPresentSupported = TRUE;\r
a550d468 844 Instance->Mode.MediaPresent = TRUE;\r
bb78cfbe
NW
845\r
846 //\r
847 // Allocate the RecycledTxBuf.\r
848 //\r
849 Instance->RecycledTxBuf = malloc (sizeof (UINT64) * Instance->MaxRecycledTxBuf);\r
850 if (Instance->RecycledTxBuf == NULL) {\r
851 return EFI_OUT_OF_RESOURCES;\r
852 }\r
853\r
854 //\r
855 // Set the interface information.\r
856 //\r
857 CopyMem (&Instance->InterfaceInfo, NetInfo, sizeof (Instance->InterfaceInfo));\r
858\r
bb78cfbe
NW
859 //\r
860 // Set broadcast address\r
861 //\r
862 SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);\r
863\r
864 //\r
865 // Copy Current/PermanentAddress MAC address\r
866 //\r
a550d468
MK
867 CopyMem (&Instance->Mode.CurrentAddress, &Instance->InterfaceInfo.MacAddr, sizeof (Instance->Mode.CurrentAddress));\r
868 CopyMem (&Instance->Mode.PermanentAddress, &Instance->InterfaceInfo.MacAddr, sizeof (Instance->Mode.PermanentAddress));\r
bb78cfbe
NW
869\r
870 //\r
871 // Since the fake SNP is based on a real NIC, to avoid conflict with the host\r
872 // NIC network stack, we use a different MAC address.\r
873 // So just change the last byte of the MAC address for the real NIC.\r
874 //\r
875 Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;\r
876\r
877 return EFI_SUCCESS;\r
878}\r
879\r
880/**\r
881 Initialize the net utility data.\r
882\r
883 @param This Pointer to the private data.\r
884 @param ActiveInstance The active network interface.\r
885\r
886 @retval EFI_SUCCESS The global data is initialized.\r
887 @retval EFI_NOT_FOUND The required DLL is not found.\r
888 @retval EFI_DEVICE_ERROR Error initialize network utility library.\r
889 @retval other Other errors.\r
890\r
891**/\r
892EFI_STATUS\r
893WintNtInitializeNetUtilityData (\r
a550d468 894 IN OUT WIN_NT_SNP_PRIVATE *Private,\r
bb78cfbe
NW
895 IN UINT8 ActiveInstance\r
896 )\r
897{\r
a550d468
MK
898 EFI_STATUS Status;\r
899 CHAR16 *DllFileNameU;\r
900 INT32 ReturnValue;\r
901 BOOLEAN NetUtilityLibInitDone;\r
902 NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];\r
903 UINT32 InterfaceCount;\r
904 UINT8 ActiveInterfaceIndex;\r
bb78cfbe
NW
905\r
906 if (Private == NULL) {\r
a550d468 907 return EFI_INVALID_PARAMETER;\r
bb78cfbe
NW
908 }\r
909\r
910 NetUtilityLibInitDone = FALSE;\r
911 InterfaceCount = MAX_INTERFACE_INFO_NUMBER;\r
912 DllFileNameU = NETWORK_LIBRARY_NAME_U;\r
913\r
914 //\r
915 // Load network utility library\r
916 //\r
917 Private->NetworkLibraryHandle = LoadLibraryEx (DllFileNameU, NULL, 0);\r
918 if (NULL == Private->NetworkLibraryHandle) {\r
919 return EFI_NOT_FOUND;\r
920 }\r
921\r
a550d468 922 Private->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_INITIALIZE);\r
bb78cfbe
NW
923 if (NULL == Private->NtNetUtilityTable.Initialize) {\r
924 Status = EFI_NOT_FOUND;\r
925 goto ErrorReturn;\r
926 }\r
927\r
a550d468 928 Private->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_FINALIZE);\r
bb78cfbe
NW
929 if (NULL == Private->NtNetUtilityTable.Finalize) {\r
930 Status = EFI_NOT_FOUND;\r
931 goto ErrorReturn;\r
932 }\r
933\r
a550d468 934 Private->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_SET_RCV_FILTER);\r
bb78cfbe
NW
935 if (NULL == Private->NtNetUtilityTable.SetReceiveFilter) {\r
936 Status = EFI_NOT_FOUND;\r
937 goto ErrorReturn;\r
938 }\r
939\r
a550d468 940 Private->NtNetUtilityTable.Receive = (NT_NET_RECEIVE)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_RECEIVE);\r
bb78cfbe
NW
941 if (NULL == Private->NtNetUtilityTable.Receive) {\r
942 Status = EFI_NOT_FOUND;\r
943 goto ErrorReturn;\r
944 }\r
945\r
a550d468 946 Private->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT)GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_TRANSMIT);\r
bb78cfbe
NW
947 if (NULL == Private->NtNetUtilityTable.Transmit) {\r
948 Status = EFI_NOT_FOUND;\r
949 goto ErrorReturn;\r
950 }\r
951\r
952 //\r
953 // Initialize the network utility library\r
954 // And enumerate the interfaces in emulator host\r
955 //\r
956 ReturnValue = Private->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);\r
957 if (ReturnValue <= 0) {\r
958 Status = EFI_DEVICE_ERROR;\r
959 goto ErrorReturn;\r
960 }\r
961\r
962 NetUtilityLibInitDone = TRUE;\r
963\r
964 if (InterfaceCount == 0) {\r
965 Status = EFI_NOT_FOUND;\r
966 goto ErrorReturn;\r
967 }\r
968\r
969 DEBUG ((DEBUG_INFO, "%a, total %d interface(s) found\n", __FUNCTION__, InterfaceCount));\r
970 //\r
971 // Active interface index is set to first interface if given instance does\r
972 // not exist.\r
973 //\r
974 ActiveInterfaceIndex = (ActiveInstance >= InterfaceCount ? DEFAULT_SELECTED_NIC_INDEX : ActiveInstance);\r
975\r
976 //\r
977 // Initialize instance\r
978 //\r
979 Status = WinNtInitializeInstanceData (&Private->Instance, &NetInterfaceInfoBuffer[ActiveInterfaceIndex]);\r
980 if (EFI_ERROR (Status)) {\r
a550d468 981 goto ErrorReturn;\r
bb78cfbe
NW
982 }\r
983\r
984 return EFI_SUCCESS;\r
985\r
986ErrorReturn:\r
987\r
988 if (Private->Instance.RecycledTxBuf != NULL) {\r
a550d468 989 free (Private->Instance.RecycledTxBuf);\r
bb78cfbe
NW
990 }\r
991\r
992 if (NetUtilityLibInitDone) {\r
993 if (Private->NtNetUtilityTable.Finalize != NULL) {\r
994 Private->NtNetUtilityTable.Finalize ();\r
995 Private->NtNetUtilityTable.Finalize = NULL;\r
996 }\r
997 }\r
998\r
999 return Status;\r
1000}\r
1001\r
1002/**\r
1003 Release the net utility data.\r
1004\r
1005 @param This Pointer to the private data.\r
1006\r
1007 @retval EFI_SUCCESS The global data is released.\r
1008 @retval other Other errors.\r
1009\r
1010**/\r
1011EFI_STATUS\r
1012WintNtReleaseNetUtilityData (\r
a550d468 1013 IN OUT WIN_NT_SNP_PRIVATE *Private\r
bb78cfbe
NW
1014 )\r
1015{\r
1016 if (Private == NULL) {\r
1017 return EFI_INVALID_PARAMETER;\r
1018 }\r
1019\r
1020 if (Private->Instance.RecycledTxBuf != NULL) {\r
a550d468 1021 free (Private->Instance.RecycledTxBuf);\r
bb78cfbe
NW
1022 }\r
1023\r
1024 if (Private->NtNetUtilityTable.Finalize != NULL) {\r
1025 Private->NtNetUtilityTable.Finalize ();\r
1026 }\r
1027\r
1028 FreeLibrary (Private->NetworkLibraryHandle);\r
1029\r
1030 return EFI_SUCCESS;\r
1031}\r
1032\r
a550d468 1033EMU_SNP_PROTOCOL mWinNtSnpProtocol = {\r
bb78cfbe
NW
1034 WinNtSnpCreateMapping,\r
1035 WinNtSnpStart,\r
1036 WinNtSnpStop,\r
1037 WinNtSnpInitialize,\r
1038 WinNtSnpReset,\r
1039 WinNtSnpShutdown,\r
1040 WinNtSnpReceiveFilters,\r
1041 WinNtSnpStationAddress,\r
1042 WinNtSnpStatistics,\r
1043 WinNtSnpMCastIpToMac,\r
1044 WinNtSnpNvData,\r
1045 WinNtSnpGetStatus,\r
1046 WinNtSnpTransmit,\r
1047 WinNtSnpReceive\r
1048};\r
1049\r
1050/**\r
1051 Open SNP thunk protocol.\r
1052\r
1053 @param This Pointer to the thunk protocol instance.\r
1054\r
1055 @retval EFI_SUCCESS SNP thunk protocol is opened successfully.\r
1056 @retval EFI_UNSUPPORTED This is not SNP thunk protocol.\r
1057 @retval EFI_OUT_OF_RESOURCES Not enough memory.\r
1058 @retval other Other errors.\r
1059\r
1060**/\r
1061EFI_STATUS\r
1062WinNtSnpThunkOpen (\r
a550d468 1063 IN EMU_IO_THUNK_PROTOCOL *This\r
bb78cfbe
NW
1064 )\r
1065{\r
1066 WIN_NT_SNP_PRIVATE *Private;\r
1067 UINT8 HostInterfaceIndex;\r
1068\r
1069 HostInterfaceIndex = 0;\r
1070\r
1071 if (This->Private != NULL) {\r
1072 return EFI_ALREADY_STARTED;\r
1073 }\r
1074\r
1075 if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) {\r
1076 return EFI_UNSUPPORTED;\r
1077 }\r
1078\r
1079 Private = malloc (sizeof (WIN_NT_SNP_PRIVATE));\r
1080 if (Private == NULL) {\r
1081 return EFI_OUT_OF_RESOURCES;\r
1082 }\r
1083\r
1084 Private->Signature = WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE;\r
1085 Private->Thunk = This;\r
1086 CopyMem (&Private->EmuSnp, &mWinNtSnpProtocol, sizeof (mWinNtSnpProtocol));\r
1087\r
1088 This->Interface = &Private->EmuSnp;\r
1089 This->Private = Private;\r
1090\r
a550d468 1091 if ((This->ConfigString != NULL) && (This->ConfigString[0] != '\0')) {\r
bb78cfbe
NW
1092 HostInterfaceIndex = (UINT8)StrDecimalToUintn (This->ConfigString);\r
1093 }\r
1094\r
1095 return WintNtInitializeNetUtilityData (Private, HostInterfaceIndex);\r
1096}\r
1097\r
1098/**\r
1099 Close SNP thunk protocol.\r
1100\r
1101 @param This Pointer to the thunk protocol instance.\r
1102\r
1103 @retval EFI_SUCCESS SNP thunk protocol is closed successfully.\r
1104 @retval EFI_UNSUPPORTED This is not SNP thunk protocol.\r
1105 @retval other Other errors.\r
1106\r
1107**/\r
1108EFI_STATUS\r
1109WinNtSnpThunkClose (\r
a550d468 1110 IN EMU_IO_THUNK_PROTOCOL *This\r
bb78cfbe
NW
1111 )\r
1112{\r
1113 WIN_NT_SNP_PRIVATE *Private;\r
1114\r
1115 if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) {\r
1116 return EFI_UNSUPPORTED;\r
1117 }\r
1118\r
1119 Private = This->Private;\r
1120 WintNtReleaseNetUtilityData (Private);\r
1121 free (Private);\r
1122\r
1123 return EFI_SUCCESS;\r
1124}\r
1125\r
a550d468 1126EMU_IO_THUNK_PROTOCOL mWinNtSnpThunkIo = {\r
bb78cfbe
NW
1127 &gEmuSnpProtocolGuid,\r
1128 NULL,\r
1129 NULL,\r
1130 0,\r
1131 WinNtSnpThunkOpen,\r
1132 WinNtSnpThunkClose,\r
1133 NULL\r
1134};\r