TianoCore EDK2 master
Loading...
Searching...
No Matches
MnpDriver.c
Go to the documentation of this file.
1
9#include "MnpDriver.h"
10#include "MnpImpl.h"
11#include "MnpVlan.h"
12
13EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
17 0xa,
18 NULL,
19 NULL
20};
21
33EFIAPI
35 IN LIST_ENTRY *Entry,
36 IN VOID *Context
37 )
38{
39 MNP_SERVICE_DATA *MnpServiceData;
40
41 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
42 return MnpDestroyServiceData (MnpServiceData);
43}
44
56EFIAPI
58 IN LIST_ENTRY *Entry,
59 IN VOID *Context
60 )
61{
62 MNP_SERVICE_DATA *MnpServiceData;
63
64 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
65 return MnpDestroyServiceChild (MnpServiceData);
66}
67
87EFIAPI
90 IN EFI_HANDLE ControllerHandle,
91 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
92 )
93{
94 EFI_STATUS Status;
96
97 //
98 // Test to open the Simple Network protocol BY_DRIVER.
99 //
100 Status = gBS->OpenProtocol (
101 ControllerHandle,
102 &gEfiSimpleNetworkProtocolGuid,
103 (VOID **)&Snp,
104 This->DriverBindingHandle,
105 ControllerHandle,
106 EFI_OPEN_PROTOCOL_BY_DRIVER
107 );
108 if (EFI_ERROR (Status)) {
109 return Status;
110 }
111
112 //
113 // Close the opened SNP protocol.
114 //
115 gBS->CloseProtocol (
116 ControllerHandle,
117 &gEfiSimpleNetworkProtocolGuid,
118 This->DriverBindingHandle,
119 ControllerHandle
120 );
121
122 return EFI_SUCCESS;
123}
124
144EFIAPI
147 IN EFI_HANDLE ControllerHandle,
148 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
149 )
150{
151 EFI_STATUS Status;
152 MNP_SERVICE_DATA *MnpServiceData;
153 MNP_DEVICE_DATA *MnpDeviceData;
154 LIST_ENTRY *Entry;
155 VLAN_TCI *VlanVariable;
156 UINTN NumberOfVlan;
157 UINTN Index;
158
159 VlanVariable = NULL;
160
161 //
162 // Initialize the Mnp Device Data
163 //
164 MnpDeviceData = AllocateZeroPool (sizeof (MNP_DEVICE_DATA));
165 if (MnpDeviceData == NULL) {
166 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));
167
168 return EFI_OUT_OF_RESOURCES;
169 }
170
171 Status = MnpInitializeDeviceData (MnpDeviceData, This->DriverBindingHandle, ControllerHandle);
172 if (EFI_ERROR (Status)) {
173 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status));
174
175 FreePool (MnpDeviceData);
176 return Status;
177 }
178
179 //
180 // Check whether NIC driver has already produced VlanConfig protocol
181 //
182 Status = gBS->OpenProtocol (
183 ControllerHandle,
184 &gEfiVlanConfigProtocolGuid,
185 NULL,
186 This->DriverBindingHandle,
187 ControllerHandle,
188 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
189 );
190 if (!EFI_ERROR (Status)) {
191 //
192 // NIC hardware already implement VLAN,
193 // no need to provide software VLAN implementation in MNP driver
194 //
195 MnpDeviceData->NumberOfVlan = 0;
196 ZeroMem (&MnpDeviceData->VlanConfig, sizeof (EFI_VLAN_CONFIG_PROTOCOL));
197 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);
198 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
199 goto Exit;
200 }
201
202 //
203 // Install VLAN Config Protocol
204 //
205 Status = gBS->InstallMultipleProtocolInterfaces (
206 &ControllerHandle,
207 &gEfiVlanConfigProtocolGuid,
208 &MnpDeviceData->VlanConfig,
209 NULL
210 );
211 if (EFI_ERROR (Status)) {
212 goto Exit;
213 }
214
215 //
216 // Get current VLAN configuration from EFI Variable
217 //
218 NumberOfVlan = 0;
219 Status = MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &VlanVariable);
220 if (EFI_ERROR (Status)) {
221 //
222 // No VLAN is set, create a default MNP service data for untagged frame
223 //
224 MnpDeviceData->NumberOfVlan = 0;
225 MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);
226 Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
227 goto Exit;
228 }
229
230 //
231 // Create MNP service data for each VLAN
232 //
233 MnpDeviceData->NumberOfVlan = NumberOfVlan;
234 for (Index = 0; Index < NumberOfVlan; Index++) {
235 MnpServiceData = MnpCreateServiceData (
236 MnpDeviceData,
237 VlanVariable[Index].Bits.Vid,
238 (UINT8)VlanVariable[Index].Bits.Priority
239 );
240
241 if (MnpServiceData == NULL) {
242 Status = EFI_OUT_OF_RESOURCES;
243
244 goto Exit;
245 }
246 }
247
248Exit:
249 if (VlanVariable != NULL) {
250 FreePool (VlanVariable);
251 }
252
253 if (EFI_ERROR (Status)) {
254 //
255 // Destroy all MNP service data
256 //
257 while (!IsListEmpty (&MnpDeviceData->ServiceList)) {
258 Entry = GetFirstNode (&MnpDeviceData->ServiceList);
259 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
260 MnpDestroyServiceData (MnpServiceData);
261 }
262
263 //
264 // Uninstall the VLAN Config Protocol if any
265 //
266 if (MnpDeviceData->VlanConfig.Set != NULL) {
267 gBS->UninstallMultipleProtocolInterfaces (
268 MnpDeviceData->ControllerHandle,
269 &gEfiVlanConfigProtocolGuid,
270 &MnpDeviceData->VlanConfig,
271 NULL
272 );
273 }
274
275 //
276 // Destroy Mnp Device Data
277 //
278 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
279 FreePool (MnpDeviceData);
280 }
281
282 return Status;
283}
284
304EFIAPI
307 IN EFI_HANDLE ControllerHandle,
308 IN UINTN NumberOfChildren,
309 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
310 )
311{
312 EFI_STATUS Status;
313 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
314 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
315 MNP_DEVICE_DATA *MnpDeviceData;
316 MNP_SERVICE_DATA *MnpServiceData;
317 LIST_ENTRY *List;
318 UINTN ListLength;
319
320 //
321 // Try to retrieve MNP service binding protocol from the ControllerHandle
322 //
323 Status = gBS->OpenProtocol (
324 ControllerHandle,
325 &gEfiManagedNetworkServiceBindingProtocolGuid,
326 (VOID **)&ServiceBinding,
327 This->DriverBindingHandle,
328 ControllerHandle,
329 EFI_OPEN_PROTOCOL_GET_PROTOCOL
330 );
331 if (EFI_ERROR (Status)) {
332 //
333 // Retrieve VLAN Config Protocol from the ControllerHandle
334 //
335 Status = gBS->OpenProtocol (
336 ControllerHandle,
337 &gEfiVlanConfigProtocolGuid,
338 (VOID **)&VlanConfig,
339 This->DriverBindingHandle,
340 ControllerHandle,
341 EFI_OPEN_PROTOCOL_GET_PROTOCOL
342 );
343 if (EFI_ERROR (Status)) {
344 DEBUG ((DEBUG_ERROR, "MnpDriverBindingStop: try to stop unknown Controller.\n"));
345 return EFI_DEVICE_ERROR;
346 }
347
348 MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (VlanConfig);
349 } else {
350 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);
351 MnpDeviceData = MnpServiceData->MnpDeviceData;
352 }
353
354 if (NumberOfChildren == 0) {
355 //
356 // Destroy all MNP service data
357 //
358 List = &MnpDeviceData->ServiceList;
359 Status = NetDestroyLinkList (
360 List,
362 NULL,
363 &ListLength
364 );
365 if (EFI_ERROR (Status) || (ListLength != 0)) {
366 return EFI_DEVICE_ERROR;
367 }
368
369 //
370 // Uninstall the VLAN Config Protocol if any
371 //
372 if (MnpDeviceData->VlanConfig.Set != NULL) {
373 gBS->UninstallMultipleProtocolInterfaces (
374 MnpDeviceData->ControllerHandle,
375 &gEfiVlanConfigProtocolGuid,
376 &MnpDeviceData->VlanConfig,
377 NULL
378 );
379 }
380
381 //
382 // Destroy Mnp Device Data
383 //
384 MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);
385 FreePool (MnpDeviceData);
386
387 if (gMnpControllerNameTable != NULL) {
388 FreeUnicodeStringTable (gMnpControllerNameTable);
389 gMnpControllerNameTable = NULL;
390 }
391
392 return EFI_SUCCESS;
393 }
394
395 //
396 // Stop all MNP child
397 //
398 List = &MnpDeviceData->ServiceList;
399 Status = NetDestroyLinkList (
400 List,
402 NULL,
403 &ListLength
404 );
405 if (EFI_ERROR (Status)) {
406 return EFI_DEVICE_ERROR;
407 }
408
409 return EFI_SUCCESS;
410}
411
429EFIAPI
432 IN OUT EFI_HANDLE *ChildHandle
433 )
434{
435 EFI_STATUS Status;
436 MNP_SERVICE_DATA *MnpServiceData;
437 MNP_INSTANCE_DATA *Instance;
438 VOID *MnpSb;
439 EFI_TPL OldTpl;
440
441 if ((This == NULL) || (ChildHandle == NULL)) {
442 return EFI_INVALID_PARAMETER;
443 }
444
445 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
446
447 //
448 // Allocate buffer for the new instance.
449 //
450 Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));
451 if (Instance == NULL) {
452 DEBUG ((DEBUG_ERROR, "MnpServiceBindingCreateChild: Failed to allocate memory for the new instance.\n"));
453
454 return EFI_OUT_OF_RESOURCES;
455 }
456
457 //
458 // Init the instance data.
459 //
460 MnpInitializeInstanceData (MnpServiceData, Instance);
461
462 Status = gBS->InstallMultipleProtocolInterfaces (
463 ChildHandle,
464 &gEfiManagedNetworkProtocolGuid,
465 &Instance->ManagedNetwork,
466 NULL
467 );
468 if (EFI_ERROR (Status)) {
469 DEBUG (
470 (DEBUG_ERROR,
471 "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",
472 Status)
473 );
474
475 goto ErrorExit;
476 }
477
478 //
479 // Save the instance's childhandle.
480 //
481 Instance->Handle = *ChildHandle;
482
483 Status = gBS->OpenProtocol (
484 MnpServiceData->ServiceHandle,
485 &gEfiManagedNetworkServiceBindingProtocolGuid,
486 (VOID **)&MnpSb,
487 gMnpDriverBinding.DriverBindingHandle,
488 Instance->Handle,
489 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
490 );
491 if (EFI_ERROR (Status)) {
492 goto ErrorExit;
493 }
494
495 //
496 // Add the child instance into ChildrenList.
497 //
498 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
499
500 InsertTailList (&MnpServiceData->ChildrenList, &Instance->InstEntry);
501 MnpServiceData->ChildrenNumber++;
502
503 gBS->RestoreTPL (OldTpl);
504
505ErrorExit:
506
507 if (EFI_ERROR (Status)) {
508 if (Instance->Handle != NULL) {
509 gBS->UninstallMultipleProtocolInterfaces (
510 Instance->Handle,
511 &gEfiManagedNetworkProtocolGuid,
512 &Instance->ManagedNetwork,
513 NULL
514 );
515 }
516
517 FreePool (Instance);
518 }
519
520 return Status;
521}
522
545EFIAPI
548 IN EFI_HANDLE ChildHandle
549 )
550{
551 EFI_STATUS Status;
552 MNP_SERVICE_DATA *MnpServiceData;
553 EFI_MANAGED_NETWORK_PROTOCOL *ManagedNetwork;
554 MNP_INSTANCE_DATA *Instance;
555 EFI_TPL OldTpl;
556
557 if ((This == NULL) || (ChildHandle == NULL)) {
558 return EFI_INVALID_PARAMETER;
559 }
560
561 MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (This);
562
563 //
564 // Try to retrieve ManagedNetwork Protocol from ChildHandle.
565 //
566 Status = gBS->OpenProtocol (
567 ChildHandle,
568 &gEfiManagedNetworkProtocolGuid,
569 (VOID **)&ManagedNetwork,
570 gMnpDriverBinding.DriverBindingHandle,
571 ChildHandle,
572 EFI_OPEN_PROTOCOL_GET_PROTOCOL
573 );
574 if (EFI_ERROR (Status)) {
575 return EFI_UNSUPPORTED;
576 }
577
578 Instance = MNP_INSTANCE_DATA_FROM_THIS (ManagedNetwork);
579
580 //
581 // MnpServiceBindingDestroyChild may be called twice: first called by
582 // MnpServiceBindingStop, second called by uninstalling the MNP protocol
583 // in this ChildHandle. Use destroyed to make sure the resource clean code
584 // will only excecute once.
585 //
586 if (Instance->Destroyed) {
587 return EFI_SUCCESS;
588 }
589
590 Instance->Destroyed = TRUE;
591
592 //
593 // Close the Simple Network protocol.
594 //
595 gBS->CloseProtocol (
596 MnpServiceData->ServiceHandle,
597 &gEfiManagedNetworkServiceBindingProtocolGuid,
598 MnpServiceData->MnpDeviceData->ImageHandle,
599 ChildHandle
600 );
601
602 //
603 // Uninstall the ManagedNetwork protocol.
604 //
605 Status = gBS->UninstallMultipleProtocolInterfaces (
606 ChildHandle,
607 &gEfiManagedNetworkProtocolGuid,
608 &Instance->ManagedNetwork,
609 NULL
610 );
611 if (EFI_ERROR (Status)) {
612 DEBUG (
613 (DEBUG_ERROR,
614 "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",
615 Status)
616 );
617
618 Instance->Destroyed = FALSE;
619 return Status;
620 }
621
622 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
623
624 //
625 // Reset the configuration.
626 //
627 ManagedNetwork->Configure (ManagedNetwork, NULL);
628
629 //
630 // Try to flush the RcvdPacketQueue.
631 //
632 MnpFlushRcvdDataQueue (Instance);
633
634 //
635 // Clean the RxTokenMap.
636 //
637 NetMapClean (&Instance->RxTokenMap);
638
639 //
640 // Remove this instance from the ChildrenList.
641 //
642 RemoveEntryList (&Instance->InstEntry);
643 MnpServiceData->ChildrenNumber--;
644
645 gBS->RestoreTPL (OldTpl);
646
647 FreePool (Instance);
648
649 return Status;
650}
651
665EFIAPI
667 IN EFI_HANDLE ImageHandle,
668 IN EFI_SYSTEM_TABLE *SystemTable
669 )
670{
672 ImageHandle,
673 SystemTable,
674 &gMnpDriverBinding,
675 ImageHandle,
676 &gMnpComponentName,
677 &gMnpComponentName2
678 );
679}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#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 DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS MnpDestroyServiceChild(IN OUT MNP_SERVICE_DATA *MnpServiceData)
Definition: MnpConfig.c:903
EFI_STATUS MnpDestroyServiceData(IN OUT MNP_SERVICE_DATA *MnpServiceData)
Definition: MnpConfig.c:807
VOID MnpDestroyDeviceData(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN EFI_HANDLE ImageHandle)
Definition: MnpConfig.c:614
EFI_STATUS MnpInitializeDeviceData(IN OUT MNP_DEVICE_DATA *MnpDeviceData, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ControllerHandle)
Definition: MnpConfig.c:420
MNP_SERVICE_DATA * MnpCreateServiceData(IN MNP_DEVICE_DATA *MnpDeviceData, IN UINT16 VlanId, IN UINT8 Priority OPTIONAL)
Definition: MnpConfig.c:690
VOID MnpInitializeInstanceData(IN MNP_SERVICE_DATA *MnpServiceData, IN OUT MNP_INSTANCE_DATA *Instance)
Definition: MnpConfig.c:966
VOID MnpFlushRcvdDataQueue(IN OUT MNP_INSTANCE_DATA *Instance)
Definition: MnpConfig.c:1361
EFI_STATUS EFIAPI MnpDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: MnpDriver.c:88
EFI_STATUS EFIAPI MnpDestroyServiceChildEntry(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: MnpDriver.c:57
EFI_STATUS EFIAPI MnpDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: MnpDriver.c:666
EFI_STATUS EFIAPI MnpDestroyServiceDataEntry(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: MnpDriver.c:34
EFI_STATUS EFIAPI MnpServiceBindingDestroyChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN EFI_HANDLE ChildHandle)
Definition: MnpDriver.c:546
EFI_STATUS EFIAPI MnpDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: MnpDriver.c:305
EFI_STATUS EFIAPI MnpServiceBindingCreateChild(IN EFI_SERVICE_BINDING_PROTOCOL *This, IN OUT EFI_HANDLE *ChildHandle)
Definition: MnpDriver.c:430
EFI_STATUS EFIAPI MnpDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: MnpDriver.c:145
EFI_STATUS MnpGetVlanVariable(IN MNP_DEVICE_DATA *MnpDeviceData, OUT UINTN *NumberOfVlan, OUT VLAN_TCI **VlanVariable)
Definition: MnpVlan.c:295
VOID EFIAPI NetMapClean(IN OUT NET_MAP *Map)
Definition: DxeNetLib.c:1368
EFI_STATUS EFIAPI NetDestroyLinkList(IN LIST_ENTRY *List, IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, IN VOID *Context OPTIONAL, OUT UINTN *ListLength OPTIONAL)
Definition: DxeNetLib.c:1236
VOID EFIAPI Exit(IN EFI_STATUS Status)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI FreeUnicodeStringTable(IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable)
Definition: UefiLib.c:1257