]> git.proxmox.com Git - mirror_edk2.git/blame - OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
Ax88772: Add logic to separate packet, fix MTU issue. Ax88772b: Fix driver model...
[mirror_edk2.git] / OptionRomPkg / Bus / Usb / UsbNetworking / Ax88772 / DriverBinding.c
CommitLineData
8dde1f6e 1/** @file\r
2 Implement the driver binding protocol for Asix AX88772 Ethernet driver.\r
3\r
4986bbaf 4 Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>\r
bce3e2ab 5 This program and the accompanying materials\r
8dde1f6e 6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Ax88772.h"\r
16\r
17/**\r
18 Verify the controller type\r
19\r
20 @param [in] pThis Protocol instance pointer.\r
21 @param [in] Controller Handle of device to test.\r
22 @param [in] pRemainingDevicePath Not used.\r
23\r
24 @retval EFI_SUCCESS This driver supports this device.\r
25 @retval other This driver does not support this device.\r
26\r
27**/\r
28EFI_STATUS\r
29EFIAPI\r
30DriverSupported (\r
31 IN EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
32 IN EFI_HANDLE Controller,\r
33 IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath\r
34 )\r
35{\r
36 EFI_USB_DEVICE_DESCRIPTOR Device;\r
37 EFI_USB_IO_PROTOCOL * pUsbIo;\r
38 EFI_STATUS Status;\r
39\r
40 //\r
41 // Connect to the USB stack\r
42 //\r
43 Status = gBS->OpenProtocol (\r
44 Controller,\r
45 &gEfiUsbIoProtocolGuid,\r
46 (VOID **) &pUsbIo,\r
47 pThis->DriverBindingHandle,\r
48 Controller,\r
49 EFI_OPEN_PROTOCOL_BY_DRIVER\r
50 );\r
51 if (!EFI_ERROR ( Status )) {\r
52\r
53 //\r
54 // Get the interface descriptor to check the USB class and find a transport\r
55 // protocol handler.\r
56 //\r
57 Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );\r
58 if (!EFI_ERROR ( Status )) {\r
59\r
60 //\r
61 // Validate the adapter\r
62 //\r
63 if (( VENDOR_ID != Device.IdVendor )\r
64 || ( PRODUCT_ID != Device.IdProduct )) {\r
65 Status = EFI_UNSUPPORTED;\r
66 }\r
67 }\r
68\r
69 //\r
70 // Done with the USB stack\r
71 //\r
72 gBS->CloseProtocol (\r
73 Controller,\r
74 &gEfiUsbIoProtocolGuid,\r
75 pThis->DriverBindingHandle,\r
76 Controller\r
77 );\r
78 }\r
79\r
80 //\r
81 // Return the device supported status\r
82 //\r
83 return Status;\r
84}\r
85\r
86\r
87/**\r
88 Start this driver on Controller by opening UsbIo and DevicePath protocols.\r
89 Initialize PXE structures, create a copy of the Controller Device Path with the\r
90 NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol\r
91 on the newly created Device Path.\r
92\r
93 @param [in] pThis Protocol instance pointer.\r
94 @param [in] Controller Handle of device to work with.\r
95 @param [in] pRemainingDevicePath Not used, always produce all possible children.\r
96\r
97 @retval EFI_SUCCESS This driver is added to Controller.\r
98 @retval other This driver does not support this device.\r
99\r
100**/\r
101EFI_STATUS\r
102EFIAPI\r
103DriverStart (\r
104 IN EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
105 IN EFI_HANDLE Controller,\r
106 IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath\r
107 )\r
108{\r
109 EFI_STATUS Status;\r
110 NIC_DEVICE * pNicDevice;\r
111 UINTN LengthInBytes;\r
112\r
113 DBG_ENTER ( );\r
114\r
115 //\r
116 // Allocate the device structure\r
117 //\r
118 LengthInBytes = sizeof ( *pNicDevice );\r
119 Status = gBS->AllocatePool (\r
120 EfiRuntimeServicesData,\r
121 LengthInBytes,\r
122 (VOID **) &pNicDevice\r
123 );\r
124 if ( !EFI_ERROR ( Status )) {\r
125 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
126 "0x%08x: Allocate pNicDevice, %d bytes\r\n",\r
127 pNicDevice,\r
128 sizeof ( *pNicDevice )));\r
129\r
130 //\r
131 // Set the structure signature\r
132 //\r
133 ZeroMem ( pNicDevice, LengthInBytes );\r
134 pNicDevice->Signature = DEV_SIGNATURE;\r
135\r
136 //\r
137 // Connect to the USB I/O protocol\r
138 //\r
139 Status = gBS->OpenProtocol (\r
140 Controller,\r
141 &gEfiUsbIoProtocolGuid,\r
142 (VOID **) &pNicDevice->pUsbIo,\r
143 pThis->DriverBindingHandle,\r
144 Controller,\r
145 EFI_OPEN_PROTOCOL_BY_DRIVER\r
146 );\r
147\r
148 if ( !EFI_ERROR ( Status )) {\r
149 //\r
150 // Allocate the necessary events\r
151 //\r
152 Status = gBS->CreateEvent ( EVT_TIMER,\r
153 TPL_AX88772,\r
154 (EFI_EVENT_NOTIFY)Ax88772Timer,\r
155 pNicDevice,\r
156 (VOID **)&pNicDevice->Timer );\r
157 if ( !EFI_ERROR ( Status )) {\r
158 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
159 "0x%08x: Allocated timer\r\n",\r
160 pNicDevice->Timer ));\r
161\r
162 //\r
163 // Initialize the simple network protocol\r
164 //\r
165 pNicDevice->Controller = Controller;\r
166 SN_Setup ( pNicDevice );\r
167\r
168 //\r
169 // Start the timer\r
170 //\r
171 Status = gBS->SetTimer ( pNicDevice->Timer,\r
172 TimerPeriodic,\r
173 TIMER_MSEC );\r
174 if ( !EFI_ERROR ( Status )) {\r
175 //\r
176 // Install both the simple network and device path protocols.\r
177 //\r
178 Status = gBS->InstallMultipleProtocolInterfaces (\r
179 &Controller,\r
180 &gEfiCallerIdGuid,\r
181 pNicDevice,\r
182 &gEfiSimpleNetworkProtocolGuid,\r
183 &pNicDevice->SimpleNetwork,\r
184 NULL\r
185 );\r
186\r
187 if ( !EFI_ERROR ( Status )) {\r
188 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
189 "Installed: gEfiCallerIdGuid on 0x%08x\r\n",\r
190 Controller ));\r
191 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
192 "Installed: gEfiSimpleNetworkProtocolGuid on 0x%08x\r\n",\r
193 Controller ));\r
194 DBG_EXIT_STATUS ( Status );\r
195 return Status;\r
196 }\r
197 DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,\r
198 "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",\r
199 Controller ));\r
200 }\r
201 else {\r
202 DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,\r
203 "ERROR - Failed to start the timer, Status: %r\r\n",\r
204 Status ));\r
205 }\r
206 }\r
207 else {\r
208 DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,\r
209 "ERROR - Failed to create timer event, Status: %r\r\n",\r
210 Status ));\r
211 }\r
212\r
213 //\r
214 // Done with the USB stack\r
215 //\r
216 gBS->CloseProtocol (\r
217 Controller,\r
218 &gEfiUsbIoProtocolGuid,\r
219 pThis->DriverBindingHandle,\r
220 Controller\r
221 );\r
222 }\r
223\r
224 //\r
225 // Done with the device\r
226 //\r
227 gBS->FreePool ( pNicDevice );\r
228 }\r
229\r
230 //\r
231 // Display the driver start status\r
232 //\r
233 DBG_EXIT_STATUS ( Status );\r
234 return Status;\r
235}\r
236\r
237\r
238/**\r
239 Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and\r
240 closing the DevicePath and PciIo protocols on Controller.\r
241\r
242 @param [in] pThis Protocol instance pointer.\r
243 @param [in] Controller Handle of device to stop driver on.\r
244 @param [in] NumberOfChildren How many children need to be stopped.\r
245 @param [in] pChildHandleBuffer Not used.\r
246\r
247 @retval EFI_SUCCESS This driver is removed Controller.\r
248 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
249 @retval other This driver was not removed from this device.\r
250\r
251**/\r
252EFI_STATUS\r
253EFIAPI\r
254DriverStop (\r
255 IN EFI_DRIVER_BINDING_PROTOCOL * pThis,\r
256 IN EFI_HANDLE Controller,\r
257 IN UINTN NumberOfChildren,\r
258 IN EFI_HANDLE * pChildHandleBuffer\r
259 )\r
260{\r
261 NIC_DEVICE * pNicDevice;\r
262 EFI_STATUS Status;\r
263\r
264 DBG_ENTER ( );\r
265\r
266 //\r
267 // Determine if this driver is already attached\r
268 //\r
269 Status = gBS->OpenProtocol (\r
270 Controller,\r
271 &gEfiCallerIdGuid,\r
272 (VOID **) &pNicDevice,\r
273 pThis->DriverBindingHandle,\r
274 Controller,\r
275 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
276 );\r
277 if ( !EFI_ERROR ( Status )) {\r
278 //\r
279 // AX88772 driver is no longer running on this device\r
280 //\r
281 gBS->UninstallMultipleProtocolInterfaces (\r
282 Controller,\r
283 &gEfiSimpleNetworkProtocolGuid,\r
284 &pNicDevice->SimpleNetwork,\r
285 &gEfiCallerIdGuid,\r
286 pNicDevice,\r
287 NULL );\r
288 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
289 "Removed: gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",\r
290 Controller ));\r
291 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
292 "Removed: gEfiCallerIdGuid from 0x%08x\r\n",\r
293 Controller ));\r
294\r
295 //\r
296 // Stop the timer\r
297 //\r
298 if ( NULL != pNicDevice->Timer ) {\r
299 gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );\r
300 gBS->CloseEvent ( pNicDevice->Timer );\r
301 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
302 "0x%08x: Released timer\r\n",\r
303 pNicDevice->Timer ));\r
304 }\r
305\r
306 //\r
307 // Done with the device context\r
308 //\r
309 DEBUG (( DEBUG_POOL | DEBUG_INIT,\r
310 "0x%08x: Free pNicDevice, %d bytes\r\n",\r
311 pNicDevice,\r
312 sizeof ( *pNicDevice )));\r
313 gBS->FreePool ( pNicDevice );\r
314 }\r
315\r
316 //\r
317 // Return the shutdown status\r
318 //\r
319 DBG_EXIT_STATUS ( Status );\r
320 return Status;\r
321}\r
322\r
323\r
324/**\r
325 Driver binding protocol declaration\r
326**/\r
327EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {\r
328 DriverSupported,\r
329 DriverStart,\r
330 DriverStop,\r
331 0xa,\r
332 NULL,\r
333 NULL\r
334};\r
335\r
336\r
337/**\r
338 Ax88772 driver unload routine.\r
339\r
340 @param [in] ImageHandle Handle for the image.\r
341\r
342 @retval EFI_SUCCESS Image may be unloaded\r
343\r
344**/\r
345EFI_STATUS\r
346EFIAPI\r
347DriverUnload (\r
348 IN EFI_HANDLE ImageHandle\r
349 )\r
350{\r
351 UINTN BufferSize;\r
352 UINTN Index;\r
353 UINTN Max;\r
354 EFI_HANDLE * pHandle;\r
355 EFI_STATUS Status;\r
356\r
357 //\r
358 // Determine which devices are using this driver\r
359 //\r
360 BufferSize = 0;\r
361 pHandle = NULL;\r
362 Status = gBS->LocateHandle (\r
363 ByProtocol,\r
364 &gEfiCallerIdGuid,\r
365 NULL,\r
366 &BufferSize,\r
367 NULL );\r
368 if ( EFI_BUFFER_TOO_SMALL == Status ) {\r
369 for ( ; ; ) {\r
370 //\r
371 // One or more block IO devices are present\r
372 //\r
373 Status = gBS->AllocatePool (\r
374 EfiRuntimeServicesData,\r
375 BufferSize,\r
376 (VOID **) &pHandle\r
377 );\r
378 if ( EFI_ERROR ( Status )) {\r
379 DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
380 "Insufficient memory, failed handle buffer allocation\r\n" ));\r
381 break;\r
382 }\r
383\r
384 //\r
385 // Locate the block IO devices\r
386 //\r
387 Status = gBS->LocateHandle (\r
388 ByProtocol,\r
389 &gEfiCallerIdGuid,\r
390 NULL,\r
391 &BufferSize,\r
392 pHandle );\r
393 if ( EFI_ERROR ( Status )) {\r
394 //\r
395 // Error getting handles\r
396 //\r
397 DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,\r
398 "Failure getting Telnet handles\r\n" ));\r
399 break;\r
400 }\r
401 \r
402 //\r
403 // Remove any use of the driver\r
404 //\r
405 Max = BufferSize / sizeof ( pHandle[ 0 ]);\r
406 for ( Index = 0; Max > Index; Index++ ) {\r
407 Status = DriverStop ( &gDriverBinding,\r
408 pHandle[ Index ],\r
409 0,\r
410 NULL );\r
411 if ( EFI_ERROR ( Status )) {\r
412 DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,\r
413 "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));\r
414 break;\r
415 }\r
416 }\r
417 break;\r
418 }\r
419 }\r
420 else {\r
421 if ( EFI_NOT_FOUND == Status ) {\r
422 //\r
423 // No devices were found\r
424 //\r
425 Status = EFI_SUCCESS;\r
426 }\r
427 }\r
428\r
429 //\r
430 // Free the handle array\r
431 //\r
432 if ( NULL != pHandle ) {\r
433 gBS->FreePool ( pHandle );\r
434 }\r
435\r
436 //\r
437 // Remove the protocols installed by the EntryPoint routine.\r
438 //\r
439 if ( !EFI_ERROR ( Status )) {\r
440 gBS->UninstallMultipleProtocolInterfaces (\r
441 ImageHandle,\r
442 &gEfiDriverBindingProtocolGuid,\r
443 &gDriverBinding,\r
444 &gEfiComponentNameProtocolGuid,\r
445 &gComponentName,\r
446 &gEfiComponentName2ProtocolGuid,\r
447 &gComponentName2,\r
448 NULL\r
449 );\r
450 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
451 "Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",\r
452 ImageHandle ));\r
453 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
454 "Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",\r
455 ImageHandle ));\r
456 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
457 "Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",\r
458 ImageHandle ));\r
459 }\r
460\r
461 //\r
462 // Return the unload status\r
463 //\r
464 return Status;\r
465}\r
466\r
467\r
468/**\r
469Ax88772 driver entry point.\r
470\r
471@param [in] ImageHandle Handle for the image.\r
472@param [in] pSystemTable Address of the system table.\r
473\r
474@retval EFI_SUCCESS Image successfully loaded.\r
475\r
476**/\r
477EFI_STATUS\r
478EFIAPI\r
479EntryPoint (\r
480 IN EFI_HANDLE ImageHandle,\r
481 IN EFI_SYSTEM_TABLE * pSystemTable\r
482 )\r
483{\r
8dde1f6e 484 EFI_STATUS Status;\r
485\r
486 DBG_ENTER ( );\r
487\r
8dde1f6e 488 //\r
489 // Add the driver to the list of drivers\r
490 //\r
491 Status = EfiLibInstallDriverBindingComponentName2 (\r
492 ImageHandle,\r
493 pSystemTable,\r
494 &gDriverBinding,\r
495 ImageHandle,\r
496 &gComponentName,\r
497 &gComponentName2\r
498 );\r
499 ASSERT_EFI_ERROR (Status);\r
500 if ( !EFI_ERROR ( Status )) {\r
501 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
502 "Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",\r
503 ImageHandle ));\r
504 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
505 "Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",\r
506 ImageHandle ));\r
507 DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,\r
508 "Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",\r
509 ImageHandle ));\r
510 }\r
511 DBG_EXIT_STATUS ( Status );\r
512 return Status;\r
513}\r