546e6aee811035002256661fa56d6b148336966a
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcDriver.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PxeBcDriver.c
15
16 Abstract:
17
18 The driver binding for IP4 CONFIG protocol.
19
20
21 **/
22
23
24 #include "PxeBcImpl.h"
25
26
27 /**
28 The entry point for PxeBc driver which install the driver
29 binding and component name protocol on its image.
30
31 @param ImageHandle The Image handle of the driver
32 @param SystemTable The system table
33
34 @return EFI_SUCCESS
35 @return Others
36
37 **/
38 EFI_STATUS
39 PxeBcDriverEntryPoint (
40 IN EFI_HANDLE ImageHandle,
41 IN EFI_SYSTEM_TABLE *SystemTable
42 )
43 {
44 return EfiLibInstallDriverBindingComponentName2 (
45 ImageHandle,
46 SystemTable,
47 &gPxeBcDriverBinding,
48 ImageHandle,
49 &gPxeBcComponentName,
50 &gPxeBcComponentName2
51 );
52 }
53
54
55 /**
56 Test to see if this driver supports ControllerHandle.
57
58 @param This Protocol instance pointer.
59 @param ControllerHandle Handle of device to test
60 @param RemainingDevicePath Optional parameter use to pick a specific child
61 device to start.
62
63 @return EFI_SUCCES
64 @return EFI_ALREADY_STARTED
65 @return Others
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 PxeBcDriverBindingSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL * This,
72 IN EFI_HANDLE ControllerHandle,
73 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
74 )
75 {
76 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
77 EFI_STATUS Status;
78
79 Status = gBS->OpenProtocol (
80 ControllerHandle,
81 &gEfiPxeBaseCodeProtocolGuid,
82 (VOID **) &PxeBc,
83 This->DriverBindingHandle,
84 ControllerHandle,
85 EFI_OPEN_PROTOCOL_GET_PROTOCOL
86 );
87
88 if (!EFI_ERROR (Status)) {
89 return EFI_ALREADY_STARTED;
90 }
91
92 Status = gBS->OpenProtocol (
93 ControllerHandle,
94 &gEfiDhcp4ServiceBindingProtocolGuid,
95 NULL,
96 This->DriverBindingHandle,
97 ControllerHandle,
98 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
99 );
100
101 if (!EFI_ERROR (Status)) {
102
103 Status = gBS->OpenProtocol (
104 ControllerHandle,
105 &gEfiMtftp4ServiceBindingProtocolGuid,
106 NULL,
107 This->DriverBindingHandle,
108 ControllerHandle,
109 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
110 );
111
112 }
113
114 return Status;
115 }
116
117
118 /**
119 Start this driver on ControllerHandle.
120
121 @param This Protocol instance pointer.
122 @param ControllerHandle Handle of device to bind driver to
123 @param RemainingDevicePath Optional parameter use to pick a specific child
124 device to start.
125
126 @return EFI_SUCCES
127 @return EFI_ALREADY_STARTED
128 @return EFI_OUT_OF_RESOURCES
129 @return Others
130
131 **/
132 EFI_STATUS
133 EFIAPI
134 PxeBcDriverBindingStart (
135 IN EFI_DRIVER_BINDING_PROTOCOL * This,
136 IN EFI_HANDLE ControllerHandle,
137 IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
138 )
139 {
140 PXEBC_PRIVATE_DATA *Private;
141 UINTN Index;
142 EFI_STATUS Status;
143
144 Private = NetAllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));
145 if (Private == NULL) {
146 return EFI_OUT_OF_RESOURCES;
147 }
148
149 Private->Signature = PXEBC_PRIVATE_DATA_SIGNATURE;
150 Private->Controller = ControllerHandle;
151 Private->Image = This->DriverBindingHandle;
152 CopyMem (&Private->PxeBc, &mPxeBcProtocolTemplate, sizeof (Private->PxeBc));
153 Private->PxeBc.Mode = &Private->Mode;
154 CopyMem (&Private->LoadFile, &mLoadFileProtocolTemplate, sizeof (Private->LoadFile));
155
156 Private->ProxyOffer.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
157 Private->Dhcp4Ack.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
158 Private->PxeReply.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
159
160 for (Index = 0; Index < PXEBC_MAX_OFFER_NUM; Index++) {
161 Private->Dhcp4Offers[Index].Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
162 }
163
164 //
165 // Get the NII interface
166 //
167 Status = gBS->OpenProtocol (
168 ControllerHandle,
169 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
170 (VOID **) &Private->Nii,
171 This->DriverBindingHandle,
172 ControllerHandle,
173 EFI_OPEN_PROTOCOL_GET_PROTOCOL
174 );
175 if (EFI_ERROR (Status)) {
176 goto ON_ERROR;
177 }
178
179 Status = NetLibCreateServiceChild (
180 ControllerHandle,
181 This->DriverBindingHandle,
182 &gEfiDhcp4ServiceBindingProtocolGuid,
183 &Private->Dhcp4Child
184 );
185 if (EFI_ERROR (Status)) {
186 goto ON_ERROR;
187 }
188
189 Status = gBS->OpenProtocol (
190 Private->Dhcp4Child,
191 &gEfiDhcp4ProtocolGuid,
192 (VOID **) &Private->Dhcp4,
193 This->DriverBindingHandle,
194 ControllerHandle,
195 EFI_OPEN_PROTOCOL_BY_DRIVER
196 );
197 if (EFI_ERROR (Status)) {
198 goto ON_ERROR;
199 }
200
201 Status = NetLibCreateServiceChild (
202 ControllerHandle,
203 This->DriverBindingHandle,
204 &gEfiMtftp4ServiceBindingProtocolGuid,
205 &Private->Mtftp4Child
206 );
207
208 if (EFI_ERROR (Status)) {
209 goto ON_ERROR;
210 }
211
212 Status = gBS->OpenProtocol (
213 Private->Mtftp4Child,
214 &gEfiMtftp4ProtocolGuid,
215 (VOID **) &Private->Mtftp4,
216 This->DriverBindingHandle,
217 ControllerHandle,
218 EFI_OPEN_PROTOCOL_BY_DRIVER
219 );
220
221 if (EFI_ERROR (Status)) {
222 goto ON_ERROR;
223 }
224
225 Status = NetLibCreateServiceChild (
226 ControllerHandle,
227 This->DriverBindingHandle,
228 &gEfiUdp4ServiceBindingProtocolGuid,
229 &Private->Udp4Child
230 );
231
232 if (EFI_ERROR (Status)) {
233 goto ON_ERROR;
234 }
235
236 Status = gBS->OpenProtocol (
237 Private->Udp4Child,
238 &gEfiUdp4ProtocolGuid,
239 (VOID **) &Private->Udp4,
240 This->DriverBindingHandle,
241 ControllerHandle,
242 EFI_OPEN_PROTOCOL_BY_DRIVER
243 );
244
245 if (EFI_ERROR (Status)) {
246 goto ON_ERROR;
247 }
248
249 NetZeroMem (&Private->Udp4CfgData, sizeof (EFI_UDP4_CONFIG_DATA));
250 Private->Udp4CfgData.AcceptBroadcast = TRUE;
251 Private->Udp4CfgData.AcceptPromiscuous = FALSE;
252 Private->Udp4CfgData.AcceptAnyPort = FALSE;
253 Private->Udp4CfgData.AllowDuplicatePort = TRUE;
254 Private->Udp4CfgData.TypeOfService = DEFAULT_ToS;
255 Private->Udp4CfgData.TimeToLive = DEFAULT_TTL;
256 Private->Udp4CfgData.DoNotFragment = FALSE;
257 Private->Udp4CfgData.ReceiveTimeout = 10000; // 10 milliseconds
258 Private->Udp4CfgData.UseDefaultAddress = FALSE;
259
260 PxeBcInitSeedPacket (&Private->SeedPacket, Private->Udp4);
261
262 Status = gBS->InstallMultipleProtocolInterfaces (
263 &ControllerHandle,
264 &gEfiPxeBaseCodeProtocolGuid,
265 &Private->PxeBc,
266 &gEfiLoadFileProtocolGuid,
267 &Private->LoadFile,
268 NULL
269 );
270 if (EFI_ERROR (Status)) {
271 goto ON_ERROR;
272 }
273
274 return EFI_SUCCESS;
275
276 ON_ERROR:
277
278 if (Private->Udp4Child != NULL) {
279 gBS->CloseProtocol (
280 Private->Udp4Child,
281 &gEfiUdp4ProtocolGuid,
282 This->DriverBindingHandle,
283 ControllerHandle
284 );
285 NetLibDestroyServiceChild (
286 ControllerHandle,
287 This->DriverBindingHandle,
288 &gEfiUdp4ProtocolGuid,
289 Private->Udp4Child
290 );
291 }
292
293 if (Private->Mtftp4Child != NULL) {
294 gBS->CloseProtocol (
295 Private->Mtftp4Child,
296 &gEfiMtftp4ProtocolGuid,
297 This->DriverBindingHandle,
298 ControllerHandle
299 );
300
301 NetLibDestroyServiceChild (
302 ControllerHandle,
303 This->DriverBindingHandle,
304 &gEfiMtftp4ProtocolGuid,
305 Private->Mtftp4Child
306 );
307 }
308
309 if (Private->Dhcp4Child != NULL) {
310 gBS->CloseProtocol (
311 Private->Dhcp4Child,
312 &gEfiDhcp4ProtocolGuid,
313 This->DriverBindingHandle,
314 ControllerHandle
315 );
316
317 NetLibDestroyServiceChild (
318 ControllerHandle,
319 This->DriverBindingHandle,
320 &gEfiDhcp4ProtocolGuid,
321 Private->Dhcp4Child
322 );
323 }
324
325 NetFreePool (Private);
326
327 return Status;
328 }
329
330
331 /**
332 Stop this driver on ControllerHandle.
333
334 @param This Protocol instance pointer.
335 @param ControllerHandle Handle of device to stop driver on
336 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
337 children is zero stop the entire bus driver.
338 @param ChildHandleBuffer List of Child Handles to Stop.
339
340 @return EFI_SUCCESS
341 @return EFI_DEVICE_ERROR
342 @return Others
343
344 **/
345 EFI_STATUS
346 EFIAPI
347 PxeBcDriverBindingStop (
348 IN EFI_DRIVER_BINDING_PROTOCOL *This,
349 IN EFI_HANDLE ControllerHandle,
350 IN UINTN NumberOfChildren,
351 IN EFI_HANDLE *ChildHandleBuffer
352 )
353 {
354 PXEBC_PRIVATE_DATA *Private;
355 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
356 EFI_HANDLE NicHandle;
357 EFI_STATUS Status;
358
359 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
360
361 if (NicHandle == NULL) {
362
363 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
364
365 if (NicHandle == NULL) {
366
367 return EFI_DEVICE_ERROR;
368 }
369 }
370
371 Status = gBS->OpenProtocol (
372 NicHandle,
373 &gEfiPxeBaseCodeProtocolGuid,
374 (VOID **) &PxeBc,
375 This->DriverBindingHandle,
376 ControllerHandle,
377 EFI_OPEN_PROTOCOL_GET_PROTOCOL
378 );
379
380 if (EFI_ERROR (Status)) {
381 return Status;
382 }
383
384 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);
385
386 Status = gBS->UninstallMultipleProtocolInterfaces (
387 NicHandle,
388 &gEfiPxeBaseCodeProtocolGuid,
389 &Private->PxeBc,
390 &gEfiLoadFileProtocolGuid,
391 &Private->LoadFile,
392 NULL
393 );
394
395 if (!EFI_ERROR (Status)) {
396
397 gBS->CloseProtocol (
398 Private->Udp4Child,
399 &gEfiUdp4ProtocolGuid,
400 This->DriverBindingHandle,
401 ControllerHandle
402 );
403 NetLibDestroyServiceChild (
404 ControllerHandle,
405 This->DriverBindingHandle,
406 &gEfiUdp4ServiceBindingProtocolGuid,
407 Private->Udp4Child
408 );
409
410 gBS->CloseProtocol (
411 Private->Dhcp4Child,
412 &gEfiDhcp4ProtocolGuid,
413 This->DriverBindingHandle,
414 ControllerHandle
415 );
416 NetLibDestroyServiceChild (
417 ControllerHandle,
418 This->DriverBindingHandle,
419 &gEfiDhcp4ServiceBindingProtocolGuid,
420 Private->Dhcp4Child
421 );
422
423 gBS->CloseProtocol (
424 Private->Mtftp4Child,
425 &gEfiMtftp4ProtocolGuid,
426 This->DriverBindingHandle,
427 ControllerHandle
428 );
429 NetLibDestroyServiceChild (
430 ControllerHandle,
431 This->DriverBindingHandle,
432 &gEfiMtftp4ServiceBindingProtocolGuid,
433 Private->Mtftp4Child
434 );
435
436 NetFreePool (Private);
437 }
438
439 return Status;
440 }
441
442 EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {
443 PxeBcDriverBindingSupported,
444 PxeBcDriverBindingStart,
445 PxeBcDriverBindingStop,
446 0xa,
447 NULL,
448 NULL
449 };
450
451