TianoCore EDK2 master
Loading...
Searching...
No Matches
DriverBinding.c
Go to the documentation of this file.
1
8#include "DriverBinding.h"
9
10PXE_SW_UNDI *gPxe = NULL;
11NIC_DEVICE *gLanDeviceList[MAX_LAN_INTERFACE];
12UINT32 gRateLimitingCredit;
13UINT32 gRateLimitingPollTimer;
14BOOLEAN gRateLimitingEnable;
15
16EFI_DRIVER_BINDING_PROTOCOL gNetworkCommonDriverBinding = {
20 NETWORK_COMMON_DRIVER_VERSION,
21 NULL,
22 NULL
23};
24
40 IN NIC_DATA *Nic
41 )
42{
43 EFI_STATUS Status;
44 MAC_ADDR_DEVICE_PATH MacAddrNode;
46 UINT8 *DevicePath;
47 UINT16 TotalLength;
48 UINT16 BaseLength;
49
50 ZeroMem (&MacAddrNode, sizeof (MAC_ADDR_DEVICE_PATH));
51 CopyMem (&MacAddrNode.MacAddress, &Nic->MacAddr, sizeof (EFI_MAC_ADDRESS));
52
53 MacAddrNode.Header.Type = MESSAGING_DEVICE_PATH;
54 MacAddrNode.Header.SubType = MSG_MAC_ADDR_DP;
55 MacAddrNode.Header.Length[0] = (UINT8)sizeof (MacAddrNode);
56 MacAddrNode.Header.Length[1] = 0;
57
58 EndNode = BaseDev;
59
60 while (!IsDevicePathEnd (EndNode)) {
61 EndNode = NextDevicePathNode (EndNode);
62 }
63
64 BaseLength = (UINT16)((UINTN)(EndNode) - (UINTN)(BaseDev));
65 TotalLength = (UINT16)(BaseLength + sizeof (MacAddrNode) + sizeof (EFI_DEVICE_PATH_PROTOCOL));
66
67 Status = gBS->AllocatePool (EfiBootServicesData, TotalLength, (VOID **)&DevicePath);
68 if (EFI_ERROR (Status)) {
69 return Status;
70 }
71
72 *Dev = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
73 CopyMem (DevicePath, (CHAR8 *)BaseDev, BaseLength);
74 DevicePath += BaseLength;
75 CopyMem (DevicePath, (CHAR8 *)&MacAddrNode, sizeof (MacAddrNode));
76 DevicePath += sizeof (MacAddrNode);
77 CopyMem (DevicePath, (CHAR8 *)EndNode, sizeof (EFI_DEVICE_PATH_PROTOCOL));
78
79 return EFI_SUCCESS;
80}
81
96EFIAPI
99 IN EFI_HANDLE ControllerHandle,
100 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
101 )
102{
103 EFI_STATUS Status;
105
106 Status = gBS->OpenProtocol (
107 ControllerHandle,
108 &gEdkIIUsbEthProtocolGuid,
109 (VOID **)&UsbEth,
110 This->DriverBindingHandle,
111 ControllerHandle,
112 EFI_OPEN_PROTOCOL_BY_DRIVER
113 );
114 if (EFI_ERROR (Status)) {
115 return Status;
116 }
117
118 gBS->CloseProtocol (
119 ControllerHandle,
120 &gEdkIIUsbEthProtocolGuid,
121 This->DriverBindingHandle,
122 ControllerHandle
123 );
124 return Status;
125}
126
142EFIAPI
145 IN EFI_HANDLE ControllerHandle,
146 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
147 )
148{
149 EFI_STATUS Status;
150 EFI_DEVICE_PATH_PROTOCOL *UsbEthPath;
152 EFI_MAC_ADDRESS MacAddress;
153 UINTN BulkDataSize;
154 NIC_DEVICE *NicDevice;
155 UINT8 *TmpPxePointer;
156
157 Status = gBS->OpenProtocol (
158 ControllerHandle,
159 &gEdkIIUsbEthProtocolGuid,
160 (VOID **)&UsbEth,
161 This->DriverBindingHandle,
162 ControllerHandle,
163 EFI_OPEN_PROTOCOL_BY_DRIVER
164 );
165 if (EFI_ERROR (Status)) {
166 return Status;
167 }
168
169 Status = gBS->OpenProtocol (
170 ControllerHandle,
171 &gEfiDevicePathProtocolGuid,
172 (VOID **)&UsbEthPath,
173 This->DriverBindingHandle,
174 ControllerHandle,
175 EFI_OPEN_PROTOCOL_BY_DRIVER
176 );
177
178 if (EFI_ERROR (Status)) {
179 gBS->CloseProtocol (
180 ControllerHandle,
181 &gEdkIIUsbEthProtocolGuid,
182 This->DriverBindingHandle,
183 ControllerHandle
184 );
185 return Status;
186 }
187
188 ZeroMem (&MacAddress, sizeof (EFI_MAC_ADDRESS));
189
190 Status = UsbEth->UsbEthMacAddress (UsbEth, &MacAddress);
191 ASSERT_EFI_ERROR (Status);
192 Status = UsbEth->UsbEthMaxBulkSize (UsbEth, &BulkDataSize);
193
194 if (EFI_ERROR (Status)) {
195 gBS->CloseProtocol (
196 ControllerHandle,
197 &gEfiDevicePathProtocolGuid,
198 This->DriverBindingHandle,
199 ControllerHandle
200 );
201 gBS->CloseProtocol (
202 ControllerHandle,
203 &gEdkIIUsbEthProtocolGuid,
204 This->DriverBindingHandle,
205 ControllerHandle
206 );
207 return Status;
208 }
209
210 NicDevice = AllocateZeroPool (sizeof (NIC_DEVICE) + BulkDataSize + 4096);
211 if (!NicDevice) {
212 gBS->CloseProtocol (
213 ControllerHandle,
214 &gEfiDevicePathProtocolGuid,
215 This->DriverBindingHandle,
216 ControllerHandle
217 );
218 gBS->CloseProtocol (
219 ControllerHandle,
220 &gEdkIIUsbEthProtocolGuid,
221 This->DriverBindingHandle,
222 ControllerHandle
223 );
224 return EFI_OUT_OF_RESOURCES;
225 }
226
227 // for alignment adjustment
228 if (gPxe == NULL) {
229 TmpPxePointer = NULL;
230 TmpPxePointer = AllocateZeroPool (sizeof (PXE_SW_UNDI) + 16);
231 if (!TmpPxePointer) {
232 if (NicDevice != NULL) {
233 FreePool (NicDevice);
234 }
235
236 gBS->CloseProtocol (
237 ControllerHandle,
238 &gEfiDevicePathProtocolGuid,
239 This->DriverBindingHandle,
240 ControllerHandle
241 );
242 gBS->CloseProtocol (
243 ControllerHandle,
244 &gEdkIIUsbEthProtocolGuid,
245 This->DriverBindingHandle,
246 ControllerHandle
247 );
248
249 return EFI_OUT_OF_RESOURCES;
250 } else {
251 // check for paragraph alignment here
252 if (((UINTN)TmpPxePointer & 0x0F) != 0) {
253 gPxe = (PXE_SW_UNDI *)(TmpPxePointer + 8);
254 } else {
255 gPxe = (PXE_SW_UNDI *)TmpPxePointer;
256 }
257
258 if (gPxe == NULL) {
259 if (NicDevice != NULL) {
260 FreePool (NicDevice);
261 }
262
263 gBS->CloseProtocol (
264 ControllerHandle,
265 &gEfiDevicePathProtocolGuid,
266 This->DriverBindingHandle,
267 ControllerHandle
268 );
269 gBS->CloseProtocol (
270 ControllerHandle,
271 &gEdkIIUsbEthProtocolGuid,
272 This->DriverBindingHandle,
273 ControllerHandle
274 );
275 return EFI_OUT_OF_RESOURCES;
276 }
277
278 PxeStructInit (gPxe);
279 }
280 }
281
282 NicDevice->NiiProtocol.Id = (UINT64)(UINTN)(gPxe);
283 NicDevice->NiiProtocol.IfNum = gPxe->IFcnt | gPxe->IFcntExt << 8;
284
285 UpdateNicNum (&NicDevice->NicInfo, gPxe);
286
287 NicDevice->NicInfo.Signature = NIC_DATA_SIGNATURE;
288
289 NicDevice->NicInfo.UsbEth = UsbEth;
290 NicDevice->NicInfo.MaxSegmentSize = (UINT16)BulkDataSize;
291 NicDevice->NicInfo.CableDetect = 0;
292 NicDevice->ReceiveBuffer = ALIGN_POINTER ((VOID *)NicDevice, 4096);
293
294 CopyMem ((CHAR8 *)&(NicDevice->NicInfo.MacAddr), (CHAR8 *)&MacAddress, sizeof (MacAddress));
295
296 NicDevice->NicInfo.TxBufferCount = 0;
297
298 if (NicDevice->NiiProtocol.IfNum < MAX_LAN_INTERFACE) {
299 gLanDeviceList[NicDevice->NiiProtocol.IfNum] = NicDevice;
300 } else {
301 gBS->CloseProtocol (
302 ControllerHandle,
303 &gEfiDevicePathProtocolGuid,
304 This->DriverBindingHandle,
305 ControllerHandle
306 );
307 gBS->CloseProtocol (
308 ControllerHandle,
309 &gEdkIIUsbEthProtocolGuid,
310 This->DriverBindingHandle,
311 ControllerHandle
312 );
313
314 if (TmpPxePointer != NULL) {
315 FreePool (TmpPxePointer);
316 }
317
318 if (NicDevice != NULL) {
319 FreePool (NicDevice);
320 }
321
322 return EFI_DEVICE_ERROR;
323 }
324
325 Status = CreateMacDevicePath (
326 &NicDevice->DevPath,
327 UsbEthPath,
328 &NicDevice->NicInfo
329 );
330
331 if (EFI_ERROR (Status)) {
332 UpdateNicNum (NULL, gPxe);
333 if (TmpPxePointer != NULL) {
334 FreePool (TmpPxePointer);
335 }
336 }
337
338 NicDevice->Signature = UNDI_DEV_SIGNATURE;
339 NicDevice->NiiProtocol.Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
340 NicDevice->NiiProtocol.Type = EfiNetworkInterfaceUndi;
341 NicDevice->NiiProtocol.MajorVer = PXE_ROMID_MAJORVER;
342 NicDevice->NiiProtocol.MinorVer = PXE_ROMID_MINORVER;
343 NicDevice->NiiProtocol.ImageSize = 0;
344 NicDevice->NiiProtocol.ImageAddr = 0;
345 NicDevice->NiiProtocol.Ipv6Supported = TRUE;
346
347 NicDevice->NiiProtocol.StringId[0] = 'U';
348 NicDevice->NiiProtocol.StringId[1] = 'N';
349 NicDevice->NiiProtocol.StringId[2] = 'D';
350 NicDevice->NiiProtocol.StringId[3] = 'I';
351 NicDevice->DeviceHandle = NULL;
352
353 NicDevice->NicInfo.RateLimitingEnable = gRateLimitingEnable;
354 NicDevice->NicInfo.RateLimitingCreditCount = 0;
355 NicDevice->NicInfo.RateLimitingCredit = gRateLimitingCredit;
356 NicDevice->NicInfo.RateLimitingPollTimer = gRateLimitingPollTimer;
357 NicDevice->NicInfo.RateLimiter = NULL;
358
359 ZeroMem (&NicDevice->NicInfo.Request, sizeof (EFI_USB_DEVICE_REQUEST));
360
361 Status = UsbEth->UsbEthInterrupt (UsbEth, TRUE, NETWORK_COMMON_POLLING_INTERVAL, &NicDevice->NicInfo.Request);
362 ASSERT_EFI_ERROR (Status);
363
364 Status = gBS->InstallMultipleProtocolInterfaces (
365 &NicDevice->DeviceHandle,
366 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
367 &NicDevice->NiiProtocol,
368 &gEfiDevicePathProtocolGuid,
369 NicDevice->DevPath,
370 NULL
371 );
372
373 if (EFI_ERROR (Status)) {
374 if (NicDevice->NiiProtocol.IfNum < MAX_LAN_INTERFACE) {
375 gLanDeviceList[NicDevice->NiiProtocol.IfNum] = NULL;
376 }
377
378 gBS->CloseProtocol (
379 ControllerHandle,
380 &gEfiDevicePathProtocolGuid,
381 This->DriverBindingHandle,
382 ControllerHandle
383 );
384 gBS->CloseProtocol (
385 ControllerHandle,
386 &gEdkIIUsbEthProtocolGuid,
387 This->DriverBindingHandle,
388 ControllerHandle
389 );
390
391 if (TmpPxePointer != NULL) {
392 FreePool (TmpPxePointer);
393 }
394
395 if (NicDevice->DevPath != NULL) {
396 FreePool (NicDevice->DevPath);
397 }
398
399 if (NicDevice != NULL) {
400 FreePool (NicDevice);
401 }
402
403 return EFI_DEVICE_ERROR;
404 }
405
406 Status = gBS->OpenProtocol (
407 ControllerHandle,
408 &gEdkIIUsbEthProtocolGuid,
409 (VOID **)&UsbEth,
410 This->DriverBindingHandle,
411 NicDevice->DeviceHandle,
412 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
413 );
414
415 return Status;
416}
417
432EFIAPI
435 IN EFI_HANDLE ControllerHandle,
436 IN UINTN NumberOfChildren,
437 IN EFI_HANDLE *ChildHandleBuffer
438 )
439{
440 EFI_STATUS Status;
441 BOOLEAN AllChildrenStopped;
442 UINTN Index;
444 NIC_DEVICE *NicDevice;
446
447 if (NumberOfChildren == 0) {
448 Status = gBS->OpenProtocol (
449 ControllerHandle,
450 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
451 (VOID **)&NiiProtocol,
452 This->DriverBindingHandle,
453 ControllerHandle,
454 EFI_OPEN_PROTOCOL_GET_PROTOCOL
455 );
456
457 if (EFI_ERROR (Status)) {
458 gBS->CloseProtocol (
459 ControllerHandle,
460 &gEfiDevicePathProtocolGuid,
461 This->DriverBindingHandle,
462 ControllerHandle
463 );
464 gBS->CloseProtocol (
465 ControllerHandle,
466 &gEdkIIUsbEthProtocolGuid,
467 This->DriverBindingHandle,
468 ControllerHandle
469 );
470 return EFI_SUCCESS;
471 }
472
473 NicDevice = UNDI_DEV_FROM_THIS (NiiProtocol);
474 Status = gBS->UninstallMultipleProtocolInterfaces (
475 ControllerHandle,
476 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
477 &NicDevice->NiiProtocol,
478 &gEfiDevicePathProtocolGuid,
479 NicDevice->DevPath,
480 NULL
481 );
482 if (EFI_ERROR (Status)) {
483 return Status;
484 }
485
486 FreePool (NicDevice->DevPath);
487 FreePool (NicDevice);
488
489 gBS->CloseProtocol (
490 ControllerHandle,
491 &gEfiDevicePathProtocolGuid,
492 This->DriverBindingHandle,
493 ControllerHandle
494 );
495 gBS->CloseProtocol (
496 ControllerHandle,
497 &gEdkIIUsbEthProtocolGuid,
498 This->DriverBindingHandle,
499 ControllerHandle
500 );
501 return EFI_SUCCESS;
502 }
503
504 AllChildrenStopped = TRUE;
505
506 for (Index = 0; Index < NumberOfChildren; Index++) {
507 Status = gBS->OpenProtocol (
508 ChildHandleBuffer[Index],
509 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
510 (VOID **)&NiiProtocol,
511 This->DriverBindingHandle,
512 ControllerHandle,
513 EFI_OPEN_PROTOCOL_GET_PROTOCOL
514 );
515 if (EFI_ERROR (Status)) {
516 AllChildrenStopped = FALSE;
517 continue;
518 }
519
520 NicDevice = UNDI_DEV_FROM_THIS (NiiProtocol);
521
522 gBS->CloseProtocol (
523 ControllerHandle,
524 &gEdkIIUsbEthProtocolGuid,
525 This->DriverBindingHandle,
526 ChildHandleBuffer[Index]
527 );
528
529 Status = gBS->UninstallMultipleProtocolInterfaces (
530 ChildHandleBuffer[Index],
531 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
532 &NicDevice->NiiProtocol,
533 &gEfiDevicePathProtocolGuid,
534 NicDevice->DevPath,
535 NULL
536 );
537 if (EFI_ERROR (Status)) {
538 Status = gBS->OpenProtocol (
539 ControllerHandle,
540 &gEdkIIUsbEthProtocolGuid,
541 (VOID **)&UsbEth,
542 This->DriverBindingHandle,
543 ChildHandleBuffer[Index],
544 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
545 );
546 } else {
547 FreePool (NicDevice->DevPath);
548 FreePool (NicDevice);
549 }
550 }
551
552 if (!AllChildrenStopped) {
553 return EFI_DEVICE_ERROR;
554 }
555
556 return Status;
557}
558
572EFIAPI
574 IN EFI_HANDLE ImageHandle,
575 IN EFI_SYSTEM_TABLE *SystemTable
576 )
577{
578 EFI_STATUS Status;
579
580 gNetworkCommonDriverBinding.DriverBindingHandle = ImageHandle;
581 gNetworkCommonDriverBinding.ImageHandle = ImageHandle;
582 gRateLimitingEnable = PcdGetBool (PcdEnableUsbNetworkRateLimiting);
583 gRateLimitingCredit = PcdGet32 (PcdUsbNetworkRateLimitingCredit);
584 gRateLimitingPollTimer = PcdGet32 (PcdUsbNetworkRateLimitingFactor);
585
586 Status = gBS->InstallMultipleProtocolInterfaces (
587 &gNetworkCommonDriverBinding.DriverBindingHandle,
588 &gEfiDriverBindingProtocolGuid,
589 &gNetworkCommonDriverBinding,
590 &gEfiComponentName2ProtocolGuid,
591 &gNetworkCommonComponentName2,
592 NULL
593 );
594 return Status;
595}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSG_MAC_ADDR_DP
Definition: DevicePath.h:550
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI NetworkCommonDriverStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
EFI_STATUS EFIAPI NetworkCommonSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: DriverBinding.c:97
EFI_STATUS EFIAPI NetworkCommonDriverStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
EFI_STATUS CreateMacDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **Dev, IN EFI_DEVICE_PATH_PROTOCOL *BaseDev, IN NIC_DATA *Nic)
Definition: DriverBinding.c:37
EFI_STATUS EFIAPI NetworkCommonEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID PxeStructInit(OUT PXE_SW_UNDI *PxeSw)
Definition: PxeFunction.c:1641
VOID UpdateNicNum(IN NIC_DATA *Nic, IN OUT PXE_SW_UNDI *PxeSw)
Definition: PxeFunction.c:1681
#define NULL
Definition: Base.h:319
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
#define PXE_ROMID_MAJORVER
Definition: UefiPxe.h:844
UINT32 ImageSize
The size of unrelocated network interface image.
UINT64 Revision
The revision of the EFI_NETWORK_INTERFACE_IDENTIFIER protocol.
BOOLEAN Ipv6Supported
TRUE if the network interface supports IPv6; otherwise FALSE.
EFI_MAC_ADDRESS MacAddress
Definition: DevicePath.h:556
PXE_UINT8 IFcnt
physical connector count lower byte.
Definition: UefiPxe.h:812
PXE_UINT8 IFcntExt
physical connector count upper byte.
Definition: UefiPxe.h:815