4 Copyright (c) 2005 - 2009, Intel Corporation.<BR>
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.
16 #include <Protocol/DriverBinding.h>
17 #include <Protocol/ServiceBinding.h>
18 #include <Protocol/SimpleNetwork.h>
19 #include <Protocol/HiiConfigRouting.h>
20 #include <Protocol/ComponentName.h>
21 #include <Protocol/ComponentName2.h>
22 #include <Protocol/Dpc.h>
24 #include <Guid/NicIp4ConfigNvData.h>
26 #include <Library/NetLib.h>
27 #include <Library/BaseLib.h>
28 #include <Library/DebugLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/UefiRuntimeServicesTableLib.h>
32 #include <Library/MemoryAllocationLib.h>
33 #include <Library/DevicePathLib.h>
34 #include <Library/HiiLib.h>
35 #include <Library/PrintLib.h>
37 EFI_DPC_PROTOCOL
*mDpc
= NULL
;
39 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mNetLibHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
41 #define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE
44 // All the supported IP4 maskes in host byte order.
46 IP4_ADDR gIp4AllMasks
[IP4_MASK_NUM
] = {
85 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
88 Return the length of the mask.
90 Return the length of the mask, the correct value is from 0 to 32.
91 If the mask is invalid, return the invalid length 33, which is IP4_MASK_NUM.
92 NetMask is in the host byte order.
94 @param[in] NetMask The netmask to get the length from.
96 @return The length of the netmask, IP4_MASK_NUM if the mask is invalid.
107 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
108 if (NetMask
== gIp4AllMasks
[Index
]) {
119 Return the class of the IP address, such as class A, B, C.
120 Addr is in host byte order.
122 The address of class A starts with 0.
123 If the address belong to class A, return IP4_ADDR_CLASSA.
124 The address of class B starts with 10.
125 If the address belong to class B, return IP4_ADDR_CLASSB.
126 The address of class C starts with 110.
127 If the address belong to class C, return IP4_ADDR_CLASSC.
128 The address of class D starts with 1110.
129 If the address belong to class D, return IP4_ADDR_CLASSD.
130 The address of class E starts with 1111.
131 If the address belong to class E, return IP4_ADDR_CLASSE.
134 @param[in] Addr The address to get the class from.
136 @return IP address class, such as IP4_ADDR_CLASSA.
147 ByteOne
= (UINT8
) (Addr
>> 24);
149 if ((ByteOne
& 0x80) == 0) {
150 return IP4_ADDR_CLASSA
;
152 } else if ((ByteOne
& 0xC0) == 0x80) {
153 return IP4_ADDR_CLASSB
;
155 } else if ((ByteOne
& 0xE0) == 0xC0) {
156 return IP4_ADDR_CLASSC
;
158 } else if ((ByteOne
& 0xF0) == 0xE0) {
159 return IP4_ADDR_CLASSD
;
162 return IP4_ADDR_CLASSE
;
169 Check whether the IP is a valid unicast address according to
170 the netmask. If NetMask is zero, use the IP address's class to get the default mask.
172 If Ip is 0, IP is not a valid unicast address.
173 Class D address is used for multicasting and class E address is reserved for future. If Ip
174 belongs to class D or class E, IP is not a valid unicast address.
175 If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address.
177 @param[in] Ip The IP to check against.
178 @param[in] NetMask The mask of the IP.
180 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE.
192 Class
= NetGetIpClass (Ip
);
194 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
199 NetMask
= gIp4AllMasks
[Class
<< 3];
202 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
211 Initialize a random seed using current time.
213 Get current time first. Then initialize a random seed based on some basic
214 mathematics operation on the hour, day, minute, second, nanosecond and year
217 @return The random seed initialized with current time.
229 gRT
->GetTime (&Time
, NULL
);
230 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
231 Seed
^= Time
.Nanosecond
;
232 Seed
^= Time
.Year
<< 7;
239 Extract a UINT32 from a byte stream.
241 Copy a UINT32 from a byte stream, then converts it from Network
242 byte order to host byte order. Use this function to avoid alignment error.
244 @param[in] Buf The buffer to extract the UINT32.
246 @return The UINT32 extracted.
257 CopyMem (&Value
, Buf
, sizeof (UINT32
));
258 return NTOHL (Value
);
263 Put a UINT32 to the byte stream in network byte order.
265 Converts a UINT32 from host byte order to network byte order. Then copy it to the
268 @param[in, out] Buf The buffer to put the UINT32.
269 @param[in] Data The data to put.
280 CopyMem (Buf
, &Data
, sizeof (UINT32
));
285 Remove the first node entry on the list, and return the removed node entry.
287 Removes the first node Entry from a doubly linked list. It is up to the caller of
288 this function to release the memory used by the first node if that is required. On
289 exit, the removed node is returned.
291 If Head is NULL, then ASSERT().
292 If Head was not initialized, then ASSERT().
293 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
294 linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
297 @param[in, out] Head The list header.
299 @return The first node entry that is removed from the list, NULL if the list is empty.
305 IN OUT LIST_ENTRY
*Head
310 ASSERT (Head
!= NULL
);
312 if (IsListEmpty (Head
)) {
316 First
= Head
->ForwardLink
;
317 Head
->ForwardLink
= First
->ForwardLink
;
318 First
->ForwardLink
->BackLink
= Head
;
321 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
322 First
->BackLink
= (LIST_ENTRY
*) NULL
;
330 Remove the last node entry on the list and and return the removed node entry.
332 Removes the last node entry from a doubly linked list. It is up to the caller of
333 this function to release the memory used by the first node if that is required. On
334 exit, the removed node is returned.
336 If Head is NULL, then ASSERT().
337 If Head was not initialized, then ASSERT().
338 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
339 linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
342 @param[in, out] Head The list head.
344 @return The last node entry that is removed from the list, NULL if the list is empty.
350 IN OUT LIST_ENTRY
*Head
355 ASSERT (Head
!= NULL
);
357 if (IsListEmpty (Head
)) {
361 Last
= Head
->BackLink
;
362 Head
->BackLink
= Last
->BackLink
;
363 Last
->BackLink
->ForwardLink
= Head
;
366 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
367 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
375 Insert a new node entry after a designated node entry of a doubly linked list.
377 Inserts a new node entry donated by NewEntry after the node entry donated by PrevEntry
378 of the doubly linked list.
380 @param[in, out] PrevEntry The previous entry to insert after.
381 @param[in, out] NewEntry The new entry to insert.
387 IN OUT LIST_ENTRY
*PrevEntry
,
388 IN OUT LIST_ENTRY
*NewEntry
391 NewEntry
->BackLink
= PrevEntry
;
392 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
393 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
394 PrevEntry
->ForwardLink
= NewEntry
;
399 Insert a new node entry before a designated node entry of a doubly linked list.
401 Inserts a new node entry donated by NewEntry after the node entry donated by PostEntry
402 of the doubly linked list.
404 @param[in, out] PostEntry The entry to insert before.
405 @param[in, out] NewEntry The new entry to insert.
410 NetListInsertBefore (
411 IN OUT LIST_ENTRY
*PostEntry
,
412 IN OUT LIST_ENTRY
*NewEntry
415 NewEntry
->ForwardLink
= PostEntry
;
416 NewEntry
->BackLink
= PostEntry
->BackLink
;
417 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
418 PostEntry
->BackLink
= NewEntry
;
423 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
425 Initialize the forward and backward links of two head nodes donated by Map->Used
426 and Map->Recycled of two doubly linked lists.
427 Initializes the count of the <Key, Value> pairs in the netmap to zero.
429 If Map is NULL, then ASSERT().
430 If the address of Map->Used is NULL, then ASSERT().
431 If the address of Map->Recycled is NULl, then ASSERT().
433 @param[in, out] Map The netmap to initialize.
442 ASSERT (Map
!= NULL
);
444 InitializeListHead (&Map
->Used
);
445 InitializeListHead (&Map
->Recycled
);
451 To clean up the netmap, that is, release allocated memories.
453 Removes all nodes of the Used doubly linked list and free memory of all related netmap items.
454 Removes all nodes of the Recycled doubly linked list and free memory of all related netmap items.
455 The number of the <Key, Value> pairs in the netmap is set to be zero.
457 If Map is NULL, then ASSERT().
459 @param[in, out] Map The netmap to clean up.
472 ASSERT (Map
!= NULL
);
474 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
475 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
477 RemoveEntryList (&Item
->Link
);
480 gBS
->FreePool (Item
);
483 ASSERT ((Map
->Count
== 0) && IsListEmpty (&Map
->Used
));
485 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
486 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
488 RemoveEntryList (&Item
->Link
);
489 gBS
->FreePool (Item
);
492 ASSERT (IsListEmpty (&Map
->Recycled
));
497 Test whether the netmap is empty and return true if it is.
499 If the number of the <Key, Value> pairs in the netmap is zero, return TRUE.
501 If Map is NULL, then ASSERT().
504 @param[in] Map The net map to test.
506 @return TRUE if the netmap is empty, otherwise FALSE.
515 ASSERT (Map
!= NULL
);
516 return (BOOLEAN
) (Map
->Count
== 0);
521 Return the number of the <Key, Value> pairs in the netmap.
523 @param[in] Map The netmap to get the entry number.
525 @return The entry number in the netmap.
539 Return one allocated item.
541 If the Recycled doubly linked list of the netmap is empty, it will try to allocate
542 a batch of items if there are enough resources and add corresponding nodes to the begining
543 of the Recycled doubly linked list of the netmap. Otherwise, it will directly remove
544 the fist node entry of the Recycled doubly linked list and return the corresponding item.
546 If Map is NULL, then ASSERT().
548 @param[in, out] Map The netmap to allocate item for.
550 @return The allocated item. If NULL, the
551 allocation failed due to resource limit.
563 ASSERT (Map
!= NULL
);
565 Head
= &Map
->Recycled
;
567 if (IsListEmpty (Head
)) {
568 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
569 Item
= AllocatePool (sizeof (NET_MAP_ITEM
));
579 InsertHeadList (Head
, &Item
->Link
);
583 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
584 NetListRemoveHead (Head
);
591 Allocate an item to save the <Key, Value> pair to the head of the netmap.
593 Allocate an item to save the <Key, Value> pair and add corresponding node entry
594 to the beginning of the Used doubly linked list. The number of the <Key, Value>
595 pairs in the netmap increase by 1.
597 If Map is NULL, then ASSERT().
599 @param[in, out] Map The netmap to insert into.
600 @param[in] Key The user's key.
601 @param[in] Value The user's value for the key.
603 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
604 @retval EFI_SUCCESS The item is inserted to the head.
612 IN VOID
*Value OPTIONAL
617 ASSERT (Map
!= NULL
);
619 Item
= NetMapAllocItem (Map
);
622 return EFI_OUT_OF_RESOURCES
;
627 InsertHeadList (&Map
->Used
, &Item
->Link
);
635 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
637 Allocate an item to save the <Key, Value> pair and add corresponding node entry
638 to the tail of the Used doubly linked list. The number of the <Key, Value>
639 pairs in the netmap increase by 1.
641 If Map is NULL, then ASSERT().
643 @param[in, out] Map The netmap to insert into.
644 @param[in] Key The user's key.
645 @param[in] Value The user's value for the key.
647 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
648 @retval EFI_SUCCESS The item is inserted to the tail.
656 IN VOID
*Value OPTIONAL
661 ASSERT (Map
!= NULL
);
663 Item
= NetMapAllocItem (Map
);
666 return EFI_OUT_OF_RESOURCES
;
671 InsertTailList (&Map
->Used
, &Item
->Link
);
680 Check whether the item is in the Map and return TRUE if it is.
682 @param[in] Map The netmap to search within.
683 @param[in] Item The item to search.
685 @return TRUE if the item is in the netmap, otherwise FALSE.
691 IN NET_MAP_ITEM
*Item
694 LIST_ENTRY
*ListEntry
;
696 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
697 if (ListEntry
== &Item
->Link
) {
707 Find the key in the netmap and returns the point to the item contains the Key.
709 Iterate the Used doubly linked list of the netmap to get every item. Compare the key of every
710 item with the key to search. It returns the point to the item contains the Key if found.
712 If Map is NULL, then ASSERT().
714 @param[in] Map The netmap to search within.
715 @param[in] Key The key to search.
717 @return The point to the item contains the Key, or NULL if Key isn't in the map.
730 ASSERT (Map
!= NULL
);
732 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
733 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
735 if (Item
->Key
== Key
) {
745 Remove the node entry of the item from the netmap and return the key of the removed item.
747 Remove the node entry of the item from the Used doubly linked list of the netmap.
748 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
749 entry of the item to the Recycled doubly linked list of the netmap. If Value is not NULL,
750 Value will point to the value of the item. It returns the key of the removed item.
752 If Map is NULL, then ASSERT().
753 If Item is NULL, then ASSERT().
754 if item in not in the netmap, then ASSERT().
756 @param[in, out] Map The netmap to remove the item from.
757 @param[in, out] Item The item to remove.
758 @param[out] Value The variable to receive the value if not NULL.
760 @return The key of the removed item.
767 IN OUT NET_MAP_ITEM
*Item
,
768 OUT VOID
**Value OPTIONAL
771 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
772 ASSERT (NetItemInMap (Map
, Item
));
774 RemoveEntryList (&Item
->Link
);
776 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
779 *Value
= Item
->Value
;
787 Remove the first node entry on the netmap and return the key of the removed item.
789 Remove the first node entry from the Used doubly linked list of the netmap.
790 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
791 entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
792 parameter Value will point to the value of the item. It returns the key of the removed item.
794 If Map is NULL, then ASSERT().
795 If the Used doubly linked list is empty, then ASSERT().
797 @param[in, out] Map The netmap to remove the head from.
798 @param[out] Value The variable to receive the value if not NULL.
800 @return The key of the item removed.
807 OUT VOID
**Value OPTIONAL
813 // Often, it indicates a programming error to remove
814 // the first entry in an empty list
816 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
818 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
819 RemoveEntryList (&Item
->Link
);
821 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
824 *Value
= Item
->Value
;
832 Remove the last node entry on the netmap and return the key of the removed item.
834 Remove the last node entry from the Used doubly linked list of the netmap.
835 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
836 entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
837 parameter Value will point to the value of the item. It returns the key of the removed item.
839 If Map is NULL, then ASSERT().
840 If the Used doubly linked list is empty, then ASSERT().
842 @param[in, out] Map The netmap to remove the tail from.
843 @param[out] Value The variable to receive the value if not NULL.
845 @return The key of the item removed.
852 OUT VOID
**Value OPTIONAL
858 // Often, it indicates a programming error to remove
859 // the last entry in an empty list
861 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
863 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
864 RemoveEntryList (&Item
->Link
);
866 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
869 *Value
= Item
->Value
;
877 Iterate through the netmap and call CallBack for each item.
879 It will contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
880 from the loop. It returns the CallBack's last return value. This function is
881 delete safe for the current item.
883 If Map is NULL, then ASSERT().
884 If CallBack is NULL, then ASSERT().
886 @param[in] Map The Map to iterate through.
887 @param[in] CallBack The callback function to call for each item.
888 @param[in] Arg The opaque parameter to the callback.
890 @retval EFI_SUCCESS There is no item in the netmap or CallBack for each item
892 @retval Others It returns the CallBack's last return value.
899 IN NET_MAP_CALLBACK CallBack
,
910 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
914 if (IsListEmpty (Head
)) {
918 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
919 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
920 Result
= CallBack (Map
, Item
, Arg
);
922 if (EFI_ERROR (Result
)) {
932 This is the default unload handle for all the network drivers.
934 Disconnect the driver specified by ImageHandle from all the devices in the handle database.
935 Uninstall all the protocols installed in the driver entry point.
937 @param[in] ImageHandle The drivers' driver image.
939 @retval EFI_SUCCESS The image is unloaded.
940 @retval Others Failed to unload the image.
945 NetLibDefaultUnload (
946 IN EFI_HANDLE ImageHandle
950 EFI_HANDLE
*DeviceHandleBuffer
;
951 UINTN DeviceHandleCount
;
953 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
954 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
955 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName2
;
958 // Get the list of all the handles in the handle database.
959 // If there is an error getting the list, then the unload
962 Status
= gBS
->LocateHandleBuffer (
970 if (EFI_ERROR (Status
)) {
975 // Disconnect the driver specified by ImageHandle from all
976 // the devices in the handle database.
978 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
979 Status
= gBS
->DisconnectController (
980 DeviceHandleBuffer
[Index
],
987 // Uninstall all the protocols installed in the driver entry point
989 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
990 Status
= gBS
->HandleProtocol (
991 DeviceHandleBuffer
[Index
],
992 &gEfiDriverBindingProtocolGuid
,
993 (VOID
**) &DriverBinding
996 if (EFI_ERROR (Status
)) {
1000 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
1004 gBS
->UninstallProtocolInterface (
1006 &gEfiDriverBindingProtocolGuid
,
1009 Status
= gBS
->HandleProtocol (
1010 DeviceHandleBuffer
[Index
],
1011 &gEfiComponentNameProtocolGuid
,
1012 (VOID
**) &ComponentName
1014 if (!EFI_ERROR (Status
)) {
1015 gBS
->UninstallProtocolInterface (
1017 &gEfiComponentNameProtocolGuid
,
1022 Status
= gBS
->HandleProtocol (
1023 DeviceHandleBuffer
[Index
],
1024 &gEfiComponentName2ProtocolGuid
,
1025 (VOID
**) &ComponentName2
1027 if (!EFI_ERROR (Status
)) {
1028 gBS
->UninstallProtocolInterface (
1030 &gEfiComponentName2ProtocolGuid
,
1037 // Free the buffer containing the list of handles from the handle database
1039 if (DeviceHandleBuffer
!= NULL
) {
1040 gBS
->FreePool (DeviceHandleBuffer
);
1049 Create a child of the service that is identified by ServiceBindingGuid.
1051 Get the ServiceBinding Protocol first, then use it to create a child.
1053 If ServiceBindingGuid is NULL, then ASSERT().
1054 If ChildHandle is NULL, then ASSERT().
1056 @param[in] Controller The controller which has the service installed.
1057 @param[in] Image The image handle used to open service.
1058 @param[in] ServiceBindingGuid The service's Guid.
1059 @param[in, out] ChildHandle The handle to receive the create child.
1061 @retval EFI_SUCCESS The child is successfully created.
1062 @retval Others Failed to create the child.
1067 NetLibCreateServiceChild (
1068 IN EFI_HANDLE Controller
,
1069 IN EFI_HANDLE Image
,
1070 IN EFI_GUID
*ServiceBindingGuid
,
1071 IN OUT EFI_HANDLE
*ChildHandle
1075 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1078 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
1081 // Get the ServiceBinding Protocol
1083 Status
= gBS
->OpenProtocol (
1089 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1092 if (EFI_ERROR (Status
)) {
1099 Status
= Service
->CreateChild (Service
, ChildHandle
);
1105 Destory a child of the service that is identified by ServiceBindingGuid.
1107 Get the ServiceBinding Protocol first, then use it to destroy a child.
1109 If ServiceBindingGuid is NULL, then ASSERT().
1111 @param[in] Controller The controller which has the service installed.
1112 @param[in] Image The image handle used to open service.
1113 @param[in] ServiceBindingGuid The service's Guid.
1114 @param[in] ChildHandle The child to destory.
1116 @retval EFI_SUCCESS The child is successfully destoried.
1117 @retval Others Failed to destory the child.
1122 NetLibDestroyServiceChild (
1123 IN EFI_HANDLE Controller
,
1124 IN EFI_HANDLE Image
,
1125 IN EFI_GUID
*ServiceBindingGuid
,
1126 IN EFI_HANDLE ChildHandle
1130 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1132 ASSERT (ServiceBindingGuid
!= NULL
);
1135 // Get the ServiceBinding Protocol
1137 Status
= gBS
->OpenProtocol (
1143 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1146 if (EFI_ERROR (Status
)) {
1151 // destory the child
1153 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1159 Convert the mac address of the simple network protocol installed on
1160 SnpHandle to a unicode string. Callers are responsible for freeing the
1163 Get the mac address of the Simple Network protocol from the SnpHandle. Then convert
1164 the mac address into a unicode string. It takes 2 unicode characters to represent
1165 a 1 byte binary buffer. Plus one unicode character for the null-terminator.
1168 @param[in] SnpHandle The handle where the simple network protocol is
1170 @param[in] ImageHandle The image handle used to act as the agent handle to
1171 get the simple network protocol.
1172 @param[out] MacString The pointer to store the address of the string
1173 representation of the mac address.
1175 @retval EFI_SUCCESS Convert the mac address a unicode string successfully.
1176 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1177 @retval Others Failed to open the simple network protocol.
1182 NetLibGetMacString (
1183 IN EFI_HANDLE SnpHandle
,
1184 IN EFI_HANDLE ImageHandle
,
1185 OUT CHAR16
**MacString
1189 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1190 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1197 // Get the Simple Network protocol from the SnpHandle.
1199 Status
= gBS
->OpenProtocol (
1201 &gEfiSimpleNetworkProtocolGuid
,
1205 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1207 if (EFI_ERROR (Status
)) {
1214 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1215 // Plus one unicode character for the null-terminator.
1217 MacAddress
= AllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1218 if (MacAddress
== NULL
) {
1219 return EFI_OUT_OF_RESOURCES
;
1223 // Convert the mac address into a unicode string.
1225 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1226 MacAddress
[Index
* 2] = (CHAR16
) mNetLibHexStr
[(Mode
->CurrentAddress
.Addr
[Index
] >> 4) & 0x0F];
1227 MacAddress
[Index
* 2 + 1] = (CHAR16
) mNetLibHexStr
[Mode
->CurrentAddress
.Addr
[Index
] & 0x0F];
1230 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1232 *MacString
= MacAddress
;
1238 Check the default address used by the IPv4 driver is static or dynamic (acquired
1241 If the controller handle does not have the NIC Ip4 Config Protocol installed, the
1242 default address is static. If the EFI variable to save the configuration is not found,
1243 the default address is static. Otherwise, get the result from the EFI variable which
1244 saving the configuration.
1246 @param[in] Controller The controller handle which has the NIC Ip4 Config Protocol
1247 relative with the default address to judge.
1249 @retval TRUE If the default address is static.
1250 @retval FALSE If the default address is acquired from DHCP.
1254 NetLibDefaultAddressIsStatic (
1255 IN EFI_HANDLE Controller
1259 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1261 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1263 EFI_STRING ConfigHdr
;
1264 EFI_STRING ConfigResp
;
1265 EFI_STRING AccessProgress
;
1266 EFI_STRING AccessResults
;
1272 AccessProgress
= NULL
;
1273 AccessResults
= NULL
;
1276 Status
= gBS
->LocateProtocol (
1277 &gEfiHiiConfigRoutingProtocolGuid
,
1279 (VOID
**) &HiiConfigRouting
1281 if (EFI_ERROR (Status
)) {
1286 // Construct config request string header
1288 ConfigHdr
= HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid
, EFI_NIC_IP4_CONFIG_VARIABLE
, Controller
);
1290 Len
= StrLen (ConfigHdr
);
1291 ConfigResp
= AllocateZeroPool ((Len
+ NIC_ITEM_CONFIG_SIZE
* 2 + 100) * sizeof (CHAR16
));
1292 if (ConfigResp
== NULL
) {
1295 StrCpy (ConfigResp
, ConfigHdr
);
1297 String
= ConfigResp
+ Len
;
1300 (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16
),
1301 L
"&OFFSET=%04X&WIDTH=%04X",
1302 OFFSET_OF (NIC_IP4_CONFIG_INFO
, Source
),
1306 Status
= HiiConfigRouting
->ExtractConfig (
1312 if (EFI_ERROR (Status
)) {
1316 ConfigInfo
= AllocateZeroPool (sizeof (NIC_ITEM_CONFIG_SIZE
));
1317 if (ConfigInfo
== NULL
) {
1321 ConfigInfo
->Source
= IP4_CONFIG_SOURCE_STATIC
;
1322 Len
= NIC_ITEM_CONFIG_SIZE
;
1323 Status
= HiiConfigRouting
->ConfigToBlock (
1326 (UINT8
*) ConfigInfo
,
1330 if (EFI_ERROR (Status
)) {
1334 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1338 if (AccessResults
!= NULL
) {
1339 FreePool (AccessResults
);
1341 if (ConfigInfo
!= NULL
) {
1342 FreePool (ConfigInfo
);
1344 if (ConfigResp
!= NULL
) {
1345 FreePool (ConfigResp
);
1347 if (ConfigHdr
!= NULL
) {
1348 FreePool (ConfigHdr
);
1355 Create an IPv4 device path node.
1357 The header type of IPv4 device path node is MESSAGING_DEVICE_PATH.
1358 The header subtype of IPv4 device path node is MSG_IPv4_DP.
1359 The length of the IPv4 device path node in bytes is 19.
1360 Get other info from parameters to make up the whole IPv4 device path node.
1362 @param[in, out] Node Pointer to the IPv4 device path node.
1363 @param[in] Controller The handle where the NIC IP4 config protocol resides.
1364 @param[in] LocalIp The local IPv4 address.
1365 @param[in] LocalPort The local port.
1366 @param[in] RemoteIp The remote IPv4 address.
1367 @param[in] RemotePort The remote port.
1368 @param[in] Protocol The protocol type in the IP header.
1369 @param[in] UseDefaultAddress Whether this instance is using default address or not.
1374 NetLibCreateIPv4DPathNode (
1375 IN OUT IPv4_DEVICE_PATH
*Node
,
1376 IN EFI_HANDLE Controller
,
1377 IN IP4_ADDR LocalIp
,
1378 IN UINT16 LocalPort
,
1379 IN IP4_ADDR RemoteIp
,
1380 IN UINT16 RemotePort
,
1382 IN BOOLEAN UseDefaultAddress
1385 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1386 Node
->Header
.SubType
= MSG_IPv4_DP
;
1387 SetDevicePathNodeLength (&Node
->Header
, 19);
1389 CopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1390 CopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1392 Node
->LocalPort
= LocalPort
;
1393 Node
->RemotePort
= RemotePort
;
1395 Node
->Protocol
= Protocol
;
1397 if (!UseDefaultAddress
) {
1398 Node
->StaticIpAddress
= TRUE
;
1400 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1406 Find the UNDI/SNP handle from controller and protocol GUID.
1408 For example, IP will open a MNP child to transmit/receive
1409 packets, when MNP is stopped, IP should also be stopped. IP
1410 needs to find its own private data which is related the IP's
1411 service binding instance that is install on UNDI/SNP handle.
1412 Now, the controller is either a MNP or ARP child handle. But
1413 IP opens these handle BY_DRIVER, use that info, we can get the
1416 @param[in] Controller Then protocol handle to check.
1417 @param[in] ProtocolGuid The protocol that is related with the handle.
1419 @return The UNDI/SNP handle or NULL for errors.
1424 NetLibGetNicHandle (
1425 IN EFI_HANDLE Controller
,
1426 IN EFI_GUID
*ProtocolGuid
1429 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1435 Status
= gBS
->OpenProtocolInformation (
1442 if (EFI_ERROR (Status
)) {
1448 for (Index
= 0; Index
< OpenCount
; Index
++) {
1449 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1450 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1455 gBS
->FreePool (OpenBuffer
);
1460 Add a Deferred Procedure Call to the end of the DPC queue.
1462 @param[in] DpcTpl The EFI_TPL that the DPC should be invoked.
1463 @param[in] DpcProcedure Pointer to the DPC's function.
1464 @param[in] DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1465 when DpcProcedure is invoked.
1467 @retval EFI_SUCCESS The DPC was queued.
1468 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL, or DpcProcedure
1470 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1471 add the DPC to the queue.
1478 IN EFI_DPC_PROCEDURE DpcProcedure
,
1479 IN VOID
*DpcContext OPTIONAL
1482 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1486 Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl
1487 value greater than or equal to the current TPL are invoked in the order that
1488 they were queued. DPCs with higher DpcTpl values are invoked before DPCs with
1489 lower DpcTpl values.
1491 @retval EFI_SUCCESS One or more DPCs were invoked.
1492 @retval EFI_NOT_FOUND No DPCs were invoked.
1501 return mDpc
->DispatchDpc(mDpc
);
1505 The constructor function caches the pointer to DPC protocol.
1507 The constructor function locates DPC protocol from protocol database.
1508 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1510 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1511 @param[in] SystemTable A pointer to the EFI System Table.
1513 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1519 IN EFI_HANDLE ImageHandle
,
1520 IN EFI_SYSTEM_TABLE
*SystemTable
1525 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1526 ASSERT_EFI_ERROR (Status
);
1527 ASSERT (mDpc
!= NULL
);