]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/BiosSnp16.c
IntelFrameworkModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / BiosThunk / Snp16Dxe / BiosSnp16.c
CommitLineData
bcecde14 1/** @file\r
2\r
0a6f4824 3Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>\r
bcecde14 4\r
c0a00b14 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
bcecde14 6\r
7**/\r
8\r
9#include "BiosSnp16.h"\r
10\r
11\r
12///\r
13/// EFI Driver Binding Protocol Instance\r
14///\r
15EFI_DRIVER_BINDING_PROTOCOL gBiosSnp16DriverBinding = {\r
16 BiosSnp16DriverBindingSupported,\r
17 BiosSnp16DriverBindingStart,\r
18 BiosSnp16DriverBindingStop,\r
19 0x3,\r
20 NULL,\r
21 NULL\r
22};\r
23\r
24///\r
25/// This boolean is used to determine if we should release the cached vector during an error condition.\r
26///\r
27BOOLEAN mCachedInt1A = FALSE;\r
28\r
29//\r
30// Private worker functions;\r
31//\r
32\r
33/**\r
34 Start the UNDI interface.\r
35\r
36 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
37 @param Ax PCI address of Undi device.\r
0a6f4824
LG
38\r
39 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.\r
40 @retval Others Status of start 16 bit UNDI ROM.\r
bcecde14 41**/\r
42EFI_STATUS\r
43Undi16SimpleNetworkStartUndi (\r
44 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,\r
45 UINT16 Ax\r
46 );\r
47\r
48/**\r
49 Start the UNDI interface\r
50\r
51 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
52\r
53 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.\r
54 @retval Others Status of start 16 bit UNDI ROM.\r
bcecde14 55**/\r
56EFI_STATUS\r
57Undi16SimpleNetworkStopUndi (\r
58 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
59 );\r
60\r
61/**\r
62 Stop the UNDI interface\r
63\r
64 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
65\r
66 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM.\r
67 @retval Others Status of stop 16 bit UNDI ROM.\r
bcecde14 68**/\r
69EFI_STATUS\r
70Undi16SimpleNetworkCleanupUndi (\r
71 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
72 );\r
73\r
74/**\r
75 Get runtime information for Undi network interface\r
76\r
77 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
78\r
79 @retval EFI_SUCCESS Sucess operation.\r
80 @retval Others Fail to get runtime information for Undi network interface.\r
bcecde14 81**/\r
82EFI_STATUS\r
83Undi16SimpleNetworkGetInformation (\r
84 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
85 );\r
86\r
87/**\r
88 Get NIC type\r
89\r
90 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
91\r
92 @retval EFI_SUCCESS Sucess operation.\r
bcecde14 93 @retval Others Fail to get NIC type.\r
94**/\r
95EFI_STATUS\r
96Undi16SimpleNetworkGetNicType (\r
97 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
98 );\r
99\r
100/**\r
101 Get NDIS information\r
102\r
103 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
104\r
105 @retval EFI_SUCCESS Sucess operation.\r
bcecde14 106 @retval Others Fail to get NDIS information.\r
107**/\r
108EFI_STATUS\r
109Undi16SimpleNetworkGetNdisInfo (\r
110 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
111 );\r
112\r
113/**\r
114 Signal handlers for ExitBootServices event.\r
0a6f4824
LG
115\r
116 Clean up any Real-mode UNDI residue from the system\r
117\r
bcecde14 118 @param Event ExitBootServices event\r
0a6f4824 119 @param Context\r
bcecde14 120**/\r
121VOID\r
122EFIAPI\r
123Undi16SimpleNetworkEvent (\r
124 IN EFI_EVENT Event,\r
125 IN VOID *Context\r
126 );\r
127\r
128/**\r
129 Loads the undi driver.\r
130\r
131 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824 132\r
bcecde14 133 @retval EFI_SUCCESS - Successfully loads undi driver.\r
134 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.\r
135**/\r
136EFI_STATUS\r
137Undi16SimpleNetworkLoadUndi (\r
138 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
139 );\r
140\r
141/**\r
142 Unload 16 bit UNDI Option ROM from memory\r
143\r
144 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
145\r
146 @return EFI_STATUS\r
bcecde14 147**/\r
148EFI_STATUS\r
149Undi16SimpleNetworkUnloadUndi (\r
150 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
151 );\r
152\r
153/**\r
154 Entry point for EFI drivers.\r
155\r
156 @param ImageHandle Handle that identifies the loaded image.\r
157 @param SystemTable System Table for this image.\r
0a6f4824
LG
158\r
159 @return EFI_STATUS Return status from EfiLibInstallAllDriverProtocols.\r
bcecde14 160**/\r
161EFI_STATUS\r
162EFIAPI\r
163BiosSnp16DriverEntryPoint (\r
164 IN EFI_HANDLE ImageHandle,\r
165 IN EFI_SYSTEM_TABLE *SystemTable\r
166 )\r
167{\r
168 return EfiLibInstallDriverBindingComponentName2 (\r
169 ImageHandle,\r
170 SystemTable,\r
171 &gBiosSnp16DriverBinding,\r
172 ImageHandle,\r
173 &gBiosSnp16ComponentName,\r
174 &gBiosSnp16ComponentName2\r
175 );\r
176}\r
177\r
178//\r
179// EFI Driver Binding Protocol Functions\r
180//\r
181/**\r
182 Tests to see if this driver supports a given controller.\r
183\r
184 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
185 @param Controller The handle of the controller to test.\r
186 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
0a6f4824 187\r
bcecde14 188 @retval EFI_SUCCESS The driver supports given controller.\r
189 @retval EFI_UNSUPPORT The driver doesn't support given controller.\r
190 @retval Other Other errors prevent driver finishing to test\r
191 if the driver supports given controller.\r
192**/\r
193EFI_STATUS\r
194EFIAPI\r
195BiosSnp16DriverBindingSupported (\r
196 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
197 IN EFI_HANDLE Controller,\r
198 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
199 )\r
200{\r
201 EFI_STATUS Status;\r
202 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
203 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
204 EFI_PCI_IO_PROTOCOL *PciIo;\r
205 PCI_TYPE00 Pci;\r
206\r
207 //\r
208 // See if the Legacy BIOS Protocol is available\r
209 //\r
210 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
211 if (EFI_ERROR (Status)) {\r
212 return Status;\r
213 }\r
214 //\r
215 // Open the IO Abstraction(s) needed to perform the supported test\r
216 //\r
217 Status = gBS->OpenProtocol (\r
218 Controller,\r
219 &gEfiDevicePathProtocolGuid,\r
220 (VOID **) &DevicePath,\r
221 This->DriverBindingHandle,\r
222 Controller,\r
223 EFI_OPEN_PROTOCOL_BY_DRIVER\r
224 );\r
225 if (EFI_ERROR (Status)) {\r
226 return Status;\r
227 }\r
228\r
229 gBS->CloseProtocol (\r
230 Controller,\r
231 &gEfiDevicePathProtocolGuid,\r
232 This->DriverBindingHandle,\r
233 Controller\r
234 );\r
235\r
236 //\r
237 // Open the IO Abstraction(s) needed to perform the supported test\r
238 //\r
239 Status = gBS->OpenProtocol (\r
240 Controller,\r
241 &gEfiPciIoProtocolGuid,\r
242 (VOID **) &PciIo,\r
243 This->DriverBindingHandle,\r
244 Controller,\r
245 EFI_OPEN_PROTOCOL_BY_DRIVER\r
246 );\r
247 if (EFI_ERROR (Status)) {\r
248 return Status;\r
249 }\r
250 //\r
251 // See if this is a PCI Network Controller by looking at the Command register and\r
252 // Class Code Register\r
253 //\r
254 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);\r
255 if (EFI_ERROR (Status)) {\r
256 Status = EFI_UNSUPPORTED;\r
257 goto Done;\r
258 }\r
259\r
260 Status = EFI_UNSUPPORTED;\r
261 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_NETWORK) {\r
262 Status = EFI_SUCCESS;\r
263 }\r
264\r
265Done:\r
266 gBS->CloseProtocol (\r
267 Controller,\r
268 &gEfiPciIoProtocolGuid,\r
269 This->DriverBindingHandle,\r
270 Controller\r
271 );\r
272\r
273 return Status;\r
274}\r
275\r
276/**\r
277 Starts the Snp device controller\r
278\r
279 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
280 @param Controller The handle of the controller to test.\r
281 @param RemainingDevicePath A pointer to the remaining portion of a device path.\r
0a6f4824
LG
282\r
283 @retval EFI_SUCCESS - The device was started.\r
bcecde14 284 @retval EFI_DEVICE_ERROR - The device could not be started due to a device error.\r
285 @retval EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.\r
286**/\r
287EFI_STATUS\r
288EFIAPI\r
289BiosSnp16DriverBindingStart (\r
290 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
291 IN EFI_HANDLE Controller,\r
292 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
293 )\r
294{\r
295 EFI_STATUS Status;\r
296 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
297 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
298 EFI_PCI_IO_PROTOCOL *PciIo;\r
299 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
300 EFI_DEV_PATH Node;\r
301 UINTN Index;\r
302 UINTN Index2;\r
303 UINTN Segment;\r
304 UINTN Bus;\r
305 UINTN Device;\r
306 UINTN Function;\r
307 UINTN Flags;\r
308 UINT64 Supports;\r
309\r
310 SimpleNetworkDevice = NULL;\r
311 PciIo = NULL;\r
312\r
313 //\r
314 // See if the Legacy BIOS Protocol is available\r
315 //\r
316 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
317 if (EFI_ERROR (Status)) {\r
318 return Status;\r
319 }\r
320 //\r
321 // Open the IO Abstraction(s) needed\r
322 //\r
323 Status = gBS->OpenProtocol (\r
324 Controller,\r
325 &gEfiDevicePathProtocolGuid,\r
326 (VOID **) &DevicePath,\r
327 This->DriverBindingHandle,\r
328 Controller,\r
329 EFI_OPEN_PROTOCOL_BY_DRIVER\r
330 );\r
331 if (EFI_ERROR (Status)) {\r
332 goto Done;\r
333 }\r
334\r
335 Status = gBS->OpenProtocol (\r
336 Controller,\r
337 &gEfiPciIoProtocolGuid,\r
338 (VOID **) &PciIo,\r
339 This->DriverBindingHandle,\r
340 Controller,\r
341 EFI_OPEN_PROTOCOL_BY_DRIVER\r
342 );\r
343 if (EFI_ERROR (Status)) {\r
344 goto Done;\r
345 }\r
346\r
347 Status = PciIo->Attributes (\r
348 PciIo,\r
349 EfiPciIoAttributeOperationSupported,\r
350 0,\r
351 &Supports\r
352 );\r
353 if (!EFI_ERROR (Status)) {\r
1a45b15e 354 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
bcecde14 355 Status = PciIo->Attributes (\r
356 PciIo,\r
357 EfiPciIoAttributeOperationEnable,\r
358 Supports,\r
359 NULL\r
360 );\r
361 }\r
362\r
363 if (EFI_ERROR (Status)) {\r
364 goto Done;\r
365 }\r
366 //\r
367 // Check to see if there is a legacy option ROM image associated with this PCI device\r
368 //\r
369 Status = LegacyBios->CheckPciRom (\r
370 LegacyBios,\r
371 Controller,\r
372 NULL,\r
373 NULL,\r
374 &Flags\r
375 );\r
376 if (EFI_ERROR (Status)) {\r
377 goto Done;\r
378 }\r
379 //\r
380 // Post the legacy option ROM if it is available.\r
381 //\r
382 Status = LegacyBios->InstallPciRom (\r
383 LegacyBios,\r
384 Controller,\r
385 NULL,\r
386 &Flags,\r
387 NULL,\r
388 NULL,\r
389 NULL,\r
390 NULL\r
391 );\r
392 if (EFI_ERROR (Status)) {\r
393 goto Done;\r
394 }\r
395 //\r
396 // Allocate memory for this SimpleNetwork device instance\r
397 //\r
398 Status = gBS->AllocatePool (\r
399 EfiBootServicesData,\r
400 sizeof (EFI_SIMPLE_NETWORK_DEV),\r
401 (VOID **) &SimpleNetworkDevice\r
402 );\r
403 if (EFI_ERROR (Status)) {\r
404 Status = EFI_OUT_OF_RESOURCES;\r
405 goto Done;\r
406 }\r
407\r
408 ZeroMem (SimpleNetworkDevice, sizeof (EFI_SIMPLE_NETWORK_DEV));\r
409\r
410 //\r
411 // Initialize the SimpleNetwork device instance\r
412 //\r
413 SimpleNetworkDevice->Signature = EFI_SIMPLE_NETWORK_DEV_SIGNATURE;\r
414 SimpleNetworkDevice->LegacyBios = LegacyBios;\r
415 SimpleNetworkDevice->BaseDevicePath = DevicePath;\r
416 SimpleNetworkDevice->PciIo = PciIo;\r
417\r
418 //\r
419 // Initialize the Nii Protocol\r
420 //\r
421 SimpleNetworkDevice->Nii.Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;\r
422 SimpleNetworkDevice->Nii.Type = EfiNetworkInterfaceUndi;\r
423\r
424 CopyMem (&SimpleNetworkDevice->Nii.StringId, "UNDI", 4);\r
425\r
426 //\r
427 // Load 16 bit UNDI Option ROM into Memory\r
428 //\r
429 Status = Undi16SimpleNetworkLoadUndi (SimpleNetworkDevice);\r
430 if (EFI_ERROR (Status)) {\r
431 DEBUG ((DEBUG_NET, "ERROR : Could not load UNDI. Status = %r\n", Status));\r
432 goto Done;\r
433 }\r
434\r
435 SimpleNetworkDevice->UndiLoaded = TRUE;\r
436\r
437 //\r
438 // Call PXENV_START_UNDI - Initilizes the UNID interface for use.\r
439 //\r
440 PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
441 Status = Undi16SimpleNetworkStartUndi (\r
442 SimpleNetworkDevice,\r
443 (UINT16) ((Bus << 0x8) | (Device << 0x3) | (Function))\r
444 );\r
445 if (EFI_ERROR (Status)) {\r
446 DEBUG ((DEBUG_NET, "ERROR : Could not StartUndi. Status = %r\n", Status));\r
447 goto Done;\r
448 }\r
449 //\r
450 // Initialize the Simple Network Protocol\r
451 //\r
452 DEBUG ((DEBUG_NET, "Initialize SimpleNetworkDevice instance\n"));\r
453\r
454 SimpleNetworkDevice->SimpleNetwork.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;\r
455 SimpleNetworkDevice->SimpleNetwork.Start = Undi16SimpleNetworkStart;\r
456 SimpleNetworkDevice->SimpleNetwork.Stop = Undi16SimpleNetworkStop;\r
457 SimpleNetworkDevice->SimpleNetwork.Initialize = Undi16SimpleNetworkInitialize;\r
458 SimpleNetworkDevice->SimpleNetwork.Reset = Undi16SimpleNetworkReset;\r
459 SimpleNetworkDevice->SimpleNetwork.Shutdown = Undi16SimpleNetworkShutdown;\r
460 SimpleNetworkDevice->SimpleNetwork.ReceiveFilters = Undi16SimpleNetworkReceiveFilters;\r
461 SimpleNetworkDevice->SimpleNetwork.StationAddress = Undi16SimpleNetworkStationAddress;\r
462 SimpleNetworkDevice->SimpleNetwork.Statistics = Undi16SimpleNetworkStatistics;\r
463 SimpleNetworkDevice->SimpleNetwork.MCastIpToMac = Undi16SimpleNetworkMCastIpToMac;\r
464 SimpleNetworkDevice->SimpleNetwork.NvData = Undi16SimpleNetworkNvData;\r
465 SimpleNetworkDevice->SimpleNetwork.GetStatus = Undi16SimpleNetworkGetStatus;\r
466 SimpleNetworkDevice->SimpleNetwork.Transmit = Undi16SimpleNetworkTransmit;\r
467 SimpleNetworkDevice->SimpleNetwork.Receive = Undi16SimpleNetworkReceive;\r
468 SimpleNetworkDevice->SimpleNetwork.Mode = &(SimpleNetworkDevice->SimpleNetworkMode);\r
469\r
470 Status = gBS->CreateEvent (\r
471 EVT_NOTIFY_WAIT,\r
472 TPL_NOTIFY,\r
473 Undi16SimpleNetworkWaitForPacket,\r
474 &SimpleNetworkDevice->SimpleNetwork,\r
475 &SimpleNetworkDevice->SimpleNetwork.WaitForPacket\r
476 );\r
477 if (EFI_ERROR (Status)) {\r
478 DEBUG ((DEBUG_ERROR, "ERROR : Could not create event. Status = %r\n", Status));\r
479 goto Done;\r
480 }\r
481 //\r
482 // Create an event to be signalled when ExitBootServices occurs in order\r
483 // to clean up nicely\r
484 //\r
485 Status = gBS->CreateEventEx (\r
486 EVT_NOTIFY_SIGNAL,\r
487 TPL_NOTIFY,\r
488 Undi16SimpleNetworkEvent,\r
489 NULL,\r
490 &gEfiEventExitBootServicesGuid,\r
491 &SimpleNetworkDevice->EfiBootEvent\r
492 );\r
493 if (EFI_ERROR (Status)) {\r
494 DEBUG ((DEBUG_ERROR, "ERROR : Could not create event. Status = %r\n", Status));\r
495 goto Done;\r
496 }\r
497\r
498 //\r
499 // Create an event to be signalled when Legacy Boot occurs to clean up the IVT\r
500 //\r
501 Status = EfiCreateEventLegacyBootEx(\r
0a6f4824
LG
502 TPL_NOTIFY,\r
503 Undi16SimpleNetworkEvent,\r
504 NULL,\r
bcecde14 505 &SimpleNetworkDevice->LegacyBootEvent\r
506 );\r
0a6f4824 507\r
bcecde14 508 if (EFI_ERROR(Status)) {\r
509 DEBUG ((DEBUG_ERROR,"ERROR : Could not create event. Status = %r\n",Status));\r
510 goto Done;\r
511 }\r
512\r
513 //\r
514 // Initialize the SimpleNetwork Mode Information\r
515 //\r
516 DEBUG ((DEBUG_NET, "Initialize Mode Information\n"));\r
517\r
518 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;\r
519 SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize = 14;\r
520 SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable = TRUE;\r
521 SimpleNetworkDevice->SimpleNetworkMode.MultipleTxSupported = TRUE;\r
522 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |\r
523 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |\r
524 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST |\r
525 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |\r
526 EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
527 SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount = MAXNUM_MCADDR;\r
528\r
529 //\r
530 // Initialize the SimpleNetwork Private Information\r
531 //\r
532 DEBUG ((DEBUG_NET, "Initialize Private Information\n"));\r
533\r
534 Status = BiosSnp16AllocatePagesBelowOneMb (\r
535 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1,\r
536 (VOID **) &SimpleNetworkDevice->Xmit\r
537 );\r
538 if (EFI_ERROR (Status)) {\r
539 goto Done;\r
540 }\r
541\r
542 Status = BiosSnp16AllocatePagesBelowOneMb (\r
543 1,\r
544 &SimpleNetworkDevice->TxRealModeMediaHeader\r
545 );\r
546 if (EFI_ERROR (Status)) {\r
547 goto Done;\r
548 }\r
549\r
550 Status = BiosSnp16AllocatePagesBelowOneMb (\r
551 1,\r
552 &SimpleNetworkDevice->TxRealModeDataBuffer\r
553 );\r
554 if (EFI_ERROR (Status)) {\r
555 goto Done;\r
556 }\r
557\r
558 Status = BiosSnp16AllocatePagesBelowOneMb (\r
559 1,\r
560 &SimpleNetworkDevice->TxDestAddr\r
561 );\r
562 if (EFI_ERROR (Status)) {\r
563 goto Done;\r
564 }\r
565\r
566 SimpleNetworkDevice->Xmit->XmitOffset = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeMediaHeader) & 0x000f);\r
567\r
568 SimpleNetworkDevice->Xmit->XmitSegment = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeMediaHeader) >> 4);\r
569\r
570 SimpleNetworkDevice->Xmit->DataBlkCount = 1;\r
571\r
572 SimpleNetworkDevice->Xmit->DataBlock[0].TDPtrType = 1;\r
573 SimpleNetworkDevice->Xmit->DataBlock[0].TDRsvdByte = 0;\r
574\r
575 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataPtrOffset = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeDataBuffer) & 0x000f);\r
576\r
577 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataPtrSegment = (UINT16) (((UINT32)(UINTN) SimpleNetworkDevice->TxRealModeDataBuffer) >> 4);\r
578\r
579 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
580 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
581\r
582 //\r
583 // Start() the SimpleNetwork device\r
584 //\r
585 DEBUG ((DEBUG_NET, "Start()\n"));\r
586\r
587 Status = Undi16SimpleNetworkStart (&SimpleNetworkDevice->SimpleNetwork);\r
588 if (EFI_ERROR (Status)) {\r
589 goto Done;\r
590 }\r
591 //\r
592 // GetInformation() the SimpleNetwork device\r
593 //\r
594 DEBUG ((DEBUG_NET, "GetInformation()\n"));\r
595\r
596 Status = Undi16SimpleNetworkGetInformation (&SimpleNetworkDevice->SimpleNetwork);\r
597 if (EFI_ERROR (Status)) {\r
598 goto Done;\r
599 }\r
600 //\r
601 // Build the device path for the child device\r
602 //\r
603 ZeroMem (&Node, sizeof (Node));\r
604 Node.DevPath.Type = MESSAGING_DEVICE_PATH;\r
605 Node.DevPath.SubType = MSG_MAC_ADDR_DP;\r
606 SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));\r
607 CopyMem (\r
608 &Node.MacAddr.MacAddress,\r
609 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
610 sizeof (EFI_MAC_ADDRESS)\r
611 );\r
612 SimpleNetworkDevice->DevicePath = AppendDevicePathNode (\r
613 SimpleNetworkDevice->BaseDevicePath,\r
614 &Node.DevPath\r
615 );\r
616\r
617 //\r
618 // GetNicType() the SimpleNetwork device\r
619 //\r
620 DEBUG ((DEBUG_NET, "GetNicType()\n"));\r
621\r
622 Status = Undi16SimpleNetworkGetNicType (&SimpleNetworkDevice->SimpleNetwork);\r
623 if (EFI_ERROR (Status)) {\r
624 goto Done;\r
625 }\r
626 //\r
627 // GetNdisInfo() the SimpleNetwork device\r
628 //\r
629 DEBUG ((DEBUG_NET, "GetNdisInfo()\n"));\r
630\r
631 Status = Undi16SimpleNetworkGetNdisInfo (&SimpleNetworkDevice->SimpleNetwork);\r
632 if (EFI_ERROR (Status)) {\r
633 goto Done;\r
634 }\r
635 //\r
636 // Stop() the SimpleNetwork device\r
637 //\r
638 DEBUG ((DEBUG_NET, "Stop()\n"));\r
639\r
640 Status = SimpleNetworkDevice->SimpleNetwork.Stop (&SimpleNetworkDevice->SimpleNetwork);\r
641 if (EFI_ERROR (Status)) {\r
642 goto Done;\r
643 }\r
644 //\r
645 // Print Mode information\r
646 //\r
647 DEBUG ((DEBUG_NET, "Mode->State = %d\n", SimpleNetworkDevice->SimpleNetworkMode.State));\r
648 DEBUG ((DEBUG_NET, "Mode->HwAddressSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize));\r
649 DEBUG ((DEBUG_NET, "Mode->MacAddressChangeable = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable));\r
650 DEBUG ((DEBUG_NET, "Mode->MultiplTxSupported = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MultipleTxSupported));\r
651 DEBUG ((DEBUG_NET, "Mode->NvRamSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.NvRamSize));\r
652 DEBUG ((DEBUG_NET, "Mode->NvRamAccessSize = %d\n", SimpleNetworkDevice->SimpleNetworkMode.NvRamAccessSize));\r
653 DEBUG ((DEBUG_NET, "Mode->ReceiveFilterSetting = %d\n", SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting));\r
654 DEBUG ((DEBUG_NET, "Mode->IfType = %d\n", SimpleNetworkDevice->SimpleNetworkMode.IfType));\r
655 DEBUG ((DEBUG_NET, "Mode->MCastFilterCount = %d\n", SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount));\r
656 for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; Index++) {\r
657 DEBUG ((DEBUG_NET, " Filter[%02d] = ", Index));\r
658 for (Index2 = 0; Index2 < 16; Index2++) {\r
659 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index].Addr[Index2]));\r
660 }\r
661\r
662 DEBUG ((DEBUG_NET, "\n"));\r
663 }\r
664\r
665 DEBUG ((DEBUG_NET, "CurrentAddress = "));\r
666 for (Index2 = 0; Index2 < 16; Index2++) {\r
667 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress.Addr[Index2]));\r
668 }\r
669\r
670 DEBUG ((DEBUG_NET, "\n"));\r
671\r
672 DEBUG ((DEBUG_NET, "BroadcastAddress = "));\r
673 for (Index2 = 0; Index2 < 16; Index2++) {\r
674 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress.Addr[Index2]));\r
675 }\r
676\r
677 DEBUG ((DEBUG_NET, "\n"));\r
678\r
679 DEBUG ((DEBUG_NET, "PermanentAddress = "));\r
680 for (Index2 = 0; Index2 < 16; Index2++) {\r
681 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress.Addr[Index2]));\r
682 }\r
683\r
684 DEBUG ((DEBUG_NET, "\n"));\r
685\r
686 //\r
687 // The network device was started, information collected, and stopped.\r
688 // Install protocol interfaces for the SimpleNetwork device.\r
689 //\r
690 DEBUG ((DEBUG_NET, "Install Protocol Interfaces on network interface\n"));\r
691\r
692 Status = gBS->InstallMultipleProtocolInterfaces (\r
693 &SimpleNetworkDevice->Handle,\r
694 &gEfiSimpleNetworkProtocolGuid,\r
695 &SimpleNetworkDevice->SimpleNetwork,\r
696 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
697 &SimpleNetworkDevice->Nii,\r
698 &gEfiDevicePathProtocolGuid,\r
699 SimpleNetworkDevice->DevicePath,\r
700 NULL\r
701 );\r
702 if (EFI_ERROR (Status)) {\r
703 goto Done;\r
704 }\r
705 //\r
706 // Open PCI I/O from the newly created child handle\r
707 //\r
708 Status = gBS->OpenProtocol (\r
709 Controller,\r
710 &gEfiPciIoProtocolGuid,\r
711 (VOID **) &PciIo,\r
712 This->DriverBindingHandle,\r
713 SimpleNetworkDevice->Handle,\r
714 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
715 );\r
716\r
717 DEBUG ((DEBUG_INIT, "UNDI16 Driver : EFI_SUCCESS\n"));\r
718\r
719Done:\r
720 if (EFI_ERROR (Status)) {\r
721 if (SimpleNetworkDevice != NULL) {\r
722\r
723 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork);\r
724 //\r
725 // CLOSE + SHUTDOWN\r
726 //\r
727 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice);\r
728 //\r
729 // CLEANUP\r
730 //\r
731 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice);\r
732 //\r
733 // STOP\r
734 //\r
735 if (SimpleNetworkDevice->UndiLoaded) {\r
736 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);\r
737 }\r
738\r
739 if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket != NULL) {\r
740 gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);\r
741 }\r
742\r
743 if (SimpleNetworkDevice->LegacyBootEvent != NULL) {\r
744 gBS->CloseEvent (SimpleNetworkDevice->LegacyBootEvent);\r
745 }\r
0a6f4824 746\r
bcecde14 747 if (SimpleNetworkDevice->EfiBootEvent != NULL) {\r
748 gBS->CloseEvent (SimpleNetworkDevice->EfiBootEvent);\r
749 }\r
750\r
751 if (SimpleNetworkDevice->Xmit != NULL) {\r
752 gBS->FreePages (\r
753 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->Xmit,\r
754 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1\r
755 );\r
756 }\r
757\r
758 if (SimpleNetworkDevice->TxRealModeMediaHeader != NULL) {\r
759 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeMediaHeader, 1);\r
760 }\r
761\r
762 if (SimpleNetworkDevice->TxRealModeDataBuffer != NULL) {\r
763 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeDataBuffer, 1);\r
764 }\r
765\r
766 if (SimpleNetworkDevice->TxDestAddr != NULL) {\r
767 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxDestAddr, 1);\r
768 }\r
769\r
770 gBS->FreePool (SimpleNetworkDevice);\r
0a6f4824 771\r
bcecde14 772 //\r
773 // Only restore the vector if it was cached.\r
774 //\r
775 if (mCachedInt1A) {\r
776 RestoreCachedVectorAddress (0x1A);\r
777 mCachedInt1A = FALSE;\r
778 }\r
779 }\r
780\r
781 if (PciIo != NULL) {\r
782 Status = PciIo->Attributes (\r
783 PciIo,\r
784 EfiPciIoAttributeOperationSupported,\r
785 0,\r
786 &Supports\r
787 );\r
788 if (!EFI_ERROR (Status)) {\r
1a45b15e 789 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
bcecde14 790 Status = PciIo->Attributes (\r
791 PciIo,\r
792 EfiPciIoAttributeOperationDisable,\r
793 Supports,\r
794 NULL\r
795 );\r
796 }\r
797 }\r
798\r
799 gBS->CloseProtocol (\r
800 Controller,\r
801 &gEfiPciIoProtocolGuid,\r
802 This->DriverBindingHandle,\r
803 Controller\r
804 );\r
805\r
806 gBS->CloseProtocol (\r
807 Controller,\r
808 &gEfiDevicePathProtocolGuid,\r
809 This->DriverBindingHandle,\r
810 Controller\r
811 );\r
812 if (Status != EFI_OUT_OF_RESOURCES) {\r
813 Status = EFI_DEVICE_ERROR;\r
814 }\r
0a6f4824 815 }\r
bcecde14 816 return Status;\r
817}\r
818\r
819/**\r
820 Stops the device by given device controller.\r
821\r
822 @param This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
823 @param Controller The handle of the controller to test.\r
824 @param NumberOfChildren The number of child device handles in ChildHandleBuffer.\r
825 @param ChildHandleBuffer An array of child handles to be freed. May be NULL if\r
826 NumberOfChildren is 0.\r
0a6f4824 827\r
bcecde14 828 @retval EFI_SUCCESS - The device was stopped.\r
829 @retval EFI_DEVICE_ERROR - The device could not be stopped due to a device error.\r
830**/\r
831EFI_STATUS\r
832EFIAPI\r
833BiosSnp16DriverBindingStop (\r
834 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
835 IN EFI_HANDLE Controller,\r
836 IN UINTN NumberOfChildren,\r
837 IN EFI_HANDLE *ChildHandleBuffer\r
838 )\r
839{\r
840 EFI_STATUS Status;\r
841 UINTN Index;\r
842 BOOLEAN AllChildrenStopped;\r
843 EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;\r
844 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
845 EFI_PCI_IO_PROTOCOL *PciIo;\r
846 UINT64 Supports;\r
847\r
848 //\r
849 // Complete all outstanding transactions to Controller.\r
850 // Don't allow any new transaction to Controller to be started.\r
851 //\r
852 if (NumberOfChildren == 0) {\r
853 //\r
854 // Close the bus driver\r
855 //\r
856 Status = gBS->OpenProtocol (\r
857 Controller,\r
858 &gEfiPciIoProtocolGuid,\r
859 (VOID **) &PciIo,\r
860 This->DriverBindingHandle,\r
861 Controller,\r
862 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
863 );\r
864 if (!EFI_ERROR (Status)) {\r
865 Status = PciIo->Attributes (\r
866 PciIo,\r
867 EfiPciIoAttributeOperationSupported,\r
868 0,\r
869 &Supports\r
870 );\r
871 if (!EFI_ERROR (Status)) {\r
1a45b15e 872 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
bcecde14 873 Status = PciIo->Attributes (\r
874 PciIo,\r
875 EfiPciIoAttributeOperationDisable,\r
876 Supports,\r
877 NULL\r
878 );\r
879 }\r
880 }\r
881\r
882 Status = gBS->CloseProtocol (\r
883 Controller,\r
884 &gEfiPciIoProtocolGuid,\r
885 This->DriverBindingHandle,\r
886 Controller\r
887 );\r
888\r
889 Status = gBS->CloseProtocol (\r
890 Controller,\r
891 &gEfiDevicePathProtocolGuid,\r
892 This->DriverBindingHandle,\r
893 Controller\r
894 );\r
0a6f4824 895\r
bcecde14 896 if (EFI_ERROR (Status)) {\r
897 Status = EFI_DEVICE_ERROR;\r
898 }\r
899 return Status;\r
900 }\r
901\r
902 AllChildrenStopped = TRUE;\r
903\r
904 for (Index = 0; Index < NumberOfChildren; Index++) {\r
905\r
906 Status = gBS->OpenProtocol (\r
907 ChildHandleBuffer[Index],\r
908 &gEfiSimpleNetworkProtocolGuid,\r
909 (VOID **) &SimpleNetwork,\r
910 This->DriverBindingHandle,\r
911 Controller,\r
912 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
913 );\r
914 if (!EFI_ERROR (Status)) {\r
915\r
916 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SimpleNetwork);\r
917\r
918 Status = gBS->CloseProtocol (\r
919 Controller,\r
920 &gEfiPciIoProtocolGuid,\r
921 This->DriverBindingHandle,\r
922 ChildHandleBuffer[Index]\r
923 );\r
924\r
925 Status = gBS->UninstallMultipleProtocolInterfaces (\r
926 SimpleNetworkDevice->Handle,\r
927 &gEfiSimpleNetworkProtocolGuid,\r
928 &SimpleNetworkDevice->SimpleNetwork,\r
929 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
930 &SimpleNetworkDevice->Nii,\r
931 &gEfiDevicePathProtocolGuid,\r
932 SimpleNetworkDevice->DevicePath,\r
933 NULL\r
934 );\r
935 if (EFI_ERROR (Status)) {\r
936 gBS->OpenProtocol (\r
937 Controller,\r
938 &gEfiPciIoProtocolGuid,\r
939 (VOID **) &PciIo,\r
940 This->DriverBindingHandle,\r
941 ChildHandleBuffer[Index],\r
942 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
943 );\r
944 } else {\r
945\r
946 Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork);\r
947 //\r
948 // CLOSE + SHUTDOWN\r
949 //\r
950 Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice);\r
951 //\r
952 // CLEANUP\r
953 //\r
954 Undi16SimpleNetworkStopUndi (SimpleNetworkDevice);\r
955 //\r
956 // STOP\r
957 //\r
958 if (SimpleNetworkDevice->UndiLoaded) {\r
959 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);\r
960 }\r
961\r
962 if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket != NULL) {\r
963 gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);\r
964 }\r
965\r
966 if (SimpleNetworkDevice->LegacyBootEvent != NULL) {\r
967 gBS->CloseEvent (SimpleNetworkDevice->LegacyBootEvent);\r
968 }\r
0a6f4824 969\r
bcecde14 970 if (SimpleNetworkDevice->EfiBootEvent != NULL) {\r
971 gBS->CloseEvent (SimpleNetworkDevice->EfiBootEvent);\r
972 }\r
973\r
974 if (SimpleNetworkDevice->Xmit != NULL) {\r
975 gBS->FreePages (\r
976 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->Xmit,\r
977 sizeof (PXENV_UNDI_TBD_T) / EFI_PAGE_SIZE + 1\r
978 );\r
979 }\r
980\r
981 if (SimpleNetworkDevice->TxRealModeMediaHeader != NULL) {\r
982 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeMediaHeader, 1);\r
983 }\r
984\r
985 if (SimpleNetworkDevice->TxRealModeDataBuffer != NULL) {\r
986 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxRealModeDataBuffer, 1);\r
987 }\r
988\r
989 if (SimpleNetworkDevice->TxDestAddr != NULL) {\r
990 gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->TxDestAddr, 1);\r
991 }\r
992\r
993 gBS->FreePool (SimpleNetworkDevice);\r
994 }\r
995\r
996 }\r
997\r
998 if (EFI_ERROR (Status)) {\r
999 AllChildrenStopped = FALSE;\r
1000 }\r
1001 }\r
1002\r
1003 if (!AllChildrenStopped) {\r
1004 return EFI_DEVICE_ERROR;\r
1005 }\r
1006\r
1007 return EFI_SUCCESS;\r
1008}\r
1009\r
1010//\r
1011// FIFO Support Functions\r
1012//\r
1013/**\r
1014 Judge whether transmit FIFO is full.\r
1015\r
1016 @param Fifo Point to trasmit FIFO structure.\r
0a6f4824 1017\r
bcecde14 1018 @return BOOLEAN whether transmit FIFO is full.\r
1019**/\r
1020BOOLEAN\r
1021SimpleNetworkTransmitFifoFull (\r
1022 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo\r
1023 )\r
1024{\r
1025 if (((Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE) == Fifo->First) {\r
1026 return TRUE;\r
1027 }\r
1028\r
1029 return FALSE;\r
1030}\r
1031\r
1032/**\r
1033 Judge whether transmit FIFO is empty.\r
1034\r
1035 @param Fifo Point to trasmit FIFO structure.\r
0a6f4824 1036\r
bcecde14 1037 @return BOOLEAN whether transmit FIFO is empty.\r
1038**/\r
1039BOOLEAN\r
1040SimpleNetworkTransmitFifoEmpty (\r
1041 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo\r
1042 )\r
1043{\r
1044 if (Fifo->Last == Fifo->First) {\r
1045 return TRUE;\r
1046 }\r
1047\r
1048 return FALSE;\r
1049}\r
1050\r
1051\r
1052/**\r
1053 Add data into transmit buffer.\r
1054\r
1055 @param Fifo Point to trasmit FIFO structure.\r
1056 @param Data The data point want to be added.\r
0a6f4824
LG
1057\r
1058 @retval EFI_OUT_OF_RESOURCES FIFO is full\r
1059 @retval EFI_SUCCESS Success operation.\r
bcecde14 1060**/\r
1061EFI_STATUS\r
1062SimpleNetworkTransmitFifoAdd (\r
1063 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,\r
1064 VOID *Data\r
1065 )\r
1066{\r
1067 if (SimpleNetworkTransmitFifoFull (Fifo)) {\r
1068 return EFI_OUT_OF_RESOURCES;\r
1069 }\r
1070\r
1071 Fifo->Data[Fifo->Last] = Data;\r
1072 Fifo->Last = (Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;\r
1073 return EFI_SUCCESS;\r
1074}\r
1075\r
1076/**\r
1077 Get a data and remove it from network transmit FIFO.\r
1078\r
1079 @param Fifo Point to trasmit FIFO structure.\r
1080 @param Data On return, point to the data point want to be got and removed.\r
0a6f4824
LG
1081\r
1082 @retval EFI_OUT_OF_RESOURCES network transmit buffer is empty.\r
1083 @retval EFI_SUCCESS Success operation.\r
bcecde14 1084**/\r
1085EFI_STATUS\r
1086SimpleNetworkTransmitFifoRemove (\r
1087 EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,\r
1088 VOID **Data\r
1089 )\r
1090{\r
1091 if (SimpleNetworkTransmitFifoEmpty (Fifo)) {\r
1092 return EFI_OUT_OF_RESOURCES;\r
1093 }\r
1094\r
1095 *Data = Fifo->Data[Fifo->First];\r
1096 Fifo->First = (Fifo->First + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;\r
1097 return EFI_SUCCESS;\r
1098}\r
1099\r
1100/**\r
1101 Get recive filter setting according to EFI mask value.\r
1102\r
1103 @param ReceiveFilterSetting filter setting EFI mask value.\r
0a6f4824 1104\r
bcecde14 1105 @return UINT16 Undi filter setting value.\r
1106**/\r
1107UINT16\r
1108Undi16GetPacketFilterSetting (\r
1109 UINTN ReceiveFilterSetting\r
1110 )\r
1111{\r
1112 UINT16 PktFilter;\r
1113\r
1114 PktFilter = 0;\r
1115 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {\r
1116 PktFilter |= FLTR_DIRECTED;\r
1117 }\r
1118\r
1119 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
1120 PktFilter |= FLTR_DIRECTED;\r
1121 }\r
1122\r
1123 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {\r
1124 PktFilter |= FLTR_BRDCST;\r
1125 }\r
1126\r
1127 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {\r
1128 PktFilter |= FLTR_PRMSCS;\r
1129 }\r
1130\r
1131 if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {\r
1132 PktFilter |= FLTR_PRMSCS;\r
1133 //\r
1134 // @bug : Do not know if this is right????\r
1135 //\r
1136 }\r
1137 //\r
1138 // @bug : What is FLTR_SRC_RTG?\r
1139 //\r
1140 return PktFilter;\r
1141}\r
1142\r
1143/**\r
1144 Get filter setting from multi cast buffer .\r
0a6f4824 1145\r
bcecde14 1146 @param Mode Point to mode structure.\r
0a6f4824 1147 @param McastBuffer The multi cast buffer\r
bcecde14 1148 @param HwAddressSize Size of filter value.\r
0a6f4824 1149\r
bcecde14 1150**/\r
1151VOID\r
1152Undi16GetMCastFilters (\r
1153 IN EFI_SIMPLE_NETWORK_MODE *Mode,\r
1154 IN OUT PXENV_UNDI_MCAST_ADDR_T *McastBuffer,\r
1155 IN UINTN HwAddressSize\r
1156 )\r
1157{\r
1158 UINTN Index;\r
1159\r
1160 //\r
1161 // @bug : What if Mode->MCastFilterCount > MAXNUM_MCADDR?\r
1162 //\r
1163 McastBuffer->MCastAddrCount = (UINT16) Mode->MCastFilterCount;\r
1164 for (Index = 0; Index < MAXNUM_MCADDR; Index++) {\r
1165 if (Index < McastBuffer->MCastAddrCount) {\r
1166 CopyMem (&McastBuffer->MCastAddr[Index], &Mode->MCastFilter[Index], HwAddressSize);\r
1167 } else {\r
1168 ZeroMem (&McastBuffer->MCastAddr[Index], HwAddressSize);\r
1169 }\r
1170 }\r
1171}\r
1172//\r
1173// Load 16 bit UNDI Option ROM into memory\r
1174//\r
1175/**\r
1176 Loads the undi driver.\r
1177\r
1178 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824 1179\r
bcecde14 1180 @retval EFI_SUCCESS - Successfully loads undi driver.\r
1181 @retval EFI_NOT_FOUND - Doesn't find undi driver or undi driver load failure.\r
1182**/\r
1183EFI_STATUS\r
1184Undi16SimpleNetworkLoadUndi (\r
1185 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1186 )\r
1187{\r
1188 EFI_STATUS Status;\r
1189 EFI_PCI_IO_PROTOCOL *PciIo;\r
1190 UINTN RomAddress;\r
1191 PCI_EXPANSION_ROM_HEADER *PciExpansionRomHeader;\r
1192 PCI_DATA_STRUCTURE *PciDataStructure;\r
1193 PCI_TYPE00 Pci;\r
0a6f4824 1194\r
bcecde14 1195 if (!mCachedInt1A) {\r
1196 Status = CacheVectorAddress (0x1A);\r
1197 if (!EFI_ERROR (Status)) {\r
0a6f4824 1198 mCachedInt1A = TRUE;\r
bcecde14 1199 }\r
1200 }\r
1201\r
1202 PciIo = SimpleNetworkDevice->PciIo;\r
1203\r
1204 PciIo->Pci.Read (\r
1205 PciIo,\r
1206 EfiPciIoWidthUint32,\r
1207 0,\r
1208 sizeof (Pci) / sizeof (UINT32),\r
1209 &Pci\r
1210 );\r
1211\r
1212 for (RomAddress = 0xc0000; RomAddress < 0xfffff; RomAddress += 0x800) {\r
1213\r
1214 PciExpansionRomHeader = (PCI_EXPANSION_ROM_HEADER *) RomAddress;\r
1215\r
1216 if (PciExpansionRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {\r
1217 continue;\r
1218 }\r
1219\r
1220 DEBUG ((DEBUG_INIT, "Option ROM found at %X\n", RomAddress));\r
1221\r
94020bb4 1222 //\r
0a6f4824
LG
1223 // If the pointer to the PCI Data Structure is invalid, no further images can be located.\r
1224 // The PCI Data Structure must be DWORD aligned.\r
94020bb4 1225 //\r
1226 if (PciExpansionRomHeader->PcirOffset == 0 ||\r
1227 (PciExpansionRomHeader->PcirOffset & 3) != 0 ||\r
1228 RomAddress + PciExpansionRomHeader->PcirOffset + sizeof (PCI_DATA_STRUCTURE) > 0x100000) {\r
1229 break;\r
1230 }\r
1231\r
bcecde14 1232 PciDataStructure = (PCI_DATA_STRUCTURE *) (RomAddress + PciExpansionRomHeader->PcirOffset);\r
1233\r
1234 if (PciDataStructure->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {\r
1235 continue;\r
1236 }\r
1237\r
1238 DEBUG ((DEBUG_INIT, "PCI Data Structure found at %X\n", PciDataStructure));\r
1239\r
1240 if (PciDataStructure->VendorId != Pci.Hdr.VendorId || PciDataStructure->DeviceId != Pci.Hdr.DeviceId) {\r
1241 continue;\r
1242 }\r
1243\r
1244 DEBUG (\r
0a6f4824 1245 (DEBUG_INIT,\r
bcecde14 1246 "PCI device with matchinng VendorId and DeviceId (%d,%d)\n",\r
1247 (UINTN) PciDataStructure->VendorId,\r
1248 (UINTN) PciDataStructure->DeviceId)\r
1249 );\r
1250\r
1251 Status = LaunchBaseCode (SimpleNetworkDevice, RomAddress);\r
1252\r
1253 if (!EFI_ERROR (Status)) {\r
1254 return EFI_SUCCESS;\r
1255 }\r
0a6f4824 1256\r
9f6c5db2
EL
1257 //\r
1258 // Free resources allocated in LaunchBaseCode\r
1259 //\r
1260 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);\r
bcecde14 1261 }\r
1262\r
1263 return EFI_NOT_FOUND;\r
1264}\r
1265\r
1266/**\r
1267 Unload 16 bit UNDI Option ROM from memory\r
1268\r
1269 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
1270\r
1271 @return EFI_STATUS\r
bcecde14 1272**/\r
1273EFI_STATUS\r
1274Undi16SimpleNetworkUnloadUndi (\r
1275 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1276 )\r
1277{\r
1278 if (SimpleNetworkDevice->UndiLoaderTable != NULL) {\r
1279 ZeroMem (SimpleNetworkDevice->UndiLoaderTable, SimpleNetworkDevice->UndiLoaderTablePages << EFI_PAGE_SHIFT);\r
1280 gBS->FreePages (\r
1281 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->UndiLoaderTable,\r
1282 SimpleNetworkDevice->UndiLoaderTablePages\r
1283 );\r
1284 }\r
1285\r
1286 if (SimpleNetworkDevice->DestinationDataSegment != NULL) {\r
1287 ZeroMem (\r
1288 SimpleNetworkDevice->DestinationDataSegment,\r
1289 SimpleNetworkDevice->DestinationDataSegmentPages << EFI_PAGE_SHIFT\r
1290 );\r
1291 gBS->FreePages (\r
1292 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationDataSegment,\r
1293 SimpleNetworkDevice->DestinationDataSegmentPages\r
1294 );\r
1295 }\r
1296\r
1297 if (SimpleNetworkDevice->DestinationStackSegment != NULL) {\r
1298 ZeroMem (\r
1299 SimpleNetworkDevice->DestinationStackSegment,\r
1300 SimpleNetworkDevice->DestinationStackSegmentPages << EFI_PAGE_SHIFT\r
1301 );\r
1302 gBS->FreePages (\r
1303 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationStackSegment,\r
1304 SimpleNetworkDevice->DestinationStackSegmentPages\r
1305 );\r
1306 }\r
1307\r
1308 if (SimpleNetworkDevice->DestinationCodeSegment != NULL) {\r
1309 ZeroMem (\r
1310 SimpleNetworkDevice->DestinationCodeSegment,\r
1311 SimpleNetworkDevice->DestinationCodeSegmentPages << EFI_PAGE_SHIFT\r
1312 );\r
1313 gBS->FreePages (\r
1314 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationCodeSegment,\r
1315 SimpleNetworkDevice->DestinationCodeSegmentPages\r
1316 );\r
1317 }\r
1318\r
1319 return EFI_SUCCESS;\r
1320}\r
1321\r
1322/**\r
1323 Start the UNDI interface.\r
1324\r
1325 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
1326 @param Ax PCI address of Undi device.\r
0a6f4824
LG
1327\r
1328 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.\r
1329 @retval Others Status of start 16 bit UNDI ROM.\r
bcecde14 1330**/\r
1331EFI_STATUS\r
1332Undi16SimpleNetworkStartUndi (\r
1333 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,\r
1334 UINT16 Ax\r
1335 )\r
1336{\r
1337 EFI_STATUS Status;\r
1338 PXENV_START_UNDI_T Start;\r
1339\r
1340 //\r
1341 // Call 16 bit UNDI ROM to start the network interface\r
1342 //\r
1343 //\r
1344 // @bug : What is this state supposed to be???\r
1345 //\r
1346 Start.Status = INIT_PXE_STATUS;\r
1347 Start.Ax = Ax;\r
1348 Start.Bx = 0x0000;\r
1349 Start.Dx = 0x0000;\r
1350 Start.Di = 0x0000;\r
1351 Start.Es = 0x0000;\r
1352\r
1353 Status = PxeStartUndi (SimpleNetworkDevice, &Start);\r
1354 if (EFI_ERROR (Status)) {\r
1355 return Status;\r
1356 }\r
1357 //\r
1358 // Check the status code from the 16 bit UNDI ROM\r
1359 //\r
1360 if (Start.Status != PXENV_STATUS_SUCCESS) {\r
1361 return EFI_DEVICE_ERROR;\r
1362 }\r
1363\r
1364 return Status;\r
1365}\r
1366\r
1367\r
1368/**\r
1369 Stop the UNDI interface\r
1370\r
1371 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
1372\r
1373 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM.\r
1374 @retval Others Status of stop 16 bit UNDI ROM.\r
bcecde14 1375**/\r
1376EFI_STATUS\r
1377Undi16SimpleNetworkStopUndi (\r
1378 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1379 )\r
1380{\r
1381 EFI_STATUS Status;\r
1382 PXENV_STOP_UNDI_T Stop;\r
1383\r
1384 //\r
1385 // Call 16 bit UNDI ROM to start the network interface\r
1386 //\r
1387 Stop.Status = INIT_PXE_STATUS;\r
1388\r
1389 Status = PxeUndiStop (SimpleNetworkDevice, &Stop);\r
1390 if (EFI_ERROR (Status)) {\r
1391 return Status;\r
1392 }\r
1393 //\r
1394 // Check the status code from the 16 bit UNDI ROM\r
1395 //\r
1396 if (Stop.Status != PXENV_STATUS_SUCCESS) {\r
1397 return EFI_DEVICE_ERROR;\r
1398 }\r
1399\r
1400 return Status;\r
1401}\r
1402\r
1403/**\r
1404 Cleanup Unid network interface\r
1405\r
1406 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.\r
0a6f4824
LG
1407\r
1408 @retval EFI_DEVICE_ERROR Fail to cleanup 16 bit UNDI ROM.\r
1409 @retval Others Status of cleanup 16 bit UNDI ROM.\r
bcecde14 1410**/\r
1411EFI_STATUS\r
1412Undi16SimpleNetworkCleanupUndi (\r
1413 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice\r
1414 )\r
1415{\r
1416 EFI_STATUS Status;\r
1417 PXENV_UNDI_CLEANUP_T Cleanup;\r
1418\r
1419 //\r
1420 // Call 16 bit UNDI ROM to cleanup the network interface\r
1421 //\r
1422 Cleanup.Status = INIT_PXE_STATUS;\r
1423\r
1424 Status = PxeUndiCleanup (SimpleNetworkDevice, &Cleanup);\r
1425 if (EFI_ERROR (Status)) {\r
1426 return Status;\r
1427 }\r
1428 //\r
1429 // Check the status code from the 16 bit UNDI ROM\r
1430 //\r
1431 if (Cleanup.Status != PXENV_STATUS_SUCCESS) {\r
1432 return EFI_DEVICE_ERROR;\r
1433 }\r
1434\r
1435 return Status;\r
1436}\r
1437\r
1438/**\r
1439 Get runtime information for Undi network interface\r
1440\r
1441 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
1442\r
1443 @retval EFI_SUCCESS Sucess operation.\r
1444 @retval Others Fail to get runtime information for Undi network interface.\r
bcecde14 1445**/\r
1446EFI_STATUS\r
1447Undi16SimpleNetworkGetInformation (\r
1448 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1449 )\r
1450{\r
1451 EFI_STATUS Status;\r
1452 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1453 UINTN Index;\r
1454\r
1455 if (This == NULL) {\r
1456 return EFI_INVALID_PARAMETER;\r
1457 }\r
1458\r
1459 Status = EFI_SUCCESS;\r
1460 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1461\r
1462 if (SimpleNetworkDevice == NULL) {\r
1463 return EFI_DEVICE_ERROR;\r
1464 }\r
1465 //\r
1466 // Verify that the current state of the adapter is valid for this call.\r
1467 //\r
1468 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1469 case EfiSimpleNetworkStarted:\r
1470 case EfiSimpleNetworkInitialized:\r
1471 break;\r
1472\r
1473 case EfiSimpleNetworkStopped:\r
1474 return EFI_NOT_STARTED;\r
1475\r
1476 default:\r
1477 return EFI_DEVICE_ERROR;\r
1478 }\r
1479 //\r
1480 // Call 16 bit UNDI ROM to start the network interface\r
1481 //\r
1482 ZeroMem (&SimpleNetworkDevice->GetInformation, sizeof (PXENV_UNDI_GET_INFORMATION_T));\r
1483\r
1484 SimpleNetworkDevice->GetInformation.Status = INIT_PXE_STATUS;\r
1485\r
1486 Status = PxeUndiGetInformation (SimpleNetworkDevice, &SimpleNetworkDevice->GetInformation);\r
1487 if (EFI_ERROR (Status)) {\r
1488 return Status;\r
1489 }\r
1490\r
1491 DEBUG ((DEBUG_NET, " GetInformation.Status = %d\n", SimpleNetworkDevice->GetInformation.Status));\r
1492 DEBUG ((DEBUG_NET, " GetInformation.BaseIo = %d\n", SimpleNetworkDevice->GetInformation.BaseIo));\r
1493 DEBUG ((DEBUG_NET, " GetInformation.IntNumber = %d\n", SimpleNetworkDevice->GetInformation.IntNumber));\r
1494 DEBUG ((DEBUG_NET, " GetInformation.MaxTranUnit = %d\n", SimpleNetworkDevice->GetInformation.MaxTranUnit));\r
1495 DEBUG ((DEBUG_NET, " GetInformation.HwType = %d\n", SimpleNetworkDevice->GetInformation.HwType));\r
1496 DEBUG ((DEBUG_NET, " GetInformation.HwAddrLen = %d\n", SimpleNetworkDevice->GetInformation.HwAddrLen));\r
1497 DEBUG ((DEBUG_NET, " GetInformation.ROMAddress = %d\n", SimpleNetworkDevice->GetInformation.ROMAddress));\r
1498 DEBUG ((DEBUG_NET, " GetInformation.RxBufCt = %d\n", SimpleNetworkDevice->GetInformation.RxBufCt));\r
1499 DEBUG ((DEBUG_NET, " GetInformation.TxBufCt = %d\n", SimpleNetworkDevice->GetInformation.TxBufCt));\r
1500\r
1501 DEBUG ((DEBUG_NET, " GetInformation.CurNodeAddr ="));\r
1502 for (Index = 0; Index < 16; Index++) {\r
1503 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.CurrentNodeAddress[Index]));\r
1504 }\r
1505\r
1506 DEBUG ((DEBUG_NET, "\n"));\r
1507\r
1508 DEBUG ((DEBUG_NET, " GetInformation.PermNodeAddr ="));\r
1509 for (Index = 0; Index < 16; Index++) {\r
1510 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.PermNodeAddress[Index]));\r
1511 }\r
1512\r
1513 DEBUG ((DEBUG_NET, "\n"));\r
1514\r
1515 //\r
1516 // Check the status code from the 16 bit UNDI ROM\r
1517 //\r
1518 if (SimpleNetworkDevice->GetInformation.Status != PXENV_STATUS_SUCCESS) {\r
1519 return EFI_DEVICE_ERROR;\r
1520 }\r
1521 //\r
1522 // The information has been retrieved. Fill in Mode data.\r
1523 //\r
1524 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize = SimpleNetworkDevice->GetInformation.HwAddrLen;\r
1525\r
1526 SimpleNetworkDevice->SimpleNetworkMode.MaxPacketSize = SimpleNetworkDevice->GetInformation.MaxTranUnit;\r
1527\r
1528 SimpleNetworkDevice->SimpleNetworkMode.IfType = (UINT8) SimpleNetworkDevice->GetInformation.HwType;\r
1529\r
1530 ZeroMem (\r
1531 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
1532 sizeof SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress\r
1533 );\r
1534\r
1535 CopyMem (\r
1536 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
1537 &SimpleNetworkDevice->GetInformation.CurrentNodeAddress,\r
1538 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
1539 );\r
1540\r
1541 ZeroMem (\r
1542 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
1543 sizeof SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress\r
1544 );\r
1545\r
1546 CopyMem (\r
1547 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
1548 &SimpleNetworkDevice->GetInformation.PermNodeAddress,\r
1549 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
1550 );\r
1551\r
1552 //\r
1553 // hard code broadcast address - not avail in PXE2.1\r
1554 //\r
1555 ZeroMem (\r
1556 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,\r
1557 sizeof SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress\r
1558 );\r
1559\r
1560 SetMem (\r
1561 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,\r
1562 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,\r
1563 0xff\r
1564 );\r
1565\r
1566 return Status;\r
1567}\r
1568\r
1569/**\r
1570 Get NIC type\r
1571\r
1572 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
1573\r
1574 @retval EFI_SUCCESS Sucess operation.\r
bcecde14 1575 @retval Others Fail to get NIC type.\r
1576**/\r
1577EFI_STATUS\r
1578Undi16SimpleNetworkGetNicType (\r
1579 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1580 )\r
1581{\r
1582 EFI_STATUS Status;\r
1583 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1584\r
1585 if (This == NULL) {\r
1586 return EFI_INVALID_PARAMETER;\r
1587 }\r
1588\r
1589 Status = EFI_SUCCESS;\r
1590 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1591\r
1592 if (SimpleNetworkDevice == NULL) {\r
1593 return EFI_DEVICE_ERROR;\r
1594 }\r
1595\r
1596 ZeroMem (&SimpleNetworkDevice->GetNicType, sizeof (PXENV_UNDI_GET_NIC_TYPE_T));\r
1597\r
1598 SimpleNetworkDevice->GetNicType.Status = INIT_PXE_STATUS;\r
1599\r
1600 Status = PxeUndiGetNicType (SimpleNetworkDevice, &SimpleNetworkDevice->GetNicType);\r
1601\r
1602 if (EFI_ERROR (Status)) {\r
1603 return Status;\r
1604 }\r
1605\r
1606 DEBUG ((DEBUG_NET, " GetNicType.Status = %d\n", SimpleNetworkDevice->GetNicType.Status));\r
1607 DEBUG ((DEBUG_NET, " GetNicType.NicType = %d\n", SimpleNetworkDevice->GetNicType.NicType));\r
1608 //\r
1609 // Check the status code from the 16 bit UNDI ROM\r
1610 //\r
1611 if (SimpleNetworkDevice->GetNicType.Status != PXENV_STATUS_SUCCESS) {\r
1612 return EFI_DEVICE_ERROR;\r
1613 }\r
1614 //\r
1615 // The information has been retrieved. Fill in Mode data.\r
1616 //\r
1617 return Status;\r
1618}\r
1619\r
1620/**\r
1621 Get NDIS information\r
1622\r
1623 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824
LG
1624\r
1625 @retval EFI_SUCCESS Sucess operation.\r
bcecde14 1626 @retval Others Fail to get NDIS information.\r
1627**/\r
1628EFI_STATUS\r
1629Undi16SimpleNetworkGetNdisInfo (\r
1630 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1631 )\r
1632{\r
1633 EFI_STATUS Status;\r
1634 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1635\r
1636 if (This == NULL) {\r
1637 return EFI_INVALID_PARAMETER;\r
1638 }\r
1639\r
1640 Status = EFI_SUCCESS;\r
1641 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1642\r
1643 if (SimpleNetworkDevice == NULL) {\r
1644 return EFI_DEVICE_ERROR;\r
1645 }\r
1646\r
1647 ZeroMem (&SimpleNetworkDevice->GetNdisInfo, sizeof (PXENV_UNDI_GET_NDIS_INFO_T));\r
1648\r
1649 SimpleNetworkDevice->GetNdisInfo.Status = INIT_PXE_STATUS;\r
1650\r
1651 Status = PxeUndiGetNdisInfo (SimpleNetworkDevice, &SimpleNetworkDevice->GetNdisInfo);\r
1652\r
1653 if (EFI_ERROR (Status)) {\r
1654 return Status;\r
1655 }\r
1656\r
1657 DEBUG ((DEBUG_NET, " GetNdisInfo.Status = %d\n", SimpleNetworkDevice->GetNdisInfo.Status));\r
1658 DEBUG ((DEBUG_NET, " GetNdisInfo.IfaceType = %a\n", SimpleNetworkDevice->GetNdisInfo.IfaceType));\r
1659 DEBUG ((DEBUG_NET, " GetNdisInfo.LinkSpeed = %d\n", SimpleNetworkDevice->GetNdisInfo.LinkSpeed));\r
1660 DEBUG ((DEBUG_NET, " GetNdisInfo.ServiceFlags = %08x\n", SimpleNetworkDevice->GetNdisInfo.ServiceFlags));\r
1661\r
1662 //\r
1663 // Check the status code from the 16 bit UNDI ROM\r
1664 //\r
1665 if (SimpleNetworkDevice->GetNdisInfo.Status != PXENV_STATUS_SUCCESS) {\r
1666 return EFI_DEVICE_ERROR;\r
1667 }\r
1668 //\r
1669 // The information has been retrieved. Fill in Mode data.\r
1670 //\r
1671 return Status;\r
1672}\r
1673\r
1674/**\r
1675 Call Undi ROM 16bit ISR() to check interrupt cause.\r
1676\r
1677 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1678 @param FrameLength The length of frame buffer.\r
1679 @param FrameHeaderLength The length of frame buffer's header if has.\r
1680 @param Frame The frame buffer to process network interrupt.\r
1681 @param ProtType The type network transmit protocol\r
1682 @param PktType The type of package.\r
0a6f4824
LG
1683\r
1684 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM's ISR, or status is invalid.\r
1685 @retval EFI_SUCCESS Success operation.\r
bcecde14 1686**/\r
1687EFI_STATUS\r
1688Undi16SimpleNetworkIsr (\r
1689 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
1690 IN UINTN *FrameLength,\r
1691 IN UINTN *FrameHeaderLength, OPTIONAL\r
1692 IN UINT8 *Frame, OPTIONAL\r
1693 IN UINT8 *ProtType, OPTIONAL\r
1694 IN UINT8 *PktType OPTIONAL\r
1695 )\r
1696{\r
1697 EFI_STATUS Status;\r
1698 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1699 BOOLEAN FrameReceived;\r
1700\r
1701 if (This == NULL) {\r
1702 return EFI_INVALID_PARAMETER;\r
1703 }\r
1704\r
1705 Status = EFI_SUCCESS;\r
1706 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1707\r
1708 if (SimpleNetworkDevice == NULL) {\r
1709 return EFI_DEVICE_ERROR;\r
1710 }\r
1711\r
1712 FrameReceived = FALSE;\r
1713\r
1714 //\r
1715 // Verify that the current state of the adapter is valid for this call.\r
1716 //\r
1717 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1718 case EfiSimpleNetworkInitialized:\r
1719 break;\r
1720\r
1721 case EfiSimpleNetworkStopped:\r
1722 return EFI_NOT_STARTED;\r
1723\r
1724 case EfiSimpleNetworkStarted:\r
1725 default:\r
1726 return EFI_DEVICE_ERROR;\r
1727 }\r
1728\r
1729 DEBUG ((DEBUG_NET, "Isr() IsrValid = %d\n", SimpleNetworkDevice->IsrValid));\r
1730\r
1731 if (!SimpleNetworkDevice->IsrValid) {\r
1732 //\r
1733 // Call 16 bit UNDI ROM to open the network interface\r
1734 //\r
1735 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1736 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1737 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_START;\r
1738\r
1739 DEBUG ((DEBUG_NET, "Isr() START\n"));\r
1740\r
1741 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1742 if (EFI_ERROR (Status)) {\r
1743 return Status;\r
1744 }\r
1745 //\r
1746 // Check the status code from the 16 bit UNDI ROM\r
1747 //\r
1748 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1749 return EFI_DEVICE_ERROR;\r
1750 }\r
1751 //\r
1752 // There have been no events on this UNDI interface, so return EFI_NOT_READY\r
1753 //\r
1754 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_NOT_OURS) {\r
1755 return EFI_SUCCESS;\r
1756 }\r
1757 //\r
1758 // There is data to process, so call until all events processed.\r
1759 //\r
1760 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1761 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1762 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;\r
1763\r
1764 DEBUG ((DEBUG_NET, "Isr() PROCESS\n"));\r
1765\r
1766 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1767 if (EFI_ERROR (Status)) {\r
1768 return Status;\r
1769 }\r
1770\r
1771 SimpleNetworkDevice->IsrValid = TRUE;\r
1772 }\r
1773 //\r
1774 // Call UNDI GET_NEXT until DONE\r
1775 //\r
1776 while (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_DONE) {\r
1777 //\r
1778 // Check the status code from the 16 bit UNDI ROM\r
1779 //\r
1780 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1781 return EFI_DEVICE_ERROR;\r
1782 }\r
1783 //\r
1784 // UNDI is busy. Caller will have to call again.\r
1785 // This should never happen with a polled mode driver.\r
1786 //\r
1787 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_BUSY) {\r
1788 DEBUG ((DEBUG_NET, " BUSY\n"));\r
1789 return EFI_SUCCESS;\r
1790 }\r
1791 //\r
1792 // Check for invalud UNDI FuncFlag\r
1793 //\r
1794 if (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE &&\r
1795 SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_TRANSMIT\r
1796 ) {\r
1797 DEBUG ((DEBUG_NET, " Invalid SimpleNetworkDevice->Isr.FuncFlag value %d\n", SimpleNetworkDevice->Isr.FuncFlag));\r
1798 return EFI_DEVICE_ERROR;\r
1799 }\r
1800 //\r
1801 // Check for Transmit Event\r
1802 //\r
1803 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {\r
1804 DEBUG ((DEBUG_NET, " TRANSMIT\n"));\r
1805 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
1806 }\r
1807 //\r
1808 // Check for Receive Event\r
1809 //\r
1810 else if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE) {\r
1811 //\r
1812 // note - this code will hang on a receive interrupt in a GetStatus loop\r
1813 //\r
1814 DEBUG ((DEBUG_NET, " RECEIVE\n"));\r
1815 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
1816\r
1817 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.BufferLength = %d\n", SimpleNetworkDevice->Isr.BufferLength));\r
1818 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameLength = %d\n", SimpleNetworkDevice->Isr.FrameLength));\r
1819 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameHeaderLength = %d\n", SimpleNetworkDevice->Isr.FrameHeaderLength));\r
1820 DEBUG (\r
1821 (\r
1822 DEBUG_NET, "SimpleNetworkDevice->Isr.Frame = %04x:%04x\n", SimpleNetworkDevice->Isr.FrameSegSel,\r
1823 SimpleNetworkDevice->Isr.FrameOffset\r
1824 )\r
1825 );\r
1826 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.ProtType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));\r
1827 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.PktType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));\r
1828\r
1829 if (FrameReceived) {\r
1830 return EFI_SUCCESS;\r
1831 }\r
1832\r
1833 if ((Frame == NULL) || (SimpleNetworkDevice->Isr.FrameLength > *FrameLength)) {\r
1834 DEBUG ((DEBUG_NET, "return EFI_BUFFER_TOO_SMALL *FrameLength = %08x\n", *FrameLength));\r
1835 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;\r
1836 return EFI_BUFFER_TOO_SMALL;\r
1837 }\r
1838\r
1839 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;\r
1840 if (FrameHeaderLength != NULL) {\r
1841 *FrameHeaderLength = SimpleNetworkDevice->Isr.FrameHeaderLength;\r
1842 }\r
1843\r
1844 if (ProtType != NULL) {\r
1845 *ProtType = SimpleNetworkDevice->Isr.ProtType;\r
1846 }\r
1847\r
1848 if (PktType != NULL) {\r
1849 *PktType = SimpleNetworkDevice->Isr.PktType;\r
1850 }\r
1851\r
1852 CopyMem (\r
1853 Frame,\r
aa5f60ae 1854 (VOID *) (((UINTN) SimpleNetworkDevice->Isr.FrameSegSel << 4) + SimpleNetworkDevice->Isr.FrameOffset),\r
bcecde14 1855 SimpleNetworkDevice->Isr.BufferLength\r
1856 );\r
1857 Frame = Frame + SimpleNetworkDevice->Isr.BufferLength;\r
1858 if (SimpleNetworkDevice->Isr.BufferLength == SimpleNetworkDevice->Isr.FrameLength) {\r
1859 FrameReceived = TRUE;\r
1860 }\r
1861 }\r
1862 //\r
1863 // There is data to process, so call until all events processed.\r
1864 //\r
1865 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));\r
1866 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;\r
1867 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;\r
1868\r
1869 DEBUG ((DEBUG_NET, "Isr() GET NEXT\n"));\r
1870\r
1871 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);\r
1872 if (EFI_ERROR (Status)) {\r
1873 return Status;\r
1874 }\r
1875 //\r
1876 // Check the status code from the 16 bit UNDI ROM\r
1877 //\r
1878 // if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {\r
1879 // return EFI_DEVICE_ERROR;\r
1880 // }\r
1881 //\r
1882 }\r
1883\r
1884 SimpleNetworkDevice->IsrValid = FALSE;\r
1885 return EFI_SUCCESS;\r
1886}\r
1887//\r
1888// ///////////////////////////////////////////////////////////////////////////////////////\r
1889// Simple Network Protocol Interface Functions using 16 bit UNDI Option ROMs\r
1890/////////////////////////////////////////////////////////////////////////////////////////\r
1891//\r
1892// Start()\r
1893//\r
1894/**\r
1895 Call 16 bit UNDI ROM to start the network interface\r
1896\r
1897 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824 1898\r
bcecde14 1899 @retval EFI_DEVICE_ERROR Network interface has not be initialized.\r
1900 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
1901 @retval EFI_SUCESS Success operation.\r
1902**/\r
1903EFI_STATUS\r
1904EFIAPI\r
1905Undi16SimpleNetworkStart (\r
1906 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1907 )\r
1908{\r
1909 EFI_STATUS Status;\r
1910 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1911 PXENV_UNDI_STARTUP_T Startup;\r
1912\r
1913 if (This == NULL) {\r
1914 return EFI_INVALID_PARAMETER;\r
1915 }\r
1916\r
1917 Status = EFI_SUCCESS;\r
1918 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1919\r
1920 if (SimpleNetworkDevice == NULL) {\r
1921 return EFI_DEVICE_ERROR;\r
1922 }\r
1923 //\r
1924 // Verify that the current state of the adapter is valid for this call.\r
1925 //\r
1926 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
1927 case EfiSimpleNetworkStopped:\r
1928 break;\r
1929\r
1930 case EfiSimpleNetworkStarted:\r
1931 case EfiSimpleNetworkInitialized:\r
1932 return EFI_ALREADY_STARTED;\r
1933\r
1934 default:\r
1935 return EFI_DEVICE_ERROR;\r
1936 }\r
1937 //\r
1938 // Call 16 bit UNDI ROM to start the network interface\r
1939 //\r
1940 Startup.Status = INIT_PXE_STATUS;\r
1941\r
1942 Status = PxeUndiStartup (SimpleNetworkDevice, &Startup);\r
1943 if (EFI_ERROR (Status)) {\r
1944 return Status;\r
1945 }\r
1946 //\r
1947 // Check the status code from the 16 bit UNDI ROM\r
1948 //\r
1949 if (Startup.Status != PXENV_STATUS_SUCCESS) {\r
1950 return EFI_DEVICE_ERROR;\r
1951 }\r
1952 //\r
1953 // The UNDI interface has been started, so update the State.\r
1954 //\r
1955 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;\r
1956\r
1957 //\r
1958 //\r
1959 //\r
1960 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = 0;\r
1961 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = 0;\r
1962\r
1963 return Status;\r
1964}\r
1965//\r
1966// Stop()\r
1967//\r
1968/**\r
1969 Call 16 bit UNDI ROM to stop the network interface\r
1970\r
1971 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824 1972\r
bcecde14 1973 @retval EFI_DEVICE_ERROR Network interface has not be initialized.\r
1974 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
1975 @retval EFI_SUCESS Success operation.\r
1976**/\r
1977EFI_STATUS\r
1978EFIAPI\r
1979Undi16SimpleNetworkStop (\r
1980 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
1981 )\r
1982{\r
1983 EFI_STATUS Status;\r
1984 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
1985\r
1986 if (This == NULL) {\r
1987 return EFI_INVALID_PARAMETER;\r
1988 }\r
1989\r
1990 Status = EFI_SUCCESS;\r
1991 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
1992\r
1993 if (SimpleNetworkDevice == NULL) {\r
1994 return EFI_DEVICE_ERROR;\r
1995 }\r
1996 //\r
1997 // Verify that the current state of the adapter is valid for this call.\r
1998 //\r
1999 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2000 case EfiSimpleNetworkStarted:\r
2001 break;\r
2002\r
2003 case EfiSimpleNetworkStopped:\r
2004 return EFI_NOT_STARTED;\r
2005\r
2006 case EfiSimpleNetworkInitialized:\r
2007 default:\r
2008 return EFI_DEVICE_ERROR;\r
2009 }\r
2010\r
2011 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;\r
2012\r
2013 return Status;\r
2014}\r
2015\r
2016//\r
2017// Initialize()\r
2018//\r
2019/**\r
0a6f4824 2020 Initialize network interface\r
bcecde14 2021\r
2022 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2023 @param ExtraRxBufferSize The size of extra request receive buffer.\r
2024 @param ExtraTxBufferSize The size of extra request transmit buffer.\r
0a6f4824 2025\r
bcecde14 2026 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.\r
2027 @retval EFI_SUCESS Success operation.\r
2028**/\r
2029EFI_STATUS\r
2030EFIAPI\r
2031Undi16SimpleNetworkInitialize (\r
2032 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2033 IN UINTN ExtraRxBufferSize OPTIONAL,\r
2034 IN UINTN ExtraTxBufferSize OPTIONAL\r
2035 )\r
2036{\r
2037 EFI_STATUS Status;\r
2038 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2039 PXENV_UNDI_INITIALIZE_T Initialize;\r
2040 PXENV_UNDI_OPEN_T Open;\r
2041\r
2042 if (This == NULL) {\r
2043 return EFI_INVALID_PARAMETER;\r
2044 }\r
2045\r
2046 Status = EFI_SUCCESS;\r
2047 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2048\r
2049 if (SimpleNetworkDevice == NULL) {\r
2050 return EFI_DEVICE_ERROR;\r
2051 }\r
2052 //\r
2053 // Verify that the current state of the adapter is valid for this call.\r
2054 //\r
2055 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2056 case EfiSimpleNetworkStopped:\r
2057 return EFI_NOT_STARTED;\r
2058\r
2059 case EfiSimpleNetworkStarted:\r
2060 break;\r
2061\r
2062 case EfiSimpleNetworkInitialized:\r
2063 default:\r
2064 return EFI_DEVICE_ERROR;\r
2065 }\r
2066 //\r
2067 // Call 16 bit UNDI ROM to start the network interface\r
2068 //\r
2069 Initialize.Status = INIT_PXE_STATUS;\r
2070 Initialize.ProtocolIni = 0;\r
2071\r
2072 Status = PxeUndiInitialize (SimpleNetworkDevice, &Initialize);\r
2073\r
2074 if (EFI_ERROR (Status)) {\r
2075 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Status = %r\n", Status));\r
2076 DEBUG ((DEBUG_ERROR, "Initialize.Status == %xh\n", Initialize.Status));\r
2077\r
2078 if (Initialize.Status == PXENV_STATUS_UNDI_MEDIATEST_FAILED) {\r
2079 Status = EFI_NO_MEDIA;\r
2080 }\r
2081\r
2082 return Status;\r
2083 }\r
2084 //\r
2085 // Check the status code from the 16 bit UNDI ROM\r
2086 //\r
2087 if (Initialize.Status != PXENV_STATUS_SUCCESS) {\r
2088 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Initialize.Status = %04x\n", Initialize.Status));\r
2089 return EFI_DEVICE_ERROR;\r
2090 }\r
2091 //\r
2092 // Call 16 bit UNDI ROM to open the network interface\r
2093 //\r
2094 Open.Status = INIT_PXE_STATUS;\r
2095 Open.OpenFlag = 0;\r
2096 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2097 Undi16GetMCastFilters (\r
2098 &SimpleNetworkDevice->SimpleNetworkMode,\r
2099 &Open.McastBuffer,\r
2100 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2101 );\r
2102\r
2103 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2104\r
2105 if (EFI_ERROR (Status)) {\r
2106 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Status = %r\n", Status));\r
2107 return Status;\r
2108 }\r
2109 //\r
2110 // Check the status code from the 16 bit UNDI ROM\r
2111 //\r
2112 if (Open.Status != PXENV_STATUS_SUCCESS) {\r
2113 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Open.Status = %04x\n", Open.Status));\r
2114 return EFI_DEVICE_ERROR;\r
2115 }\r
2116 //\r
2117 // The UNDI interface has been initialized, so update the State.\r
2118 //\r
2119 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkInitialized;\r
2120\r
2121 //\r
2122 // If initialize succeeds, then assume that media is present.\r
2123 //\r
2124 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = TRUE;\r
2125\r
2126 //\r
2127 // Reset the recycled transmit buffer FIFO\r
2128 //\r
2129 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2130 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2131 SimpleNetworkDevice->IsrValid = FALSE;\r
2132\r
2133 return Status;\r
2134}\r
2135//\r
2136// Reset()\r
2137//\r
2138/**\r
2139 Reset network interface.\r
2140\r
2141 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2142 @param ExtendedVerification Need extended verfication.\r
0a6f4824 2143\r
70d3fe9d 2144 @retval EFI_INVALID_PARAMETER Invalid This parameter.\r
bcecde14 2145 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2146 @retval EFI_NOT_STARTED Network device has been stopped.\r
2147 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2148 @retval EFI_SUCCESS Success operation.\r
2149**/\r
2150EFI_STATUS\r
2151EFIAPI\r
2152Undi16SimpleNetworkReset (\r
2153 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2154 IN BOOLEAN ExtendedVerification\r
2155 )\r
2156{\r
2157 EFI_STATUS Status;\r
2158 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2159 PXENV_UNDI_RESET_T Reset;\r
2160 UINT16 Rx_filter;\r
2161\r
2162 if (This == NULL) {\r
2163 return EFI_INVALID_PARAMETER;\r
2164 }\r
2165\r
2166 Status = EFI_SUCCESS;\r
2167 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2168\r
2169 if (SimpleNetworkDevice == NULL) {\r
2170 return EFI_DEVICE_ERROR;\r
2171 }\r
2172 //\r
2173 // Verify that the current state of the adapter is valid for this call.\r
2174 //\r
2175 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2176 case EfiSimpleNetworkStopped:\r
2177 return EFI_NOT_STARTED;\r
2178\r
2179 case EfiSimpleNetworkInitialized:\r
2180 break;\r
2181\r
2182 case EfiSimpleNetworkStarted:\r
2183 default:\r
2184 return EFI_DEVICE_ERROR;\r
2185 }\r
2186\r
2187 Reset.Status = INIT_PXE_STATUS;\r
2188\r
2189 Rx_filter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2190\r
2191 Undi16GetMCastFilters (\r
2192 &SimpleNetworkDevice->SimpleNetworkMode,\r
2193 &Reset.R_Mcast_Buf,\r
2194 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2195 );\r
2196\r
2197 Status = PxeUndiResetNic (SimpleNetworkDevice, &Reset, Rx_filter);\r
2198\r
2199 if (EFI_ERROR (Status)) {\r
2200 return Status;\r
2201 }\r
2202 //\r
2203 // Check the status code from the 16 bit UNDI ROM\r
2204 //\r
2205 if (Reset.Status != PXENV_STATUS_SUCCESS) {\r
2206 return EFI_DEVICE_ERROR;\r
2207 }\r
2208 //\r
2209 // Reset the recycled transmit buffer FIFO\r
2210 //\r
2211 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2212 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2213 SimpleNetworkDevice->IsrValid = FALSE;\r
2214\r
2215 return Status;\r
2216}\r
2217//\r
2218// Shutdown()\r
2219//\r
2220/**\r
2221 Shutdown network interface.\r
2222\r
2223 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
0a6f4824 2224\r
70d3fe9d 2225 @retval EFI_INVALID_PARAMETER Invalid This parameter.\r
bcecde14 2226 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2227 @retval EFI_NOT_STARTED Network device has been stopped.\r
2228 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2229 @retval EFI_SUCCESS Success operation.\r
2230**/\r
2231EFI_STATUS\r
2232EFIAPI\r
2233Undi16SimpleNetworkShutdown (\r
2234 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
2235 )\r
2236{\r
2237 EFI_STATUS Status;\r
2238 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2239 PXENV_UNDI_CLOSE_T Close;\r
2240 PXENV_UNDI_SHUTDOWN_T Shutdown;\r
2241\r
2242 if (This == NULL) {\r
2243 return EFI_INVALID_PARAMETER;\r
2244 }\r
2245\r
2246 Status = EFI_SUCCESS;\r
2247 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2248\r
2249 if (SimpleNetworkDevice == NULL) {\r
2250 return EFI_DEVICE_ERROR;\r
2251 }\r
2252 //\r
2253 // Verify that the current state of the adapter is valid for this call.\r
2254 //\r
2255 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2256 case EfiSimpleNetworkStopped:\r
2257 return EFI_NOT_STARTED;\r
2258\r
2259 case EfiSimpleNetworkInitialized:\r
2260 break;\r
2261\r
2262 case EfiSimpleNetworkStarted:\r
2263 default:\r
2264 return EFI_DEVICE_ERROR;\r
2265 }\r
2266\r
2267 SimpleNetworkDevice->IsrValid = FALSE;\r
2268\r
2269 //\r
2270 // Call 16 bit UNDI ROM to start the network interface\r
2271 //\r
2272 Close.Status = INIT_PXE_STATUS;\r
2273\r
2274 Status = PxeUndiClose (SimpleNetworkDevice, &Close);\r
2275\r
2276 if (EFI_ERROR (Status)) {\r
2277 return Status;\r
2278 }\r
2279 //\r
2280 // Check the status code from the 16 bit UNDI ROM\r
2281 //\r
2282 if (Close.Status != PXENV_STATUS_SUCCESS) {\r
2283 return EFI_DEVICE_ERROR;\r
2284 }\r
2285 //\r
2286 // Call 16 bit UNDI ROM to open the network interface\r
2287 //\r
2288 Shutdown.Status = INIT_PXE_STATUS;\r
2289\r
2290 Status = PxeUndiShutdown (SimpleNetworkDevice, &Shutdown);\r
2291\r
2292 if (EFI_ERROR (Status)) {\r
2293 return Status;\r
2294 }\r
2295 //\r
2296 // Check the status code from the 16 bit UNDI ROM\r
2297 //\r
2298 if (Shutdown.Status != PXENV_STATUS_SUCCESS) {\r
2299 return EFI_DEVICE_ERROR;\r
2300 }\r
2301 //\r
2302 // The UNDI interface has been initialized, so update the State.\r
2303 //\r
2304 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;\r
2305\r
2306 //\r
2307 // If shutdown succeeds, then assume that media is not present.\r
2308 //\r
2309 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = FALSE;\r
2310\r
2311 //\r
2312 // Reset the recycled transmit buffer FIFO\r
2313 //\r
2314 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2315 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2316\r
2317 //\r
2318 // A short delay. Without this an initialize immediately following\r
2319 // a shutdown will cause some versions of UNDI-16 to stop operating.\r
2320 //\r
2321 gBS->Stall (250000);\r
2322\r
2323 return Status;\r
2324}\r
2325//\r
2326// ReceiveFilters()\r
2327//\r
2328/**\r
2329 Reset network interface.\r
2330\r
2331 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2332 @param Enable Enable mask value\r
2333 @param Disable Disable mask value\r
2334 @param ResetMCastFilter Whether reset multi cast filter or not\r
2335 @param MCastFilterCnt Count of mutli cast filter for different MAC address\r
2336 @param MCastFilter Buffer for mustli cast filter for different MAC address.\r
0a6f4824 2337\r
70d3fe9d 2338 @retval EFI_INVALID_PARAMETER Invalid This parameter.\r
bcecde14 2339 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2340 @retval EFI_NOT_STARTED Network device has been stopped.\r
2341 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2342 @retval EFI_SUCCESS Success operation.\r
2343**/\r
2344EFI_STATUS\r
2345EFIAPI\r
2346Undi16SimpleNetworkReceiveFilters (\r
2347 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2348 IN UINT32 Enable,\r
2349 IN UINT32 Disable,\r
2350 IN BOOLEAN ResetMCastFilter,\r
2351 IN UINTN MCastFilterCnt OPTIONAL,\r
2352 IN EFI_MAC_ADDRESS * MCastFilter OPTIONAL\r
2353 )\r
2354{\r
2355 EFI_STATUS Status;\r
2356 UINTN Index;\r
2357 UINT32 NewFilter;\r
2358 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2359 PXENV_UNDI_CLOSE_T Close;\r
2360 PXENV_UNDI_OPEN_T Open;\r
2361\r
2362 if (This == NULL) {\r
2363 return EFI_INVALID_PARAMETER;\r
2364 }\r
2365\r
2366 Status = EFI_SUCCESS;\r
2367 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2368\r
2369 if (SimpleNetworkDevice == NULL) {\r
2370 return EFI_DEVICE_ERROR;\r
2371 }\r
2372 //\r
2373 // Verify that the current state of the adapter is valid for this call.\r
2374 //\r
2375 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2376 case EfiSimpleNetworkStopped:\r
2377 return EFI_NOT_STARTED;\r
2378\r
2379 case EfiSimpleNetworkInitialized:\r
2380 break;\r
2381\r
2382 case EfiSimpleNetworkStarted:\r
2383 default:\r
2384 return EFI_DEVICE_ERROR;\r
2385 }\r
2386 //\r
2387 // First deal with possible filter setting changes\r
2388 //\r
2389 if ((Enable == 0) && (Disable == 0) && !ResetMCastFilter) {\r
2390 return EFI_SUCCESS;\r
2391 }\r
2392\r
2393 NewFilter = (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting | Enable) &~Disable;\r
2394\r
2395 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2396 if ((MCastFilterCnt == 0) || (MCastFilter == 0) || MCastFilterCnt > SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount) {\r
2397 return EFI_INVALID_PARAMETER;\r
2398 }\r
2399 }\r
2400 //\r
2401 // Call 16 bit UNDI ROM to close the network interface\r
2402 //\r
2403 Close.Status = INIT_PXE_STATUS;\r
2404\r
2405 Status = PxeUndiClose (SimpleNetworkDevice, &Close);\r
2406\r
2407 if (EFI_ERROR (Status)) {\r
2408 return Status;\r
2409 }\r
2410 //\r
2411 // Check the status code from the 16 bit UNDI ROM\r
2412 //\r
2413 if (Close.Status != PXENV_STATUS_SUCCESS) {\r
2414 return EFI_DEVICE_ERROR;\r
2415 }\r
2416 //\r
2417 // Call 16 bit UNDI ROM to open the network interface\r
2418 //\r
2419 //\r
2420 // Reset the recycled transmit buffer FIFO\r
2421 //\r
2422 SimpleNetworkDevice->TxBufferFifo.First = 0;\r
2423 SimpleNetworkDevice->TxBufferFifo.Last = 0;\r
2424\r
2425 //\r
2426 // Call 16 bit UNDI ROM to open the network interface\r
2427 //\r
2428 ZeroMem (&Open, sizeof Open);\r
2429\r
2430 Open.Status = INIT_PXE_STATUS;\r
2431 Open.PktFilter = Undi16GetPacketFilterSetting (NewFilter);\r
2432\r
2433 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2434 //\r
2435 // Copy the MAC addresses into the UNDI open parameter structure\r
2436 //\r
2437 Open.McastBuffer.MCastAddrCount = (UINT16) MCastFilterCnt;\r
2438 for (Index = 0; Index < MCastFilterCnt; ++Index) {\r
2439 CopyMem (\r
2440 Open.McastBuffer.MCastAddr[Index],\r
2441 &MCastFilter[Index],\r
2442 sizeof Open.McastBuffer.MCastAddr[Index]\r
2443 );\r
2444 }\r
2445 } else if (!ResetMCastFilter) {\r
2446 for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; ++Index) {\r
2447 CopyMem (\r
2448 Open.McastBuffer.MCastAddr[Index],\r
2449 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],\r
2450 sizeof Open.McastBuffer.MCastAddr[Index]\r
2451 );\r
2452 }\r
2453 }\r
2454\r
2455 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2456\r
2457 if (EFI_ERROR (Status)) {\r
2458 return Status;\r
2459 }\r
2460 //\r
2461 // Check the status code from the 16 bit UNDI ROM\r
2462 //\r
2463 if (Open.Status != PXENV_STATUS_SUCCESS) {\r
2464 return EFI_DEVICE_ERROR;\r
2465 }\r
2466\r
2467 SimpleNetworkDevice->IsrValid = FALSE;\r
2468 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = NewFilter;\r
2469\r
2470 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {\r
2471 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = (UINT32) MCastFilterCnt;\r
2472 for (Index = 0; Index < MCastFilterCnt; ++Index) {\r
2473 CopyMem (\r
2474 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],\r
2475 &MCastFilter[Index],\r
2476 sizeof (EFI_MAC_ADDRESS)\r
0a6f4824 2477 );\r
bcecde14 2478 }\r
2479 }\r
2480 //\r
2481 // Read back multicast addresses.\r
2482 //\r
2483 return EFI_SUCCESS;\r
2484}\r
2485//\r
2486// StationAddress()\r
2487//\r
2488/**\r
2489 Set new MAC address.\r
2490\r
2491 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
70d3fe9d 2492 @param Reset Whether reset station MAC address to permanent address\r
bcecde14 2493 @param New A pointer to New address\r
0a6f4824 2494\r
70d3fe9d 2495 @retval EFI_INVALID_PARAMETER Invalid This parameter.\r
bcecde14 2496 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2497 @retval EFI_NOT_STARTED Network device has been stopped.\r
2498 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2499 @retval EFI_SUCCESS Success operation.\r
2500**/\r
2501EFI_STATUS\r
2502EFIAPI\r
2503Undi16SimpleNetworkStationAddress (\r
2504 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2505 IN BOOLEAN Reset,\r
2506 IN EFI_MAC_ADDRESS * New OPTIONAL\r
2507 )\r
2508{\r
2509 EFI_STATUS Status;\r
2510 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2511 PXENV_UNDI_SET_STATION_ADDR_T SetStationAddr;\r
2512 //\r
2513 // EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;\r
2514 //\r
2515 PXENV_UNDI_CLOSE_T Close;\r
2516 PXENV_UNDI_OPEN_T Open;\r
2517\r
2518 if (This == NULL) {\r
2519 return EFI_INVALID_PARAMETER;\r
2520 }\r
2521\r
2522 Status = EFI_SUCCESS;\r
2523\r
2524 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2525\r
2526 if (SimpleNetworkDevice == NULL) {\r
2527 return EFI_DEVICE_ERROR;\r
2528 }\r
2529 //\r
2530 // Verify that the current state of the adapter is valid for this call.\r
2531 //\r
2532 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2533 case EfiSimpleNetworkInitialized:\r
2534 break;\r
2535\r
2536 case EfiSimpleNetworkStopped:\r
2537 return EFI_NOT_STARTED;\r
2538\r
2539 case EfiSimpleNetworkStarted:\r
2540 default:\r
2541 return EFI_DEVICE_ERROR;\r
2542 }\r
2543 //\r
2544 // Call 16 bit UNDI ROM to open the network interface\r
2545 //\r
2546 SetStationAddr.Status = INIT_PXE_STATUS;\r
2547\r
2548 if (Reset) {\r
2549 //\r
70d3fe9d 2550 // If we are resetting the Station Address to the permanent address, and the\r
bcecde14 2551 // Station Address is not programmable, then just return EFI_SUCCESS.\r
2552 //\r
2553 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {\r
2554 return EFI_SUCCESS;\r
2555 }\r
2556 //\r
2557 // If the address is already the permanent address, then just return success.\r
2558 //\r
2559 if (CompareMem (\r
2560 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2561 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
2562 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2563 ) == 0) {\r
2564 return EFI_SUCCESS;\r
2565 }\r
2566 //\r
2567 // Copy the adapters permanent address to the new station address\r
2568 //\r
2569 CopyMem (\r
2570 &SetStationAddr.StationAddress,\r
2571 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,\r
2572 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2573 );\r
2574 } else {\r
2575 //\r
2576 // If we are setting the Station Address, and the\r
2577 // Station Address is not programmable, return invalid parameter.\r
2578 //\r
2579 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {\r
2580 return EFI_INVALID_PARAMETER;\r
2581 }\r
2582 //\r
2583 // If the address is already the new address, then just return success.\r
2584 //\r
2585 if (CompareMem (\r
2586 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2587 New,\r
2588 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2589 ) == 0) {\r
2590 return EFI_SUCCESS;\r
2591 }\r
2592 //\r
2593 // Copy New to the new station address\r
2594 //\r
2595 CopyMem (\r
2596 &SetStationAddr.StationAddress,\r
2597 New,\r
2598 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2599 );\r
2600\r
2601 }\r
2602 //\r
2603 // Call 16 bit UNDI ROM to stop the network interface\r
2604 //\r
2605 Close.Status = INIT_PXE_STATUS;\r
2606\r
2607 PxeUndiClose (SimpleNetworkDevice, &Close);\r
2608\r
2609 //\r
2610 // Call 16-bit UNDI ROM to set the station address\r
2611 //\r
2612 SetStationAddr.Status = PXENV_STATUS_SUCCESS;\r
2613\r
2614 Status = PxeUndiSetStationAddr (SimpleNetworkDevice, &SetStationAddr);\r
2615\r
2616 //\r
2617 // Call 16-bit UNDI ROM to start the network interface\r
2618 //\r
2619 Open.Status = PXENV_STATUS_SUCCESS;\r
2620 Open.OpenFlag = 0;\r
2621 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);\r
2622 Undi16GetMCastFilters (\r
2623 &SimpleNetworkDevice->SimpleNetworkMode,\r
2624 &Open.McastBuffer,\r
2625 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2626 );\r
2627\r
2628 PxeUndiOpen (SimpleNetworkDevice, &Open);\r
2629\r
2630 //\r
2631 // Check status from station address change\r
2632 //\r
2633 if (EFI_ERROR (Status)) {\r
2634 return Status;\r
2635 }\r
2636 //\r
2637 // Check the status code from the 16 bit UNDI ROM\r
2638 //\r
2639 if (SetStationAddr.Status != PXENV_STATUS_SUCCESS) {\r
2640 return EFI_DEVICE_ERROR;\r
2641 }\r
2642\r
2643 CopyMem (\r
2644 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,\r
2645 &SetStationAddr.StationAddress,\r
2646 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2647 );\r
2648\r
2649#if 0 /* The device path is based on the permanent address not the current address. */\r
2650 //\r
2651 // The station address was changed, so update the device path with the new MAC address.\r
2652 //\r
2653 OldDevicePath = SimpleNetworkDevice->DevicePath;\r
2654 SimpleNetworkDevice->DevicePath = DuplicateDevicePath (SimpleNetworkDevice->BaseDevicePath);\r
2655 SimpleNetworkAppendMacAddressDevicePath (\r
2656 &SimpleNetworkDevice->DevicePath,\r
2657 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress\r
2658 );\r
2659\r
2660 Status = LibReinstallProtocolInterfaces (\r
2661 SimpleNetworkDevice->Handle,\r
2662 &DevicePathProtocol,\r
2663 OldDevicePath,\r
2664 SimpleNetworkDevice->DevicePath,\r
2665 NULL\r
2666 );\r
2667\r
2668 if (EFI_ERROR (Status)) {\r
2669 DEBUG ((DEBUG_ERROR, "Failed to reinstall the DevicePath protocol for the Simple Network Device\n"));\r
2670 DEBUG ((DEBUG_ERROR, " Status = %r\n", Status));\r
2671 }\r
2672\r
2673 FreePool (OldDevicePath);\r
2674#endif /* 0 */\r
2675\r
2676 return Status;\r
2677}\r
2678//\r
2679// Statistics()\r
2680//\r
2681/**\r
2682 Resets or collects the statistics on a network interface.\r
2683\r
2684 @param This Protocol instance pointer.\r
2685 @param Reset Set to TRUE to reset the statistics for the network interface.\r
2686 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On\r
2687 output the size, in bytes, of the resulting table of\r
2688 statistics.\r
2689 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
2690 contains the statistics.\r
2691\r
2692 @retval EFI_SUCCESS The statistics were collected from the network interface.\r
2693 @retval EFI_NOT_STARTED The network interface has not been started.\r
2694 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer\r
2695 size needed to hold the statistics is returned in\r
2696 StatisticsSize.\r
2697 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2698 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2699 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2700\r
2701**/\r
2702EFI_STATUS\r
2703EFIAPI\r
2704Undi16SimpleNetworkStatistics (\r
2705 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2706 IN BOOLEAN Reset,\r
2707 IN OUT UINTN *StatisticsSize OPTIONAL,\r
2708 OUT EFI_NETWORK_STATISTICS * StatisticsTable OPTIONAL\r
2709 )\r
2710{\r
2711 EFI_STATUS Status;\r
2712 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2713 PXENV_UNDI_CLEAR_STATISTICS_T ClearStatistics;\r
2714 PXENV_UNDI_GET_STATISTICS_T GetStatistics;\r
2715\r
2716 if (This == NULL) {\r
2717 return EFI_INVALID_PARAMETER;\r
2718 }\r
2719\r
2720 Status = EFI_SUCCESS;\r
2721 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2722\r
2723 if (SimpleNetworkDevice == NULL) {\r
2724 return EFI_DEVICE_ERROR;\r
2725 }\r
2726 //\r
2727 // Verify that the current state of the adapter is valid for this call.\r
2728 //\r
2729 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2730 case EfiSimpleNetworkInitialized:\r
2731 break;\r
2732\r
2733 case EfiSimpleNetworkStopped:\r
2734 return EFI_NOT_STARTED;\r
2735\r
2736 case EfiSimpleNetworkStarted:\r
2737 default:\r
2738 return EFI_DEVICE_ERROR;\r
2739 }\r
2740\r
2741 if ((StatisticsSize != NULL) && (*StatisticsSize != 0) && (StatisticsTable == NULL)) {\r
2742 return EFI_INVALID_PARAMETER;\r
2743 }\r
2744\r
2745 //\r
2746 // If Reset is TRUE, then clear all the statistics.\r
2747 //\r
2748 if (Reset) {\r
2749\r
2750 DEBUG ((DEBUG_NET, " RESET Statistics\n"));\r
2751\r
2752 //\r
2753 // Call 16 bit UNDI ROM to open the network interface\r
2754 //\r
2755 ClearStatistics.Status = INIT_PXE_STATUS;\r
2756\r
2757 Status = PxeUndiClearStatistics (SimpleNetworkDevice, &ClearStatistics);\r
2758\r
2759 if (EFI_ERROR (Status)) {\r
2760 return Status;\r
2761 }\r
2762 //\r
2763 // Check the status code from the 16 bit UNDI ROM\r
2764 //\r
2765 if (ClearStatistics.Status != PXENV_STATUS_SUCCESS) {\r
2766 return EFI_DEVICE_ERROR;\r
2767 }\r
2768\r
2769 DEBUG ((DEBUG_NET, " RESET Statistics Complete"));\r
2770 }\r
2771\r
2772 if (StatisticsSize != NULL) {\r
2773 EFI_NETWORK_STATISTICS LocalStatisticsTable;\r
2774\r
2775 DEBUG ((DEBUG_NET, " GET Statistics\n"));\r
2776\r
2777 //\r
2778 // If the size if valid, then see if the table is valid\r
2779 //\r
2780 if (StatisticsTable == NULL) {\r
2781 DEBUG ((DEBUG_NET, " StatisticsTable is NULL\n"));\r
2782 return EFI_INVALID_PARAMETER;\r
2783 }\r
2784 //\r
2785 // Call 16 bit UNDI ROM to open the network interface\r
2786 //\r
2787 GetStatistics.Status = INIT_PXE_STATUS;\r
2788 GetStatistics.XmtGoodFrames = 0;\r
2789 GetStatistics.RcvGoodFrames = 0;\r
2790 GetStatistics.RcvCRCErrors = 0;\r
2791 GetStatistics.RcvResourceErrors = 0;\r
2792\r
2793 Status = PxeUndiGetStatistics (SimpleNetworkDevice, &GetStatistics);\r
2794\r
2795 if (EFI_ERROR (Status)) {\r
2796 return Status;\r
2797 }\r
2798 //\r
2799 // Check the status code from the 16 bit UNDI ROM\r
2800 //\r
2801 if (GetStatistics.Status != PXENV_STATUS_SUCCESS) {\r
2802 return EFI_DEVICE_ERROR;\r
2803 }\r
2804 //\r
2805 // Fill in the Statistics Table with the collected values.\r
2806 //\r
2807 SetMem (&LocalStatisticsTable, sizeof LocalStatisticsTable, 0xff);\r
2808\r
2809 LocalStatisticsTable.TxGoodFrames = GetStatistics.XmtGoodFrames;\r
2810 LocalStatisticsTable.RxGoodFrames = GetStatistics.RcvGoodFrames;\r
2811 LocalStatisticsTable.RxCrcErrorFrames = GetStatistics.RcvCRCErrors;\r
2812 LocalStatisticsTable.RxDroppedFrames = GetStatistics.RcvResourceErrors;\r
2813\r
2814 CopyMem (StatisticsTable, &LocalStatisticsTable, *StatisticsSize);\r
2815\r
2816 DEBUG (\r
2817 (DEBUG_NET,\r
2818 " Statistics Collected : Size=%d Buf=%08x\n",\r
2819 *StatisticsSize,\r
2820 StatisticsTable)\r
2821 );\r
2822\r
2823 DEBUG ((DEBUG_NET, " GET Statistics Complete"));\r
2824\r
2825 if (*StatisticsSize < sizeof LocalStatisticsTable) {\r
2826 DEBUG ((DEBUG_NET, " BUFFER TOO SMALL\n"));\r
2827 Status = EFI_BUFFER_TOO_SMALL;\r
2828 }\r
2829\r
2830 *StatisticsSize = sizeof LocalStatisticsTable;\r
2831\r
2832 return Status;\r
2833\r
2834 }\r
2835\r
2836 return EFI_SUCCESS;\r
2837}\r
2838//\r
2839// MCastIpToMac()\r
2840//\r
2841/**\r
2842 Translate IP address to MAC address.\r
2843\r
2844 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
2845 @param IPv6 IPv6 or IPv4\r
2846 @param IP A pointer to given Ip address.\r
2847 @param MAC On return, translated MAC address.\r
0a6f4824 2848\r
70d3fe9d 2849 @retval EFI_INVALID_PARAMETER Invalid This parameter.\r
bcecde14 2850 @retval EFI_INVALID_PARAMETER Invalid IP address.\r
2851 @retval EFI_INVALID_PARAMETER Invalid return buffer for holding MAC address.\r
0a6f4824 2852 @retval EFI_UNSUPPORTED Do not support IPv6\r
bcecde14 2853 @retval EFI_DEVICE_ERROR Network device has not been initialized.\r
2854 @retval EFI_NOT_STARTED Network device has been stopped.\r
2855 @retval EFI_DEVICE_ERROR Invalid status for network device\r
2856 @retval EFI_SUCCESS Success operation.\r
2857**/\r
2858EFI_STATUS\r
2859EFIAPI\r
2860Undi16SimpleNetworkMCastIpToMac (\r
2861 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2862 IN BOOLEAN IPv6,\r
2863 IN EFI_IP_ADDRESS *IP,\r
2864 OUT EFI_MAC_ADDRESS *MAC\r
2865 )\r
2866{\r
2867 EFI_STATUS Status;\r
2868 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
2869 PXENV_UNDI_GET_MCAST_ADDR_T GetMcastAddr;\r
2870\r
2871 if (This == NULL || IP == NULL || MAC == NULL) {\r
2872 return EFI_INVALID_PARAMETER;\r
2873 }\r
2874\r
2875 Status = EFI_SUCCESS;\r
2876 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
2877\r
2878 if (SimpleNetworkDevice == NULL) {\r
2879 return EFI_DEVICE_ERROR;\r
2880 }\r
2881 //\r
2882 // Verify that the current state of the adapter is valid for this call.\r
2883 //\r
2884 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
2885 case EfiSimpleNetworkStopped:\r
2886 return EFI_NOT_STARTED;\r
2887\r
2888 case EfiSimpleNetworkInitialized:\r
2889 break;\r
2890\r
2891 case EfiSimpleNetworkStarted:\r
2892 default:\r
2893 return EFI_DEVICE_ERROR;\r
2894 }\r
2895 //\r
2896 // 16 bit UNDI Option ROMS do not support IPv6. Check for IPv6 usage.\r
2897 //\r
2898 if (IPv6) {\r
2899 return EFI_UNSUPPORTED;\r
2900 }\r
2901 //\r
2902 // Call 16 bit UNDI ROM to open the network interface\r
2903 //\r
2904 GetMcastAddr.Status = INIT_PXE_STATUS;\r
2905 CopyMem (&GetMcastAddr.InetAddr, IP, 4);\r
2906\r
2907 Status = PxeUndiGetMcastAddr (SimpleNetworkDevice, &GetMcastAddr);\r
2908\r
2909 if (EFI_ERROR (Status)) {\r
2910 return Status;\r
2911 }\r
2912 //\r
2913 // Check the status code from the 16 bit UNDI ROM\r
2914 //\r
2915 if (GetMcastAddr.Status != PXENV_STATUS_SUCCESS) {\r
2916 return EFI_DEVICE_ERROR;\r
2917 }\r
2918 //\r
2919 // Copy the MAC address from the returned data structure.\r
2920 //\r
2921 CopyMem (\r
2922 MAC,\r
2923 &GetMcastAddr.MediaAddr,\r
2924 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
2925 );\r
2926\r
2927 return Status;\r
2928}\r
2929//\r
2930// NvData()\r
2931//\r
2932/**\r
0a6f4824 2933 Performs read and write operations on the NVRAM device attached to a\r
bcecde14 2934 network interface.\r
2935\r
2936 @param This The protocol instance pointer.\r
2937 @param ReadWrite TRUE for read operations, FALSE for write operations.\r
2938 @param Offset Byte offset in the NVRAM device at which to start the read or\r
2939 write operation. This must be a multiple of NvRamAccessSize and\r
2940 less than NvRamSize.\r
2941 @param BufferSize The number of bytes to read or write from the NVRAM device.\r
2942 This must also be a multiple of NvramAccessSize.\r
2943 @param Buffer A pointer to the data buffer.\r
2944\r
2945 @retval EFI_SUCCESS The NVRAM access was performed.\r
2946 @retval EFI_NOT_STARTED The network interface has not been started.\r
2947 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2948 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2949 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2950\r
2951**/\r
2952EFI_STATUS\r
2953EFIAPI\r
2954Undi16SimpleNetworkNvData (\r
2955 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
2956 IN BOOLEAN ReadWrite,\r
2957 IN UINTN Offset,\r
2958 IN UINTN BufferSize,\r
2959 IN OUT VOID *Buffer\r
2960 )\r
2961{\r
2962 return EFI_UNSUPPORTED;\r
2963}\r
2964//\r
2965// GetStatus()\r
2966//\r
2967/**\r
0a6f4824 2968 Reads the current interrupt status and recycled transmit buffer status from\r
bcecde14 2969 a network interface.\r
2970\r
2971 @param This The protocol instance pointer.\r
2972 @param InterruptStatus A pointer to the bit mask of the currently active interrupts\r
2973 If this is NULL, the interrupt status will not be read from\r
2974 the device. If this is not NULL, the interrupt status will\r
2975 be read from the device. When the interrupt status is read,\r
2976 it will also be cleared. Clearing the transmit interrupt\r
2977 does not empty the recycled transmit buffer array.\r
2978 @param TxBuf Recycled transmit buffer address. The network interface will\r
2979 not transmit if its internal recycled transmit buffer array\r
2980 is full. Reading the transmit buffer does not clear the\r
2981 transmit interrupt. If this is NULL, then the transmit buffer\r
2982 status will not be read. If there are no transmit buffers to\r
2983 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.\r
2984\r
2985 @retval EFI_SUCCESS The status of the network interface was retrieved.\r
2986 @retval EFI_NOT_STARTED The network interface has not been started.\r
2987 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
2988 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
2989 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
2990\r
2991**/\r
2992EFI_STATUS\r
2993EFIAPI\r
2994Undi16SimpleNetworkGetStatus (\r
2995 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,\r
2996 OUT UINT32 *InterruptStatus OPTIONAL,\r
2997 OUT VOID **TxBuf OPTIONAL\r
2998 )\r
2999{\r
3000 EFI_STATUS Status;\r
3001 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3002 UINTN FrameLength;\r
3003\r
3004 if (This == NULL) {\r
3005 return EFI_INVALID_PARAMETER;\r
3006 }\r
3007\r
3008 Status = EFI_SUCCESS;\r
3009 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3010\r
3011 if (SimpleNetworkDevice == NULL) {\r
3012 return EFI_DEVICE_ERROR;\r
3013 }\r
3014 //\r
3015 // Verify that the current state of the adapter is valid for this call.\r
3016 //\r
3017 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3018 case EfiSimpleNetworkInitialized:\r
3019 break;\r
3020\r
3021 case EfiSimpleNetworkStopped:\r
3022 return EFI_NOT_STARTED;\r
3023\r
3024 case EfiSimpleNetworkStarted:\r
3025 default:\r
3026 return EFI_DEVICE_ERROR;\r
3027 }\r
3028\r
3029 if (InterruptStatus == NULL && TxBuf == NULL) {\r
3030 return EFI_INVALID_PARAMETER;\r
3031 }\r
3032\r
3033 FrameLength = 0;\r
3034 Status = Undi16SimpleNetworkIsr (This, &FrameLength, NULL, NULL, NULL, NULL);\r
3035\r
3036 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3037 if (EFI_ERROR (Status)) {\r
3038 return Status;\r
3039 }\r
3040 }\r
3041 //\r
3042 // See if the caller wants interrupt info.\r
3043 //\r
3044 if (InterruptStatus != NULL) {\r
3045 *InterruptStatus = SimpleNetworkDevice->InterruptStatus;\r
3046 SimpleNetworkDevice->InterruptStatus = 0;\r
3047 }\r
3048 //\r
3049 // See if the caller wants transmit buffer status info.\r
3050 //\r
3051 if (TxBuf != NULL) {\r
3052 *TxBuf = 0;\r
3053 SimpleNetworkTransmitFifoRemove (&(SimpleNetworkDevice->TxBufferFifo), TxBuf);\r
3054 }\r
3055\r
3056 return EFI_SUCCESS;\r
3057}\r
3058\r
3059/**\r
3060 Places a packet in the transmit queue of a network interface.\r
3061\r
3062 @param This The protocol instance pointer.\r
3063 @param HeaderSize The size, in bytes, of the media header to be filled in by\r
3064 the Transmit() function. If HeaderSize is non-zero, then it\r
3065 must be equal to This->Mode->MediaHeaderSize and the DestAddr\r
3066 and Protocol parameters must not be NULL.\r
3067 @param BufferSize The size, in bytes, of the entire packet (media header and\r
3068 data) to be transmitted through the network interface.\r
3069 @param Buffer A pointer to the packet (media header followed by data) to be\r
3070 transmitted. This parameter cannot be NULL. If HeaderSize is zero,\r
3071 then the media header in Buffer must already be filled in by the\r
3072 caller. If HeaderSize is non-zero, then the media header will be\r
3073 filled in by the Transmit() function.\r
3074 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter\r
3075 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then\r
3076 This->Mode->CurrentAddress is used for the source HW MAC address.\r
3077 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this\r
3078 parameter is ignored.\r
3079 @param Protocol The type of header to build. If HeaderSize is zero, then this\r
3080 parameter is ignored. See RFC 1700, section "Ether Types", for\r
3081 examples.\r
3082\r
3083 @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
3084 @retval EFI_NOT_STARTED The network interface has not been started.\r
0a6f4824 3085 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.\r
bcecde14 3086 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3087 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3088 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3089 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3090\r
3091**/\r
3092EFI_STATUS\r
3093EFIAPI\r
3094Undi16SimpleNetworkTransmit (\r
3095 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
3096 IN UINTN HeaderSize,\r
3097 IN UINTN BufferSize,\r
3098 IN VOID *Buffer,\r
3099 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
3100 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
3101 IN UINT16 *Protocol OPTIONAL\r
3102 )\r
3103{\r
3104 EFI_STATUS Status;\r
3105 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3106 PXENV_UNDI_TRANSMIT_T XmitInfo;\r
3107\r
3108 if (This == NULL) {\r
3109 return EFI_INVALID_PARAMETER;\r
3110 }\r
3111\r
3112 Status = EFI_SUCCESS;\r
3113 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3114\r
3115 if (SimpleNetworkDevice == NULL) {\r
3116 return EFI_DEVICE_ERROR;\r
3117 }\r
3118 //\r
3119 // Verify that the current state of the adapter is valid for this call.\r
3120 //\r
3121 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3122 case EfiSimpleNetworkInitialized:\r
3123 break;\r
3124\r
3125 case EfiSimpleNetworkStopped:\r
3126 return EFI_NOT_STARTED;\r
3127\r
3128 case EfiSimpleNetworkStarted:\r
3129 default:\r
3130 return EFI_DEVICE_ERROR;\r
3131 }\r
3132\r
3133 if (Buffer == NULL) {\r
3134 return EFI_INVALID_PARAMETER;\r
3135 }\r
3136\r
3137 if (BufferSize < SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {\r
3138 return EFI_BUFFER_TOO_SMALL;\r
3139 }\r
3140\r
3141 if (HeaderSize != 0) {\r
3142 if (HeaderSize != SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {\r
3143 return EFI_INVALID_PARAMETER;\r
3144 }\r
3145\r
3146 if (DestAddr == NULL || Protocol == NULL) {\r
3147 return EFI_INVALID_PARAMETER;\r
3148 }\r
3149\r
3150 if (DestAddr != NULL) {\r
3151 CopyMem (\r
3152 Buffer,\r
3153 DestAddr,\r
3154 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3155 );\r
3156 }\r
3157\r
3158 if (SrcAddr == NULL) {\r
3159 SrcAddr = &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress;\r
3160 }\r
3161\r
3162 CopyMem (\r
3163 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,\r
3164 SrcAddr,\r
3165 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3166 );\r
3167\r
3168 if (Protocol != NULL) {\r
3169 *(UINT16 *) ((UINT8 *) Buffer + 2 * SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize) = (UINT16) (((*Protocol & 0xFF) << 8) | ((*Protocol >> 8) & 0xFF));\r
3170 }\r
3171 }\r
3172 //\r
3173 // See if the recycled transmit buffer FIFO is full.\r
3174 // If it is full, then we can not transmit until the caller calls GetStatus() to pull\r
3175 // off recycled transmit buffers.\r
3176 //\r
3177 if (SimpleNetworkTransmitFifoFull (&(SimpleNetworkDevice->TxBufferFifo))) {\r
3178 return EFI_NOT_READY;\r
3179 }\r
3180 //\r
3181 // Output debug trace message.\r
3182 //\r
3183 DEBUG ((DEBUG_NET, "Undi16SimpleNetworkTransmit\n\r "));\r
3184\r
3185 //\r
3186 // Initialize UNDI WRITE parameter structure.\r
3187 //\r
3188 XmitInfo.Status = INIT_PXE_STATUS;\r
3189 XmitInfo.Protocol = P_UNKNOWN;\r
3190 XmitInfo.XmitFlag = XMT_DESTADDR;\r
3191 XmitInfo.DestAddrOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr & 0x000f);\r
3192 XmitInfo.DestAddrSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr >> 4);\r
3193 XmitInfo.TBDOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit & 0x000f);\r
3194 XmitInfo.TBDSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit >> 4);\r
3195 XmitInfo.Reserved[0] = 0;\r
3196 XmitInfo.Reserved[1] = 0;\r
3197\r
3198 CopyMem (\r
3199 SimpleNetworkDevice->TxDestAddr,\r
3200 Buffer,\r
3201 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize\r
3202 );\r
3203\r
3204 CopyMem (\r
3205 SimpleNetworkDevice->TxRealModeMediaHeader,\r
3206 Buffer,\r
3207 SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize\r
3208 );\r
3209\r
3210 SimpleNetworkDevice->Xmit->ImmedLength = (UINT16) SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize;\r
3211\r
3212 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen = (UINT16) (BufferSize - SimpleNetworkDevice->Xmit->ImmedLength);\r
3213\r
3214 CopyMem (\r
3215 SimpleNetworkDevice->TxRealModeDataBuffer,\r
3216 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize,\r
3217 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen\r
3218 );\r
3219\r
3220 //\r
3221 // Make API call to UNDI TRANSMIT\r
3222 //\r
3223 XmitInfo.Status = 0;\r
3224\r
3225 Status = PxeUndiTransmit (SimpleNetworkDevice, &XmitInfo);\r
3226\r
3227 if (EFI_ERROR (Status)) {\r
3228 return Status;\r
3229 }\r
3230 //\r
3231 // Check the status code from the 16 bit UNDI ROM\r
3232 //\r
3233 switch (XmitInfo.Status) {\r
3234 case PXENV_STATUS_OUT_OF_RESOURCES:\r
3235 return EFI_NOT_READY;\r
3236\r
3237 case PXENV_STATUS_SUCCESS:\r
3238 break;\r
3239\r
3240 default:\r
3241 return EFI_DEVICE_ERROR;\r
3242 }\r
3243 //\r
3244 // Add address of Buffer to the recycled transmit buffer FIFO\r
3245 //\r
3246 SimpleNetworkTransmitFifoAdd (&(SimpleNetworkDevice->TxBufferFifo), Buffer);\r
3247\r
3248 return EFI_SUCCESS;\r
3249}\r
3250\r
3251/**\r
3252 Receives a packet from a network interface.\r
0a6f4824 3253\r
bcecde14 3254 @param This The protocol instance pointer.\r
3255 @param HeaderSize The size, in bytes, of the media header received on the network\r
3256 interface. If this parameter is NULL, then the media header size\r
3257 will not be returned.\r
3258 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
3259 bytes, of the packet that was received on the network interface.\r
3260 @param Buffer A pointer to the data buffer to receive both the media header and\r
3261 the data.\r
3262 @param SrcAddr The source HW MAC address. If this parameter is NULL, the\r
3263 HW MAC source address will not be extracted from the media\r
3264 header.\r
3265 @param DestAddr The destination HW MAC address. If this parameter is NULL,\r
3266 the HW MAC destination address will not be extracted from the\r
3267 media header.\r
3268 @param Protocol The media header type. If this parameter is NULL, then the\r
3269 protocol will not be extracted from the media header. See\r
3270 RFC 1700 section "Ether Types" for examples.\r
3271\r
3272 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has\r
3273 been updated to the number of bytes received.\r
3274 @retval EFI_NOT_STARTED The network interface has not been started.\r
3275 @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
3276 request.\r
3277 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3278 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3279 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3280 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3281\r
3282**/\r
3283EFI_STATUS\r
3284EFIAPI\r
3285Undi16SimpleNetworkReceive (\r
3286 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
3287 OUT UINTN *HeaderSize OPTIONAL,\r
3288 IN OUT UINTN *BufferSize,\r
3289 OUT VOID *Buffer,\r
3290 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
3291 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
3292 OUT UINT16 *Protocol OPTIONAL\r
3293 )\r
3294{\r
3295 EFI_STATUS Status;\r
3296 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3297 UINTN MediaAddrSize;\r
3298 UINT8 ProtType;\r
3299\r
3300 if (This == NULL || BufferSize == NULL || Buffer == NULL) {\r
3301 return EFI_INVALID_PARAMETER;\r
3302 }\r
3303\r
3304 Status = EFI_SUCCESS;\r
3305 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3306\r
3307 if (SimpleNetworkDevice == NULL) {\r
3308 return EFI_DEVICE_ERROR;\r
3309 }\r
3310 //\r
3311 // Verify that the current state of the adapter is valid for this call.\r
3312 //\r
3313 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3314 case EfiSimpleNetworkInitialized:\r
3315 break;\r
3316\r
3317 case EfiSimpleNetworkStopped:\r
3318 return EFI_NOT_STARTED;\r
3319\r
3320 case EfiSimpleNetworkStarted:\r
3321 default:\r
3322 return EFI_DEVICE_ERROR;\r
3323 }\r
3324\r
3325 Status = Undi16SimpleNetworkIsr (\r
3326 This,\r
3327 BufferSize,\r
3328 HeaderSize,\r
3329 Buffer,\r
3330 &ProtType,\r
3331 NULL\r
3332 );\r
3333\r
3334 if (EFI_ERROR (Status)) {\r
3335 return Status;\r
3336 }\r
3337\r
3338 if ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) == 0) {\r
3339 return EFI_NOT_READY;\r
3340\r
3341 }\r
3342\r
3343 SimpleNetworkDevice->InterruptStatus &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
3344\r
3345 MediaAddrSize = This->Mode->HwAddressSize;\r
3346\r
3347 if (SrcAddr != NULL) {\r
3348 CopyMem (SrcAddr, (UINT8 *) Buffer + MediaAddrSize, MediaAddrSize);\r
3349 }\r
3350\r
3351 if (DestAddr != NULL) {\r
3352 CopyMem (DestAddr, Buffer, MediaAddrSize);\r
3353 }\r
3354\r
3355 if (Protocol != NULL) {\r
3356 *((UINT8 *) Protocol) = *((UINT8 *) Buffer + (2 * MediaAddrSize) + 1);\r
3357 *((UINT8 *) Protocol + 1) = *((UINT8 *) Buffer + (2 * MediaAddrSize));\r
3358 }\r
3359\r
3360 DEBUG ((DEBUG_NET, "Packet Received: BufferSize=%d HeaderSize = %d\n", *BufferSize, *HeaderSize));\r
3361\r
3362 return Status;\r
3363\r
3364}\r
3365//\r
3366// WaitForPacket()\r
3367//\r
3368/**\r
3369 wait for a packet to be received.\r
3370\r
3371 @param Event Event used with WaitForEvent() to wait for a packet to be received.\r
3372 @param Context Event Context\r
0a6f4824 3373\r
bcecde14 3374**/\r
3375VOID\r
3376EFIAPI\r
3377Undi16SimpleNetworkWaitForPacket (\r
3378 IN EFI_EVENT Event,\r
3379 IN VOID *Context\r
3380 )\r
3381{\r
3382 //\r
3383 // Someone is waiting on the receive packet event, if there's\r
3384 // a packet pending, signal the event\r
3385 //\r
3386 if (!EFI_ERROR (Undi16SimpleNetworkCheckForPacket (Context))) {\r
3387 gBS->SignalEvent (Event);\r
3388 }\r
3389}\r
3390//\r
3391// CheckForPacket()\r
3392//\r
3393/**\r
3394 Check whether packet is ready for receive.\r
3395\r
3396 @param This The protocol instance pointer.\r
0a6f4824 3397\r
bcecde14 3398 @retval EFI_SUCCESS Receive data is ready.\r
3399 @retval EFI_NOT_STARTED The network interface has not been started.\r
3400 @retval EFI_NOT_READY The network interface is too busy to accept this transmit\r
3401 request.\r
3402 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
3403 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.\r
3404 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3405 @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
3406**/\r
3407EFI_STATUS\r
3408Undi16SimpleNetworkCheckForPacket (\r
3409 IN EFI_SIMPLE_NETWORK_PROTOCOL *This\r
3410 )\r
3411{\r
3412 EFI_STATUS Status;\r
3413 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;\r
3414 UINTN FrameLength;\r
3415\r
3416 if (This == NULL) {\r
3417 return EFI_INVALID_PARAMETER;\r
3418 }\r
3419\r
3420 Status = EFI_SUCCESS;\r
3421 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3422\r
3423 if (SimpleNetworkDevice == NULL) {\r
3424 return EFI_DEVICE_ERROR;\r
3425 }\r
3426 //\r
3427 // Verify that the current state of the adapter is valid for this call.\r
3428 //\r
3429 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {\r
3430 case EfiSimpleNetworkInitialized:\r
3431 break;\r
3432\r
3433 case EfiSimpleNetworkStopped:\r
3434 return EFI_NOT_STARTED;\r
3435\r
3436 case EfiSimpleNetworkStarted:\r
3437 default:\r
3438 return EFI_DEVICE_ERROR;\r
3439 }\r
3440\r
3441 FrameLength = 0;\r
3442 Status = Undi16SimpleNetworkIsr (\r
3443 This,\r
3444 &FrameLength,\r
3445 NULL,\r
3446 NULL,\r
3447 NULL,\r
3448 NULL\r
3449 );\r
3450\r
3451 if (Status != EFI_BUFFER_TOO_SMALL) {\r
3452 if (EFI_ERROR (Status)) {\r
3453 return Status;\r
3454 }\r
3455 }\r
3456\r
3457 return ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) != 0) ? EFI_SUCCESS : EFI_NOT_READY;\r
3458}\r
3459\r
3460/**\r
3461 Signal handlers for ExitBootServices event.\r
0a6f4824
LG
3462\r
3463 Clean up any Real-mode UNDI residue from the system\r
3464\r
bcecde14 3465 @param Event ExitBootServices event\r
0a6f4824 3466 @param Context\r
bcecde14 3467**/\r
3468VOID\r
3469EFIAPI\r
3470Undi16SimpleNetworkEvent (\r
3471 IN EFI_EVENT Event,\r
3472 IN VOID *Context\r
3473 )\r
3474{\r
3475 //\r
3476 // NOTE: This is not the only way to effect this cleanup. The prescribed mechanism\r
3477 // would be to perform an UNDI STOP command. This strategam has been attempted\r
3478 // but results in problems making some of the EFI core services from TPL_CALLBACK.\r
3479 // This issue needs to be resolved, but the other alternative has been to perform\r
3480 // the unchain logic explicitly, as done below.\r
3481 //\r
3482 RestoreCachedVectorAddress (0x1A);\r
3483}\r
3484\r
3485/**\r
3486 Allocate buffer below 1M for real mode.\r
3487\r
3488 @param NumPages The number pages want to be allocated.\r
3489 @param Buffer On return, allocated buffer.\r
0a6f4824 3490\r
bcecde14 3491 @return Status of allocating pages.\r
3492**/\r
3493EFI_STATUS\r
3494BiosSnp16AllocatePagesBelowOneMb (\r
3495 UINTN NumPages,\r
3496 VOID **Buffer\r
3497 )\r
3498{\r
3499 EFI_STATUS Status;\r
3500 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
3501\r
3502 PhysicalAddress = 0x000fffff;\r
3503 Status = gBS->AllocatePages (\r
3504 AllocateMaxAddress,\r
3505 EfiRuntimeServicesData,\r
3506 NumPages,\r
3507 &PhysicalAddress\r
3508 );\r
3509 if (EFI_ERROR (Status)) {\r
3510 return Status;\r
3511 }\r
3512\r
3513 *Buffer = (VOID *) (UINTN) PhysicalAddress;\r
3514 return EFI_SUCCESS;\r
3515}\r