2 Implement the driver binding protocol for Asix AX88772 Ethernet driver.
4 Copyright (c) 2011-2013, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 ASIX_DONGLE ASIX_DONGLES
[] = {
12 { 0x05AC, 0x1402, FLAG_TYPE_AX88772
}, // Apple USB Ethernet Adapter
14 { 0x0B95, 0x772B, FLAG_TYPE_AX88772B
| FLAG_EEPROM_MAC
},
15 { 0x0000, 0x0000, FLAG_NONE
} // END - Do not remove
19 Verify the controller type
21 @param [in] pThis Protocol instance pointer.
22 @param [in] Controller Handle of device to test.
23 @param [in] pRemainingDevicePath Not used.
25 @retval EFI_SUCCESS This driver supports this device.
26 @retval other This driver does not support this device.
32 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
33 IN EFI_HANDLE Controller
,
34 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
37 EFI_USB_DEVICE_DESCRIPTOR Device
;
38 EFI_USB_IO_PROTOCOL
* pUsbIo
;
43 // Connect to the USB stack
45 Status
= gBS
->OpenProtocol (
47 &gEfiUsbIoProtocolGuid
,
49 pThis
->DriverBindingHandle
,
51 EFI_OPEN_PROTOCOL_BY_DRIVER
53 if (!EFI_ERROR ( Status
)) {
56 // Get the interface descriptor to check the USB class and find a transport
59 Status
= pUsbIo
->UsbGetDeviceDescriptor ( pUsbIo
, &Device
);
60 if (EFI_ERROR ( Status
)) {
61 Status
= EFI_UNSUPPORTED
;
65 // Validate the adapter
67 for (Index
= 0; ASIX_DONGLES
[Index
].VendorId
!= 0; Index
++) {
68 if (ASIX_DONGLES
[Index
].VendorId
== Device
.IdVendor
&&
69 ASIX_DONGLES
[Index
].ProductId
== Device
.IdProduct
) {
70 DEBUG ((EFI_D_INFO
, "Found the AX88772B\r\n"));
75 if (ASIX_DONGLES
[Index
].VendorId
== 0)
76 Status
= EFI_UNSUPPORTED
;
80 // Done with the USB stack
84 &gEfiUsbIoProtocolGuid
,
85 pThis
->DriverBindingHandle
,
94 Start this driver on Controller by opening UsbIo and DevicePath protocols.
95 Initialize PXE structures, create a copy of the Controller Device Path with the
96 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
97 on the newly created Device Path.
99 @param [in] pThis Protocol instance pointer.
100 @param [in] Controller Handle of device to work with.
101 @param [in] pRemainingDevicePath Not used, always produce all possible children.
103 @retval EFI_SUCCESS This driver is added to Controller.
104 @retval other This driver does not support this device.
110 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
111 IN EFI_HANDLE Controller
,
112 IN EFI_DEVICE_PATH_PROTOCOL
* pRemainingDevicePath
117 NIC_DEVICE
*pNicDevice
;
119 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
= NULL
;
120 MAC_ADDR_DEVICE_PATH MacDeviceNode
;
121 EFI_USB_DEVICE_DESCRIPTOR Device
;
125 // Allocate the device structure
127 LengthInBytes
= sizeof ( *pNicDevice
);
128 Status
= gBS
->AllocatePool (
129 EfiRuntimeServicesData
,
131 (VOID
**) &pNicDevice
134 if (EFI_ERROR (Status
)) {
135 DEBUG ((EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status
));
140 // Set the structure signature
142 ZeroMem ( pNicDevice
, LengthInBytes
);
143 pNicDevice
->Signature
= DEV_SIGNATURE
;
145 Status
= gBS
->OpenProtocol (
147 &gEfiUsbIoProtocolGuid
,
148 (VOID
**) &pNicDevice
->pUsbIo
,
149 pThis
->DriverBindingHandle
,
151 EFI_OPEN_PROTOCOL_BY_DRIVER
154 if (EFI_ERROR (Status
)) {
155 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status
));
156 gBS
->FreePool ( pNicDevice
);
161 // Initialize the simple network protocol
163 Status
= SN_Setup ( pNicDevice
);
165 if (EFI_ERROR(Status
)){
166 DEBUG ((EFI_D_ERROR
, "SN_Setup ERROR Status = %r\n", Status
));
169 &gEfiUsbIoProtocolGuid
,
170 pThis
->DriverBindingHandle
,
173 gBS
->FreePool ( pNicDevice
);
177 Status
= pNicDevice
->pUsbIo
->UsbGetDeviceDescriptor ( pNicDevice
->pUsbIo
, &Device
);
178 if (EFI_ERROR ( Status
)) {
181 &gEfiUsbIoProtocolGuid
,
182 pThis
->DriverBindingHandle
,
185 gBS
->FreePool ( pNicDevice
);
189 // Validate the adapter
191 for (Index
= 0; ASIX_DONGLES
[Index
].VendorId
!= 0; Index
++) {
192 if (ASIX_DONGLES
[Index
].VendorId
== Device
.IdVendor
&&
193 ASIX_DONGLES
[Index
].ProductId
== Device
.IdProduct
) {
198 if (ASIX_DONGLES
[Index
].VendorId
== 0) {
201 &gEfiUsbIoProtocolGuid
,
202 pThis
->DriverBindingHandle
,
205 gBS
->FreePool ( pNicDevice
);
209 pNicDevice
->Flags
= ASIX_DONGLES
[Index
].Flags
;
215 Status
= gBS
->OpenProtocol (
217 &gEfiDevicePathProtocolGuid
,
218 (VOID
**) &ParentDevicePath
,
219 pThis
->DriverBindingHandle
,
221 EFI_OPEN_PROTOCOL_BY_DRIVER
223 if (EFI_ERROR(Status
)) {
224 DEBUG ((EFI_D_ERROR
, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
228 &gEfiUsbIoProtocolGuid
,
229 pThis
->DriverBindingHandle
,
232 gBS
->FreePool ( pNicDevice
);
236 ZeroMem (&MacDeviceNode
, sizeof (MAC_ADDR_DEVICE_PATH
));
237 MacDeviceNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
238 MacDeviceNode
.Header
.SubType
= MSG_MAC_ADDR_DP
;
240 SetDevicePathNodeLength (&MacDeviceNode
.Header
, sizeof (MAC_ADDR_DEVICE_PATH
));
242 CopyMem (&MacDeviceNode
.MacAddress
,
243 &pNicDevice
->SimpleNetworkData
.CurrentAddress
,
244 PXE_HWADDR_LEN_ETHER
);
246 MacDeviceNode
.IfType
= pNicDevice
->SimpleNetworkData
.IfType
;
248 pNicDevice
->MyDevPath
= AppendDevicePathNode (
250 (EFI_DEVICE_PATH_PROTOCOL
*) &MacDeviceNode
253 pNicDevice
->Controller
= NULL
;
256 // Install both the simple network and device path protocols.
258 Status
= gBS
->InstallMultipleProtocolInterfaces (
259 &pNicDevice
->Controller
,
262 &gEfiSimpleNetworkProtocolGuid
,
263 &pNicDevice
->SimpleNetwork
,
264 &gEfiDevicePathProtocolGuid
,
265 pNicDevice
->MyDevPath
,
269 if (EFI_ERROR(Status
)){
270 DEBUG ((EFI_D_ERROR
, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
274 &gEfiDevicePathProtocolGuid
,
275 pThis
->DriverBindingHandle
,
279 &gEfiUsbIoProtocolGuid
,
280 pThis
->DriverBindingHandle
,
283 gBS
->FreePool ( pNicDevice
);
288 // Open For Child Device
290 Status
= gBS
->OpenProtocol (
292 &gEfiUsbIoProtocolGuid
,
293 (VOID
**) &pNicDevice
->pUsbIo
,
294 pThis
->DriverBindingHandle
,
295 pNicDevice
->Controller
,
296 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
299 if (EFI_ERROR(Status
)){
300 gBS
->UninstallMultipleProtocolInterfaces (
301 &pNicDevice
->Controller
,
304 &gEfiSimpleNetworkProtocolGuid
,
305 &pNicDevice
->SimpleNetwork
,
306 &gEfiDevicePathProtocolGuid
,
307 pNicDevice
->MyDevPath
,
312 &gEfiDevicePathProtocolGuid
,
313 pThis
->DriverBindingHandle
,
317 &gEfiUsbIoProtocolGuid
,
318 pThis
->DriverBindingHandle
,
321 gBS
->FreePool ( pNicDevice
);
330 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
331 closing the DevicePath and PciIo protocols on Controller.
333 @param [in] pThis Protocol instance pointer.
334 @param [in] Controller Handle of device to stop driver on.
335 @param [in] NumberOfChildren How many children need to be stopped.
336 @param [in] pChildHandleBuffer Not used.
338 @retval EFI_SUCCESS This driver is removed Controller.
339 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
340 @retval other This driver was not removed from this device.
346 IN EFI_DRIVER_BINDING_PROTOCOL
* pThis
,
347 IN EFI_HANDLE Controller
,
348 IN UINTN NumberOfChildren
,
349 IN EFI_HANDLE
* ChildHandleBuffer
352 BOOLEAN AllChildrenStopped
;
354 EFI_SIMPLE_NETWORK_PROTOCOL
*SimpleNetwork
;
355 EFI_STATUS Status
= EFI_SUCCESS
;
356 NIC_DEVICE
*pNicDevice
;
359 // Complete all outstanding transactions to Controller.
360 // Don't allow any new transaction to Controller to be started.
362 if (NumberOfChildren
== 0) {
364 Status
= gBS
->OpenProtocol (
366 &gEfiSimpleNetworkProtocolGuid
,
367 (VOID
**) &SimpleNetwork
,
368 pThis
->DriverBindingHandle
,
370 EFI_OPEN_PROTOCOL_GET_PROTOCOL
373 if (EFI_ERROR(Status
)) {
375 // This is a 2nd type handle(multi-lun root), it needs to close devicepath
376 // and usbio protocol.
380 &gEfiDevicePathProtocolGuid
,
381 pThis
->DriverBindingHandle
,
386 &gEfiUsbIoProtocolGuid
,
387 pThis
->DriverBindingHandle
,
393 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
395 Status
= gBS
->UninstallMultipleProtocolInterfaces (
399 &gEfiSimpleNetworkProtocolGuid
,
400 &pNicDevice
->SimpleNetwork
,
401 &gEfiDevicePathProtocolGuid
,
402 pNicDevice
->MyDevPath
,
406 if (EFI_ERROR (Status
)) {
410 // Close the bus driver
412 Status
= gBS
->CloseProtocol (
414 &gEfiDevicePathProtocolGuid
,
415 pThis
->DriverBindingHandle
,
419 if (EFI_ERROR(Status
)){
420 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status
));
423 Status
= gBS
->CloseProtocol (
425 &gEfiUsbIoProtocolGuid
,
426 pThis
->DriverBindingHandle
,
430 if (EFI_ERROR(Status
)){
431 DEBUG ((EFI_D_ERROR
, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status
));
435 AllChildrenStopped
= TRUE
;
437 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
439 Status
= gBS
->OpenProtocol (
440 ChildHandleBuffer
[Index
],
441 &gEfiSimpleNetworkProtocolGuid
,
442 (VOID
**) &SimpleNetwork
,
443 pThis
->DriverBindingHandle
,
445 EFI_OPEN_PROTOCOL_GET_PROTOCOL
448 if (EFI_ERROR (Status
)) {
449 AllChildrenStopped
= FALSE
;
450 DEBUG ((EFI_D_ERROR
, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32
)Index
));
454 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork
);
458 &gEfiUsbIoProtocolGuid
,
459 pThis
->DriverBindingHandle
,
460 ChildHandleBuffer
[Index
]
463 Status
= gBS
->UninstallMultipleProtocolInterfaces (
464 ChildHandleBuffer
[Index
],
467 &gEfiSimpleNetworkProtocolGuid
,
468 &pNicDevice
->SimpleNetwork
,
469 &gEfiDevicePathProtocolGuid
,
470 pNicDevice
->MyDevPath
,
474 if (EFI_ERROR (Status
)) {
475 Status
= gBS
->OpenProtocol (
477 &gEfiUsbIoProtocolGuid
,
478 (VOID
**) &pNicDevice
->pUsbIo
,
479 pThis
->DriverBindingHandle
,
480 ChildHandleBuffer
[Index
],
481 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
486 RX_PKT
* pCurr
= pNicDevice
->QueueHead
;
489 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
490 if ( NULL
!= pCurr
) {
492 pCurr
= pCurr
->pNext
;
493 gBS
->FreePool (pFree
);
497 if ( NULL
!= pNicDevice
->pRxTest
)
498 gBS
->FreePool (pNicDevice
->pRxTest
);
500 if ( NULL
!= pNicDevice
->pTxTest
)
501 gBS
->FreePool (pNicDevice
->pTxTest
);
503 if ( NULL
!= pNicDevice
->MyDevPath
)
504 gBS
->FreePool (pNicDevice
->MyDevPath
);
506 if ( NULL
!= pNicDevice
)
507 gBS
->FreePool (pNicDevice
);
511 if (!AllChildrenStopped
) {
512 return EFI_DEVICE_ERROR
;
519 Driver binding protocol declaration
521 EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
= {
532 Ax88772 driver unload routine.
534 @param [in] ImageHandle Handle for the image.
536 @retval EFI_SUCCESS Image may be unloaded
542 IN EFI_HANDLE ImageHandle
548 EFI_HANDLE
* pHandle
;
552 // Determine which devices are using this driver
556 Status
= gBS
->LocateHandle (
562 if ( EFI_BUFFER_TOO_SMALL
== Status
) {
565 // One or more block IO devices are present
567 Status
= gBS
->AllocatePool (
568 EfiRuntimeServicesData
,
572 if ( EFI_ERROR ( Status
)) {
573 DEBUG ((EFI_D_ERROR
, "Insufficient memory, failed handle buffer allocation\r\n"));
578 // Locate the block IO devices
580 Status
= gBS
->LocateHandle (
586 if ( EFI_ERROR ( Status
)) {
588 // Error getting handles
594 // Remove any use of the driver
596 Max
= BufferSize
/ sizeof ( pHandle
[ 0 ]);
597 for ( Index
= 0; Max
> Index
; Index
++ ) {
598 Status
= DriverStop ( &gDriverBinding
,
602 if ( EFI_ERROR ( Status
)) {
603 DEBUG ((EFI_D_ERROR
, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle
[ Index
]));
611 if ( EFI_NOT_FOUND
== Status
) {
613 // No devices were found
615 Status
= EFI_SUCCESS
;
620 // Free the handle array
622 if ( NULL
!= pHandle
) {
623 gBS
->FreePool ( pHandle
);
627 // Remove the protocols installed by the EntryPoint routine.
629 if ( !EFI_ERROR ( Status
)) {
630 gBS
->UninstallMultipleProtocolInterfaces (
632 &gEfiDriverBindingProtocolGuid
,
634 &gEfiComponentNameProtocolGuid
,
636 &gEfiComponentName2ProtocolGuid
,
641 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
642 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
644 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
645 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
647 DEBUG (( DEBUG_POOL
| DEBUG_INIT
| DEBUG_INFO
,
648 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
658 Ax88772 driver entry point.
660 @param [in] ImageHandle Handle for the image.
661 @param [in] pSystemTable Address of the system table.
663 @retval EFI_SUCCESS Image successfully loaded.
669 IN EFI_HANDLE ImageHandle
,
670 IN EFI_SYSTEM_TABLE
* pSystemTable
676 // Add the driver to the list of drivers
678 Status
= EfiLibInstallDriverBindingComponentName2 (
686 if ( !EFI_ERROR ( Status
)) {
687 DEBUG ((EFI_D_INFO
, "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
689 DEBUG ((EFI_D_INFO
, "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
691 DEBUG ((EFI_D_INFO
,"Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",