]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c
NetworkPkg: Apply uncrustify changes
[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
221 Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE;
222 Nic->DriverHandle = This->DriverBindingHandle;
223 Nic->ControllerHandle = ControllerHandle;
224 Nic->Private = mPrivate;
225 Nic->Wmp = Wmp;
226 Nic->Supplicant = Supplicant;
227 Nic->EapConfig = EapConfig;
228 Nic->UserSelectedProfile = NULL;
229 Nic->OneTimeScanRequest = FALSE;
230 Nic->ScanTickTime = WIFI_SCAN_FREQUENCY; // Initialize the first scan
231
232 if (Nic->Supplicant != NULL) {
233 WifiMgrGetSupportedSuites (Nic);
234 }
235
236 InitializeListHead (&Nic->ProfileList);
237
238 //
239 // Record the MAC address of the incoming NIC.
240 //
241 Status = NetLibGetMacAddress (
242 ControllerHandle,
243 (EFI_MAC_ADDRESS *)&Nic->MacAddress,
244 &AddressSize
245 );
246 if (EFI_ERROR (Status)) {
247 goto ERROR2;
248 }
249
250 //
251 // Create and start the timer for the status check
252 //
253 Status = gBS->CreateEvent (
254 EVT_NOTIFY_SIGNAL | EVT_TIMER,
255 TPL_CALLBACK,
256 WifiMgrOnTimerTick,
257 Nic,
258 &Nic->TickTimer
259 );
260 if (EFI_ERROR (Status)) {
261 goto ERROR2;
262 }
263
264 Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (500));
265 if (EFI_ERROR (Status)) {
266 goto ERROR3;
267 }
268
269 Nic->ConnectState = WifiMgrDisconnected;
270 Nic->ScanState = WifiMgrScanFinished;
271
272 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
273 InsertTailList (&mPrivate->NicList, &Nic->Link);
274 Nic->NicIndex = mPrivate->NicCount++;
275 if (mPrivate->CurrentNic == NULL) {
276 mPrivate->CurrentNic = Nic;
277 }
278
279 gBS->RestoreTPL (OldTpl);
280
281 Status = gBS->InstallProtocolInterface (
282 &ControllerHandle,
283 &mEfiWifiMgrPrivateGuid,
284 EFI_NATIVE_INTERFACE,
285 &Nic->WifiMgrIdentifier
286 );
287 if (EFI_ERROR (Status)) {
288 goto ERROR4;
289 }
290
291 return EFI_SUCCESS;
292
293 ERROR4:
294
295 gBS->SetTimer (Nic->TickTimer, TimerCancel, 0);
296 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
297 RemoveEntryList (&Nic->Link);
298 mPrivate->NicCount--;
299 gBS->RestoreTPL (OldTpl);
300
301 ERROR3:
302
303 gBS->CloseEvent (Nic->TickTimer);
304
305 ERROR2:
306
307 if (Nic->Supplicant != NULL) {
308 if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
309 FreePool (Nic->SupportedSuites.SupportedAKMSuites);
310 }
311
312 if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
313 FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
314 }
315
316 if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
317 FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
318 }
319 }
320
321 FreePool (Nic);
322
323 ERROR1:
324
325 if (Supplicant != NULL) {
326 gBS->CloseProtocol (
327 ControllerHandle,
328 &gEfiSupplicantProtocolGuid,
329 This->DriverBindingHandle,
330 ControllerHandle
331 );
332 }
333
334 if (EapConfig != NULL) {
335 gBS->CloseProtocol (
336 ControllerHandle,
337 &gEfiEapConfigurationProtocolGuid,
338 This->DriverBindingHandle,
339 ControllerHandle
340 );
341 }
342
343 gBS->CloseProtocol (
344 ControllerHandle,
345 &gEfiWiFi2ProtocolGuid,
346 This->DriverBindingHandle,
347 ControllerHandle
348 );
349
350 return Status;
351 }
352
353 /**
354 Stops a device controller or a bus controller.
355
356 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
357 As a result, much of the error checking on the parameters to Stop() has been moved
358 into this common boot service. It is legal to call Stop() from other locations,
359 but the following calling restrictions must be followed, or the system behavior will not be deterministic.
360 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
361 same driver's Start() function.
362 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
363 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
364 Start() function, and the Start() function must have called OpenProtocol() on
365 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
366
367 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
368 @param[in] ControllerHandle A handle to the device being stopped. The handle must
369 support a bus specific I/O protocol for the driver
370 to use to stop the device.
371 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
372 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
373 if NumberOfChildren is 0.
374
375 @retval EFI_SUCCESS The device was stopped.
376 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
377
378 **/
379 EFI_STATUS
380 EFIAPI
381 WifiMgrDxeDriverBindingStop (
382 IN EFI_DRIVER_BINDING_PROTOCOL *This,
383 IN EFI_HANDLE ControllerHandle,
384 IN UINTN NumberOfChildren,
385 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
386 )
387 {
388 EFI_STATUS Status;
389 EFI_TPL OldTpl;
390 WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier;
391 WIFI_MGR_DEVICE_DATA *Nic;
392
393 Status = gBS->OpenProtocol (
394 ControllerHandle,
395 &mEfiWifiMgrPrivateGuid,
396 (VOID **)&WifiMgrIdentifier,
397 This->DriverBindingHandle,
398 ControllerHandle,
399 EFI_OPEN_PROTOCOL_GET_PROTOCOL
400 );
401 if (EFI_ERROR (Status)) {
402 return EFI_DEVICE_ERROR;
403 }
404
405 Nic = WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER (WifiMgrIdentifier);
406 if (Nic == NULL) {
407 return EFI_DEVICE_ERROR;
408 }
409
410 //
411 // Close Event
412 //
413 gBS->SetTimer (Nic->TickTimer, TimerCancel, 0);
414 gBS->CloseEvent (Nic->TickTimer);
415
416 //
417 // Clean Supported Suites
418 //
419 if (Nic->Supplicant != NULL) {
420 if (Nic->SupportedSuites.SupportedAKMSuites != NULL) {
421 FreePool (Nic->SupportedSuites.SupportedAKMSuites);
422 }
423
424 if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) {
425 FreePool (Nic->SupportedSuites.SupportedSwCipherSuites);
426 }
427
428 if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) {
429 FreePool (Nic->SupportedSuites.SupportedHwCipherSuites);
430 }
431 }
432
433 //
434 // Close Protocols
435 //
436 Status = gBS->UninstallProtocolInterface (
437 ControllerHandle,
438 &mEfiWifiMgrPrivateGuid,
439 &Nic->WifiMgrIdentifier
440 );
441 if (EFI_ERROR (Status)) {
442 return Status;
443 }
444
445 Status = gBS->CloseProtocol (
446 ControllerHandle,
447 &gEfiWiFi2ProtocolGuid,
448 Nic->DriverHandle,
449 Nic->ControllerHandle
450 );
451 if (EFI_ERROR (Status)) {
452 return Status;
453 }
454
455 if (Nic->Supplicant != NULL) {
456 Status = gBS->CloseProtocol (
457 ControllerHandle,
458 &gEfiSupplicantProtocolGuid,
459 Nic->DriverHandle,
460 Nic->ControllerHandle
461 );
462 if (EFI_ERROR (Status)) {
463 return Status;
464 }
465 }
466
467 if (Nic->EapConfig != NULL) {
468 Status = gBS->CloseProtocol (
469 ControllerHandle,
470 &gEfiEapConfigurationProtocolGuid,
471 Nic->DriverHandle,
472 Nic->ControllerHandle
473 );
474 if (EFI_ERROR (Status)) {
475 return Status;
476 }
477 }
478
479 //
480 // Remove this Nic from Nic list
481 //
482 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
483
484 RemoveEntryList (&Nic->Link);
485 mPrivate->NicCount--;
486 if (mPrivate->CurrentNic == Nic) {
487 mPrivate->CurrentNic = NULL;
488 }
489
490 gBS->RestoreTPL (OldTpl);
491
492 WifiMgrFreeProfileList (&Nic->ProfileList);
493 FreePool (Nic);
494
495 DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Device Controller has been Disconnected!\n"));
496 return EFI_SUCCESS;
497 }
498
499 /**
500 This is the declaration of an EFI image entry point. This entry point is
501 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
502 both device drivers and bus drivers.
503
504 @param ImageHandle The firmware allocated handle for the UEFI image.
505 @param SystemTable A pointer to the EFI System Table.
506
507 @retval EFI_SUCCESS The operation completed successfully.
508 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
509 @retval Others An unexpected error occurred.
510
511 **/
512 EFI_STATUS
513 EFIAPI
514 WifiMgrDxeDriverEntryPoint (
515 IN EFI_HANDLE ImageHandle,
516 IN EFI_SYSTEM_TABLE *SystemTable
517 )
518 {
519 EFI_STATUS Status;
520
521 Status = EfiLibInstallDriverBindingComponentName2 (
522 ImageHandle,
523 SystemTable,
524 &gWifiMgrDxeDriverBinding,
525 ImageHandle,
526 &gWifiMgrDxeComponentName,
527 &gWifiMgrDxeComponentName2
528 );
529 if (EFI_ERROR (Status)) {
530 return Status;
531 }
532
533 //
534 // Initialize the global private data structure.
535 //
536 mPrivate = AllocateZeroPool (sizeof (WIFI_MGR_PRIVATE_DATA));
537 if (mPrivate == NULL) {
538 Status = EFI_OUT_OF_RESOURCES;
539 goto ERROR1;
540 }
541
542 mPrivate->Signature = WIFI_MGR_PRIVATE_DATA_SIGNATURE;
543 mPrivate->DriverHandle = ImageHandle;
544 InitializeListHead (&mPrivate->NicList);
545 mPrivate->NicCount = 0;
546 mPrivate->CurrentNic = NULL;
547 InitializeListHead (&mPrivate->HiddenNetworkList);
548 mPrivate->HiddenNetworkCount = 0;
549
550 //
551 // Create events for page refresh
552 //
553 Status = gBS->CreateEventEx (
554 EVT_NOTIFY_SIGNAL,
555 TPL_CALLBACK,
556 WifiMgrInternalEmptyFunction,
557 NULL,
558 &mWifiConfigNetworkListRefreshGuid,
559 &mPrivate->NetworkListRefreshEvent
560 );
561 if (EFI_ERROR (Status)) {
562 goto ERROR2;
563 }
564
565 Status = gBS->CreateEventEx (
566 EVT_NOTIFY_SIGNAL,
567 TPL_CALLBACK,
568 WifiMgrInternalEmptyFunction,
569 NULL,
570 &mWifiConfigConnectFormRefreshGuid,
571 &mPrivate->ConnectFormRefreshEvent
572 );
573 if (EFI_ERROR (Status)) {
574 goto ERROR3;
575 }
576
577 Status = gBS->CreateEventEx (
578 EVT_NOTIFY_SIGNAL,
579 TPL_CALLBACK,
580 WifiMgrInternalEmptyFunction,
581 NULL,
582 &mWifiConfigMainFormRefreshGuid,
583 &mPrivate->MainPageRefreshEvent
584 );
585 if (EFI_ERROR (Status)) {
586 goto ERROR4;
587 }
588
589 Status = WifiMgrDxeConfigFormInit (mPrivate);
590 if (EFI_ERROR (Status)) {
591 goto ERROR5;
592 }
593
594 return Status;
595
596 ERROR5:
597 gBS->CloseEvent (mPrivate->MainPageRefreshEvent);
598
599 ERROR4:
600 gBS->CloseEvent (mPrivate->ConnectFormRefreshEvent);
601
602 ERROR3:
603 gBS->CloseEvent (mPrivate->NetworkListRefreshEvent);
604
605 ERROR2:
606 if (mPrivate != NULL) {
607 FreePool (mPrivate);
608 mPrivate = NULL;
609 }
610
611 ERROR1:
612 gBS->UninstallMultipleProtocolInterfaces (
613 ImageHandle,
614 &gEfiDriverBindingProtocolGuid,
615 &gWifiMgrDxeDriverBinding,
616 &gEfiComponentNameProtocolGuid,
617 &gWifiMgrDxeComponentName,
618 &gEfiComponentName2ProtocolGuid,
619 &gWifiMgrDxeComponentName2,
620 NULL
621 );
622
623 return Status;
624 }