• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**  <at> file
2   Implementation of driver entry point and driver binding protocol.
3 
4 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2011 - 2016, ARM Limited. All rights reserved.
6 
7 This program and the accompanying materials are licensed
8 and made available under the terms and conditions of the BSD License which
9 accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include <Library/NetLib.h>
18 #include <Library/DevicePathLib.h>
19 #include "MarvellYukon.h"
20 #include "if_msk.h"
21 
22 STATIC LIST_ENTRY MarvellYukonDrvDataHead;
23 
24 /**
25   Test to see if this driver supports ControllerHandle. This service
26   is called by the EFI boot service ConnectController(). In
27   order to make drivers as small as possible, there are a few calling
28   restrictions for this service. ConnectController() must
29   follow these calling restrictions. If any other agent wishes to call
30   Supported() it must also follow these calling restrictions.
31 
32    <at> param  This                   Protocol instance pointer.
33    <at> param  ControllerHandle       Handle of device to test.
34    <at> param  RemainingDevicePath    Optional parameter use to pick a specific child
35                                                              device to start.
36 
37    <at> retval EFI_SUCCESS            This driver supports this device.
38    <at> retval EFI_ALREADY_STARTED    This driver is already running on this device.
39    <at> retval other                  This driver does not support this device.
40 
41 **/
42 EFI_STATUS
43 EFIAPI
MarvellYukonDriverSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)44 MarvellYukonDriverSupported (
45     IN EFI_DRIVER_BINDING_PROTOCOL    *This,
46     IN EFI_HANDLE                     Controller,
47     IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
48     )
49 {
50   EFI_STATUS              Status;
51   EFI_PCI_IO_PROTOCOL     *PciIo;
52 
53   //
54   // Test that the PCI IO Protocol is attached to the controller handle and no other driver is consuming it
55   //
56   Status = gBS->OpenProtocol (
57         Controller,
58         &gEfiPciIoProtocolGuid,
59         (VOID **) &PciIo,
60         This->DriverBindingHandle,
61         Controller,
62         EFI_OPEN_PROTOCOL_BY_DRIVER
63         );
64 
65   if (!EFI_ERROR (Status)) {
66     //
67     // Test whether the controller is on a supported NIC
68     //
69     Status = mskc_probe (PciIo);
70     if (EFI_ERROR (Status)) {
71       Status = EFI_UNSUPPORTED;
72     } else {
73       DEBUG ((EFI_D_NET, "Marvell Yukon: MarvellYukonDriverSupported: Supported Controller = %p\n", Controller));
74     }
75 
76     gBS->CloseProtocol (
77           Controller,
78           &gEfiPciIoProtocolGuid,
79           This->DriverBindingHandle,
80           Controller
81           );
82   }
83 
84   return Status;
85 }
86 
87 /**
88   Start this driver on Controller by opening PciIo and DevicePath protocols.
89   Initialize PXE structures, create a copy of the Controller Device Path with the
90   NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
91   on the newly created Device Path.
92 
93   @param [in] pThis                   Protocol instance pointer.
94   @param [in] Controller              Handle of device to work with.
95   @param [in] pRemainingDevicePath    Not used, always produce all possible children.
96 
97   @retval EFI_SUCCESS                 This driver is added to Controller.
98   @retval other                       This driver does not support this device.
99 
100 **/
101 EFI_STATUS
102 EFIAPI
MarvellYukonDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL * pThis,IN EFI_HANDLE Controller,IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath)103 MarvellYukonDriverStart (
104     IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
105     IN EFI_HANDLE Controller,
106     IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
107     )
108 {
109 
110   EFI_STATUS                       Status;
111   EFI_DEVICE_PATH_PROTOCOL         *ParentDevicePath;
112   MAC_ADDR_DEVICE_PATH             MacDeviceNode;
113   VOID                            *ChildPciIo;
114   YUKON_DRIVER                    *YukonDriver;
115   struct msk_softc                *ScData;
116   EFI_PCI_IO_PROTOCOL             *PciIo;
117   UINTN                            Port;
118 
119   Status = gBS->OpenProtocol (
120         Controller,
121         &gEfiPciIoProtocolGuid,
122         (VOID **) &PciIo,
123         pThis->DriverBindingHandle,
124         Controller,
125         EFI_OPEN_PROTOCOL_BY_DRIVER
126         );
127 
128   if (EFI_ERROR (Status)) {
129     DEBUG ((EFI_D_ERROR, "Marvell Yukon: OpenProtocol: EFI_PCI_IO_PROTOCOL ERROR Status = %r\n", Status));
130     gBS->FreePool (YukonDriver);
131     return Status;
132   }
133 
134   //
135   // Initialize Marvell Yukon controller
136   // Get number of ports and MAC address for each port
137   //
138   Status = mskc_attach (PciIo, &ScData);
139   if (EFI_ERROR (Status)) {
140     return Status;
141   }
142 
143   Status = MarvellYukonAddControllerData (Controller, ScData);
144   if (EFI_ERROR (Status)) {
145     return Status;
146   }
147 
148   for (Port = 0; Port < ScData->msk_num_port; Port++) {
149 
150     Status = gBS->AllocatePool (EfiBootServicesData,
151                                 sizeof (YUKON_DRIVER),
152                                 (VOID**) &YukonDriver);
153     if (EFI_ERROR (Status)) {
154       DEBUG ((DEBUG_ERROR, "Marvell Yukon: AllocatePool() failed with Status = %r\n", Status));
155       return Status;
156     }
157 
158     if (ScData->msk_if[Port] == NULL) {
159       DEBUG ((DEBUG_ERROR, "Marvell Yukon: AllocatePool() failed with Status = %r\n", EFI_BAD_BUFFER_SIZE));
160       return EFI_BAD_BUFFER_SIZE;
161     }
162 
163     gBS->SetMem (YukonDriver, sizeof (YUKON_DRIVER), 0);
164     EfiInitializeLock (&YukonDriver->Lock, TPL_NOTIFY);
165 
166     //
167     //  Set the structure signature
168     //
169     YukonDriver->Signature = YUKON_DRIVER_SIGNATURE;
170 
171     //
172     // Set MAC address
173     //
174     gBS->CopyMem (&YukonDriver->SnpMode.PermanentAddress, &(ScData->msk_if[Port])->MacAddress,
175                   sizeof (EFI_MAC_ADDRESS));
176 
177     //
178     // Set Port number
179     //
180     YukonDriver->Port = Port;
181 
182     //
183     //  Initialize the simple network protocol
184     //
185     Status = InitializeSNPProtocol (YukonDriver);
186 
187     if (EFI_ERROR (Status)) {
188       DEBUG ((DEBUG_ERROR, "Marvell Yukon: InitializeSNPProtocol: ERROR Status = %r\n", Status));
189       gBS->CloseProtocol (
190             Controller,
191             &gEfiPciIoProtocolGuid,
192             pThis->DriverBindingHandle,
193             Controller
194             );
195     }
196 
197     //
198     // Set Device Path
199     //
200     Status = gBS->OpenProtocol (
201           Controller,
202           &gEfiDevicePathProtocolGuid,
203           (VOID **) &ParentDevicePath,
204           pThis->DriverBindingHandle,
205           Controller,
206           EFI_OPEN_PROTOCOL_GET_PROTOCOL
207           );
208 
209     if (EFI_ERROR (Status)) {
210       DEBUG ((DEBUG_ERROR, "Marvell Yukon: OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n", Status));
211 
212       gBS->CloseProtocol (
213             Controller,
214             &gEfiPciIoProtocolGuid,
215             pThis->DriverBindingHandle,
216             Controller
217             );
218 
219       gBS->FreePool (YukonDriver);
220       return Status;
221     }
222 
223     gBS->SetMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH), 0);
224     MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
225     MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
226 
227     SetDevicePathNodeLength (&MacDeviceNode, sizeof (MacDeviceNode));
228 
229     //
230     // Assign fields for device path
231     //
232     gBS->CopyMem (&YukonDriver->SnpMode.CurrentAddress, &YukonDriver->SnpMode.PermanentAddress,
233                   sizeof (EFI_MAC_ADDRESS));
234     gBS->CopyMem (&MacDeviceNode.MacAddress, &YukonDriver->SnpMode.CurrentAddress, sizeof (EFI_MAC_ADDRESS));
235 
236     MacDeviceNode.IfType = YukonDriver->SnpMode.IfType;
237     YukonDriver->DevicePath = AppendDevicePathNode (ParentDevicePath, &MacDeviceNode.Header);
238     if (YukonDriver->DevicePath == NULL) {
239       DEBUG ((DEBUG_ERROR, "Marvell Yukon: AppendDevicePathNode: ERROR Status = %r\n", EFI_OUT_OF_RESOURCES));
240       gBS->CloseProtocol (
241             Controller,
242             &gEfiPciIoProtocolGuid,
243             pThis->DriverBindingHandle,
244             Controller
245             );
246       gBS->FreePool (YukonDriver);
247       return EFI_OUT_OF_RESOURCES;
248     }
249 
250     //
251     //  Install both the simple network and device path protocols.
252     //
253     Status = gBS->InstallMultipleProtocolInterfaces (
254           &YukonDriver->Controller,
255           &gEfiSimpleNetworkProtocolGuid,
256           &YukonDriver->Snp,
257           &gEfiDevicePathProtocolGuid,
258           YukonDriver->DevicePath,
259           NULL
260           );
261 
262     if (EFI_ERROR (Status)) {
263       DEBUG ((DEBUG_ERROR, "Marvell Yukon: InstallMultipleProtocolInterfaces error. Status = %r\n", Status));
264 
265       gBS->CloseProtocol (
266             Controller,
267             &gEfiPciIoProtocolGuid,
268             pThis->DriverBindingHandle,
269             Controller
270             );
271 
272       gBS->FreePool (YukonDriver->DevicePath);
273       gBS->FreePool (YukonDriver);
274       return Status;
275     } else {
276 
277       //
278       // Hook as a child device
279       //
280       Status = gBS->OpenProtocol (Controller,
281                                   &gEfiPciIoProtocolGuid,
282                                   &ChildPciIo,
283                                   pThis->DriverBindingHandle,
284                                   YukonDriver->Controller,
285                                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
286       if (EFI_ERROR (Status)) {
287         DEBUG ((DEBUG_ERROR, "Marvell Yukon: OpenProtocol: child controller error. Status = %r\n", Status));
288 
289         gBS->UninstallMultipleProtocolInterfaces (
290               Controller,
291               &gEfiSimpleNetworkProtocolGuid,
292               &YukonDriver->Snp,
293               &gEfiDevicePathProtocolGuid,
294               YukonDriver->DevicePath,
295               NULL
296               );
297 
298         gBS->CloseProtocol (
299               Controller,
300               &gEfiPciIoProtocolGuid,
301               pThis->DriverBindingHandle,
302               Controller
303               );
304 
305         gBS->FreePool (YukonDriver->DevicePath);
306         gBS->FreePool (YukonDriver);
307         return Status;
308       } else {
309         DEBUG ((DEBUG_NET, "Marvell Yukon: MarvellYukonDriverSupported: New Controller Handle = %p\n",
310                YukonDriver->Controller));
311       }
312 
313       Status = MarvellYukonAddControllerData (YukonDriver->Controller, ScData);
314       if (EFI_ERROR (Status)) {
315         DEBUG ((DEBUG_ERROR, "Marvell Yukon: Failed to register port %d with controller handle %p\n", Port,
316                YukonDriver->Controller));
317       }
318 
319     }
320 
321     if (!EFI_ERROR (Status)) {
322       Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
323                       &MarvellYukonNotifyExitBoot, YukonDriver, &YukonDriver->ExitBootEvent);
324     }
325   }
326 
327   return Status;
328 }
329 
330 /**
331   Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
332   closing the DevicePath and PciIo protocols on Controller.
333 
334   @param [in] pThis                   Protocol instance pointer.
335   @param [in] Controller              Handle of device to stop driver on.
336   @param [in] NumberOfChildren        How many children need to be stopped.
337   @param [in] pChildHandleBuffer      Not used.
338 
339   @retval EFI_SUCCESS                 This driver is removed Controller.
340   @retval EFI_DEVICE_ERROR            The device could not be stopped due to a device error.
341   @retval other                       This driver was not removed from this device.
342 
343 **/
344 EFI_STATUS
345 EFIAPI
MarvellYukonDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL * pThis,IN EFI_HANDLE Controller,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)346 MarvellYukonDriverStop (
347     IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
348     IN  EFI_HANDLE Controller,
349     IN  UINTN NumberOfChildren,
350     IN  EFI_HANDLE * ChildHandleBuffer
351     )
352 {
353   EFI_SIMPLE_NETWORK_PROTOCOL  *SimpleNetwork;
354   EFI_STATUS                   Status;
355   YUKON_DRIVER                 *YukonDriver;
356   EFI_TPL                      OldTpl;
357   UINTN                        ChildController;
358   struct msk_softc             *ScData;
359 
360   if (pThis == NULL) {
361     DEBUG ((EFI_D_ERROR, "Marvell Yukon: MarvellYukonDriverStop() failed with Status = %r\n", EFI_INVALID_PARAMETER));
362     return EFI_INVALID_PARAMETER;
363   }
364 
365   if (NumberOfChildren > 0 && ChildHandleBuffer == NULL) {
366     DEBUG ((EFI_D_ERROR, "Marvell Yukon: MarvellYukonDriverStop() failed with Status = %r\n", EFI_INVALID_PARAMETER));
367     return EFI_INVALID_PARAMETER;
368   }
369 
370   for (ChildController = 0; ChildController < NumberOfChildren; ChildController ++) {
371 
372     Status = gBS->OpenProtocol (
373           ChildHandleBuffer[ChildController],
374           &gEfiSimpleNetworkProtocolGuid,
375           (VOID **) &SimpleNetwork,
376           pThis->DriverBindingHandle,
377           Controller,
378           EFI_OPEN_PROTOCOL_GET_PROTOCOL
379           );
380 
381     if (!EFI_ERROR(Status)) {
382 
383       YukonDriver = YUKON_DEV_FROM_THIS_SNP (SimpleNetwork);
384 
385       Status = MarvellYukonGetControllerData (YukonDriver->Controller, &ScData);
386       if (EFI_ERROR (Status)) {
387         continue;
388       }
389 
390       OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
391 
392       ASSERT (YukonDriver->Controller == ChildHandleBuffer[ChildController]);
393       if (YukonDriver->SnpMode.State != EfiSimpleNetworkStopped) {
394 
395          //
396          // Device in use, cannot stop driver instance
397          //
398          Status = EFI_DEVICE_ERROR;
399          DEBUG ((DEBUG_ERROR,
400                 "Marvell Yukon: MarvellYukonDriverStop: Error: SNP is not stopped. Status %r\n", Status));
401        } else {
402 
403          //
404          // Unhook the child controller
405          //
406          Status = gBS->CloseProtocol (Controller,
407                              &gEfiPciIoProtocolGuid,
408                              pThis->DriverBindingHandle,
409                              YukonDriver->Controller);
410 
411          if (EFI_ERROR (Status)) {
412            DEBUG ((DEBUG_ERROR,
413                   "Marvell Yukon: MarvellYukonDriverStop:Close Child EfiPciIoProtocol error. Status %r\n", Status));
414          }
415 
416          Status = gBS->UninstallMultipleProtocolInterfaces (
417               YukonDriver->Controller,
418               &gEfiSimpleNetworkProtocolGuid,
419               &YukonDriver->Snp,
420               &gEfiDevicePathProtocolGuid,
421               YukonDriver->DevicePath,
422               NULL
423               );
424 
425          if (EFI_ERROR(Status)){
426            DEBUG ((DEBUG_ERROR,
427                   "Marvell Yukon: MarvellYukonDriverStop:UninstallMultipleProtocolInterfaces error. Status %r\n",
428                   Status));
429          }
430 
431          MarvellYukonDelControllerData (YukonDriver->Controller);
432 
433          gBS->CloseEvent (YukonDriver->ExitBootEvent);
434          gBS->FreePool (YukonDriver->DevicePath);
435          gBS->FreePool (YukonDriver);
436        }
437        gBS->RestoreTPL (OldTpl);
438     }
439   }
440 
441   Status = gBS->CloseProtocol (
442         Controller,
443         &gEfiPciIoProtocolGuid,
444         pThis->DriverBindingHandle,
445         Controller
446         );
447 
448   if (EFI_ERROR (Status)) {
449     DEBUG ((DEBUG_ERROR, "Marvell Yukon: MarvellYukonDriverStop:Close EfiPciIoProtocol error. Status %r\n", Status));
450   }
451 
452   Status = MarvellYukonGetControllerData (Controller, &ScData);
453   if (EFI_ERROR (Status)) {
454     return Status;
455   }
456 
457   mskc_detach (ScData);
458   gBS->FreePool (ScData);
459   Status = MarvellYukonDelControllerData (Controller);
460 
461   return Status;
462 }
463 
464 /**
465   Process exit boot event.
466 
467   @param [in] Event                   Event id.
468   @param [in] Context                 Driver context.
469 
470 **/
471 VOID
472 EFIAPI
MarvellYukonNotifyExitBoot(IN EFI_EVENT Event,IN VOID * Context)473 MarvellYukonNotifyExitBoot (
474   IN EFI_EVENT Event,
475   IN VOID *Context
476   )
477 {
478   YUKON_DRIVER    *YukonDriver;
479   EFI_STATUS      Status;
480 
481   if (Context == NULL) {
482     DEBUG ((DEBUG_ERROR,
483            "Marvell Yukon: MarvellYukonNotifyExitBoot() failed with Status = %r\n", EFI_INVALID_PARAMETER));
484   } else {
485 
486     YukonDriver = Context;
487 
488     if (YukonDriver->SnpMode.State != EfiSimpleNetworkStopped) {
489       Status  = YukonDriver->Snp.Shutdown(&YukonDriver->Snp);
490       if (!EFI_ERROR (Status)) {
491         YukonDriver->Snp.Stop(&YukonDriver->Snp);
492       }
493     }
494   }
495 }
496 
497 /**
498   Get driver's data structure associated with controller
499 
500   @param [in] Controller           Controller Id.
501   @param [out] Data                Driver's data.
502 
503 **/
504 EFI_STATUS
505 EFIAPI
MarvellYukonGetControllerData(IN EFI_HANDLE Controller,OUT struct msk_softc ** Data)506 MarvellYukonGetControllerData (
507   IN EFI_HANDLE Controller,
508   OUT struct msk_softc **Data
509   )
510 {
511   MSK_LINKED_DRV_BUF *DrvNode;
512   EFI_STATUS         Status;
513 
514   Status = MarvellYukonFindControllerNode (Controller, &DrvNode);
515   if (!EFI_ERROR (Status)) {
516     *Data = DrvNode->Data;
517   }
518   return Status;
519 }
520 
521 /**
522   Add driver's data structure associated with controller
523 
524   @param [in] Controller           Controller Id.
525   @param [in] Data                 Driver's data.
526 
527 **/
528 EFI_STATUS
529 EFIAPI
MarvellYukonAddControllerData(IN EFI_HANDLE Controller,IN struct msk_softc * Data)530 MarvellYukonAddControllerData (
531   IN EFI_HANDLE Controller,
532   IN struct msk_softc *Data
533   )
534 {
535   MSK_LINKED_DRV_BUF *DrvNode;
536   EFI_STATUS         Status;
537 
538   Status = MarvellYukonFindControllerNode (Controller, &DrvNode);
539   if (EFI_ERROR (Status)) {
540     Status = gBS->AllocatePool (EfiBootServicesData,
541                                 sizeof (MSK_LINKED_DRV_BUF),
542                                 (VOID**) &DrvNode);
543     if (!EFI_ERROR (Status)) {
544       DrvNode->Signature = MSK_DRV_SIGNATURE;
545       DrvNode->Controller = Controller;
546       DrvNode->Data = Data;
547       InsertTailList (&MarvellYukonDrvDataHead, &DrvNode->Link);
548     }
549   } else {
550     Status = EFI_ALREADY_STARTED;
551   }
552 
553   return Status;
554 }
555 
556 /**
557   Delete driver's data structure associated with controller
558 
559   @param [in] Controller           Controller Id.
560 
561 **/
562 EFI_STATUS
563 EFIAPI
MarvellYukonDelControllerData(IN EFI_HANDLE Controller)564 MarvellYukonDelControllerData (
565   IN EFI_HANDLE Controller
566   )
567 {
568   MSK_LINKED_DRV_BUF *DrvNode;
569   EFI_STATUS         Status;
570 
571   Status = MarvellYukonFindControllerNode (Controller, &DrvNode);
572   if (!EFI_ERROR (Status)) {
573     RemoveEntryList (&DrvNode->Link);
574     gBS->FreePool (DrvNode);
575   }
576 
577   return Status;
578 }
579 
580 /**
581   Find node associated with controller
582 
583   @param [in] Controller           Controller Id.
584   @param [out] DrvLinkedBuff       Controller's node.
585 
586 **/
587 EFI_STATUS
588 EFIAPI
MarvellYukonFindControllerNode(IN EFI_HANDLE Controller,OUT MSK_LINKED_DRV_BUF ** DrvLinkedBuff)589 MarvellYukonFindControllerNode (
590   IN EFI_HANDLE Controller,
591   OUT MSK_LINKED_DRV_BUF **DrvLinkedBuff
592   )
593 {
594   MSK_LINKED_DRV_BUF *DrvBuffNode;
595   EFI_STATUS         Status;
596   LIST_ENTRY         *Node;
597 
598   Status = EFI_NOT_FOUND;
599 
600   Node = GetFirstNode (&MarvellYukonDrvDataHead);
601   while (!IsNull (&MarvellYukonDrvDataHead, Node)) {
602     DrvBuffNode = MSK_DRV_INFO_FROM_THIS (Node);
603     if (DrvBuffNode->Controller == Controller) {
604       *DrvLinkedBuff = DrvBuffNode;
605       Status = EFI_SUCCESS;
606       break;
607     }
608     Node = GetNextNode (&MarvellYukonDrvDataHead, Node);
609   }
610 
611   return Status;
612 }
613 
614 //
615 // Simple Network Protocol Driver Global Variables
616 //
617 EFI_DRIVER_BINDING_PROTOCOL gMarvellYukonDriverBinding = {
618   MarvellYukonDriverSupported,
619   MarvellYukonDriverStart,
620   MarvellYukonDriverStop,
621   0xa,
622   NULL,
623   NULL
624 };
625 
626 /**
627   The Marvell Yukon driver entry point.
628 
629    <at> param ImageHandle             The driver image handle.
630    <at> param SystemTable             The system table.
631 
632    <at> retval EFI_SUCCESS            Initialization routine has found and initialized
633                                       hardware successfully.
634    <at> retval Other                  Return value from HandleProtocol for
635                                       DeviceIoProtocol or LoadedImageProtocol
636 
637 **/
638 EFI_STATUS
639 EFIAPI
InitializeMarvellYukonDriver(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)640 InitializeMarvellYukonDriver (
641     IN EFI_HANDLE       ImageHandle,
642     IN EFI_SYSTEM_TABLE *SystemTable
643     )
644 {
645   EFI_STATUS                           Status;
646 
647   DEBUG ((EFI_D_NET, "Marvell Yukon: InitializeMarvellYukonDriver()\n"));
648 
649   if (SystemTable == NULL) {
650     DEBUG ((DEBUG_ERROR,
651            "Marvell Yukon: InitializeMarvellYukonDriver() failed with Status = %r\n", EFI_INVALID_PARAMETER));
652     return EFI_INVALID_PARAMETER;
653   }
654 
655   Status = EfiLibInstallDriverBindingComponentName2 (
656         ImageHandle,
657         SystemTable,
658         &gMarvellYukonDriverBinding,
659         NULL,
660         &gSimpleNetworkComponentName,
661         &gSimpleNetworkComponentName2
662         );
663 
664   if (EFI_ERROR (Status)) {
665     DEBUG ((EFI_D_ERROR, "Marvell Yukon: InitializeMarvellYukonDriver(): Driver binding failed\n"));
666     return Status;
667   }
668 
669   InitializeListHead (&MarvellYukonDrvDataHead);
670 
671   return Status;
672 }
673