2 Initialization functions for EFI UNDI32 driver.
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 PXE_SW_UNDI
*pxe_31
= NULL
; // 3.1 entry
21 UNDI32_DEV
*UNDI32DeviceList
[MAX_NIC_INTERFACES
];
22 NII_TABLE
*UndiDataPointer
= NULL
;
25 // UNDI Class Driver Global Variables
27 EFI_DRIVER_BINDING_PROTOCOL gUndiDriverBinding
= {
38 When address mapping changes to virtual this should make the appropriate
41 (Standard Event handler)
57 Pxe31Pointer
= (VOID
*) pxe_31
;
61 (VOID
**) &Pxe31Pointer
65 // UNDI32DeviceList is an array of pointers
67 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
68 UNDI32DeviceList
[Index
]->NIIProtocol_31
.Id
= (UINT64
) (UINTN
) Pxe31Pointer
;
71 (VOID
**) &(UNDI32DeviceList
[Index
])
77 (VOID
**) &(pxe_31
->EntryPoint
)
79 pxe_31
= Pxe31Pointer
;
82 for (Index
= 0; Index
<= PXE_OPCODE_LAST_VALID
; Index
++) {
85 (VOID
**) &api_table
[Index
].api_ptr
92 When EFI is shuting down the boot services, we need to install a
93 configuration table for UNDI to work at runtime!
95 (Standard Event handler)
107 InstallConfigTable ();
112 Test to see if this driver supports ControllerHandle. Any ControllerHandle
113 than contains a DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,
114 and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||
115 ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||
116 ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.
118 @param This Protocol instance pointer.
119 @param Controller Handle of device to test.
120 @param RemainingDevicePath Not used.
122 @retval EFI_SUCCESS This driver supports this device.
123 @retval other This driver does not support this device.
128 UndiDriverSupported (
129 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
130 IN EFI_HANDLE Controller
,
131 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
135 EFI_PCI_IO_PROTOCOL
*PciIo
;
138 Status
= gBS
->OpenProtocol (
140 &gEfiDevicePathProtocolGuid
,
142 This
->DriverBindingHandle
,
144 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
146 if (EFI_ERROR (Status
)) {
150 Status
= gBS
->OpenProtocol (
152 &gEfiPciIoProtocolGuid
,
154 This
->DriverBindingHandle
,
156 EFI_OPEN_PROTOCOL_BY_DRIVER
158 if (EFI_ERROR (Status
)) {
162 Status
= PciIo
->Pci
.Read (
166 sizeof (PCI_CONFIG_HEADER
),
170 if (!EFI_ERROR (Status
)) {
171 Status
= EFI_UNSUPPORTED
;
173 if (Pci
.Hdr
.ClassCode
[2] == 0x02 && Pci
.Hdr
.VendorId
== PCI_VENDOR_ID_INTEL
) {
174 switch (Pci
.Hdr
.DeviceId
) {
177 case ICH3_DEVICE_ID_1
:
178 case ICH3_DEVICE_ID_2
:
179 case ICH3_DEVICE_ID_3
:
180 case ICH3_DEVICE_ID_4
:
181 case ICH3_DEVICE_ID_5
:
182 case ICH3_DEVICE_ID_6
:
183 case ICH3_DEVICE_ID_7
:
184 case ICH3_DEVICE_ID_8
:
201 Status
= EFI_SUCCESS
;
208 &gEfiPciIoProtocolGuid
,
209 This
->DriverBindingHandle
,
218 Start this driver on Controller by opening PciIo and DevicePath protocol.
219 Initialize PXE structures, create a copy of the Controller Device Path with the
220 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
221 on the newly created Device Path.
223 @param This Protocol instance pointer.
224 @param Controller Handle of device to work with.
225 @param RemainingDevicePath Not used, always produce all possible children.
227 @retval EFI_SUCCESS This driver is added to Controller.
228 @retval other This driver does not support this device.
234 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
235 IN EFI_HANDLE Controller
,
236 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
240 EFI_DEVICE_PATH_PROTOCOL
*UndiDevicePath
;
241 PCI_CONFIG_HEADER
*CfgHdr
;
242 UNDI32_DEV
*UNDI32Device
;
244 UINT8
*TmpPxePointer
;
245 EFI_PCI_IO_PROTOCOL
*PciIoFncs
;
248 BOOLEAN PciAttributesSaved
;
250 Status
= gBS
->OpenProtocol (
252 &gEfiPciIoProtocolGuid
,
253 (VOID
**) &PciIoFncs
,
254 This
->DriverBindingHandle
,
256 EFI_OPEN_PROTOCOL_BY_DRIVER
259 if (EFI_ERROR (Status
)) {
263 Status
= gBS
->OpenProtocol (
265 &gEfiDevicePathProtocolGuid
,
266 (VOID
**) &UndiDevicePath
,
267 This
->DriverBindingHandle
,
269 EFI_OPEN_PROTOCOL_BY_DRIVER
272 if (EFI_ERROR (Status
)) {
275 &gEfiPciIoProtocolGuid
,
276 This
->DriverBindingHandle
,
283 PciAttributesSaved
= FALSE
;
285 Status
= gBS
->AllocatePool (
286 EfiRuntimeServicesData
,
288 (VOID
**) &UNDI32Device
291 if (EFI_ERROR (Status
)) {
295 ZeroMem ((CHAR8
*) UNDI32Device
, sizeof (UNDI32_DEV
));
298 // Get original PCI attributes
300 Status
= PciIoFncs
->Attributes (
302 EfiPciIoAttributeOperationGet
,
304 &UNDI32Device
->NicInfo
.OriginalPciAttributes
307 if (EFI_ERROR (Status
)) {
308 goto UndiErrorDeleteDevice
;
310 PciAttributesSaved
= TRUE
;
313 // allocate and initialize both (old and new) the !pxe structures here,
314 // there should only be one copy of each of these structure for any number
315 // of NICs this undi supports. Also, these structures need to be on a
316 // paragraph boundary as per the spec. so, while allocating space for these,
317 // make sure that there is space for 2 !pxe structures (old and new) and a
318 // 32 bytes padding for alignment adjustment (in case)
320 TmpPxePointer
= NULL
;
321 if (pxe_31
== NULL
) {
322 Status
= gBS
->AllocatePool (
323 EfiRuntimeServicesData
,
324 (sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32),
325 (VOID
**) &TmpPxePointer
328 if (EFI_ERROR (Status
)) {
329 goto UndiErrorDeleteDevice
;
334 sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32
337 // check for paragraph alignment here, assuming that the pointer is
338 // already 8 byte aligned.
340 if (((UINTN
) TmpPxePointer
& 0x0F) != 0) {
341 pxe_31
= (PXE_SW_UNDI
*) ((UINTN
) (TmpPxePointer
+ 8));
343 pxe_31
= (PXE_SW_UNDI
*) TmpPxePointer
;
346 PxeStructInit (pxe_31
);
349 UNDI32Device
->NIIProtocol_31
.Id
= (UINT64
) (UINTN
) (pxe_31
);
351 Status
= PciIoFncs
->Attributes (
353 EfiPciIoAttributeOperationSupported
,
357 if (!EFI_ERROR (Status
)) {
358 Supports
&= EFI_PCI_DEVICE_ENABLE
;
359 Status
= PciIoFncs
->Attributes (
361 EfiPciIoAttributeOperationEnable
,
367 // Read all the registers from device's PCI Configuration space
369 Status
= PciIoFncs
->Pci
.Read (
374 &UNDI32Device
->NicInfo
.Config
377 CfgHdr
= (PCI_CONFIG_HEADER
*) &(UNDI32Device
->NicInfo
.Config
[0]);
380 // make sure that this device is a PCI bus master
383 NewCommand
= (UINT16
) (CfgHdr
->Command
| PCI_COMMAND_MASTER
| PCI_COMMAND_IO
);
384 if (CfgHdr
->Command
!= NewCommand
) {
385 PciIoFncs
->Pci
.Write (
392 CfgHdr
->Command
= NewCommand
;
396 // make sure that the latency timer is at least 32
398 if (CfgHdr
->LatencyTimer
< 32) {
399 CfgHdr
->LatencyTimer
= 32;
400 PciIoFncs
->Pci
.Write (
405 &CfgHdr
->LatencyTimer
409 // the IfNum index for the current interface will be the total number
410 // of interfaces initialized so far
412 UNDI32Device
->NIIProtocol_31
.IfNum
= pxe_31
->IFcnt
;
414 PxeUpdate (&UNDI32Device
->NicInfo
, pxe_31
);
416 UNDI32Device
->NicInfo
.Io_Function
= PciIoFncs
;
417 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = UNDI32Device
;
418 UNDI32Device
->Undi32BaseDevPath
= UndiDevicePath
;
420 Status
= AppendMac2DevPath (
421 &UNDI32Device
->Undi32DevPath
,
422 UNDI32Device
->Undi32BaseDevPath
,
423 &UNDI32Device
->NicInfo
427 goto UndiErrorDeletePxe
;
430 UNDI32Device
->Signature
= UNDI_DEV_SIGNATURE
;
432 UNDI32Device
->NIIProtocol_31
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
;
433 UNDI32Device
->NIIProtocol_31
.Type
= EfiNetworkInterfaceUndi
;
434 UNDI32Device
->NIIProtocol_31
.MajorVer
= PXE_ROMID_MAJORVER
;
435 UNDI32Device
->NIIProtocol_31
.MinorVer
= PXE_ROMID_MINORVER_31
;
436 UNDI32Device
->NIIProtocol_31
.ImageSize
= 0;
437 UNDI32Device
->NIIProtocol_31
.ImageAddr
= 0;
438 UNDI32Device
->NIIProtocol_31
.Ipv6Supported
= FALSE
;
440 UNDI32Device
->NIIProtocol_31
.StringId
[0] = 'U';
441 UNDI32Device
->NIIProtocol_31
.StringId
[1] = 'N';
442 UNDI32Device
->NIIProtocol_31
.StringId
[2] = 'D';
443 UNDI32Device
->NIIProtocol_31
.StringId
[3] = 'I';
445 UNDI32Device
->DeviceHandle
= NULL
;
448 // install both the 3.0 and 3.1 NII protocols.
450 Status
= gBS
->InstallMultipleProtocolInterfaces (
451 &UNDI32Device
->DeviceHandle
,
452 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
453 &UNDI32Device
->NIIProtocol_31
,
454 &gEfiDevicePathProtocolGuid
,
455 UNDI32Device
->Undi32DevPath
,
459 if (EFI_ERROR (Status
)) {
460 goto UndiErrorDeleteDevicePath
;
464 // if the table exists, free it and alloc again, or alloc it directly
466 if (UndiDataPointer
!= NULL
) {
467 Status
= gBS
->FreePool(UndiDataPointer
);
469 if (EFI_ERROR (Status
)) {
470 goto UndiErrorDeleteDevicePath
;
473 Len
= (pxe_31
->IFcnt
* sizeof (NII_ENTRY
)) + sizeof (UndiDataPointer
);
474 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UndiDataPointer
);
476 if (EFI_ERROR (Status
)) {
477 goto UndiErrorAllocDataPointer
;
481 // Open For Child Device
483 Status
= gBS
->OpenProtocol (
485 &gEfiPciIoProtocolGuid
,
486 (VOID
**) &PciIoFncs
,
487 This
->DriverBindingHandle
,
488 UNDI32Device
->DeviceHandle
,
489 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
493 UndiErrorAllocDataPointer
:
494 gBS
->UninstallMultipleProtocolInterfaces (
495 &UNDI32Device
->DeviceHandle
,
496 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
497 &UNDI32Device
->NIIProtocol_31
,
498 &gEfiDevicePathProtocolGuid
,
499 UNDI32Device
->Undi32DevPath
,
503 UndiErrorDeleteDevicePath
:
504 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = NULL
;
505 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
508 PxeUpdate (NULL
, pxe_31
);
509 if (TmpPxePointer
!= NULL
) {
510 gBS
->FreePool (TmpPxePointer
);
514 UndiErrorDeleteDevice
:
515 if (PciAttributesSaved
) {
517 // Restore original PCI attributes
519 PciIoFncs
->Attributes (
521 EfiPciIoAttributeOperationSet
,
522 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
527 gBS
->FreePool (UNDI32Device
);
532 &gEfiDevicePathProtocolGuid
,
533 This
->DriverBindingHandle
,
539 &gEfiPciIoProtocolGuid
,
540 This
->DriverBindingHandle
,
549 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
550 closing the DevicePath and PciIo protocols on Controller.
552 @param This Protocol instance pointer.
553 @param Controller Handle of device to stop driver on.
554 @param NumberOfChildren How many children need to be stopped.
555 @param ChildHandleBuffer Not used.
557 @retval EFI_SUCCESS This driver is removed Controller.
558 @retval other This driver was not removed from this device.
561 // TODO: EFI_DEVICE_ERROR - add return value to function comment
565 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
566 IN EFI_HANDLE Controller
,
567 IN UINTN NumberOfChildren
,
568 IN EFI_HANDLE
*ChildHandleBuffer
572 BOOLEAN AllChildrenStopped
;
574 UNDI32_DEV
*UNDI32Device
;
575 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
578 // Complete all outstanding transactions to Controller.
579 // Don't allow any new transaction to Controller to be started.
581 if (NumberOfChildren
== 0) {
584 // Close the bus driver
586 Status
= gBS
->CloseProtocol (
588 &gEfiDevicePathProtocolGuid
,
589 This
->DriverBindingHandle
,
593 Status
= gBS
->CloseProtocol (
595 &gEfiPciIoProtocolGuid
,
596 This
->DriverBindingHandle
,
603 AllChildrenStopped
= TRUE
;
605 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
607 Status
= gBS
->OpenProtocol (
608 ChildHandleBuffer
[Index
],
609 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
610 (VOID
**) &NIIProtocol
,
611 This
->DriverBindingHandle
,
613 EFI_OPEN_PROTOCOL_GET_PROTOCOL
615 if (!EFI_ERROR (Status
)) {
617 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
619 Status
= gBS
->UninstallMultipleProtocolInterfaces (
620 ChildHandleBuffer
[Index
],
621 &gEfiDevicePathProtocolGuid
,
622 UNDI32Device
->Undi32DevPath
,
623 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
624 &UNDI32Device
->NIIProtocol_31
,
627 if (!EFI_ERROR (Status
)) {
629 // Restore original PCI attributes
631 Status
= UNDI32Device
->NicInfo
.Io_Function
->Attributes (
632 UNDI32Device
->NicInfo
.Io_Function
,
633 EfiPciIoAttributeOperationSet
,
634 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
637 ASSERT_EFI_ERROR (Status
);
639 Status
= gBS
->CloseProtocol (
641 &gEfiPciIoProtocolGuid
,
642 This
->DriverBindingHandle
,
643 ChildHandleBuffer
[Index
]
646 ASSERT_EFI_ERROR (Status
);
648 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
649 gBS
->FreePool (UNDI32Device
);
654 if (EFI_ERROR (Status
)) {
655 AllChildrenStopped
= FALSE
;
659 if (!AllChildrenStopped
) {
660 return EFI_DEVICE_ERROR
;
669 Use the EFI boot services to produce a pause. This is also the routine which
670 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
673 @param UnqId Runtime O/S routine might use this, this temp
674 routine does not use it
675 @param MicroSeconds Determines the length of pause.
683 IN UINTN MicroSeconds
686 gBS
->Stall ((UINT32
) MicroSeconds
);
691 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
692 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
694 @param UnqId Runtime O/S routine may use this field, this temp
696 @param ReadWrite Determine if it is an I/O or Memory Read/Write
698 @param Len Determines the width of the data operation.
699 @param Port What port to Read/Write from.
700 @param BuffAddr Address to read to or write from.
714 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
715 NIC_DATA_INSTANCE
*AdapterInfo
;
717 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
718 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
721 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
725 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
729 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
735 AdapterInfo
->Io_Function
->Io
.Read (
736 AdapterInfo
->Io_Function
,
741 (VOID
*) (UINTN
) (BuffAddr
)
746 AdapterInfo
->Io_Function
->Io
.Write (
747 AdapterInfo
->Io_Function
,
752 (VOID
*) (UINTN
) (BuffAddr
)
757 AdapterInfo
->Io_Function
->Mem
.Read (
758 AdapterInfo
->Io_Function
,
763 (VOID
*) (UINTN
) (BuffAddr
)
768 AdapterInfo
->Io_Function
->Mem
.Write (
769 AdapterInfo
->Io_Function
,
774 (VOID
*) (UINTN
) (BuffAddr
)
784 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
785 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
786 and an added MAC node.
788 @param DevPtr Pointer which will point to the newly created device
789 path with the MAC node attached.
790 @param BaseDevPtr Pointer to the device path which the UNDI device
791 driver is latching on to.
792 @param AdapterInfo Pointer to the NIC data structure information which
793 the UNDI driver is layering on..
795 @retval EFI_SUCCESS A MAC address was successfully appended to the Base
797 @retval other Not enough resources available to create new Device
803 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
804 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
805 IN NIC_DATA_INSTANCE
*AdapterInfo
808 EFI_MAC_ADDRESS MACAddress
;
809 PCI_CONFIG_HEADER
*CfgHdr
;
814 MAC_ADDR_DEVICE_PATH MacAddrNode
;
815 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
822 // set the environment ready (similar to UNDI_Start call) so that we can
823 // execute the other UNDI_ calls to get the mac address
824 // we are using undi 3.1 style
826 AdapterInfo
->Delay
= TmpDelay
;
827 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
828 AdapterInfo
->Block
= (VOID
*) 0;
829 AdapterInfo
->Map_Mem
= (VOID
*) 0;
830 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
831 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
832 AdapterInfo
->Mem_Io
= TmpMemIo
;
834 // these tmp call-backs follow 3.1 undi style
835 // i.e. they have the unique_id parameter.
837 AdapterInfo
->VersionFlag
= 0x31;
838 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
843 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
844 AdapterInfo
->ioaddr
= 0;
845 AdapterInfo
->RevID
= CfgHdr
->RevID
;
847 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
849 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
850 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
851 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
852 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
855 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
856 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
857 // MACAddress.Addr[Index2] = 0;
862 AdapterInfo
->Delay
= (VOID
*) 0;
863 AdapterInfo
->Mem_Io
= (VOID
*) 0;
866 // fill the mac address node first
868 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
870 (CHAR8
*) &MacAddrNode
.MacAddress
,
871 (CHAR8
*) &MACAddress
,
872 sizeof (EFI_MAC_ADDRESS
)
875 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
876 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
877 MacAddrNode
.Header
.Length
[0] = (UINT8
) sizeof (MacAddrNode
);
878 MacAddrNode
.Header
.Length
[1] = 0;
881 // find the size of the base dev path.
883 EndNode
= BaseDevPtr
;
885 while (!IsDevicePathEnd (EndNode
)) {
886 EndNode
= NextDevicePathNode (EndNode
);
889 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
892 // create space for full dev path
894 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
896 Status
= gBS
->AllocatePool (
897 EfiRuntimeServicesData
,
902 if (Status
!= EFI_SUCCESS
) {
906 // copy the base path, mac addr and end_dev_path nodes
908 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
909 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
910 DevicePtr
+= BasePathLen
;
911 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
912 DevicePtr
+= sizeof (MacAddrNode
);
913 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
920 Install a GUID/Pointer pair into the system's configuration table.
924 @retval EFI_SUCCESS Install a GUID/Pointer pair into the system's
926 @retval other Did not successfully install the GUID/Pointer pair
927 into the configuration table.
930 // TODO: VOID - add argument and description to function comment
937 EFI_CONFIGURATION_TABLE
*CfgPtr
;
942 if (pxe_31
== NULL
) {
946 if(UndiDataPointer
== NULL
) {
950 UndiData
= (NII_TABLE
*)UndiDataPointer
;
952 UndiData
->NumEntries
= pxe_31
->IFcnt
;
953 UndiData
->NextLink
= NULL
;
955 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
956 UndiData
->NiiEntry
[Index
].InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
957 UndiData
->NiiEntry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
961 // see if there is an entry in the config table already
963 CfgPtr
= gST
->ConfigurationTable
;
965 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
966 Status
= CompareGuid (
968 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
970 if (Status
!= EFI_SUCCESS
) {
977 if (Index
< gST
->NumberOfTableEntries
) {
978 TmpData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
981 // go to the last link
983 while (TmpData
->NextLink
!= NULL
) {
984 TmpData
= TmpData
->NextLink
;
987 TmpData
->NextLink
= UndiData
;
992 UndiData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
996 // create an entry in the configuration table for our GUID
998 Status
= gBS
->InstallConfigurationTable (
999 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1011 IN EFI_HANDLE ImageHandle
,
1012 IN EFI_SYSTEM_TABLE
*SystemTable
1018 Status
= EfiLibInstallDriverBinding (
1021 &gUndiDriverBinding
,
1024 ASSERT_EFI_ERROR (Status
);
1026 Status
= gBS
->CreateEventEx (
1031 &gEfiEventExitBootServicesGuid
,
1034 ASSERT_EFI_ERROR (Status
);
1036 Status
= gBS
->CreateEventEx (
1041 &gEfiEventVirtualAddressChangeGuid
,
1044 ASSERT_EFI_ERROR (Status
);