1. Import SnpNt32Dxe. That is a thunk driver could produce SNP protocol on NT32 platf...
[mirror_edk2.git] / Nt32Pkg / SnpNt32Dxe / SnpNt32.c
1 /** @file
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 SnpNt32.c
15
16 Abstract:
17
18 -**/
19
20 #include "SnpNt32.h"
21
22 EFI_DRIVER_BINDING_PROTOCOL gSnpNt32DriverBinding = {
23 SnpNt32DriverBindingSupported,
24 SnpNt32DriverBindingStart,
25 SnpNt32DriverBindingStop,
26 0xa,
27 NULL,
28 NULL
29 };
30
31 SNPNT32_GLOBAL_DATA gSnpNt32GlobalData = {
32 SNP_NT32_DRIVER_SIGNATURE, // Signature
33 {
34 NULL,
35 NULL
36 }, // InstanceList
37 NULL, // WinNtThunk
38 NULL, // NetworkLibraryHandle
39 {
40 0
41 }, // NtNetUtilityTable
42 {
43 0,
44 0,
45 0
46 }, // Lock
47 //
48 // Private functions
49 //
50 SnpNt32InitializeGlobalData, // InitializeGlobalData
51 SnpNt32InitializeInstanceData, // InitializeInstanceData
52 SnpNt32CloseInstance // CloseInstance
53 };
54
55
56 /**
57 Test to see if this driver supports ControllerHandle.
58
59 @param This Protocol instance pointer.
60 @param ControllerHandle Handle of device to test.
61 @param RemainingDevicePath Optional parameter use to pick a specific child
62 device to start.
63
64 @retval EFI_SUCCES This driver supports this device.
65 @retval other This driver does not support this device.
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 SnpNt32DriverBindingSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL * This,
72 IN EFI_HANDLE ControllerHandle,
73 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
74 )
75 {
76
77 SNPNT32_GLOBAL_DATA *GlobalData;
78 NET_LIST_ENTRY *Entry;
79 SNPNT32_INSTANCE_DATA *Instance;
80
81 GlobalData = &gSnpNt32GlobalData;
82
83 NET_LIST_FOR_EACH (Entry, &GlobalData->InstanceList) {
84
85 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
86
87 if (Instance->DeviceHandle == ControllerHandle) {
88 return EFI_SUCCESS;
89 }
90
91 }
92
93 return EFI_UNSUPPORTED;
94 }
95
96
97 /**
98 Start this driver on ControllerHandle.
99
100 @param This Protocol instance pointer.
101 @param ControllerHandle Handle of device to bind driver to.
102 @param RemainingDevicePath Optional parameter use to pick a specific child
103 device to start.
104
105 @retval EFI_SUCCES This driver is added to ControllerHandle.
106
107 **/
108 EFI_STATUS
109 EFIAPI
110 SnpNt32DriverBindingStart (
111 IN EFI_DRIVER_BINDING_PROTOCOL * This,
112 IN EFI_HANDLE ControllerHandle,
113 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
114 )
115 {
116 return EFI_SUCCESS;
117 }
118
119
120 /**
121 Stop this driver on ControllerHandle.
122
123 @param This Protocol instance pointer.
124 @param ControllerHandle Handle of device to stop driver on.
125 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
126 of children is zero stop the entire bus driver.
127 @param ChildHandleBuffer List of Child Handles to Stop.
128
129 @retval EFI_SUCCES This driver is removed ControllerHandle.
130
131 **/
132 EFI_STATUS
133 EFIAPI
134 SnpNt32DriverBindingStop (
135 IN EFI_DRIVER_BINDING_PROTOCOL *This,
136 IN EFI_HANDLE ControllerHandle,
137 IN UINTN NumberOfChildren,
138 IN EFI_HANDLE *ChildHandleBuffer
139 )
140 {
141
142 return EFI_SUCCESS;
143 }
144
145
146 /**
147 Start the SnpNt32 interface.
148
149 @param This Context pointer.
150
151 @retval EFI_SUCCESS The interface is started.
152
153 **/
154 EFI_STATUS
155 SnpNt32Start (
156 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
157 )
158 {
159 return EFI_SUCCESS;
160 }
161
162
163 /**
164 Stop the SnpNt32 interface.
165
166 @param This Context pointer.
167
168 @retval EFI_SUCCESS The interface is stopped.
169
170 **/
171 EFI_STATUS
172 SnpNt32Stop (
173 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
174 )
175 {
176 return EFI_SUCCESS;
177 }
178
179
180 /**
181 Initialize the SnpNt32 interface.
182
183 @param This Context pointer.
184 @param ExtraRxBufferSize Number of extra receive buffer.
185 @param ExtraTxBufferSize Number of extra transmit buffer.
186
187 @retval EFI_SUCCESS The interface is initialized.
188
189 **/
190 EFI_STATUS
191 SnpNt32Initialize (
192 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
193 IN UINTN ExtraRxBufferSize OPTIONAL,
194 IN UINTN ExtraTxBufferSize OPTIONAL
195 )
196 {
197 return EFI_SUCCESS;
198 }
199
200
201 /**
202 Reset the snpnt32 interface.
203
204 @param This Context pointer.
205 @param ExtendedVerification Not implemented.
206
207 @retval EFI_SUCCESS The interface is reseted.
208
209 **/
210 EFI_STATUS
211 SnpNt32Reset (
212 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
213 IN BOOLEAN ExtendedVerification
214 )
215 {
216 return EFI_SUCCESS;
217 }
218
219
220 /**
221 Shut down the snpnt32 interface.
222
223 @param This Context pointer.
224
225 @retval EFI_SUCCESS The interface is shut down.
226
227 **/
228 EFI_STATUS
229 SnpNt32Shutdown (
230 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
231 )
232 {
233 return EFI_SUCCESS;
234 }
235
236
237 /**
238 Change the interface's receive filter setting.
239
240 @param This Context pointer.
241 @param EnableBits The receive filters to enable.
242 @param DisableBits The receive filters to disable
243 @param ResetMcastFilter Reset the multicast filters or not.
244 @param McastFilterCount The count of multicast filter to set.
245 @param McastFilter Pointer to the arrya of multicast addresses to set.
246
247 @retval EFI_SUCCESS The receive filter is updated.
248 @retval EFI_ACCESS_DENIED The snpnt32 lock is already owned by another
249 routine.
250 @retval EFI_DEVICE_ERROR Failed to update the receive filter.
251
252 **/
253 EFI_STATUS
254 SnpNt32ReceiveFilters (
255 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
256 IN UINT32 EnableBits,
257 IN UINT32 DisableBits,
258 IN BOOLEAN ResetMcastFilter,
259 IN UINTN McastFilterCount OPTIONAL,
260 IN EFI_MAC_ADDRESS *McastFilter OPTIONAL
261 )
262 {
263 SNPNT32_INSTANCE_DATA *Instance;
264 SNPNT32_GLOBAL_DATA *GlobalData;
265 INT32 ReturnValue;
266
267 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
268
269 GlobalData = Instance->GlobalData;
270
271 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {
272 return EFI_ACCESS_DENIED;
273 }
274
275 ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (
276 Instance->InterfaceInfo.InterfaceIndex,
277 EnableBits,
278 McastFilterCount,
279 McastFilter
280 );
281
282 NET_UNLOCK (&GlobalData->Lock);
283
284 if (ReturnValue <= 0) {
285 return EFI_DEVICE_ERROR;
286 }
287
288 return EFI_SUCCESS;
289 }
290
291
292 /**
293 Change or reset the mac address of the interface.
294
295 @param This Context pointer.
296 @param reset Reset the mac address to the original one or not.
297 @param NewMacAddr Pointer to the new mac address to set.
298
299 @retval EFI_UNSUPPORTED Not supported yet.
300
301 **/
302 EFI_STATUS
303 SnpNt32StationAddress (
304 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
305 IN BOOLEAN Reset,
306 IN EFI_MAC_ADDRESS *NewMacAddr OPTIONAL
307 )
308 {
309 return EFI_UNSUPPORTED;
310 }
311
312
313 /**
314 Get or reset the statistics data.
315
316 @param This Context pointer.
317 @param Reset Reset the statistics or not.
318 @param StatisticsSize The size of the buffer used to receive the
319 statistics data.
320 @param StatisticsTable Pointer to the table used to receive the statistics
321 data.
322
323 @retval EFI_UNSUPPORTED Not supported yet.
324
325 **/
326 EFI_STATUS
327 SnpNt32Statistics (
328 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
329 IN BOOLEAN Reset,
330 IN OUT UINTN *StatisticsSize OPTIONAL,
331 IN OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
332 )
333 {
334 return EFI_UNSUPPORTED;
335 }
336
337
338 /**
339 Convert a multicast ip address to the multicast mac address.
340
341 @param This Context pointer.
342 @param Ipv6 The Ip is an Ipv6 address or not.
343 @param Ip Pointer to the Ip address to convert.
344 @param Mac Pointer to the buffer used to hold the converted
345 mac address.
346
347 @retval EFI_UNSUPPORTED Not supported yet.
348
349 **/
350 EFI_STATUS
351 SnpNt32McastIptoMac (
352 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
353 IN BOOLEAN Ipv6,
354 IN EFI_IP_ADDRESS *Ip,
355 OUT EFI_MAC_ADDRESS *Mac
356 )
357 {
358 return EFI_UNSUPPORTED;
359 }
360
361
362 /**
363 Read or write the nv data.
364
365 @param This Context pinter.
366 @param ReadOrWrite Read or write the nv data.
367 @param Offset The offset to the start of the nv data.
368 @param BufferSize Size of the buffer.
369 @param Buffer Pointer to the buffer containing the data to write
370 or used to receive the data read.
371
372 @retval EFI_UNSUPPORTED Not supported yet.
373
374 **/
375 EFI_STATUS
376 SnpNt32Nvdata (
377 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
378 IN BOOLEAN ReadOrWrite,
379 IN UINTN Offset,
380 IN UINTN BufferSize,
381 IN OUT VOID *Buffer
382 )
383 {
384 return EFI_UNSUPPORTED;
385 }
386
387
388 /**
389 Get the status information of the interface.
390
391 @param This Context pointer.
392 @param InterruptStatus The storage to hold the interrupt status.
393 @param TxBuffer Pointer to get the list of pointers of previously
394 transmitted buffers whose transmission was
395 completed asynchrnously.
396
397 @retval EFI_SUCCESS The status is got.
398
399 **/
400 EFI_STATUS
401 SnpNt32GetStatus (
402 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
403 OUT UINT32 *InterruptStatus,
404 OUT VOID **TxBuffer
405 )
406 {
407
408 if (TxBuffer != NULL) {
409 *((UINT8 **) TxBuffer) = (UINT8 *) 1;
410 }
411
412 if (InterruptStatus != NULL) {
413 *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
414 }
415
416 return EFI_SUCCESS;
417 }
418
419
420 /**
421 Transmit a packet.
422
423 @param This Context pointer.
424 @param HeaderSize The media header size contained in the packet
425 buffer.
426 @param BufferSize The size of the packet buffer.
427 @param Buffer Pointer to the buffer containing the packet data.
428 @param SrcAddr If non null, points to the source address of this
429 packet.
430 @param DestAddr If non null, points to the destination address of
431 this packet.
432 @param Protocol The protocol type of this packet.
433
434 @retval EFI_SUCCESS The packet is transmitted or put into the transmit
435 queue.
436 @retval other Some error occurs.
437
438 **/
439 EFI_STATUS
440 SnpNt32Transmit (
441 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
442 IN UINTN HeaderSize,
443 IN UINTN BufferSize,
444 IN VOID *Buffer,
445 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
446 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
447 IN UINT16 *Protocol OPTIONAL
448 )
449 {
450 SNPNT32_INSTANCE_DATA *Instance;
451 SNPNT32_GLOBAL_DATA *GlobalData;
452 INT32 ReturnValue;
453
454 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
455
456 GlobalData = Instance->GlobalData;
457
458 if ((HeaderSize != 0) && (SrcAddr == NULL)) {
459 SrcAddr = &Instance->Mode.CurrentAddress;
460 }
461
462 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {
463 return EFI_ACCESS_DENIED;
464 }
465
466 ReturnValue = GlobalData->NtNetUtilityTable.Transmit (
467 Instance->InterfaceInfo.InterfaceIndex,
468 HeaderSize,
469 BufferSize,
470 Buffer,
471 SrcAddr,
472 DestAddr,
473 Protocol
474 );
475
476 NET_UNLOCK (&GlobalData->Lock);
477
478 if (ReturnValue < 0) {
479 return EFI_DEVICE_ERROR;
480 }
481
482 return EFI_SUCCESS;
483 }
484
485
486 /**
487 Receive network data.
488
489 @param This Context pointer.
490 @param HeaderSize Optional parameter and is a pointer to the header
491 portion of the data received.
492 @param BuffSize Pointer to the length of the Buffer on entry and
493 contains the length of the received data on return
494 @param Buffer Pointer to the memory for the received data
495 @param SourceAddr Optional parameter, is a pointer to contain the
496 source ethernet address on return
497 @param DestinationAddr Optional parameter, is a pointer to contain the
498 destination ethernet address on return.
499 @param Protocol Optional parameter, is a pointer to contain the
500 Protocol type from the ethernet header on return.
501
502 @retval EFI_SUCCESS A packet is received and put into the buffer.
503 @retval EFI_BUFFER_TOO_SMALL The provided buffer is too small to receive the
504 packet.
505 @retval EFI_NOT_READY There is no packet received.
506
507 **/
508 EFI_STATUS
509 SnpNt32Receive (
510 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
511 OUT UINTN *HeaderSize,
512 IN OUT UINTN *BuffSize,
513 OUT VOID *Buffer,
514 OUT EFI_MAC_ADDRESS *SourceAddr,
515 OUT EFI_MAC_ADDRESS *DestinationAddr,
516 OUT UINT16 *Protocol
517 )
518 {
519 SNPNT32_INSTANCE_DATA *Instance;
520 SNPNT32_GLOBAL_DATA *GlobalData;
521 INT32 ReturnValue;
522
523 Instance = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
524
525 GlobalData = Instance->GlobalData;
526
527 ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);
528
529 if (EFI_ERROR (NET_TRYLOCK (&GlobalData->Lock))) {
530 return EFI_ACCESS_DENIED;
531 }
532
533 ReturnValue = GlobalData->NtNetUtilityTable.Receive (
534 Instance->InterfaceInfo.InterfaceIndex,
535 BuffSize,
536 Buffer
537 );
538
539 NET_UNLOCK (&GlobalData->Lock);
540
541 if (ReturnValue < 0) {
542 if (ReturnValue == -100) {
543 return EFI_BUFFER_TOO_SMALL;
544 }
545
546 return EFI_DEVICE_ERROR;
547 } else if (ReturnValue == 0) {
548 return EFI_NOT_READY;
549 }
550
551 if (HeaderSize != NULL) {
552 *HeaderSize = 14;
553 }
554
555 if (SourceAddr != NULL) {
556 NetZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));
557 NetCopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);
558 }
559
560 if (DestinationAddr != NULL) {
561 NetZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));
562 NetCopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);
563 }
564
565 if (Protocol != NULL) {
566 *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12)));
567 }
568
569 return EFI_SUCCESS;
570 }
571
572 SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {
573 SNP_NT32_INSTANCE_SIGNATURE, // Signature
574 {
575 NULL,
576 NULL
577 }, // Entry
578 NULL, // GlobalData
579 NULL, // DeviceHandle
580 NULL, // DevicePath
581 { // Snp
582 EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, // Revision
583 SnpNt32Start, // Start
584 SnpNt32Stop, // Stop
585 SnpNt32Initialize, // Initialize
586 SnpNt32Reset, // Reset
587 SnpNt32Shutdown, // Shutdown
588 SnpNt32ReceiveFilters, // ReceiveFilters
589 SnpNt32StationAddress, // StationAddress
590 SnpNt32Statistics, // Statistics
591 SnpNt32McastIptoMac, // MCastIpToMac
592 SnpNt32Nvdata, // NvData
593 SnpNt32GetStatus, // GetStatus
594 SnpNt32Transmit, // Transmit
595 SnpNt32Receive, // Receive
596 NULL, // WaitForPacket
597 NULL // Mode
598 },
599 { // Mode
600 EfiSimpleNetworkInitialized, // State
601 NET_ETHER_ADDR_LEN, // HwAddressSize
602 NET_ETHER_HEADER_SIZE, // MediaHeaderSize
603 1500, // MaxPacketSize
604 0, // NvRamSize
605 0, // NvRamAccessSize
606 0, // ReceiveFilterMask
607 0, // ReceiveFilterSetting
608 MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount
609 0, // MCastFilterCount
610 {
611 0
612 }, // MCastFilter
613 {
614 0
615 }, // CurrentAddress
616 {
617 0
618 }, // BroadcastAddress
619 {
620 0
621 }, // PermanentAddress
622 NET_IFTYPE_ETHERNET, // IfType
623 FALSE, // MacAddressChangeable
624 FALSE, // MultipleTxSupported
625 FALSE, // MediaPresentSupported
626 TRUE // MediaPresent
627 },
628 {
629 0
630 } // InterfaceInfo
631 };
632
633
634 /**
635 Initialize the driver's global data.
636
637 @param This Pointer to the global context data.
638
639 @retval EFI_SUCCESS The global data is initialized.
640 @retval EFI_NOT_FOUND The required DLL is not found.
641
642 **/
643 EFI_STATUS
644 SnpNt32InitializeGlobalData (
645 IN SNPNT32_GLOBAL_DATA *This
646 )
647 {
648 EFI_STATUS Status;
649 CHAR16 *DllFileNameU;
650 UINT32 Index;
651 INT32 ReturnValue;
652 BOOLEAN NetUtilityLibInitDone;
653 NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];
654 SNPNT32_INSTANCE_DATA *Instance;
655 NET_LIST_ENTRY *Entry;
656 UINT32 InterfaceCount;
657
658 ASSERT (This != NULL);
659
660 NetUtilityLibInitDone = FALSE;
661 InterfaceCount = MAX_INTERFACE_INFO_NUMBER;
662
663 NetListInit (&This->InstanceList);
664 NET_LOCK_INIT (&This->Lock);
665
666 //
667 // Get the WinNT thunk
668 //
669 Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, &This->WinNtThunk);
670
671 if (EFI_ERROR (Status)) {
672 return Status;
673 }
674
675 ASSERT (This->WinNtThunk != NULL);
676
677 DllFileNameU = NETWORK_LIBRARY_NAME_U;
678
679 //
680 // Load network utility library
681 //
682 This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);
683
684 if (NULL == This->NetworkLibraryHandle) {
685 return EFI_NOT_FOUND;
686 }
687
688 This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (
689 This->NetworkLibraryHandle,
690 NETWORK_LIBRARY_INITIALIZE
691 );
692
693 if (NULL == This->NtNetUtilityTable.Initialize) {
694 Status = EFI_NOT_FOUND;
695 goto ErrorReturn;
696 }
697
698 This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (
699 This->NetworkLibraryHandle,
700 NETWORK_LIBRARY_FINALIZE
701 );
702
703 if (NULL == This->NtNetUtilityTable.Finalize) {
704 Status = EFI_NOT_FOUND;
705 goto ErrorReturn;
706 }
707
708 This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (
709 This->NetworkLibraryHandle,
710 NETWORK_LIBRARY_SET_RCV_FILTER
711 );
712
713 if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {
714 Status = EFI_NOT_FOUND;
715 goto ErrorReturn;
716 }
717
718 This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (
719 This->NetworkLibraryHandle,
720 NETWORK_LIBRARY_RECEIVE
721 );
722
723 if (NULL == This->NtNetUtilityTable.Receive) {
724 Status = EFI_NOT_FOUND;
725 goto ErrorReturn;
726 }
727
728 This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (
729 This->NetworkLibraryHandle,
730 NETWORK_LIBRARY_TRANSMIT
731 );
732
733 if (NULL == This->NtNetUtilityTable.Transmit) {
734 Status = EFI_NOT_FOUND;
735 goto ErrorReturn;
736 }
737 //
738 // Initialize the network utility library
739 // And enumerate the interfaces in NT32 host
740 //
741 ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);
742 if (ReturnValue <= 0) {
743 Status = EFI_DEVICE_ERROR;
744 goto ErrorReturn;
745 }
746
747 NetUtilityLibInitDone = TRUE;
748
749 if (InterfaceCount == 0) {
750 Status = EFI_NOT_FOUND;
751 goto ErrorReturn;
752 }
753 //
754 // Create fake SNP instances
755 //
756 for (Index = 0; Index < InterfaceCount; Index++) {
757
758 Instance = NetAllocatePool (sizeof (SNPNT32_INSTANCE_DATA));
759
760 if (NULL == Instance) {
761 Status = EFI_OUT_OF_RESOURCES;
762 goto ErrorReturn;
763 }
764 //
765 // Copy the content from a template
766 //
767 NetCopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));
768
769 //
770 // Set the interface information.
771 //
772 Instance->InterfaceInfo = NetInterfaceInfoBuffer[Index];
773 //
774 // Initialize this instance
775 //
776 Status = This->InitializeInstanceData (This, Instance);
777 if (EFI_ERROR (Status)) {
778
779 NetFreePool (Instance);
780 goto ErrorReturn;
781 }
782 //
783 // Insert this instance into the instance list
784 //
785 NetListInsertTail (&This->InstanceList, &Instance->Entry);
786 }
787
788 return EFI_SUCCESS;
789
790 ErrorReturn:
791
792 while (!NetListIsEmpty (&This->InstanceList)) {
793
794 Entry = This->InstanceList.ForwardLink;
795
796 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
797
798 NetListRemoveEntry (Entry);
799
800 This->CloseInstance (This, Instance);
801 NetFreePool (Instance);
802 }
803
804 if (NetUtilityLibInitDone) {
805
806 ASSERT (This->WinNtThunk != NULL);
807
808 if (This->NtNetUtilityTable.Finalize != NULL) {
809 This->NtNetUtilityTable.Finalize ();
810 This->NtNetUtilityTable.Finalize = NULL;
811 }
812 }
813
814 return Status;
815 }
816
817
818 /**
819 Initialize the snpnt32 driver instance.
820
821 @param This Pointer to the SnpNt32 global data.
822 @param Instance Pointer to the instance context data.
823
824 @retval EFI_SUCCESS The driver instance is initialized.
825
826 **/
827 EFI_STATUS
828 SnpNt32InitializeInstanceData (
829 IN SNPNT32_GLOBAL_DATA *This,
830 IN SNPNT32_INSTANCE_DATA *Instance
831 )
832 {
833 EFI_STATUS Status;
834 EFI_DEV_PATH EndNode;
835 EFI_DEV_PATH Node;
836
837 Instance->GlobalData = This;
838 Instance->Snp.Mode = &Instance->Mode;
839 //
840 // Set broadcast address
841 //
842 SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
843
844 //
845 // Copy Current/PermanentAddress MAC address
846 //
847 Instance->Mode.CurrentAddress = Instance->InterfaceInfo.MacAddr;
848 Instance->Mode.PermanentAddress = Instance->InterfaceInfo.MacAddr;
849
850 //
851 // Since the fake SNP is based on a real NIC, to avoid conflict with the host
852 // NIC network stack, we use a different MAC address.
853 // So just change the last byte of the MAC address for the real NIC.
854 //
855 Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;
856
857 //
858 // Create a fake device path for the instance
859 //
860 NetZeroMem (&Node, sizeof (Node));
861
862 Node.DevPath.Type = MESSAGING_DEVICE_PATH;
863 Node.DevPath.SubType = MSG_MAC_ADDR_DP;
864 SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));
865
866 NetCopyMem (
867 &Node.MacAddr.MacAddress,
868 &Instance->Mode.CurrentAddress,
869 sizeof (EFI_MAC_ADDRESS)
870 );
871
872 Node.MacAddr.IfType = Instance->Mode.IfType;
873
874 SetDevicePathEndNode (&EndNode.DevPath);
875
876 Instance->DevicePath = AppendDevicePathNode (
877 &EndNode.DevPath,
878 &Node.DevPath
879 );
880
881 //
882 // Create a fake device handle for the fake SNP
883 //
884 Status = gBS->InstallMultipleProtocolInterfaces (
885 &Instance->DeviceHandle,
886 &gEfiSimpleNetworkProtocolGuid,
887 &Instance->Snp,
888 &gEfiDevicePathProtocolGuid,
889 Instance->DevicePath,
890 NULL
891 );
892 if (EFI_ERROR (Status)) {
893 goto ErrorReturn;
894 }
895
896 return EFI_SUCCESS;
897
898 ErrorReturn:
899 return Status;
900 }
901
902
903 /**
904 Close the SnpNt32 driver instance.
905
906 @param This Pointer to the SnpNt32 global data.
907 @param Instance Pointer to the instance context data.
908
909 @retval EFI_SUCCESS The instance is closed.
910
911 **/
912 EFI_STATUS
913 SnpNt32CloseInstance (
914 IN SNPNT32_GLOBAL_DATA *This,
915 IN SNPNT32_INSTANCE_DATA *Instance
916 )
917 {
918 ASSERT (This != NULL);
919 ASSERT (Instance != NULL);
920
921 gBS->UninstallMultipleProtocolInterfaces (
922 Instance->DeviceHandle,
923 &gEfiSimpleNetworkProtocolGuid,
924 &Instance->Snp,
925 &gEfiDevicePathProtocolGuid,
926 Instance->DevicePath,
927 NULL
928 );
929
930 if (Instance->DevicePath != NULL) {
931 gBS->FreePool (Instance->DevicePath);
932 }
933
934 return EFI_SUCCESS;
935 }
936
937
938 /**
939 Unload the SnpNt32 driver.
940
941 @param ImageHandle The handle of the driver image.
942
943 @retval EFI_SUCCESS The driver is unloaded.
944 @retval other Some error occurs.
945
946 **/
947 EFI_STATUS
948 EFIAPI
949 SnpNt32Unload (
950 IN EFI_HANDLE ImageHandle
951 )
952 {
953 EFI_STATUS Status;
954 SNPNT32_GLOBAL_DATA *This;
955 NET_LIST_ENTRY *Entry;
956 SNPNT32_INSTANCE_DATA *Instance;
957
958 This = &gSnpNt32GlobalData;
959
960 Status = NetLibDefaultUnload (ImageHandle);
961
962 if (EFI_ERROR (Status)) {
963 return Status;
964 }
965
966 while (!NetListIsEmpty (&This->InstanceList)) {
967 //
968 // Walkthrough the interfaces and remove all the SNP instance
969 //
970 Entry = This->InstanceList.ForwardLink;
971
972 Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
973
974 NetListRemoveEntry (Entry);
975
976 This->CloseInstance (This, Instance);
977 NetFreePool (Instance);
978 }
979
980 if (This->NtNetUtilityTable.Finalize != NULL) {
981 This->NtNetUtilityTable.Finalize ();
982 }
983
984 This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);
985
986 return EFI_SUCCESS;
987 }
988
989
990 EFI_STATUS
991 InitializeSnpNt32river (
992 IN EFI_HANDLE ImageHandle,
993 IN EFI_SYSTEM_TABLE *SystemTable
994 )
995 /*++
996
997 Routine Description:
998
999 Install DriverBinding Protocol for the Win NT Bus driver on the drivers
1000 image handle.
1001
1002 Arguments:
1003
1004 ImageHandle - The handle of this image.
1005 SystemTable - Pointer to the EFI system table.
1006
1007 Returns:
1008
1009 EFI_SUCEESS - The protocols are installed and the SnpNt32 is initialized.
1010 other - Some error occurs.
1011
1012 --*/
1013 {
1014
1015 EFI_STATUS Status;
1016
1017 //
1018 // Install the Driver Protocols
1019 //
1020
1021 Status = NetLibInstallAllDriverProtocolsWithUnload (
1022 ImageHandle,
1023 SystemTable,
1024 &gSnpNt32DriverBinding,
1025 ImageHandle,
1026 &gSnpNt32DriverComponentName,
1027 NULL,
1028 NULL,
1029 SnpNt32Unload
1030 );
1031 if (EFI_ERROR (Status)) {
1032 return Status;
1033 }
1034
1035 //
1036 // Initialize the global data
1037 //
1038 Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);
1039 if (EFI_ERROR (Status)) {
1040 SnpNt32Unload (ImageHandle);
1041 }
1042
1043 return Status;
1044 }