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