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