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
;
129 // Allocate the device structure
131 LengthInBytes
= sizeof ( *pNicDevice
);
132 Status
= gBS
->AllocatePool (
133 EfiRuntimeServicesData
,
135 (VOID
**) &pNicDevice
138 if (EFI_ERROR (Status
)) {
139 DEBUG ((EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status
));
144 // Set the structure signature
146 ZeroMem ( pNicDevice
, LengthInBytes
);
147 pNicDevice
->Signature
= DEV_SIGNATURE
;
149 Status
= gBS
->OpenProtocol (
151 &gEfiUsbIoProtocolGuid
,
152 (VOID
**) &pNicDevice
->pUsbIo
,
153 pThis
->DriverBindingHandle
,
155 EFI_OPEN_PROTOCOL_BY_DRIVER
158 if (EFI_ERROR (Status
)) {
159 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status
));
160 gBS
->FreePool ( pNicDevice
);
165 // Initialize the simple network protocol
167 Status
= SN_Setup ( pNicDevice
);
169 if (EFI_ERROR(Status
)){
170 DEBUG ((EFI_D_ERROR
, "SN_Setup ERROR Status = %r\n", Status
));
173 &gEfiUsbIoProtocolGuid
,
174 pThis
->DriverBindingHandle
,
177 gBS
->FreePool ( pNicDevice
);
184 Status
= gBS
->OpenProtocol (
186 &gEfiDevicePathProtocolGuid
,
187 (VOID
**) &ParentDevicePath
,
188 pThis
->DriverBindingHandle
,
190 EFI_OPEN_PROTOCOL_BY_DRIVER
192 if (EFI_ERROR(Status
)) {
193 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
197 &gEfiUsbIoProtocolGuid
,
198 pThis
->DriverBindingHandle
,
201 gBS
->FreePool ( pNicDevice
);
205 ZeroMem (&MacDeviceNode
, sizeof (MAC_ADDR_DEVICE_PATH
));
206 MacDeviceNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
207 MacDeviceNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
209 SetDevicePathNodeLength (&MacDeviceNode
.Header
, sizeof (MAC_ADDR_DEVICE_PATH
));
211 CopyMem (&MacDeviceNode
.MacAddress
,
212 &pNicDevice
->SimpleNetworkData
.CurrentAddress
,
213 PXE_HWADDR_LEN_ETHER
);
215 MacDeviceNode
.IfType
= pNicDevice
->SimpleNetworkData
.IfType
;
217 pNicDevice
->MyDevPath
= AppendDevicePathNode (
219 (EFI_DEVICE_PATH_PROTOCOL
*) &MacDeviceNode
222 pNicDevice
->Controller
= NULL
;
225 // Install both the simple network and device path protocols.
227 Status
= gBS
->InstallMultipleProtocolInterfaces (
228 &pNicDevice
->Controller
,
231 &gEfiSimpleNetworkProtocolGuid
,
232 &pNicDevice
->SimpleNetwork
,
233 &gEfiDevicePathProtocolGuid
,
234 pNicDevice
->MyDevPath
,
238 if (EFI_ERROR(Status
)){
239 DEBUG ((EFI_D_ERROR
, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
243 &gEfiDevicePathProtocolGuid
,
244 pThis
->DriverBindingHandle
,
248 &gEfiUsbIoProtocolGuid
,
249 pThis
->DriverBindingHandle
,
252 gBS
->FreePool ( pNicDevice
);
257 // Open For Child Device
259 Status
= gBS
->OpenProtocol (
261 &gEfiUsbIoProtocolGuid
,
262 (VOID
**) &pNicDevice
->pUsbIo
,
263 pThis
->DriverBindingHandle
,
264 pNicDevice
->Controller
,
265 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
268 if (EFI_ERROR(Status
)){
269 gBS
->UninstallMultipleProtocolInterfaces (
270 &pNicDevice
->Controller
,
273 &gEfiSimpleNetworkProtocolGuid
,
274 &pNicDevice
->SimpleNetwork
,
275 &gEfiDevicePathProtocolGuid
,
276 pNicDevice
->MyDevPath
,
281 &gEfiDevicePathProtocolGuid
,
282 pThis
->DriverBindingHandle
,
286 &gEfiUsbIoProtocolGuid
,
287 pThis
->DriverBindingHandle
,
290 gBS
->FreePool ( pNicDevice
);
299 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
300 closing the DevicePath and PciIo protocols on Controller.
302 @param [in] pThis Protocol instance pointer.
303 @param [in] Controller Handle of device to stop driver on.
304 @param [in] NumberOfChildren How many children need to be stopped.
305 @param [in] pChildHandleBuffer Not used.
307 @retval EFI_SUCCESS This driver is removed Controller.
308 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
309 @retval other This driver was not removed from this device.
315 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
316 IN EFI_HANDLE Controller
,
317 IN UINTN NumberOfChildren
,
318 IN EFI_HANDLE
* ChildHandleBuffer
321 BOOLEAN AllChildrenStopped
;
323 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetwork
;
324 EFI_STATUS Status
= EFI_SUCCESS
;
325 NIC_DEVICE
*pNicDevice
;
328 // Complete all outstanding transactions to Controller.
329 // Don't allow any new transaction to Controller to be started.
331 if (NumberOfChildren
== 0) {
333 Status
= gBS
->OpenProtocol (
335 &gEfiSimpleNetworkProtocolGuid
,
336 (VOID
**) &SimpleNetwork
,
337 pThis
->DriverBindingHandle
,
339 EFI_OPEN_PROTOCOL_GET_PROTOCOL
342 if (EFI_ERROR(Status
)) {
344 // This is a 2nd type handle(multi-lun root), it needs to close devicepath
345 // and usbio protocol.
349 &gEfiDevicePathProtocolGuid
,
350 pThis
->DriverBindingHandle
,
355 &gEfiUsbIoProtocolGuid
,
356 pThis
->DriverBindingHandle
,
362 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
364 Status
= gBS
->UninstallMultipleProtocolInterfaces (
368 &gEfiSimpleNetworkProtocolGuid
,
369 &pNicDevice
->SimpleNetwork
,
370 &gEfiDevicePathProtocolGuid
,
371 pNicDevice
->MyDevPath
,
375 if (EFI_ERROR (Status
)) {
379 // Close the bus driver
381 Status
= gBS
->CloseProtocol (
383 &gEfiDevicePathProtocolGuid
,
384 pThis
->DriverBindingHandle
,
388 if (EFI_ERROR(Status
)){
389 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status
));
392 Status
= gBS
->CloseProtocol (
394 &gEfiUsbIoProtocolGuid
,
395 pThis
->DriverBindingHandle
,
399 if (EFI_ERROR(Status
)){
400 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status
));
404 AllChildrenStopped
= TRUE
;
406 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
408 Status
= gBS
->OpenProtocol (
409 ChildHandleBuffer
[Index
],
410 &gEfiSimpleNetworkProtocolGuid
,
411 (VOID
**) &SimpleNetwork
,
412 pThis
->DriverBindingHandle
,
414 EFI_OPEN_PROTOCOL_GET_PROTOCOL
417 if (EFI_ERROR (Status
)) {
418 AllChildrenStopped
= FALSE
;
419 DEBUG ((EFI_D_ERROR
, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32
)Index
));
423 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
427 &gEfiUsbIoProtocolGuid
,
428 pThis
->DriverBindingHandle
,
429 ChildHandleBuffer
[Index
]
432 Status
= gBS
->UninstallMultipleProtocolInterfaces (
433 ChildHandleBuffer
[Index
],
436 &gEfiSimpleNetworkProtocolGuid
,
437 &pNicDevice
->SimpleNetwork
,
438 &gEfiDevicePathProtocolGuid
,
439 pNicDevice
->MyDevPath
,
443 if (EFI_ERROR (Status
)) {
444 Status
= gBS
->OpenProtocol (
446 &gEfiUsbIoProtocolGuid
,
447 (VOID
**) &pNicDevice
->pUsbIo
,
448 pThis
->DriverBindingHandle
,
449 ChildHandleBuffer
[Index
],
450 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
455 RX_PKT
* pCurr
= pNicDevice
->QueueHead
;
458 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
459 if ( NULL
!= pCurr
) {
461 pCurr
= pCurr
->pNext
;
462 gBS
->FreePool (pFree
);
466 if ( NULL
!= pNicDevice
->pRxTest
)
467 gBS
->FreePool (pNicDevice
->pRxTest
);
469 if ( NULL
!= pNicDevice
->pTxTest
)
470 gBS
->FreePool (pNicDevice
->pTxTest
);
472 if ( NULL
!= pNicDevice
->MyDevPath
)
473 gBS
->FreePool (pNicDevice
->MyDevPath
);
475 if ( NULL
!= pNicDevice
)
476 gBS
->FreePool (pNicDevice
);
480 if (!AllChildrenStopped
) {
481 return EFI_DEVICE_ERROR
;
488 Driver binding protocol declaration
490 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
501 Ax88772 driver unload routine.
503 @param [in] ImageHandle Handle for the image.
505 @retval EFI_SUCCESS Image may be unloaded
511 IN EFI_HANDLE ImageHandle
517 EFI_HANDLE
* pHandle
;
521 // Determine which devices are using this driver
525 Status
= gBS
->LocateHandle (
531 if ( EFI_BUFFER_TOO_SMALL
== Status
) {
534 // One or more block IO devices are present
536 Status
= gBS
->AllocatePool (
537 EfiRuntimeServicesData
,
541 if ( EFI_ERROR ( Status
)) {
542 DEBUG ((EFI_D_ERROR
, "Insufficient memory, failed handle buffer allocation\r\n"));
547 // Locate the block IO devices
549 Status
= gBS
->LocateHandle (
555 if ( EFI_ERROR ( Status
)) {
557 // Error getting handles
563 // Remove any use of the driver
565 Max
= BufferSize
/ sizeof ( pHandle
[ 0 ]);
566 for ( Index
= 0; Max
> Index
; Index
++ ) {
567 Status
= DriverStop ( &gDriverBinding
,
571 if ( EFI_ERROR ( Status
)) {
572 DEBUG ((EFI_D_ERROR
, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle
[ Index
]));
580 if ( EFI_NOT_FOUND
== Status
) {
582 // No devices were found
584 Status
= EFI_SUCCESS
;
589 // Free the handle array
591 if ( NULL
!= pHandle
) {
592 gBS
->FreePool ( pHandle
);
596 // Remove the protocols installed by the EntryPoint routine.
598 if ( !EFI_ERROR ( Status
)) {
599 gBS
->UninstallMultipleProtocolInterfaces (
601 &gEfiDriverBindingProtocolGuid
,
603 &gEfiComponentNameProtocolGuid
,
605 &gEfiComponentName2ProtocolGuid
,
610 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
611 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
613 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
614 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
616 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
617 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
627 Ax88772 driver entry point.
629 @param [in] ImageHandle Handle for the image.
630 @param [in] pSystemTable Address of the system table.
632 @retval EFI_SUCCESS Image successfully loaded.
638 IN EFI_HANDLE ImageHandle
,
639 IN EFI_SYSTEM_TABLE
* pSystemTable
645 // Add the driver to the list of drivers
647 Status
= EfiLibInstallDriverBindingComponentName2 (
655 if ( !EFI_ERROR ( Status
)) {
656 DEBUG ((EFI_D_INFO
, "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
658 DEBUG ((EFI_D_INFO
, "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
660 DEBUG ((EFI_D_INFO
,"Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",