• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Driver Binding functions and Service Binding functions for the Network driver module.
3 
4   Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
5 
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php.
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "Udp6Impl.h"
17 
18 EFI_DRIVER_BINDING_PROTOCOL gUdp6DriverBinding = {
19   Udp6DriverBindingSupported,
20   Udp6DriverBindingStart,
21   Udp6DriverBindingStop,
22   0xa,
23   NULL,
24   NULL
25 };
26 
27 EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding = {
28   Udp6ServiceBindingCreateChild,
29   Udp6ServiceBindingDestroyChild
30 };
31 
32 /**
33   Tests to see if this driver supports a given controller. If a child device is provided,
34   it further tests to see if this driver supports creating a handle for the specified child device.
35 
36   This function checks to see if the driver specified by This supports the device specified by
37   ControllerHandle. Drivers will typically use the device path attached to
38   ControllerHandle and/or the services from the bus I/O abstraction attached to
39   ControllerHandle to determine if the driver supports ControllerHandle. This function
40   may be called many times during platform initialization. In order to reduce boot times, the tests
41   performed by this function must be very small, and take as little time as possible to execute. This
42   function must not change the state of any hardware devices, and this function must be aware that the
43   device specified by ControllerHandle may already be managed by the same driver or a
44   different driver. This function must match its calls to AllocatePages() with FreePages(),
45   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
46   Because ControllerHandle may have been previously started by the same driver, if a protocol is
47   already in the opened state, then it must not be closed with CloseProtocol(). This is required
48   to guarantee the state of ControllerHandle is not modified by this function.
49 
50   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
51   @param[in]  ControllerHandle     The handle of the controller to test. This handle
52                                    must support a protocol interface that supplies
53                                    an I/O abstraction to the driver.
54   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
55                                    parameter is ignored by device drivers, and is optional for bus
56                                    drivers. For bus drivers, if this parameter is not NULL, then
57                                    the bus driver must determine if the bus controller specified
58                                    by ControllerHandle and the child controller specified
59                                    by RemainingDevicePath are both supported by this
60                                    bus driver.
61 
62   @retval EFI_SUCCESS              The device specified by ControllerHandle and
63                                    RemainingDevicePath is supported by the driver specified by This.
64   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
65                                    RemainingDevicePath is already being managed by the driver
66                                    specified by This.
67   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
68                                    RemainingDevicePath is already being managed by a different
69                                    driver or an application that requires exclusive access.
70                                    Currently not implemented.
71   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
72                                    RemainingDevicePath is not supported by the driver specified by This.
73 **/
74 EFI_STATUS
75 EFIAPI
Udp6DriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)76 Udp6DriverBindingSupported (
77   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
78   IN EFI_HANDLE                   ControllerHandle,
79   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
80   )
81 {
82   EFI_STATUS  Status;
83   //
84   // Test for the Udp6ServiceBinding Protocol
85   //
86   Status = gBS->OpenProtocol (
87                   ControllerHandle,
88                   &gEfiUdp6ServiceBindingProtocolGuid,
89                   NULL,
90                   This->DriverBindingHandle,
91                   ControllerHandle,
92                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
93                   );
94   if (!EFI_ERROR (Status)) {
95     return EFI_ALREADY_STARTED;
96   }
97   //
98   // Test for the Ip6ServiceBinding Protocol
99   //
100   Status = gBS->OpenProtocol (
101                   ControllerHandle,
102                   &gEfiIp6ServiceBindingProtocolGuid,
103                   NULL,
104                   This->DriverBindingHandle,
105                   ControllerHandle,
106                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
107                   );
108 
109   return Status;
110 }
111 
112 /**
113   Start this driver on ControllerHandle.
114 
115   This service is called by the EFI boot service ConnectController(). In order to make
116   drivers as small as possible, there are a few calling restrictions for
117   this service. ConnectController() must follow these
118   calling restrictions. If any other agent wishes to call Start() it
119   must also follow these calling restrictions.
120 
121   @param[in]  This                   Protocol instance pointer.
122   @param[in]  ControllerHandle       Handle of device to bind the driver to.
123   @param[in]  RemainingDevicePath    Optional parameter use to pick a specific child
124                                      device to start.
125 
126   @retval EFI_SUCCES             This driver is added to ControllerHandle.
127   @retval EFI_OUT_OF_RESOURCES   The required system resource can't be allocated.
128   @retval other                  This driver does not support this device.
129 
130 **/
131 EFI_STATUS
132 EFIAPI
Udp6DriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL)133 Udp6DriverBindingStart (
134   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
135   IN EFI_HANDLE                   ControllerHandle,
136   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath  OPTIONAL
137   )
138 {
139   EFI_STATUS         Status;
140   UDP6_SERVICE_DATA  *Udp6Service;
141 
142   //
143   // Allocate Private Context Data Structure.
144   //
145   Udp6Service = AllocateZeroPool (sizeof (UDP6_SERVICE_DATA));
146   if (Udp6Service == NULL) {
147     Status = EFI_OUT_OF_RESOURCES;
148     goto EXIT;
149   }
150 
151   Status = Udp6CreateService (Udp6Service, This->DriverBindingHandle, ControllerHandle);
152   if (EFI_ERROR (Status)) {
153     goto EXIT;
154   }
155 
156   //
157   // Install the Udp6ServiceBindingProtocol on the ControllerHandle.
158   //
159   Status = gBS->InstallMultipleProtocolInterfaces (
160                   &ControllerHandle,
161                   &gEfiUdp6ServiceBindingProtocolGuid,
162                   &Udp6Service->ServiceBinding,
163                   NULL
164                   );
165   if (EFI_ERROR (Status)) {
166     Udp6CleanService (Udp6Service);
167     goto EXIT;
168   }
169 
170 EXIT:
171   if (EFI_ERROR (Status)) {
172     if (Udp6Service != NULL) {
173       FreePool (Udp6Service);
174     }
175   }
176   return Status;
177 }
178 
179 /**
180   Callback function which provided by user to remove one node in NetDestroyLinkList process.
181 
182   @param[in]    Entry           The entry to be removed.
183   @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
184 
185   @retval EFI_SUCCESS           The entry has been removed successfully.
186   @retval Others                Fail to remove the entry.
187 
188 **/
189 EFI_STATUS
190 EFIAPI
Udp6DestroyChildEntryInHandleBuffer(IN LIST_ENTRY * Entry,IN VOID * Context)191 Udp6DestroyChildEntryInHandleBuffer (
192   IN LIST_ENTRY         *Entry,
193   IN VOID               *Context
194   )
195 {
196   UDP6_INSTANCE_DATA            *Instance;
197   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
198   UINTN                         NumberOfChildren;
199   EFI_HANDLE                    *ChildHandleBuffer;
200 
201   if (Entry == NULL || Context == NULL) {
202     return EFI_INVALID_PARAMETER;
203   }
204 
205   Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE);
206   ServiceBinding    = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding;
207   NumberOfChildren  = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren;
208   ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer;
209 
210   if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) {
211     return EFI_SUCCESS;
212   }
213 
214   return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle);
215 }
216 
217 /**
218   Stop this driver on ControllerHandle.
219 
220   This service is called by the  EFI boot service DisconnectController(). In order to
221   make drivers as small as possible, there are a few calling
222   restrictions for this service. DisconnectController()
223   must follow these calling restrictions. If any other agent wishes
224   to call Stop(), it must also follow these calling restrictions.
225 
226   @param[in]  This                   Protocol instance pointer.
227   @param[in]  ControllerHandle       Handle of device to stop the driver on.
228   @param[in]  NumberOfChildren       Number of Handles in ChildHandleBuffer. If the number
229                                      of children is zero stop the entire bus driver.
230   @param[in]  ChildHandleBuffer      List of Child Handles to Stop. It is optional.
231 
232   @retval EFI_SUCCES             This driver is removed ControllerHandle.
233   @retval EFI_DEVICE_ERROR       Can't find the NicHandle from the ControllerHandle and specified GUID.
234   @retval other                  This driver was not removed from this device.
235 
236 **/
237 EFI_STATUS
238 EFIAPI
Udp6DriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE ControllerHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer OPTIONAL)239 Udp6DriverBindingStop (
240   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
241   IN  EFI_HANDLE                   ControllerHandle,
242   IN  UINTN                        NumberOfChildren,
243   IN  EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
244   )
245 {
246   EFI_STATUS                    Status;
247   EFI_HANDLE                    NicHandle;
248   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
249   UDP6_SERVICE_DATA             *Udp6Service;
250   LIST_ENTRY                    *List;
251   UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context;
252 
253   //
254   // Find the NicHandle where UDP6 ServiceBinding Protocol is installed.
255   //
256   NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
257   if (NicHandle == NULL) {
258     return EFI_SUCCESS;
259   }
260 
261   //
262   // Retrieve the UDP6 ServiceBinding Protocol.
263   //
264   Status = gBS->OpenProtocol (
265                   NicHandle,
266                   &gEfiUdp6ServiceBindingProtocolGuid,
267                   (VOID **) &ServiceBinding,
268                   This->DriverBindingHandle,
269                   NicHandle,
270                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
271                   );
272   if (EFI_ERROR (Status)) {
273     return EFI_DEVICE_ERROR;
274   }
275 
276   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding);
277 
278   if (NumberOfChildren != 0) {
279     //
280     // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer.
281     //
282     List = &Udp6Service->ChildrenList;
283     Context.ServiceBinding    = ServiceBinding;
284     Context.NumberOfChildren  = NumberOfChildren;
285     Context.ChildHandleBuffer = ChildHandleBuffer;
286     Status = NetDestroyLinkList (
287                List,
288                Udp6DestroyChildEntryInHandleBuffer,
289                &Context,
290                NULL
291                );
292   } else if (IsListEmpty (&Udp6Service->ChildrenList)) {
293     gBS->UninstallMultipleProtocolInterfaces (
294            NicHandle,
295            &gEfiUdp6ServiceBindingProtocolGuid,
296            &Udp6Service->ServiceBinding,
297            NULL
298            );
299 
300     Udp6CleanService (Udp6Service);
301 
302     FreePool (Udp6Service);
303 
304     Status = EFI_SUCCESS;
305   }
306 
307   return Status;
308 }
309 
310 /**
311   Creates a child handle and installs a protocol.
312 
313   The CreateChild() function installs a protocol on ChildHandle.
314   If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
315   If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
316 
317   @param[in]       This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
318   @param[in, out]  ChildHandle Pointer to the handle of the child to create. If it is NULL,
319                                then a new handle is created. If it is a pointer to an existing UEFI handle,
320                                then the protocol is added to the existing UEFI handle.
321 
322   @retval EFI_SUCCES            The protocol was added to ChildHandle.
323   @retval EFI_INVALID_PARAMETER This is NULL or ChildHandle is NULL.
324   @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
325                                 the child.
326   @retval other                 The child handle was not created.
327 
328 **/
329 EFI_STATUS
330 EFIAPI
Udp6ServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL * This,IN OUT EFI_HANDLE * ChildHandle)331 Udp6ServiceBindingCreateChild (
332   IN EFI_SERVICE_BINDING_PROTOCOL  *This,
333   IN OUT EFI_HANDLE                *ChildHandle
334   )
335 {
336   EFI_STATUS          Status;
337   UDP6_SERVICE_DATA   *Udp6Service;
338   UDP6_INSTANCE_DATA  *Instance;
339   EFI_TPL             OldTpl;
340   VOID                *Ip6;
341 
342   if ((This == NULL) || (ChildHandle == NULL)) {
343     return EFI_INVALID_PARAMETER;
344   }
345 
346   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
347 
348   //
349   // Allocate the instance private data structure.
350   //
351   Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE_DATA));
352   if (Instance == NULL) {
353     return EFI_OUT_OF_RESOURCES;
354   }
355 
356   Udp6InitInstance (Udp6Service, Instance);
357 
358   //
359   // Add an IpInfo for this instance.
360   //
361   Instance->IpInfo = IpIoAddIp (Udp6Service->IpIo);
362   if (Instance->IpInfo == NULL) {
363     Status = EFI_OUT_OF_RESOURCES;
364     goto ON_ERROR;
365   }
366 
367   //
368   // Install the Udp6Protocol for this instance.
369   //
370   Status = gBS->InstallMultipleProtocolInterfaces (
371                   ChildHandle,
372                   &gEfiUdp6ProtocolGuid,
373                   &Instance->Udp6Proto,
374                   NULL
375                   );
376   if (EFI_ERROR (Status)) {
377     goto ON_ERROR;
378   }
379 
380   Instance->ChildHandle = *ChildHandle;
381 
382   //
383   // Open the default Ip6 protocol in the IP_IO BY_CHILD.
384   //
385   Status = gBS->OpenProtocol (
386                   Udp6Service->IpIo->ChildHandle,
387                   &gEfiIp6ProtocolGuid,
388                   (VOID **) &Ip6,
389                   gUdp6DriverBinding.DriverBindingHandle,
390                   Instance->ChildHandle,
391                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
392                   );
393   if (EFI_ERROR (Status)) {
394     goto ON_ERROR;
395   }
396 
397   //
398   // Open this instance's Ip6 protocol in the IpInfo BY_CHILD.
399   //
400   Status = gBS->OpenProtocol (
401                   Instance->IpInfo->ChildHandle,
402                   &gEfiIp6ProtocolGuid,
403                   (VOID **) &Ip6,
404                   gUdp6DriverBinding.DriverBindingHandle,
405                   Instance->ChildHandle,
406                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
407                   );
408   if (EFI_ERROR (Status)) {
409     goto ON_ERROR;
410   }
411 
412   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
413 
414   //
415   // Link this instance into the service context data and increase the ChildrenNumber.
416   //
417   InsertTailList (&Udp6Service->ChildrenList, &Instance->Link);
418   Udp6Service->ChildrenNumber++;
419 
420   gBS->RestoreTPL (OldTpl);
421 
422   return EFI_SUCCESS;
423 
424 ON_ERROR:
425 
426   if (Instance->ChildHandle != NULL) {
427     gBS->UninstallMultipleProtocolInterfaces (
428            Instance->ChildHandle,
429            &gEfiUdp6ProtocolGuid,
430            &Instance->Udp6Proto,
431            NULL
432            );
433   }
434 
435   if (Instance->IpInfo != NULL) {
436     IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
437   }
438 
439   Udp6CleanInstance (Instance);
440 
441   FreePool (Instance);
442 
443   return Status;
444 }
445 
446 /**
447   Destroys a child handle with a set of I/O services.
448   The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
449   that was installed by CreateChild() from ChildHandle. If the removed protocol is the
450   last protocol on ChildHandle, then ChildHandle is destroyed.
451 
452   @param[in]  This               Protocol instance pointer.
453   @param[in]  ChildHandle        Handle of the child to destroy.
454 
455   @retval EFI_SUCCES             The I/O services were removed from the child
456                                  handle.
457   @retval EFI_UNSUPPORTED        The child handle does not support the I/O services
458                                  that are being removed.
459   @retval EFI_INVALID_PARAMETER  Child handle is NULL.
460   @retval EFI_ACCESS_DENIED      The child handle could not be destroyed because
461                                  its  I/O services are being used.
462   @retval other                  The child handle was not destroyed.
463 
464 **/
465 EFI_STATUS
466 EFIAPI
Udp6ServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL * This,IN EFI_HANDLE ChildHandle)467 Udp6ServiceBindingDestroyChild (
468   IN EFI_SERVICE_BINDING_PROTOCOL  *This,
469   IN EFI_HANDLE                    ChildHandle
470   )
471 {
472   EFI_STATUS          Status;
473   UDP6_SERVICE_DATA   *Udp6Service;
474   EFI_UDP6_PROTOCOL   *Udp6Proto;
475   UDP6_INSTANCE_DATA  *Instance;
476   EFI_TPL             OldTpl;
477 
478   if ((This == NULL) || (ChildHandle == NULL)) {
479     return EFI_INVALID_PARAMETER;
480   }
481 
482   Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This);
483 
484   //
485   // Try to get the Udp6 protocol from the ChildHandle.
486   //
487   Status = gBS->OpenProtocol (
488                   ChildHandle,
489                   &gEfiUdp6ProtocolGuid,
490                   (VOID **) &Udp6Proto,
491                   gUdp6DriverBinding.DriverBindingHandle,
492                   ChildHandle,
493                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
494                   );
495   if (EFI_ERROR (Status)) {
496     return EFI_UNSUPPORTED;
497   }
498 
499   Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto);
500 
501   if (Instance->InDestroy) {
502     return EFI_SUCCESS;
503   }
504 
505   //
506   // Use the Destroyed flag to avoid the re-entering of the following code.
507   //
508   Instance->InDestroy = TRUE;
509 
510   //
511   // Close the Ip6 protocol on the default IpIo.
512   //
513   gBS->CloseProtocol (
514          Udp6Service->IpIo->ChildHandle,
515          &gEfiIp6ProtocolGuid,
516          gUdp6DriverBinding.DriverBindingHandle,
517          Instance->ChildHandle
518          );
519   //
520   // Close the Ip6 protocol on this instance's IpInfo.
521   //
522   gBS->CloseProtocol (
523          Instance->IpInfo->ChildHandle,
524          &gEfiIp6ProtocolGuid,
525          gUdp6DriverBinding.DriverBindingHandle,
526          Instance->ChildHandle
527          );
528 
529   //
530   // Uninstall the Udp6Protocol previously installed on the ChildHandle.
531   //
532   Status = gBS->UninstallMultipleProtocolInterfaces (
533                   ChildHandle,
534                   &gEfiUdp6ProtocolGuid,
535                   (VOID *) &Instance->Udp6Proto,
536                   NULL
537                   );
538   if (EFI_ERROR (Status)) {
539     Instance->InDestroy = FALSE;
540     return Status;
541   }
542 
543   //
544   // Reset the configuration in case the instance's consumer forgets to do this.
545   //
546   Udp6Proto->Configure (Udp6Proto, NULL);
547 
548   //
549   // Remove the IpInfo this instance consumes.
550   //
551   IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo);
552 
553   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
554 
555   //
556   // Remove this instance from the service context data's ChildrenList.
557   //
558   RemoveEntryList (&Instance->Link);
559   Udp6Service->ChildrenNumber--;
560 
561   //
562   // Clean the instance.
563   //
564   Udp6CleanInstance (Instance);
565 
566   gBS->RestoreTPL (OldTpl);
567 
568   FreePool (Instance);
569 
570   return EFI_SUCCESS;
571 }
572 
573 /**
574   This is the declaration of an EFI image entry point. This entry point is
575   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
576   both device drivers and bus drivers.
577 
578   The entry point for Udp6 driver that installs the driver binding
579   and component name protocol on its ImageHandle.
580 
581   @param[in] ImageHandle        The firmware allocated handle for the UEFI image.
582   @param[in] SystemTable        A pointer to the EFI System Table.
583 
584   @retval EFI_SUCCESS           The operation completed successfully.
585   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
586 
587 **/
588 EFI_STATUS
589 EFIAPI
Udp6DriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)590 Udp6DriverEntryPoint (
591   IN EFI_HANDLE        ImageHandle,
592   IN EFI_SYSTEM_TABLE  *SystemTable
593   )
594 {
595   EFI_STATUS  Status;
596 
597   //
598   // Install the Udp6DriverBinding and Udp6ComponentName protocols.
599   //
600 
601   Status = EfiLibInstallDriverBindingComponentName2 (
602              ImageHandle,
603              SystemTable,
604              &gUdp6DriverBinding,
605              ImageHandle,
606              &gUdp6ComponentName,
607              &gUdp6ComponentName2
608              );
609   if (!EFI_ERROR (Status)) {
610     //
611     // Initialize the UDP random port.
612     //
613     mUdp6RandomPort = (UINT16)(
614                         ((UINT16) NetRandomInitSeed ()) %
615                          UDP6_PORT_KNOWN +
616                          UDP6_PORT_KNOWN
617                          );
618   }
619 
620   return Status;
621 }
622 
623 
624