2 Initialization functions for EFI UNDI32 driver.
4 Copyright (c) 2006 - 2015, 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 UNDI_CONFIG_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
| pxe_31
->IFcntExt
<< 8); 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)
102 UndiNotifyReadyToBoot (
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
| pxe_31
->IFcntExt
<< 8;
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
= TRUE
;
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
;
447 UNDI32Device
->Aip
.GetInformation
= UndiAipGetInfo
;
448 UNDI32Device
->Aip
.SetInformation
= UndiAipSetInfo
;
449 UNDI32Device
->Aip
.GetSupportedTypes
= UndiAipGetSupportedTypes
;
452 // install both the 3.0 and 3.1 NII protocols.
454 Status
= gBS
->InstallMultipleProtocolInterfaces (
455 &UNDI32Device
->DeviceHandle
,
456 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
457 &UNDI32Device
->NIIProtocol_31
,
458 &gEfiDevicePathProtocolGuid
,
459 UNDI32Device
->Undi32DevPath
,
460 &gEfiAdapterInformationProtocolGuid
,
465 if (EFI_ERROR (Status
)) {
466 goto UndiErrorDeleteDevicePath
;
470 // if the table exists, free it and alloc again, or alloc it directly
472 if (UndiDataPointer
!= NULL
) {
473 Status
= gBS
->FreePool(UndiDataPointer
);
475 if (EFI_ERROR (Status
)) {
476 goto UndiErrorDeleteDevicePath
;
479 Len
= ((pxe_31
->IFcnt
|pxe_31
->IFcntExt
<< 8)* sizeof (UndiDataPointer
->NII_entry
)) + sizeof (UndiDataPointer
);
480 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
, Len
, (VOID
**) &UndiDataPointer
);
482 if (EFI_ERROR (Status
)) {
483 goto UndiErrorAllocDataPointer
;
487 // Open For Child Device
489 Status
= gBS
->OpenProtocol (
491 &gEfiPciIoProtocolGuid
,
492 (VOID
**) &PciIoFncs
,
493 This
->DriverBindingHandle
,
494 UNDI32Device
->DeviceHandle
,
495 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
499 UndiErrorAllocDataPointer
:
500 gBS
->UninstallMultipleProtocolInterfaces (
501 &UNDI32Device
->DeviceHandle
,
502 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
503 &UNDI32Device
->NIIProtocol_31
,
504 &gEfiDevicePathProtocolGuid
,
505 UNDI32Device
->Undi32DevPath
,
506 &gEfiAdapterInformationProtocolGuid
,
511 UndiErrorDeleteDevicePath
:
512 UNDI32DeviceList
[UNDI32Device
->NIIProtocol_31
.IfNum
] = NULL
;
513 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
516 PxeUpdate (NULL
, pxe_31
);
517 if (TmpPxePointer
!= NULL
) {
518 gBS
->FreePool (TmpPxePointer
);
522 UndiErrorDeleteDevice
:
523 if (PciAttributesSaved
) {
525 // Restore original PCI attributes
527 PciIoFncs
->Attributes (
529 EfiPciIoAttributeOperationSet
,
530 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
535 gBS
->FreePool (UNDI32Device
);
540 &gEfiDevicePathProtocolGuid
,
541 This
->DriverBindingHandle
,
547 &gEfiPciIoProtocolGuid
,
548 This
->DriverBindingHandle
,
557 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
558 closing the DevicePath and PciIo protocols on Controller.
560 @param This Protocol instance pointer.
561 @param Controller Handle of device to stop driver on.
562 @param NumberOfChildren How many children need to be stopped.
563 @param ChildHandleBuffer Not used.
565 @retval EFI_SUCCESS This driver is removed Controller.
566 @retval other This driver was not removed from this device.
569 // TODO: EFI_DEVICE_ERROR - add return value to function comment
573 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
574 IN EFI_HANDLE Controller
,
575 IN UINTN NumberOfChildren
,
576 IN EFI_HANDLE
*ChildHandleBuffer
580 BOOLEAN AllChildrenStopped
;
582 UNDI32_DEV
*UNDI32Device
;
583 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NIIProtocol
;
586 // Complete all outstanding transactions to Controller.
587 // Don't allow any new transaction to Controller to be started.
589 if (NumberOfChildren
== 0) {
592 // Close the bus driver
594 Status
= gBS
->CloseProtocol (
596 &gEfiDevicePathProtocolGuid
,
597 This
->DriverBindingHandle
,
601 Status
= gBS
->CloseProtocol (
603 &gEfiPciIoProtocolGuid
,
604 This
->DriverBindingHandle
,
611 AllChildrenStopped
= TRUE
;
613 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
615 Status
= gBS
->OpenProtocol (
616 ChildHandleBuffer
[Index
],
617 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
618 (VOID
**) &NIIProtocol
,
619 This
->DriverBindingHandle
,
621 EFI_OPEN_PROTOCOL_GET_PROTOCOL
623 if (!EFI_ERROR (Status
)) {
625 UNDI32Device
= UNDI_DEV_FROM_THIS (NIIProtocol
);
627 Status
= gBS
->CloseProtocol (
629 &gEfiPciIoProtocolGuid
,
630 This
->DriverBindingHandle
,
631 ChildHandleBuffer
[Index
]
633 if (!EFI_ERROR (Status
)) {
634 Status
= gBS
->UninstallMultipleProtocolInterfaces (
635 ChildHandleBuffer
[Index
],
636 &gEfiDevicePathProtocolGuid
,
637 UNDI32Device
->Undi32DevPath
,
638 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
639 &UNDI32Device
->NIIProtocol_31
,
642 if (!EFI_ERROR (Status
)) {
644 // Restore original PCI attributes
646 Status
= UNDI32Device
->NicInfo
.Io_Function
->Attributes (
647 UNDI32Device
->NicInfo
.Io_Function
,
648 EfiPciIoAttributeOperationSet
,
649 UNDI32Device
->NicInfo
.OriginalPciAttributes
,
653 ASSERT_EFI_ERROR (Status
);
655 gBS
->FreePool (UNDI32Device
->Undi32DevPath
);
656 gBS
->FreePool (UNDI32Device
);
662 if (EFI_ERROR (Status
)) {
663 AllChildrenStopped
= FALSE
;
667 if (!AllChildrenStopped
) {
668 return EFI_DEVICE_ERROR
;
677 Use the EFI boot services to produce a pause. This is also the routine which
678 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can
681 @param UnqId Runtime O/S routine might use this, this temp
682 routine does not use it
683 @param MicroSeconds Determines the length of pause.
691 IN UINTN MicroSeconds
694 gBS
->Stall ((UINT32
) MicroSeconds
);
699 Use the PCI IO abstraction to issue memory or I/O reads and writes. This is also the routine which
700 gets replaced during RunTime by the O/S in the NIC_DATA_INSTANCE so it can do it's own I/O abstractions.
702 @param UnqId Runtime O/S routine may use this field, this temp
704 @param ReadWrite Determine if it is an I/O or Memory Read/Write
706 @param Len Determines the width of the data operation.
707 @param Port What port to Read/Write from.
708 @param BuffAddr Address to read to or write from.
722 EFI_PCI_IO_PROTOCOL_WIDTH Width
;
723 NIC_DATA_INSTANCE
*AdapterInfo
;
725 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 0;
726 AdapterInfo
= (NIC_DATA_INSTANCE
*) (UINTN
) UnqId
;
729 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 1;
733 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 2;
737 Width
= (EFI_PCI_IO_PROTOCOL_WIDTH
) 3;
743 AdapterInfo
->Io_Function
->Io
.Read (
744 AdapterInfo
->Io_Function
,
749 (VOID
*) (UINTN
) (BuffAddr
)
754 AdapterInfo
->Io_Function
->Io
.Write (
755 AdapterInfo
->Io_Function
,
760 (VOID
*) (UINTN
) (BuffAddr
)
765 AdapterInfo
->Io_Function
->Mem
.Read (
766 AdapterInfo
->Io_Function
,
771 (VOID
*) (UINTN
) (BuffAddr
)
776 AdapterInfo
->Io_Function
->Mem
.Write (
777 AdapterInfo
->Io_Function
,
782 (VOID
*) (UINTN
) (BuffAddr
)
792 Using the NIC data structure information, read the EEPROM to get the MAC address and then allocate space
793 for a new devicepath (**DevPtr) which will contain the original device path the NIC was found on (*BaseDevPtr)
794 and an added MAC node.
796 @param DevPtr Pointer which will point to the newly created device
797 path with the MAC node attached.
798 @param BaseDevPtr Pointer to the device path which the UNDI device
799 driver is latching on to.
800 @param AdapterInfo Pointer to the NIC data structure information which
801 the UNDI driver is layering on..
803 @retval EFI_SUCCESS A MAC address was successfully appended to the Base
805 @retval other Not enough resources available to create new Device
811 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DevPtr
,
812 IN EFI_DEVICE_PATH_PROTOCOL
*BaseDevPtr
,
813 IN NIC_DATA_INSTANCE
*AdapterInfo
816 EFI_MAC_ADDRESS MACAddress
;
817 PCI_CONFIG_HEADER
*CfgHdr
;
822 MAC_ADDR_DEVICE_PATH MacAddrNode
;
823 EFI_DEVICE_PATH_PROTOCOL
*EndNode
;
830 // set the environment ready (similar to UNDI_Start call) so that we can
831 // execute the other UNDI_ calls to get the mac address
832 // we are using undi 3.1 style
834 AdapterInfo
->Delay
= TmpDelay
;
835 AdapterInfo
->Virt2Phys
= (VOID
*) 0;
836 AdapterInfo
->Block
= (VOID
*) 0;
837 AdapterInfo
->Map_Mem
= (VOID
*) 0;
838 AdapterInfo
->UnMap_Mem
= (VOID
*) 0;
839 AdapterInfo
->Sync_Mem
= (VOID
*) 0;
840 AdapterInfo
->Mem_Io
= TmpMemIo
;
842 // these tmp call-backs follow 3.1 undi style
843 // i.e. they have the unique_id parameter.
845 AdapterInfo
->VersionFlag
= 0x31;
846 AdapterInfo
->Unique_ID
= (UINT64
) (UINTN
) AdapterInfo
;
851 CfgHdr
= (PCI_CONFIG_HEADER
*) &(AdapterInfo
->Config
[0]);
852 AdapterInfo
->ioaddr
= 0;
853 AdapterInfo
->RevID
= CfgHdr
->RevID
;
855 AddrLen
= E100bGetEepromAddrLen (AdapterInfo
);
857 for (Index
= 0, Index2
= 0; Index
< 3; Index
++) {
858 Val
= E100bReadEeprom (AdapterInfo
, Index
, AddrLen
);
859 MACAddress
.Addr
[Index2
++] = (UINT8
) Val
;
860 MACAddress
.Addr
[Index2
++] = (UINT8
) (Val
>> 8);
863 SetMem (MACAddress
.Addr
+ Index2
, sizeof (EFI_MAC_ADDRESS
) - Index2
, 0);
864 //for (; Index2 < sizeof (EFI_MAC_ADDRESS); Index2++) {
865 // MACAddress.Addr[Index2] = 0;
870 AdapterInfo
->Delay
= (VOID
*) 0;
871 AdapterInfo
->Mem_Io
= (VOID
*) 0;
874 // fill the mac address node first
876 ZeroMem ((CHAR8
*) &MacAddrNode
, sizeof MacAddrNode
);
878 (CHAR8
*) &MacAddrNode
.MacAddress
,
879 (CHAR8
*) &MACAddress
,
880 sizeof (EFI_MAC_ADDRESS
)
883 MacAddrNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
884 MacAddrNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
885 MacAddrNode
.Header
.Length
[0] = (UINT8
) sizeof (MacAddrNode
);
886 MacAddrNode
.Header
.Length
[1] = 0;
889 // find the size of the base dev path.
891 EndNode
= BaseDevPtr
;
893 while (!IsDevicePathEnd (EndNode
)) {
894 EndNode
= NextDevicePathNode (EndNode
);
897 BasePathLen
= (UINT16
) ((UINTN
) (EndNode
) - (UINTN
) (BaseDevPtr
));
900 // create space for full dev path
902 TotalPathLen
= (UINT16
) (BasePathLen
+ sizeof (MacAddrNode
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
));
904 Status
= gBS
->AllocatePool (
905 EfiRuntimeServicesData
,
910 if (Status
!= EFI_SUCCESS
) {
914 // copy the base path, mac addr and end_dev_path nodes
916 *DevPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) DevicePtr
;
917 CopyMem (DevicePtr
, (CHAR8
*) BaseDevPtr
, BasePathLen
);
918 DevicePtr
+= BasePathLen
;
919 CopyMem (DevicePtr
, (CHAR8
*) &MacAddrNode
, sizeof (MacAddrNode
));
920 DevicePtr
+= sizeof (MacAddrNode
);
921 CopyMem (DevicePtr
, (CHAR8
*) EndNode
, sizeof (EFI_DEVICE_PATH_PROTOCOL
));
928 Install a GUID/Pointer pair into the system's configuration table.
932 @retval EFI_SUCCESS Install a GUID/Pointer pair into the system's
934 @retval other Did not successfully install the GUID/Pointer pair
935 into the configuration table.
938 // TODO: VOID - add argument and description to function comment
945 EFI_CONFIGURATION_TABLE
*CfgPtr
;
946 UNDI_CONFIG_TABLE
*TmpData
;
948 UNDI_CONFIG_TABLE
*UndiData
;
950 if (pxe_31
== NULL
) {
954 if(UndiDataPointer
== NULL
) {
958 UndiData
= (UNDI_CONFIG_TABLE
*)UndiDataPointer
;
960 UndiData
->NumberOfInterfaces
= (pxe_31
->IFcnt
| pxe_31
->IFcntExt
<< 8);
961 UndiData
->nextlink
= NULL
;
963 for (Index
= 0; Index
< (pxe_31
->IFcnt
| pxe_31
->IFcntExt
<< 8); Index
++) {
964 UndiData
->NII_entry
[Index
].NII_InterfacePointer
= &UNDI32DeviceList
[Index
]->NIIProtocol_31
;
965 UndiData
->NII_entry
[Index
].DevicePathPointer
= UNDI32DeviceList
[Index
]->Undi32DevPath
;
969 // see if there is an entry in the config table already
971 CfgPtr
= gST
->ConfigurationTable
;
973 for (Index
= 0; Index
< gST
->NumberOfTableEntries
; Index
++) {
974 Status
= CompareGuid (
976 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
978 if (Status
!= EFI_SUCCESS
) {
985 if (Index
< gST
->NumberOfTableEntries
) {
986 TmpData
= (UNDI_CONFIG_TABLE
*) CfgPtr
->VendorTable
;
989 // go to the last link
991 while (TmpData
->nextlink
!= NULL
) {
992 TmpData
= TmpData
->nextlink
;
995 TmpData
->nextlink
= UndiData
;
1000 UndiData
= (UNDI_CONFIG_TABLE
*) CfgPtr
->VendorTable
;
1004 // create an entry in the configuration table for our GUID
1006 Status
= gBS
->InstallConfigurationTable (
1007 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1019 IN EFI_HANDLE ImageHandle
,
1020 IN EFI_SYSTEM_TABLE
*SystemTable
1026 Status
= EfiLibInstallDriverBindingComponentName2 (
1029 &gUndiDriverBinding
,
1031 &gUndiComponentName
,
1032 &gUndiComponentName2
1034 ASSERT_EFI_ERROR (Status
);
1036 Status
= gBS
->CreateEventEx (
1039 UndiNotifyReadyToBoot
,
1041 &gEfiEventReadyToBootGuid
,
1044 ASSERT_EFI_ERROR (Status
);
1046 Status
= gBS
->CreateEventEx (
1051 &gEfiEventVirtualAddressChangeGuid
,
1054 ASSERT_EFI_ERROR (Status
);