2 Initialization functions for EFI UNDI32 driver.
4 Copyright (c) 2006 - 2008, Intel Corporation
5 All rights reserved. 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
;
26 When address mapping changes to virtual this should make the appropriate
29 (Standard Event handler)
34 // TODO: Context - add argument and description to function comment
46 Pxe31Pointer
= (VOID
*) pxe_31
;
50 (VOID
**) &Pxe31Pointer
54 // UNDI32DeviceList is an array of pointers
56 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
57 UNDI32DeviceList
[Index
]->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) Pxe31Pointer
;
60 (VOID
**) &(UNDI32DeviceList
[Index
])
66 (VOID
**) &(pxe_31
->EntryPoint
)
68 pxe_31
= Pxe31Pointer
;
71 for (Index
= 0; Index
<= PXE_OPCODE_LAST_VALID
; Index
++) {
74 (VOID
**) &api_table
[Index
].api_ptr
81 When EFI is shuting down the boot services, we need to install a
82 configuration table for UNDI to work at runtime!
84 (Standard Event handler)
89 // TODO: Context - add argument and description to function comment
97 InstallConfigTable ();
100 // UNDI Class Driver Global Variables
102 EFI_DRIVER_BINDING_PROTOCOL gUndiDriverBinding
= {
114 Test to see if this driver supports ControllerHandle. Any ControllerHandle
115 than contains a DevicePath, PciIo protocol, Class code of 2, Vendor ID of 0x8086,
116 and DeviceId of (D100_DEVICE_ID || D102_DEVICE_ID || ICH3_DEVICE_ID_1 ||
117 ICH3_DEVICE_ID_2 || ICH3_DEVICE_ID_3 || ICH3_DEVICE_ID_4 || ICH3_DEVICE_ID_5 ||
118 ICH3_DEVICE_ID_6 || ICH3_DEVICE_ID_7 || ICH3_DEVICE_ID_8) can be supported.
120 @param This Protocol instance pointer.
121 @param Controller Handle of device to test.
122 @param RemainingDevicePath Not used.
124 @retval EFI_SUCCESS This driver supports this device.
125 @retval other This driver does not support this device.
130 UndiDriverSupported (
131 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
132 IN EFI_HANDLE Controller
,
133 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
137 EFI_PCI_IO_PROTOCOL
*PciIo
;
140 Status
= gBS
->OpenProtocol (
142 &gEfiDevicePathProtocolGuid
,
144 This
->DriverBindingHandle
,
146 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
148 if (EFI_ERROR (Status
)) {
152 Status
= gBS
->OpenProtocol (
154 &gEfiPciIoProtocolGuid
,
156 This
->DriverBindingHandle
,
158 EFI_OPEN_PROTOCOL_BY_DRIVER
160 if (EFI_ERROR (Status
)) {
164 Status
= PciIo
->Pci
.Read (
168 sizeof (PCI_CONFIG_HEADER
),
172 if (!EFI_ERROR (Status
)) {
173 Status
= EFI_UNSUPPORTED
;
175 if (Pci
.Hdr
.ClassCode
[2] == 0x02 && Pci
.Hdr
.VendorId
== PCI_VENDOR_ID_INTEL
) {
176 switch (Pci
.Hdr
.DeviceId
) {
179 case ICH3_DEVICE_ID_1
:
180 case ICH3_DEVICE_ID_2
:
181 case ICH3_DEVICE_ID_3
:
182 case ICH3_DEVICE_ID_4
:
183 case ICH3_DEVICE_ID_5
:
184 case ICH3_DEVICE_ID_6
:
185 case ICH3_DEVICE_ID_7
:
186 case ICH3_DEVICE_ID_8
:
203 Status
= EFI_SUCCESS
;
210 &gEfiPciIoProtocolGuid
,
211 This
->DriverBindingHandle
,
220 Start this driver on Controller by opening PciIo and DevicePath protocol.
221 Initialize PXE structures, create a copy of the Controller Device Path with the
222 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
223 on the newly created Device Path.
225 @param This Protocol instance pointer.
226 @param Controller Handle of device to work with.
227 @param RemainingDevicePath Not used, always produce all possible children.
229 @retval EFI_SUCCESS This driver is added to Controller.
230 @retval other This driver does not support this device.
236 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
237 IN EFI_HANDLE Controller
,
238 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
242 EFI_DEVICE_PATH_PROTOCOL
*UndiDevicePath
;
243 PCI_CONFIG_HEADER
*CfgHdr
;
244 UNDI32_DEV
*UNDI32Device
;
246 UINT8
*TmpPxePointer
;
247 EFI_PCI_IO_PROTOCOL
*PciIoFncs
;
250 BOOLEAN PciAttributesSaved
;
252 Status
= gBS
->OpenProtocol (
254 &gEfiPciIoProtocolGuid
,
255 (VOID
**) &PciIoFncs
,
256 This
->DriverBindingHandle
,
258 EFI_OPEN_PROTOCOL_BY_DRIVER
261 if (EFI_ERROR (Status
)) {
265 Status
= gBS
->OpenProtocol (
267 &gEfiDevicePathProtocolGuid
,
268 (VOID
**) &UndiDevicePath
,
269 This
->DriverBindingHandle
,
271 EFI_OPEN_PROTOCOL_BY_DRIVER
274 if (EFI_ERROR (Status
)) {
277 &gEfiPciIoProtocolGuid
,
278 This
->DriverBindingHandle
,
285 PciAttributesSaved
= FALSE
;
287 Status
= gBS
->AllocatePool (
288 EfiRuntimeServicesData
,
290 (VOID
**) &UNDI32Device
293 if (EFI_ERROR (Status
)) {
297 ZeroMem ((CHAR8
*) UNDI32Device
, sizeof (UNDI32_DEV
));
300 // Get original PCI attributes
302 Status
= PciIoFncs
->Attributes (
304 EfiPciIoAttributeOperationGet
,
306 &UNDI32Device
->NicInfo
.OriginalPciAttributes
309 if (EFI_ERROR (Status
)) {
310 goto UndiErrorDeleteDevice
;
312 PciAttributesSaved
= TRUE
;
315 // allocate and initialize both (old and new) the !pxe structures here,
316 // there should only be one copy of each of these structure for any number
317 // of NICs this undi supports. Also, these structures need to be on a
318 // paragraph boundary as per the spec. so, while allocating space for these,
319 // make sure that there is space for 2 !pxe structures (old and new) and a
320 // 32 bytes padding for alignment adjustment (in case)
322 TmpPxePointer
= NULL
;
323 if (pxe_31
== NULL
) {
324 Status
= gBS
->AllocatePool (
325 EfiRuntimeServicesData
,
326 (sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32),
327 (VOID
**) &TmpPxePointer
330 if (EFI_ERROR (Status
)) {
331 goto UndiErrorDeleteDevice
;
336 sizeof (PXE_SW_UNDI
) + sizeof (PXE_SW_UNDI
) + 32
339 // check for paragraph alignment here, assuming that the pointer is
340 // already 8 byte aligned.
342 if (((UINTN
) TmpPxePointer
& 0x0F) != 0) {
343 pxe_31
= (PXE_SW_UNDI
*) ((UINTN
) (TmpPxePointer
+ 8));
345 pxe_31
= (PXE_SW_UNDI
*) TmpPxePointer
;
348 PxeStructInit (pxe_31
);
351 UNDI32Device
->NIIProtocol_31
.ID
= (UINT64
) (UINTN
) (pxe_31
);
353 Status
= PciIoFncs
->Attributes (
355 EfiPciIoAttributeOperationSupported
,
359 if (!EFI_ERROR (Status
)) {
360 Supports
&= EFI_PCI_DEVICE_ENABLE
;
361 Status
= PciIoFncs
->Attributes (
363 EfiPciIoAttributeOperationEnable
,
369 // Read all the registers from device's PCI Configuration space
371 Status
= PciIoFncs
->Pci
.Read (
376 &UNDI32Device
->NicInfo
.Config
379 CfgHdr
= (PCI_CONFIG_HEADER
*) &(UNDI32Device
->NicInfo
.Config
[0]);
382 // make sure that this device is a PCI bus master
385 NewCommand
= (UINT16
) (CfgHdr
->Command
| PCI_COMMAND_MASTER
| PCI_COMMAND_IO
);
386 if (CfgHdr
->Command
!= NewCommand
) {
387 PciIoFncs
->Pci
.Write (
394 CfgHdr
->Command
= NewCommand
;
398 // make sure that the latency timer is at least 32
400 if (CfgHdr
->LatencyTimer
< 32) {
401 CfgHdr
->LatencyTimer
= 32;
402 PciIoFncs
->Pci
.Write (
407 &CfgHdr
->LatencyTimer
411 // the IfNum index for the current interface will be the total number
412 // of interfaces initialized so far
414 UNDI32Device
->NIIProtocol_31
.IfNum
= pxe_31
->IFcnt
;
416 PxeUpdate (&UNDI32Device
->NicInfo
, pxe_31
);
418 UNDI32Device
->NicInfo
.Io_Function
= PciIoFncs
;
419 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = UNDI32Device
;
420 UNDI32Device
->Undi32BaseDevPath
= UndiDevicePath
;
422 Status
= AppendMac2DevPath (
423 &UNDI32Device
->Undi32DevPath
,
424 UNDI32Device
->Undi32BaseDevPath
,
425 &UNDI32Device
->NicInfo
429 goto UndiErrorDeletePxe
;
432 UNDI32Device
->Signature
= UNDI_DEV_SIGNATURE
;
434 UNDI32Device
->NIIProtocol_31
.Revision
= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION_31
;
435 UNDI32Device
->NIIProtocol_31
.Type
= EfiNetworkInterfaceUndi
;
436 UNDI32Device
->NIIProtocol_31
.MajorVer
= PXE_ROMID_MAJORVER
;
437 UNDI32Device
->NIIProtocol_31
.MinorVer
= PXE_ROMID_MINORVER_31
;
438 UNDI32Device
->NIIProtocol_31
.ImageSize
= 0;
439 UNDI32Device
->NIIProtocol_31
.ImageAddr
= 0;
440 UNDI32Device
->NIIProtocol_31
.Ipv6Supported
= FALSE
;
442 UNDI32Device
->NIIProtocol_31
.StringId
[0] = 'U';
443 UNDI32Device
->NIIProtocol_31
.StringId
[1] = 'N';
444 UNDI32Device
->NIIProtocol_31
.StringId
[2] = 'D';
445 UNDI32Device
->NIIProtocol_31
.StringId
[3] = 'I';
447 UNDI32Device
->DeviceHandle
= NULL
;
450 // install both the 3.0 and 3.1 NII protocols.
452 Status
= gBS
->InstallMultipleProtocolInterfaces (
453 &UNDI32Device
->DeviceHandle
,
454 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
455 &UNDI32Device
->NIIProtocol_31
,
456 &gEfiDevicePathProtocolGuid
,
457 UNDI32Device
->Undi32DevPath
,
461 if (EFI_ERROR (Status
)) {
462 goto UndiErrorDeleteDevicePath
;
466 // if the table exists, free it and alloc again, or alloc it directly
468 if (UndiDataPointer
!= NULL
) {
469 Status
= gBS
->FreePool(UndiDataPointer
);
471 if (EFI_ERROR (Status
)) {
472 goto UndiErrorDeleteDevicePath
;
475 Len
= (pxe_31
->IFcnt
* sizeof (NII_ENTRY
)) + sizeof (UndiDataPointer
);
476 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UndiDataPointer
);
478 if (EFI_ERROR (Status
)) {
479 goto UndiErrorAllocDataPointer
;
483 // Open For Child Device
485 Status
= gBS
->OpenProtocol (
487 &gEfiPciIoProtocolGuid
,
488 (VOID
**) &PciIoFncs
,
489 This
->DriverBindingHandle
,
490 UNDI32Device
->DeviceHandle
,
491 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
495 UndiErrorAllocDataPointer
:
496 gBS
->UninstallMultipleProtocolInterfaces (
497 &UNDI32Device
->DeviceHandle
,
498 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
499 &UNDI32Device
->NIIProtocol_31
,
500 &gEfiDevicePathProtocolGuid
,
501 UNDI32Device
->Undi32DevPath
,
505 UndiErrorDeleteDevicePath
:
506 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = NULL
;
507 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
510 PxeUpdate (NULL
, pxe_31
);
511 if (TmpPxePointer
!= NULL
) {
512 gBS
->FreePool (TmpPxePointer
);
516 UndiErrorDeleteDevice
:
517 if (PciAttributesSaved
) {
519 // Restore original PCI attributes
521 PciIoFncs
->Attributes (
523 EfiPciIoAttributeOperationSet
,
524 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
529 gBS
->FreePool (UNDI32Device
);
534 &gEfiDevicePathProtocolGuid
,
535 This
->DriverBindingHandle
,
541 &gEfiPciIoProtocolGuid
,
542 This
->DriverBindingHandle
,
551 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
552 closing the DevicePath and PciIo protocols on Controller.
554 @param This Protocol instance pointer.
555 @param Controller Handle of device to stop driver on.
556 @param NumberOfChildren How many children need to be stopped.
557 @param ChildHandleBuffer Not used.
559 @retval EFI_SUCCESS This driver is removed Controller.
560 @retval other This driver was not removed from this device.
563 // TODO: EFI_DEVICE_ERROR - add return value to function comment
567 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
568 IN EFI_HANDLE Controller
,
569 IN UINTN NumberOfChildren
,
570 IN EFI_HANDLE
*ChildHandleBuffer
574 BOOLEAN AllChildrenStopped
;
576 UNDI32_DEV
*UNDI32Device
;
577 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
578 EFI_PCI_IO_PROTOCOL
*PciIo
;
581 // Complete all outstanding transactions to Controller.
582 // Don't allow any new transaction to Controller to be started.
584 if (NumberOfChildren
== 0) {
587 // Close the bus driver
589 Status
= gBS
->CloseProtocol (
591 &gEfiDevicePathProtocolGuid
,
592 This
->DriverBindingHandle
,
596 Status
= gBS
->CloseProtocol (
598 &gEfiPciIoProtocolGuid
,
599 This
->DriverBindingHandle
,
606 AllChildrenStopped
= TRUE
;
608 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
610 Status
= gBS
->OpenProtocol (
611 ChildHandleBuffer
[Index
],
612 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
613 (VOID
**) &NIIProtocol
,
614 This
->DriverBindingHandle
,
616 EFI_OPEN_PROTOCOL_GET_PROTOCOL
618 if (!EFI_ERROR (Status
)) {
620 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
623 // Restore original PCI attributes
625 Status
= UNDI32Device
->NicInfo
.Io_Function
->Attributes (
626 UNDI32Device
->NicInfo
.Io_Function
,
627 EfiPciIoAttributeOperationSet
,
628 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
631 ASSERT_EFI_ERROR (Status
);
633 Status
= gBS
->CloseProtocol (
635 &gEfiPciIoProtocolGuid
,
636 This
->DriverBindingHandle
,
637 ChildHandleBuffer
[Index
]
640 Status
= gBS
->UninstallMultipleProtocolInterfaces (
641 ChildHandleBuffer
[Index
],
642 &gEfiDevicePathProtocolGuid
,
643 UNDI32Device
->Undi32DevPath
,
644 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
645 &UNDI32Device
->NIIProtocol_31
,
649 if (EFI_ERROR (Status
)) {
652 &gEfiPciIoProtocolGuid
,
654 This
->DriverBindingHandle
,
655 ChildHandleBuffer
[Index
],
656 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
659 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
660 gBS
->FreePool (UNDI32Device
);
664 if (EFI_ERROR (Status
)) {
665 AllChildrenStopped
= FALSE
;
669 if (!AllChildrenStopped
) {
670 return EFI_DEVICE_ERROR
;
679 Use the EFI boot services to produce a pause. This is also the routine which
680 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
683 @param UnqId Runtime O/S routine might use this, this temp
684 routine does not use it
685 @param MicroSeconds Determines the length of pause.
693 IN UINTN MicroSeconds
696 gBS
->Stall ((UINT32
) MicroSeconds
);
701 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
702 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
704 @param UnqId Runtime O/S routine may use this field, this temp
706 @param ReadWrite Determine if it is an I/O or Memory Read/Write
708 @param Len Determines the width of the data operation.
709 @param Port What port to Read/Write from.
710 @param BuffAddr Address to read to or write from.
724 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
725 NIC_DATA_INSTANCE
*AdapterInfo
;
727 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
728 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
731 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
735 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
739 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
745 AdapterInfo
->Io_Function
->Io
.Read (
746 AdapterInfo
->Io_Function
,
751 (VOID
*) (UINTN
) (BuffAddr
)
756 AdapterInfo
->Io_Function
->Io
.Write (
757 AdapterInfo
->Io_Function
,
762 (VOID
*) (UINTN
) (BuffAddr
)
767 AdapterInfo
->Io_Function
->Mem
.Read (
768 AdapterInfo
->Io_Function
,
773 (VOID
*) (UINTN
) (BuffAddr
)
778 AdapterInfo
->Io_Function
->Mem
.Write (
779 AdapterInfo
->Io_Function
,
784 (VOID
*) (UINTN
) (BuffAddr
)
794 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
795 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
796 and an added MAC node.
798 @param DevPtr Pointer which will point to the newly created device
799 path with the MAC node attached.
800 @param BaseDevPtr Pointer to the device path which the UNDI device
801 driver is latching on to.
802 @param AdapterInfo Pointer to the NIC data structure information which
803 the UNDI driver is layering on..
805 @retval EFI_SUCCESS A MAC address was successfully appended to the Base
807 @retval other Not enough resources available to create new Device
813 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
814 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
815 IN NIC_DATA_INSTANCE
*AdapterInfo
818 EFI_MAC_ADDRESS MACAddress
;
819 PCI_CONFIG_HEADER
*CfgHdr
;
824 MAC_ADDR_DEVICE_PATH MacAddrNode
;
825 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
832 // set the environment ready (similar to UNDI_Start call) so that we can
833 // execute the other UNDI_ calls to get the mac address
834 // we are using undi 3.1 style
836 AdapterInfo
->Delay
= TmpDelay
;
837 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
838 AdapterInfo
->Block
= (VOID
*) 0;
839 AdapterInfo
->Map_Mem
= (VOID
*) 0;
840 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
841 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
842 AdapterInfo
->Mem_Io
= TmpMemIo
;
844 // these tmp call-backs follow 3.1 undi style
845 // i.e. they have the unique_id parameter.
847 AdapterInfo
->VersionFlag
= 0x31;
848 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
853 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
854 AdapterInfo
->ioaddr
= 0;
855 AdapterInfo
->RevID
= CfgHdr
->RevID
;
857 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
859 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
860 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
861 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
862 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
865 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
866 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
867 // MACAddress.Addr[Index2] = 0;
872 AdapterInfo
->Delay
= (VOID
*) 0;
873 AdapterInfo
->Mem_Io
= (VOID
*) 0;
876 // fill the mac address node first
878 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
880 (CHAR8
*) &MacAddrNode
.MacAddress
,
881 (CHAR8
*) &MACAddress
,
882 sizeof (EFI_MAC_ADDRESS
)
885 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
886 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
887 MacAddrNode
.Header
.Length
[0] = sizeof (MacAddrNode
);
888 MacAddrNode
.Header
.Length
[1] = 0;
891 // find the size of the base dev path.
893 EndNode
= BaseDevPtr
;
895 while (!IsDevicePathEnd (EndNode
)) {
896 EndNode
= NextDevicePathNode (EndNode
);
899 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
902 // create space for full dev path
904 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
906 Status
= gBS
->AllocatePool (
907 EfiRuntimeServicesData
,
912 if (Status
!= EFI_SUCCESS
) {
916 // copy the base path, mac addr and end_dev_path nodes
918 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
919 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
920 DevicePtr
+= BasePathLen
;
921 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
922 DevicePtr
+= sizeof (MacAddrNode
);
923 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
930 Install a GUID/Pointer pair into the system's configuration table.
934 @retval EFI_SUCCESS Install a GUID/Pointer pair into the system's
936 @retval other Did not successfully install the GUID/Pointer pair
937 into the configuration table.
940 // TODO: VOID - add argument and description to function comment
947 EFI_CONFIGURATION_TABLE
*CfgPtr
;
952 if (pxe_31
== NULL
) {
956 if(UndiDataPointer
== NULL
) {
960 UndiData
= (NII_TABLE
*)UndiDataPointer
;
962 UndiData
->NumEntries
= pxe_31
->IFcnt
;
963 UndiData
->NextLink
= NULL
;
965 for (Index
= 0; Index
< pxe_31
->IFcnt
; Index
++) {
966 UndiData
->NiiEntry
[Index
].InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
967 UndiData
->NiiEntry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
971 // see if there is an entry in the config table already
973 CfgPtr
= gST
->ConfigurationTable
;
975 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
976 Status
= CompareGuid (
978 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
980 if (Status
!= EFI_SUCCESS
) {
987 if (Index
< gST
->NumberOfTableEntries
) {
988 TmpData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
991 // go to the last link
993 while (TmpData
->NextLink
!= NULL
) {
994 TmpData
= TmpData
->NextLink
;
997 TmpData
->NextLink
= UndiData
;
1002 UndiData
= (NII_TABLE
*) CfgPtr
->VendorTable
;
1006 // create an entry in the configuration table for our GUID
1008 Status
= gBS
->InstallConfigurationTable (
1009 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1021 IN EFI_HANDLE ImageHandle
,
1022 IN EFI_SYSTEM_TABLE
*SystemTable
1028 Status
= EfiLibInstallDriverBinding (
1031 &gUndiDriverBinding
,
1034 ASSERT_EFI_ERROR (Status
);
1036 Status
= gBS
->CreateEvent (
1037 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
1043 ASSERT_EFI_ERROR (Status
);
1045 Status
= gBS
->CreateEvent (
1046 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
1052 ASSERT_EFI_ERROR (Status
);