2 Implement the driver binding protocol for Asix AX88772 Ethernet driver.
4 Copyright (c) 2011-2013, Intel Corporation
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.
17 ASIX_DONGLE ASIX_DONGLES
[] = {
18 { 0x05AC, 0x1402, FLAG_TYPE_AX88772
}, // Apple USB Ethernet Adapter
20 { 0x0B95, 0x772B, FLAG_TYPE_AX88772B
| FLAG_EEPROM_MAC
},
21 { 0x0000, 0x0000, FLAG_NONE
} // END - Do not remove
25 Verify the controller type
27 @param [in] pThis Protocol instance pointer.
28 @param [in] Controller Handle of device to test.
29 @param [in] pRemainingDevicePath Not used.
31 @retval EFI_SUCCESS This driver supports this device.
32 @retval other This driver does not support this device.
38 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
39 IN EFI_HANDLE Controller
,
40 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
43 EFI_USB_DEVICE_DESCRIPTOR Device
;
44 EFI_USB_IO_PROTOCOL
* pUsbIo
;
49 // Connect to the USB stack
51 Status
= gBS
->OpenProtocol (
53 &gEfiUsbIoProtocolGuid
,
55 pThis
->DriverBindingHandle
,
57 EFI_OPEN_PROTOCOL_BY_DRIVER
59 if (!EFI_ERROR ( Status
)) {
62 // Get the interface descriptor to check the USB class and find a transport
65 Status
= pUsbIo
->UsbGetDeviceDescriptor ( pUsbIo
, &Device
);
66 if (EFI_ERROR ( Status
)) {
67 Status
= EFI_UNSUPPORTED
;
71 // Validate the adapter
73 for (Index
= 0; ASIX_DONGLES
[Index
].VendorId
!= 0; Index
++) {
74 if (ASIX_DONGLES
[Index
].VendorId
== Device
.IdVendor
&&
75 ASIX_DONGLES
[Index
].ProductId
== Device
.IdProduct
) {
76 DEBUG ((EFI_D_INFO
, "Found the AX88772B\r\n"));
81 if (ASIX_DONGLES
[Index
].VendorId
== 0)
82 Status
= EFI_UNSUPPORTED
;
86 // Done with the USB stack
90 &gEfiUsbIoProtocolGuid
,
91 pThis
->DriverBindingHandle
,
100 Start this driver on Controller by opening UsbIo and DevicePath protocols.
101 Initialize PXE structures, create a copy of the Controller Device Path with the
102 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
103 on the newly created Device Path.
105 @param [in] pThis Protocol instance pointer.
106 @param [in] Controller Handle of device to work with.
107 @param [in] pRemainingDevicePath Not used, always produce all possible children.
109 @retval EFI_SUCCESS This driver is added to Controller.
110 @retval other This driver does not support this device.
116 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
117 IN EFI_HANDLE Controller
,
118 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
123 NIC_DEVICE
*pNicDevice
;
125 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
= NULL
;
126 MAC_ADDR_DEVICE_PATH MacDeviceNode
;
127 EFI_USB_DEVICE_DESCRIPTOR Device
;
131 // Allocate the device structure
133 LengthInBytes
= sizeof ( *pNicDevice
);
134 Status
= gBS
->AllocatePool (
135 EfiRuntimeServicesData
,
137 (VOID
**) &pNicDevice
140 if (EFI_ERROR (Status
)) {
141 DEBUG ((EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status
));
146 // Set the structure signature
148 ZeroMem ( pNicDevice
, LengthInBytes
);
149 pNicDevice
->Signature
= DEV_SIGNATURE
;
151 Status
= gBS
->OpenProtocol (
153 &gEfiUsbIoProtocolGuid
,
154 (VOID
**) &pNicDevice
->pUsbIo
,
155 pThis
->DriverBindingHandle
,
157 EFI_OPEN_PROTOCOL_BY_DRIVER
160 if (EFI_ERROR (Status
)) {
161 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status
));
162 gBS
->FreePool ( pNicDevice
);
167 // Initialize the simple network protocol
169 Status
= SN_Setup ( pNicDevice
);
171 if (EFI_ERROR(Status
)){
172 DEBUG ((EFI_D_ERROR
, "SN_Setup ERROR Status = %r\n", Status
));
175 &gEfiUsbIoProtocolGuid
,
176 pThis
->DriverBindingHandle
,
179 gBS
->FreePool ( pNicDevice
);
183 Status
= pNicDevice
->pUsbIo
->UsbGetDeviceDescriptor ( pNicDevice
->pUsbIo
, &Device
);
184 if (EFI_ERROR ( Status
)) {
187 &gEfiUsbIoProtocolGuid
,
188 pThis
->DriverBindingHandle
,
191 gBS
->FreePool ( pNicDevice
);
195 // Validate the adapter
197 for (Index
= 0; ASIX_DONGLES
[Index
].VendorId
!= 0; Index
++) {
198 if (ASIX_DONGLES
[Index
].VendorId
== Device
.IdVendor
&&
199 ASIX_DONGLES
[Index
].ProductId
== Device
.IdProduct
) {
204 if (ASIX_DONGLES
[Index
].VendorId
== 0) {
207 &gEfiUsbIoProtocolGuid
,
208 pThis
->DriverBindingHandle
,
211 gBS
->FreePool ( pNicDevice
);
215 pNicDevice
->Flags
= ASIX_DONGLES
[Index
].Flags
;
221 Status
= gBS
->OpenProtocol (
223 &gEfiDevicePathProtocolGuid
,
224 (VOID
**) &ParentDevicePath
,
225 pThis
->DriverBindingHandle
,
227 EFI_OPEN_PROTOCOL_BY_DRIVER
229 if (EFI_ERROR(Status
)) {
230 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
234 &gEfiUsbIoProtocolGuid
,
235 pThis
->DriverBindingHandle
,
238 gBS
->FreePool ( pNicDevice
);
242 ZeroMem (&MacDeviceNode
, sizeof (MAC_ADDR_DEVICE_PATH
));
243 MacDeviceNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
244 MacDeviceNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
246 SetDevicePathNodeLength (&MacDeviceNode
.Header
, sizeof (MAC_ADDR_DEVICE_PATH
));
248 CopyMem (&MacDeviceNode
.MacAddress
,
249 &pNicDevice
->SimpleNetworkData
.CurrentAddress
,
250 PXE_HWADDR_LEN_ETHER
);
252 MacDeviceNode
.IfType
= pNicDevice
->SimpleNetworkData
.IfType
;
254 pNicDevice
->MyDevPath
= AppendDevicePathNode (
256 (EFI_DEVICE_PATH_PROTOCOL
*) &MacDeviceNode
259 pNicDevice
->Controller
= NULL
;
262 // Install both the simple network and device path protocols.
264 Status
= gBS
->InstallMultipleProtocolInterfaces (
265 &pNicDevice
->Controller
,
268 &gEfiSimpleNetworkProtocolGuid
,
269 &pNicDevice
->SimpleNetwork
,
270 &gEfiDevicePathProtocolGuid
,
271 pNicDevice
->MyDevPath
,
275 if (EFI_ERROR(Status
)){
276 DEBUG ((EFI_D_ERROR
, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
280 &gEfiDevicePathProtocolGuid
,
281 pThis
->DriverBindingHandle
,
285 &gEfiUsbIoProtocolGuid
,
286 pThis
->DriverBindingHandle
,
289 gBS
->FreePool ( pNicDevice
);
294 // Open For Child Device
296 Status
= gBS
->OpenProtocol (
298 &gEfiUsbIoProtocolGuid
,
299 (VOID
**) &pNicDevice
->pUsbIo
,
300 pThis
->DriverBindingHandle
,
301 pNicDevice
->Controller
,
302 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
305 if (EFI_ERROR(Status
)){
306 gBS
->UninstallMultipleProtocolInterfaces (
307 &pNicDevice
->Controller
,
310 &gEfiSimpleNetworkProtocolGuid
,
311 &pNicDevice
->SimpleNetwork
,
312 &gEfiDevicePathProtocolGuid
,
313 pNicDevice
->MyDevPath
,
318 &gEfiDevicePathProtocolGuid
,
319 pThis
->DriverBindingHandle
,
323 &gEfiUsbIoProtocolGuid
,
324 pThis
->DriverBindingHandle
,
327 gBS
->FreePool ( pNicDevice
);
336 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
337 closing the DevicePath and PciIo protocols on Controller.
339 @param [in] pThis Protocol instance pointer.
340 @param [in] Controller Handle of device to stop driver on.
341 @param [in] NumberOfChildren How many children need to be stopped.
342 @param [in] pChildHandleBuffer Not used.
344 @retval EFI_SUCCESS This driver is removed Controller.
345 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
346 @retval other This driver was not removed from this device.
352 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
353 IN EFI_HANDLE Controller
,
354 IN UINTN NumberOfChildren
,
355 IN EFI_HANDLE
* ChildHandleBuffer
358 BOOLEAN AllChildrenStopped
;
360 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetwork
;
361 EFI_STATUS Status
= EFI_SUCCESS
;
362 NIC_DEVICE
*pNicDevice
;
365 // Complete all outstanding transactions to Controller.
366 // Don't allow any new transaction to Controller to be started.
368 if (NumberOfChildren
== 0) {
370 Status
= gBS
->OpenProtocol (
372 &gEfiSimpleNetworkProtocolGuid
,
373 (VOID
**) &SimpleNetwork
,
374 pThis
->DriverBindingHandle
,
376 EFI_OPEN_PROTOCOL_GET_PROTOCOL
379 if (EFI_ERROR(Status
)) {
381 // This is a 2nd type handle(multi-lun root), it needs to close devicepath
382 // and usbio protocol.
386 &gEfiDevicePathProtocolGuid
,
387 pThis
->DriverBindingHandle
,
392 &gEfiUsbIoProtocolGuid
,
393 pThis
->DriverBindingHandle
,
399 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
401 Status
= gBS
->UninstallMultipleProtocolInterfaces (
405 &gEfiSimpleNetworkProtocolGuid
,
406 &pNicDevice
->SimpleNetwork
,
407 &gEfiDevicePathProtocolGuid
,
408 pNicDevice
->MyDevPath
,
412 if (EFI_ERROR (Status
)) {
416 // Close the bus driver
418 Status
= gBS
->CloseProtocol (
420 &gEfiDevicePathProtocolGuid
,
421 pThis
->DriverBindingHandle
,
425 if (EFI_ERROR(Status
)){
426 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status
));
429 Status
= gBS
->CloseProtocol (
431 &gEfiUsbIoProtocolGuid
,
432 pThis
->DriverBindingHandle
,
436 if (EFI_ERROR(Status
)){
437 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status
));
441 AllChildrenStopped
= TRUE
;
443 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
445 Status
= gBS
->OpenProtocol (
446 ChildHandleBuffer
[Index
],
447 &gEfiSimpleNetworkProtocolGuid
,
448 (VOID
**) &SimpleNetwork
,
449 pThis
->DriverBindingHandle
,
451 EFI_OPEN_PROTOCOL_GET_PROTOCOL
454 if (EFI_ERROR (Status
)) {
455 AllChildrenStopped
= FALSE
;
456 DEBUG ((EFI_D_ERROR
, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32
)Index
));
460 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
464 &gEfiUsbIoProtocolGuid
,
465 pThis
->DriverBindingHandle
,
466 ChildHandleBuffer
[Index
]
469 Status
= gBS
->UninstallMultipleProtocolInterfaces (
470 ChildHandleBuffer
[Index
],
473 &gEfiSimpleNetworkProtocolGuid
,
474 &pNicDevice
->SimpleNetwork
,
475 &gEfiDevicePathProtocolGuid
,
476 pNicDevice
->MyDevPath
,
480 if (EFI_ERROR (Status
)) {
481 Status
= gBS
->OpenProtocol (
483 &gEfiUsbIoProtocolGuid
,
484 (VOID
**) &pNicDevice
->pUsbIo
,
485 pThis
->DriverBindingHandle
,
486 ChildHandleBuffer
[Index
],
487 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
492 RX_PKT
* pCurr
= pNicDevice
->QueueHead
;
495 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
496 if ( NULL
!= pCurr
) {
498 pCurr
= pCurr
->pNext
;
499 gBS
->FreePool (pFree
);
503 if ( NULL
!= pNicDevice
->pRxTest
)
504 gBS
->FreePool (pNicDevice
->pRxTest
);
506 if ( NULL
!= pNicDevice
->pTxTest
)
507 gBS
->FreePool (pNicDevice
->pTxTest
);
509 if ( NULL
!= pNicDevice
->MyDevPath
)
510 gBS
->FreePool (pNicDevice
->MyDevPath
);
512 if ( NULL
!= pNicDevice
)
513 gBS
->FreePool (pNicDevice
);
517 if (!AllChildrenStopped
) {
518 return EFI_DEVICE_ERROR
;
525 Driver binding protocol declaration
527 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
538 Ax88772 driver unload routine.
540 @param [in] ImageHandle Handle for the image.
542 @retval EFI_SUCCESS Image may be unloaded
548 IN EFI_HANDLE ImageHandle
554 EFI_HANDLE
* pHandle
;
558 // Determine which devices are using this driver
562 Status
= gBS
->LocateHandle (
568 if ( EFI_BUFFER_TOO_SMALL
== Status
) {
571 // One or more block IO devices are present
573 Status
= gBS
->AllocatePool (
574 EfiRuntimeServicesData
,
578 if ( EFI_ERROR ( Status
)) {
579 DEBUG ((EFI_D_ERROR
, "Insufficient memory, failed handle buffer allocation\r\n"));
584 // Locate the block IO devices
586 Status
= gBS
->LocateHandle (
592 if ( EFI_ERROR ( Status
)) {
594 // Error getting handles
600 // Remove any use of the driver
602 Max
= BufferSize
/ sizeof ( pHandle
[ 0 ]);
603 for ( Index
= 0; Max
> Index
; Index
++ ) {
604 Status
= DriverStop ( &gDriverBinding
,
608 if ( EFI_ERROR ( Status
)) {
609 DEBUG ((EFI_D_ERROR
, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle
[ Index
]));
617 if ( EFI_NOT_FOUND
== Status
) {
619 // No devices were found
621 Status
= EFI_SUCCESS
;
626 // Free the handle array
628 if ( NULL
!= pHandle
) {
629 gBS
->FreePool ( pHandle
);
633 // Remove the protocols installed by the EntryPoint routine.
635 if ( !EFI_ERROR ( Status
)) {
636 gBS
->UninstallMultipleProtocolInterfaces (
638 &gEfiDriverBindingProtocolGuid
,
640 &gEfiComponentNameProtocolGuid
,
642 &gEfiComponentName2ProtocolGuid
,
647 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
648 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
650 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
651 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
653 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
654 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
664 Ax88772 driver entry point.
666 @param [in] ImageHandle Handle for the image.
667 @param [in] pSystemTable Address of the system table.
669 @retval EFI_SUCCESS Image successfully loaded.
675 IN EFI_HANDLE ImageHandle
,
676 IN EFI_SYSTEM_TABLE
* pSystemTable
682 // Add the driver to the list of drivers
684 Status
= EfiLibInstallDriverBindingComponentName2 (
692 if ( !EFI_ERROR ( Status
)) {
693 DEBUG ((EFI_D_INFO
, "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
695 DEBUG ((EFI_D_INFO
, "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
697 DEBUG ((EFI_D_INFO
,"Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",