]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / WifiConnectionManagerDxe / WifiConnectionMgrDriver.c
1 /** @file
2 The driver binding protocol for the WiFi Connection Manager.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "WifiConnectionMgrDxe.h"
11
12 ///
13 /// Driver Binding Protocol instance
14 ///
15 EFI_DRIVER_BINDING_PROTOCOL gWifiMgrDxeDriverBinding = {
16 WifiMgrDxeDriverBindingSupported,
17 WifiMgrDxeDriverBindingStart,
18 WifiMgrDxeDriverBindingStop,
19 WIFI_MGR_DXE_VERSION,
20 NULL,
21 NULL
22 };
23
24 //
25 //The private global data for WiFi Connection Manager
26 //
27 WIFI_MGR_PRIVATE_DATA *mPrivate = NULL;
28
29 //
30 //The private guid to identify WiFi Connection Manager
31 //
32 EFI_GUID mEfiWifiMgrPrivateGuid = EFI_WIFIMGR_PRIVATE_GUID;
33
34 //
35 //The Hii config guids
36 //
37 EFI_GUID gWifiConfigFormSetGuid = WIFI_CONNECTION_MANAGER_CONFIG_GUID;
38 EFI_GUID mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID;
39 EFI_GUID mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID;
40 EFI_GUID mWifiConfigMainFormRefreshGuid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID;
41
42 /**
43 Tests to see if this driver supports a given controller. If a child device is provided,
44 it further tests to see if this driver supports creating a handle for the specified child device.
45
46 This function checks to see if the driver specified by This supports the device specified by
47 ControllerHandle. Drivers will typically use the device path attached to
48 ControllerHandle and/or the services from the bus I/O abstraction attached to
49 ControllerHandle to determine if the driver supports ControllerHandle. This function
50 may be called many times during platform initialization. In order to reduce boot times, the tests
51 performed by this function must be very small, and take as little time as possible to execute. This
52 function must not change the state of any hardware devices, and this function must be aware that the
53 device specified by ControllerHandle may already be managed by the same driver or a
54 different driver. This function must match its calls to AllocatePages() with FreePages(),
55 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
56 Because ControllerHandle may have been previously started by the same driver, if a protocol is
57 already in the opened state, then it must not be closed with CloseProtocol(). This is required
58 to guarantee the state of ControllerHandle is not modified by this function.
59
60 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
61 @param[in] ControllerHandle The handle of the controller to test. This handle
62 must support a protocol interface that supplies
63 an I/O abstraction to the driver.
64 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
65 parameter is ignored by device drivers, and is optional for bus
66 drivers. For bus drivers, if this parameter is not NULL, then
67 the bus driver must determine if the bus controller specified
68 by ControllerHandle and the child controller specified
69 by RemainingDevicePath are both supported by this
70 bus driver.
71
72 @retval EFI_SUCCESS The device specified by ControllerHandle and
73 RemainingDevicePath is supported by the driver specified by This.
74 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
75 RemainingDevicePath is already being managed by the driver
76 specified by This.
77 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
78 RemainingDevicePath is already being managed by a different
79 driver or an application that requires exclusive access.
80 Currently not implemented.
81 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
82 RemainingDevicePath is not supported by the driver specified by This.
83
84 **/
85 EFI_STATUS
86 EFIAPI
87 WifiMgrDxeDriverBindingSupported (
88 IN EFI_DRIVER_BINDING_PROTOCOL *This,
89 IN EFI_HANDLE ControllerHandle,
90 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
91 )
92 {
93 EFI_STATUS Status;
94
95 Status = gBS->OpenProtocol (
96 ControllerHandle,
97 &mEfiWifiMgrPrivateGuid,
98 NULL,
99 This->DriverBindingHandle,
100 ControllerHandle,
101 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
102 );
103 if (!EFI_ERROR (Status)) {
104 return EFI_ALREADY_STARTED;
105 }
106
107 //
108 // Test for the wireless MAC connection 2 protocol
109 //
110 return gBS->OpenProtocol (
111 ControllerHandle,
112 &gEfiWiFi2ProtocolGuid,
113 NULL,
114 This->DriverBindingHandle,
115 ControllerHandle,
116 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
117 );
118 }
119
120 /**
121 Starts a device controller or a bus controller.
122
123 The Start() function is designed to be invoked from the EFI boot service ConnectController().
124 As a result, much of the error checking on the parameters to Start() has been moved into this
125 common boot service. It is legal to call Start() from other locations,
126 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
127 1. ControllerHandle must be a valid EFI_HANDLE.
128 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
129 EFI_DEVICE_PATH_PROTOCOL.
130 3. Prior to calling Start(), the Supported() function for the driver specified by This must
131 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
132
133 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
134 @param[in] ControllerHandle The handle of the controller to start. This handle
135 must support a protocol interface that supplies
136 an I/O abstraction to the driver.
137 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
138 parameter is ignored by device drivers, and is optional for bus
139 drivers. For a bus driver, if this parameter is NULL, then handles
140 for all the children of Controller are created by this driver.
141 If this parameter is not NULL and the first Device Path Node is
142 not the End of Device Path Node, then only the handle for the
143 child device specified by the first Device Path Node of
144 RemainingDevicePath is created by this driver.
145 If the first Device Path Node of RemainingDevicePath is
146 the End of Device Path Node, no child handle is created by this
147 driver.
148
149 @retval EFI_SUCCESS The device was started.
150 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
151 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
152 @retval Others The driver failded to start the device.
153
154 **/
155 EFI_STATUS
156 EFIAPI
157 WifiMgrDxeDriverBindingStart (
158 IN EFI_DRIVER_BINDING_PROTOCOL *This,
159 IN EFI_HANDLE ControllerHandle,
160 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
161 )
162 {
163 EFI_STATUS Status;
164 EFI_TPL OldTpl;
165 UINTN AddressSize;
166 WIFI_MGR_DEVICE_DATA *Nic;
167 EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp;
168 EFI_SUPPLICANT_PROTOCOL *Supplicant;
169 EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig;
170
171 Nic = NULL;
172
173 //
174 //Open Protocols
175 //
176 Status = gBS->OpenProtocol (
177 ControllerHandle,
178 &gEfiWiFi2ProtocolGuid,
179 (VOID**) &Wmp,
180 This->DriverBindingHandle,
181 ControllerHandle,
182 EFI_OPEN_PROTOCOL_BY_DRIVER
183 );
184 if (EFI_ERROR (Status)) {
185 return Status;
186 }
187
188 Status = gBS->OpenProtocol (
189 ControllerHandle,
190 &gEfiSupplicantProtocolGuid,
191 (VOID**) &Supplicant,
192 This->DriverBindingHandle,
193 ControllerHandle,
194 EFI_OPEN_PROTOCOL_BY_DRIVER
195 );
196 if (EFI_ERROR (Status)) {
197 Supplicant = NULL;
198 }
199
200 Status = gBS->OpenProtocol (
201 ControllerHandle,
202 &gEfiEapConfigurationProtocolGuid,
203 (VOID**) &EapConfig,
204 This->DriverBindingHandle,
205 ControllerHandle,
206 EFI_OPEN_PROTOCOL_BY_DRIVER
207 );
208 if (EFI_ERROR (Status)) {
209 EapConfig = NULL;
210 }
211
212 //
213 //Initialize Nic device data
214 //
215 Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA));
216 if (Nic == NULL) {
217 Status = EFI_OUT_OF_RESOURCES;
218 goto ERROR1;
219 }
220 Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE;
221 Nic->DriverHandle = This->DriverBindingHandle;
222 Nic->ControllerHandle = ControllerHandle;
223 Nic->Private = mPrivate;
224 Nic->Wmp = Wmp;
225 Nic->Supplicant = Supplicant;
226 Nic->EapConfig = EapConfig;
227 Nic->UserSelectedProfile = NULL;
228 Nic->OneTimeScanRequest = FALSE;
229 Nic->ScanTickTime = WIFI_SCAN_FREQUENCY; //Initialize the first scan
230
231 if (Nic->Supplicant != NULL) {
232 WifiMgrGetSupportedSuites(Nic);
233 }
234
235 InitializeListHead (&Nic->ProfileList);
236
237 //
238 // Record the MAC address of the incoming NIC.
239 //
240 Status = NetLibGetMacAddress (
241 ControllerHandle,
242 (EFI_MAC_ADDRESS*) &Nic->MacAddress,
243 &AddressSize
244 );
245 if (EFI_ERROR (Status)) {
246 goto ERROR2;
247 }
248
249 //
250 // Create and start the timer for the status check
251 //
252 Status = gBS->CreateEvent (
253 EVT_NOTIFY_SIGNAL | EVT_TIMER,
254 TPL_CALLBACK,
255 WifiMgrOnTimerTick,
256 Nic,
257 &Nic->TickTimer
258 );
259 if (EFI_ERROR (Status)) {
260 goto ERROR2;
261 }
262
263 Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS(500));
264 if (EFI_ERROR (Status)) {
265 goto ERROR3;
266 }
267
268 Nic->ConnectState = WifiMgrDisconnected;
269 Nic->ScanState = WifiMgrScanFinished;
270
271 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
272 InsertTailList (&mPrivate->NicList, &Nic->Link);
273 Nic->NicIndex = mPrivate->NicCount ++;
274 if (mPrivate->CurrentNic == NULL) {
275 mPrivate->CurrentNic = Nic;
276 }
277 gBS->RestoreTPL (OldTpl);
278
279 Status = gBS->InstallProtocolInterface (
280 &ControllerHandle,
281 &mEfiWifiMgrPrivateGuid,
282 EFI_NATIVE_INTERFACE,
283 &Nic->WifiMgrIdentifier
284 );
285 if (EFI_ERROR (Status)) {
286 goto ERROR4;
287 }
288
289 return EFI_SUCCESS;
290
291 ERROR4:
292
293 gBS->SetTimer (Nic->TickTimer, TimerCancel, 0);
294 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
295 RemoveEntryList (&Nic->Link);
296 mPrivate->NicCount--;
297 gBS->RestoreTPL (OldTpl);
298
299 ERROR3:
300
301 gBS->CloseEvent (Nic->TickTimer);
302
303 ERROR2:
304
305 if (Nic->Supplicant != NULL) {
306 if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
307 FreePool (Nic->SupportedSuites.SupportedAKMSuites);
308 }
309 if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
310 FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
311 }
312 if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
313 FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
314 }
315 }
316 FreePool (Nic);
317
318 ERROR1:
319
320 if (Supplicant != NULL) {
321 gBS->CloseProtocol (
322 ControllerHandle,
323 &gEfiSupplicantProtocolGuid,
324 This->DriverBindingHandle,
325 ControllerHandle
326 );
327 }
328
329 if (EapConfig != NULL) {
330 gBS->CloseProtocol (
331 ControllerHandle,
332 &gEfiEapConfigurationProtocolGuid,
333 This->DriverBindingHandle,
334 ControllerHandle
335 );
336 }
337
338 gBS->CloseProtocol (
339 ControllerHandle,
340 &gEfiWiFi2ProtocolGuid,
341 This->DriverBindingHandle,
342 ControllerHandle
343 );
344
345 return Status;
346 }
347
348 /**
349 Stops a device controller or a bus controller.
350
351 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
352 As a result, much of the error checking on the parameters to Stop() has been moved
353 into this common boot service. It is legal to call Stop() from other locations,
354 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
355 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
356 same driver's Start() function.
357 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
358 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
359 Start() function, and the Start() function must have called OpenProtocol() on
360 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
361
362 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
363 @param[in] ControllerHandle A handle to the device being stopped. The handle must
364 support a bus specific I/O protocol for the driver
365 to use to stop the device.
366 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
367 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
368 if NumberOfChildren is 0.
369
370 @retval EFI_SUCCESS The device was stopped.
371 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
372
373 **/
374 EFI_STATUS
375 EFIAPI
376 WifiMgrDxeDriverBindingStop (
377 IN EFI_DRIVER_BINDING_PROTOCOL *This,
378 IN EFI_HANDLE ControllerHandle,
379 IN UINTN NumberOfChildren,
380 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
381 )
382 {
383 EFI_STATUS Status;
384 EFI_TPL OldTpl;
385 WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier;
386 WIFI_MGR_DEVICE_DATA *Nic;
387
388 Status = gBS->OpenProtocol (
389 ControllerHandle,
390 &mEfiWifiMgrPrivateGuid,
391 (VOID **) &WifiMgrIdentifier,
392 This->DriverBindingHandle,
393 ControllerHandle,
394 EFI_OPEN_PROTOCOL_GET_PROTOCOL
395 );
396 if (EFI_ERROR (Status)) {
397 return EFI_DEVICE_ERROR;
398 }
399
400 Nic = WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER (WifiMgrIdentifier);
401 if (Nic == NULL) {
402 return EFI_DEVICE_ERROR;
403 }
404
405 //
406 // Close Event
407 //
408 gBS->SetTimer (Nic->TickTimer, TimerCancel, 0);
409 gBS->CloseEvent (Nic->TickTimer);
410
411 //
412 // Clean Supported Suites
413 //
414 if (Nic->Supplicant != NULL) {
415 if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
416 FreePool (Nic->SupportedSuites.SupportedAKMSuites);
417 }
418 if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
419 FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
420 }
421 if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
422 FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
423 }
424 }
425
426 //
427 // Close Protocols
428 //
429 Status = gBS->UninstallProtocolInterface (
430 ControllerHandle,
431 &mEfiWifiMgrPrivateGuid,
432 &Nic->WifiMgrIdentifier
433 );
434 if (EFI_ERROR (Status)) {
435 return Status;
436 }
437
438 Status = gBS->CloseProtocol (
439 ControllerHandle,
440 &gEfiWiFi2ProtocolGuid,
441 Nic->DriverHandle,
442 Nic->ControllerHandle
443 );
444 if (EFI_ERROR (Status)) {
445 return Status;
446 }
447
448 if (Nic->Supplicant != NULL) {
449 Status = gBS->CloseProtocol (
450 ControllerHandle,
451 &gEfiSupplicantProtocolGuid,
452 Nic->DriverHandle,
453 Nic->ControllerHandle
454 );
455 if (EFI_ERROR (Status)) {
456 return Status;
457 }
458 }
459
460 if (Nic->EapConfig != NULL) {
461 Status = gBS->CloseProtocol (
462 ControllerHandle,
463 &gEfiEapConfigurationProtocolGuid,
464 Nic->DriverHandle,
465 Nic->ControllerHandle
466 );
467 if (EFI_ERROR (Status)) {
468 return Status;
469 }
470 }
471
472 //
473 // Remove this Nic from Nic list
474 //
475 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
476
477 RemoveEntryList (&Nic->Link);
478 mPrivate->NicCount--;
479 if (mPrivate->CurrentNic == Nic) {
480 mPrivate->CurrentNic = NULL;
481 }
482
483 gBS->RestoreTPL (OldTpl);
484
485 WifiMgrFreeProfileList (&Nic->ProfileList);
486 FreePool (Nic);
487
488 DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Device Controller has been Disconnected!\n"));
489 return EFI_SUCCESS;
490 }
491
492 /**
493 This is the declaration of an EFI image entry point. This entry point is
494 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
495 both device drivers and bus drivers.
496
497 @param ImageHandle The firmware allocated handle for the UEFI image.
498 @param SystemTable A pointer to the EFI System Table.
499
500 @retval EFI_SUCCESS The operation completed successfully.
501 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
502 @retval Others An unexpected error occurred.
503
504 **/
505 EFI_STATUS
506 EFIAPI
507 WifiMgrDxeDriverEntryPoint (
508 IN EFI_HANDLE ImageHandle,
509 IN EFI_SYSTEM_TABLE *SystemTable
510 )
511 {
512 EFI_STATUS Status;
513
514 Status = EfiLibInstallDriverBindingComponentName2 (
515 ImageHandle,
516 SystemTable,
517 &gWifiMgrDxeDriverBinding,
518 ImageHandle,
519 &gWifiMgrDxeComponentName,
520 &gWifiMgrDxeComponentName2
521 );
522 if (EFI_ERROR (Status)) {
523 return Status;
524 }
525
526 //
527 // Initialize the global private data structure.
528 //
529 mPrivate = AllocateZeroPool (sizeof (WIFI_MGR_PRIVATE_DATA));
530 if (mPrivate == NULL) {
531 Status = EFI_OUT_OF_RESOURCES;
532 goto ERROR1;
533 }
534 mPrivate->Signature = WIFI_MGR_PRIVATE_DATA_SIGNATURE;
535 mPrivate->DriverHandle = ImageHandle;
536 InitializeListHead (&mPrivate->NicList);
537 mPrivate->NicCount = 0;
538 mPrivate->CurrentNic = NULL;
539 InitializeListHead (&mPrivate->HiddenNetworkList);
540 mPrivate->HiddenNetworkCount = 0;
541
542 //
543 //Create events for page refresh
544 //
545 Status = gBS->CreateEventEx (
546 EVT_NOTIFY_SIGNAL,
547 TPL_CALLBACK,
548 WifiMgrInternalEmptyFunction,
549 NULL,
550 &mWifiConfigNetworkListRefreshGuid,
551 &mPrivate->NetworkListRefreshEvent
552 );
553 if (EFI_ERROR (Status)) {
554 goto ERROR2;
555 }
556
557 Status = gBS->CreateEventEx (
558 EVT_NOTIFY_SIGNAL,
559 TPL_CALLBACK,
560 WifiMgrInternalEmptyFunction,
561 NULL,
562 &mWifiConfigConnectFormRefreshGuid,
563 &mPrivate->ConnectFormRefreshEvent
564 );
565 if (EFI_ERROR (Status)) {
566 goto ERROR3;
567 }
568
569 Status = gBS->CreateEventEx (
570 EVT_NOTIFY_SIGNAL,
571 TPL_CALLBACK,
572 WifiMgrInternalEmptyFunction,
573 NULL,
574 &mWifiConfigMainFormRefreshGuid,
575 &mPrivate->MainPageRefreshEvent
576 );
577 if (EFI_ERROR (Status)) {
578 goto ERROR4;
579 }
580
581 Status = WifiMgrDxeConfigFormInit (mPrivate);
582 if (EFI_ERROR (Status)) {
583 goto ERROR5;
584 }
585
586 return Status;
587
588 ERROR5:
589 gBS->CloseEvent (mPrivate->MainPageRefreshEvent);
590
591 ERROR4:
592 gBS->CloseEvent (mPrivate->ConnectFormRefreshEvent);
593
594 ERROR3:
595 gBS->CloseEvent (mPrivate->NetworkListRefreshEvent);
596
597 ERROR2:
598 if (mPrivate != NULL) {
599 FreePool (mPrivate);
600 mPrivate = NULL;
601 }
602
603 ERROR1:
604 gBS->UninstallMultipleProtocolInterfaces (
605 ImageHandle,
606 &gEfiDriverBindingProtocolGuid,
607 &gWifiMgrDxeDriverBinding,
608 &gEfiComponentNameProtocolGuid,
609 &gWifiMgrDxeComponentName,
610 &gEfiComponentName2ProtocolGuid,
611 &gWifiMgrDxeComponentName2,
612 NULL
613 );
614
615 return Status;
616 }