]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Csm/BiosThunk/Snp16Dxe/BiosSnp16.c
a2a7797f0748e13608a1cbcbfa221b446a1ad5ca
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / BiosThunk / Snp16Dxe / BiosSnp16.c
1 /** @file
2
3 Copyright (c) 1999 - 2014, 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 &= (UINT64)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 &= (UINT64)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 &= (UINT64)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 // Free resources allocated in LaunchBaseCode
1266 //
1267 Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);
1268 }
1269
1270 return EFI_NOT_FOUND;
1271 }
1272
1273 /**
1274 Unload 16 bit UNDI Option ROM from memory
1275
1276 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1277
1278 @return EFI_STATUS
1279 **/
1280 EFI_STATUS
1281 Undi16SimpleNetworkUnloadUndi (
1282 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
1283 )
1284 {
1285 if (SimpleNetworkDevice->UndiLoaderTable != NULL) {
1286 ZeroMem (SimpleNetworkDevice->UndiLoaderTable, SimpleNetworkDevice->UndiLoaderTablePages << EFI_PAGE_SHIFT);
1287 gBS->FreePages (
1288 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->UndiLoaderTable,
1289 SimpleNetworkDevice->UndiLoaderTablePages
1290 );
1291 }
1292
1293 if (SimpleNetworkDevice->DestinationDataSegment != NULL) {
1294 ZeroMem (
1295 SimpleNetworkDevice->DestinationDataSegment,
1296 SimpleNetworkDevice->DestinationDataSegmentPages << EFI_PAGE_SHIFT
1297 );
1298 gBS->FreePages (
1299 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationDataSegment,
1300 SimpleNetworkDevice->DestinationDataSegmentPages
1301 );
1302 }
1303
1304 if (SimpleNetworkDevice->DestinationStackSegment != NULL) {
1305 ZeroMem (
1306 SimpleNetworkDevice->DestinationStackSegment,
1307 SimpleNetworkDevice->DestinationStackSegmentPages << EFI_PAGE_SHIFT
1308 );
1309 gBS->FreePages (
1310 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationStackSegment,
1311 SimpleNetworkDevice->DestinationStackSegmentPages
1312 );
1313 }
1314
1315 if (SimpleNetworkDevice->DestinationCodeSegment != NULL) {
1316 ZeroMem (
1317 SimpleNetworkDevice->DestinationCodeSegment,
1318 SimpleNetworkDevice->DestinationCodeSegmentPages << EFI_PAGE_SHIFT
1319 );
1320 gBS->FreePages (
1321 (EFI_PHYSICAL_ADDRESS) (UINTN) SimpleNetworkDevice->DestinationCodeSegment,
1322 SimpleNetworkDevice->DestinationCodeSegmentPages
1323 );
1324 }
1325
1326 return EFI_SUCCESS;
1327 }
1328
1329 /**
1330 Start the UNDI interface.
1331
1332 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1333 @param Ax PCI address of Undi device.
1334
1335 @retval EFI_DEVICE_ERROR Fail to start 16 bit UNDI ROM.
1336 @retval Others Status of start 16 bit UNDI ROM.
1337 **/
1338 EFI_STATUS
1339 Undi16SimpleNetworkStartUndi (
1340 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,
1341 UINT16 Ax
1342 )
1343 {
1344 EFI_STATUS Status;
1345 PXENV_START_UNDI_T Start;
1346
1347 //
1348 // Call 16 bit UNDI ROM to start the network interface
1349 //
1350 //
1351 // @bug : What is this state supposed to be???
1352 //
1353 Start.Status = INIT_PXE_STATUS;
1354 Start.Ax = Ax;
1355 Start.Bx = 0x0000;
1356 Start.Dx = 0x0000;
1357 Start.Di = 0x0000;
1358 Start.Es = 0x0000;
1359
1360 Status = PxeStartUndi (SimpleNetworkDevice, &Start);
1361 if (EFI_ERROR (Status)) {
1362 return Status;
1363 }
1364 //
1365 // Check the status code from the 16 bit UNDI ROM
1366 //
1367 if (Start.Status != PXENV_STATUS_SUCCESS) {
1368 return EFI_DEVICE_ERROR;
1369 }
1370
1371 return Status;
1372 }
1373
1374
1375 /**
1376 Stop the UNDI interface
1377
1378 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1379
1380 @retval EFI_DEVICE_ERROR Fail to stop 16 bit UNDI ROM.
1381 @retval Others Status of stop 16 bit UNDI ROM.
1382 **/
1383 EFI_STATUS
1384 Undi16SimpleNetworkStopUndi (
1385 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
1386 )
1387 {
1388 EFI_STATUS Status;
1389 PXENV_STOP_UNDI_T Stop;
1390
1391 //
1392 // Call 16 bit UNDI ROM to start the network interface
1393 //
1394 Stop.Status = INIT_PXE_STATUS;
1395
1396 Status = PxeUndiStop (SimpleNetworkDevice, &Stop);
1397 if (EFI_ERROR (Status)) {
1398 return Status;
1399 }
1400 //
1401 // Check the status code from the 16 bit UNDI ROM
1402 //
1403 if (Stop.Status != PXENV_STATUS_SUCCESS) {
1404 return EFI_DEVICE_ERROR;
1405 }
1406
1407 return Status;
1408 }
1409
1410 /**
1411 Cleanup Unid network interface
1412
1413 @param SimpleNetworkDevice A pointer to EFI_SIMPLE_NETWORK_DEV data structure.
1414
1415 @retval EFI_DEVICE_ERROR Fail to cleanup 16 bit UNDI ROM.
1416 @retval Others Status of cleanup 16 bit UNDI ROM.
1417 **/
1418 EFI_STATUS
1419 Undi16SimpleNetworkCleanupUndi (
1420 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
1421 )
1422 {
1423 EFI_STATUS Status;
1424 PXENV_UNDI_CLEANUP_T Cleanup;
1425
1426 //
1427 // Call 16 bit UNDI ROM to cleanup the network interface
1428 //
1429 Cleanup.Status = INIT_PXE_STATUS;
1430
1431 Status = PxeUndiCleanup (SimpleNetworkDevice, &Cleanup);
1432 if (EFI_ERROR (Status)) {
1433 return Status;
1434 }
1435 //
1436 // Check the status code from the 16 bit UNDI ROM
1437 //
1438 if (Cleanup.Status != PXENV_STATUS_SUCCESS) {
1439 return EFI_DEVICE_ERROR;
1440 }
1441
1442 return Status;
1443 }
1444
1445 /**
1446 Get runtime information for Undi network interface
1447
1448 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1449
1450 @retval EFI_SUCCESS Sucess operation.
1451 @retval Others Fail to get runtime information for Undi network interface.
1452 **/
1453 EFI_STATUS
1454 Undi16SimpleNetworkGetInformation (
1455 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1456 )
1457 {
1458 EFI_STATUS Status;
1459 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1460 UINTN Index;
1461
1462 if (This == NULL) {
1463 return EFI_INVALID_PARAMETER;
1464 }
1465
1466 Status = EFI_SUCCESS;
1467 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1468
1469 if (SimpleNetworkDevice == NULL) {
1470 return EFI_DEVICE_ERROR;
1471 }
1472 //
1473 // Verify that the current state of the adapter is valid for this call.
1474 //
1475 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
1476 case EfiSimpleNetworkStarted:
1477 case EfiSimpleNetworkInitialized:
1478 break;
1479
1480 case EfiSimpleNetworkStopped:
1481 return EFI_NOT_STARTED;
1482
1483 default:
1484 return EFI_DEVICE_ERROR;
1485 }
1486 //
1487 // Call 16 bit UNDI ROM to start the network interface
1488 //
1489 ZeroMem (&SimpleNetworkDevice->GetInformation, sizeof (PXENV_UNDI_GET_INFORMATION_T));
1490
1491 SimpleNetworkDevice->GetInformation.Status = INIT_PXE_STATUS;
1492
1493 Status = PxeUndiGetInformation (SimpleNetworkDevice, &SimpleNetworkDevice->GetInformation);
1494 if (EFI_ERROR (Status)) {
1495 return Status;
1496 }
1497
1498 DEBUG ((DEBUG_NET, " GetInformation.Status = %d\n", SimpleNetworkDevice->GetInformation.Status));
1499 DEBUG ((DEBUG_NET, " GetInformation.BaseIo = %d\n", SimpleNetworkDevice->GetInformation.BaseIo));
1500 DEBUG ((DEBUG_NET, " GetInformation.IntNumber = %d\n", SimpleNetworkDevice->GetInformation.IntNumber));
1501 DEBUG ((DEBUG_NET, " GetInformation.MaxTranUnit = %d\n", SimpleNetworkDevice->GetInformation.MaxTranUnit));
1502 DEBUG ((DEBUG_NET, " GetInformation.HwType = %d\n", SimpleNetworkDevice->GetInformation.HwType));
1503 DEBUG ((DEBUG_NET, " GetInformation.HwAddrLen = %d\n", SimpleNetworkDevice->GetInformation.HwAddrLen));
1504 DEBUG ((DEBUG_NET, " GetInformation.ROMAddress = %d\n", SimpleNetworkDevice->GetInformation.ROMAddress));
1505 DEBUG ((DEBUG_NET, " GetInformation.RxBufCt = %d\n", SimpleNetworkDevice->GetInformation.RxBufCt));
1506 DEBUG ((DEBUG_NET, " GetInformation.TxBufCt = %d\n", SimpleNetworkDevice->GetInformation.TxBufCt));
1507
1508 DEBUG ((DEBUG_NET, " GetInformation.CurNodeAddr ="));
1509 for (Index = 0; Index < 16; Index++) {
1510 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.CurrentNodeAddress[Index]));
1511 }
1512
1513 DEBUG ((DEBUG_NET, "\n"));
1514
1515 DEBUG ((DEBUG_NET, " GetInformation.PermNodeAddr ="));
1516 for (Index = 0; Index < 16; Index++) {
1517 DEBUG ((DEBUG_NET, "%02x ", SimpleNetworkDevice->GetInformation.PermNodeAddress[Index]));
1518 }
1519
1520 DEBUG ((DEBUG_NET, "\n"));
1521
1522 //
1523 // Check the status code from the 16 bit UNDI ROM
1524 //
1525 if (SimpleNetworkDevice->GetInformation.Status != PXENV_STATUS_SUCCESS) {
1526 return EFI_DEVICE_ERROR;
1527 }
1528 //
1529 // The information has been retrieved. Fill in Mode data.
1530 //
1531 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize = SimpleNetworkDevice->GetInformation.HwAddrLen;
1532
1533 SimpleNetworkDevice->SimpleNetworkMode.MaxPacketSize = SimpleNetworkDevice->GetInformation.MaxTranUnit;
1534
1535 SimpleNetworkDevice->SimpleNetworkMode.IfType = (UINT8) SimpleNetworkDevice->GetInformation.HwType;
1536
1537 ZeroMem (
1538 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
1539 sizeof SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress
1540 );
1541
1542 CopyMem (
1543 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
1544 &SimpleNetworkDevice->GetInformation.CurrentNodeAddress,
1545 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
1546 );
1547
1548 ZeroMem (
1549 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
1550 sizeof SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress
1551 );
1552
1553 CopyMem (
1554 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
1555 &SimpleNetworkDevice->GetInformation.PermNodeAddress,
1556 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
1557 );
1558
1559 //
1560 // hard code broadcast address - not avail in PXE2.1
1561 //
1562 ZeroMem (
1563 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,
1564 sizeof SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress
1565 );
1566
1567 SetMem (
1568 &SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,
1569 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,
1570 0xff
1571 );
1572
1573 return Status;
1574 }
1575
1576 /**
1577 Get NIC type
1578
1579 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1580
1581 @retval EFI_SUCCESS Sucess operation.
1582 @retval Others Fail to get NIC type.
1583 **/
1584 EFI_STATUS
1585 Undi16SimpleNetworkGetNicType (
1586 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1587 )
1588 {
1589 EFI_STATUS Status;
1590 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1591
1592 if (This == NULL) {
1593 return EFI_INVALID_PARAMETER;
1594 }
1595
1596 Status = EFI_SUCCESS;
1597 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1598
1599 if (SimpleNetworkDevice == NULL) {
1600 return EFI_DEVICE_ERROR;
1601 }
1602
1603 ZeroMem (&SimpleNetworkDevice->GetNicType, sizeof (PXENV_UNDI_GET_NIC_TYPE_T));
1604
1605 SimpleNetworkDevice->GetNicType.Status = INIT_PXE_STATUS;
1606
1607 Status = PxeUndiGetNicType (SimpleNetworkDevice, &SimpleNetworkDevice->GetNicType);
1608
1609 if (EFI_ERROR (Status)) {
1610 return Status;
1611 }
1612
1613 DEBUG ((DEBUG_NET, " GetNicType.Status = %d\n", SimpleNetworkDevice->GetNicType.Status));
1614 DEBUG ((DEBUG_NET, " GetNicType.NicType = %d\n", SimpleNetworkDevice->GetNicType.NicType));
1615 //
1616 // Check the status code from the 16 bit UNDI ROM
1617 //
1618 if (SimpleNetworkDevice->GetNicType.Status != PXENV_STATUS_SUCCESS) {
1619 return EFI_DEVICE_ERROR;
1620 }
1621 //
1622 // The information has been retrieved. Fill in Mode data.
1623 //
1624 return Status;
1625 }
1626
1627 /**
1628 Get NDIS information
1629
1630 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1631
1632 @retval EFI_SUCCESS Sucess operation.
1633 @retval Others Fail to get NDIS information.
1634 **/
1635 EFI_STATUS
1636 Undi16SimpleNetworkGetNdisInfo (
1637 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1638 )
1639 {
1640 EFI_STATUS Status;
1641 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1642
1643 if (This == NULL) {
1644 return EFI_INVALID_PARAMETER;
1645 }
1646
1647 Status = EFI_SUCCESS;
1648 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1649
1650 if (SimpleNetworkDevice == NULL) {
1651 return EFI_DEVICE_ERROR;
1652 }
1653
1654 ZeroMem (&SimpleNetworkDevice->GetNdisInfo, sizeof (PXENV_UNDI_GET_NDIS_INFO_T));
1655
1656 SimpleNetworkDevice->GetNdisInfo.Status = INIT_PXE_STATUS;
1657
1658 Status = PxeUndiGetNdisInfo (SimpleNetworkDevice, &SimpleNetworkDevice->GetNdisInfo);
1659
1660 if (EFI_ERROR (Status)) {
1661 return Status;
1662 }
1663
1664 DEBUG ((DEBUG_NET, " GetNdisInfo.Status = %d\n", SimpleNetworkDevice->GetNdisInfo.Status));
1665 DEBUG ((DEBUG_NET, " GetNdisInfo.IfaceType = %a\n", SimpleNetworkDevice->GetNdisInfo.IfaceType));
1666 DEBUG ((DEBUG_NET, " GetNdisInfo.LinkSpeed = %d\n", SimpleNetworkDevice->GetNdisInfo.LinkSpeed));
1667 DEBUG ((DEBUG_NET, " GetNdisInfo.ServiceFlags = %08x\n", SimpleNetworkDevice->GetNdisInfo.ServiceFlags));
1668
1669 //
1670 // Check the status code from the 16 bit UNDI ROM
1671 //
1672 if (SimpleNetworkDevice->GetNdisInfo.Status != PXENV_STATUS_SUCCESS) {
1673 return EFI_DEVICE_ERROR;
1674 }
1675 //
1676 // The information has been retrieved. Fill in Mode data.
1677 //
1678 return Status;
1679 }
1680
1681 /**
1682 Call Undi ROM 16bit ISR() to check interrupt cause.
1683
1684 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1685 @param FrameLength The length of frame buffer.
1686 @param FrameHeaderLength The length of frame buffer's header if has.
1687 @param Frame The frame buffer to process network interrupt.
1688 @param ProtType The type network transmit protocol
1689 @param PktType The type of package.
1690
1691 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM's ISR, or status is invalid.
1692 @retval EFI_SUCCESS Success operation.
1693 **/
1694 EFI_STATUS
1695 Undi16SimpleNetworkIsr (
1696 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
1697 IN UINTN *FrameLength,
1698 IN UINTN *FrameHeaderLength, OPTIONAL
1699 IN UINT8 *Frame, OPTIONAL
1700 IN UINT8 *ProtType, OPTIONAL
1701 IN UINT8 *PktType OPTIONAL
1702 )
1703 {
1704 EFI_STATUS Status;
1705 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1706 BOOLEAN FrameReceived;
1707
1708 if (This == NULL) {
1709 return EFI_INVALID_PARAMETER;
1710 }
1711
1712 Status = EFI_SUCCESS;
1713 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1714
1715 if (SimpleNetworkDevice == NULL) {
1716 return EFI_DEVICE_ERROR;
1717 }
1718
1719 FrameReceived = FALSE;
1720
1721 //
1722 // Verify that the current state of the adapter is valid for this call.
1723 //
1724 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
1725 case EfiSimpleNetworkInitialized:
1726 break;
1727
1728 case EfiSimpleNetworkStopped:
1729 return EFI_NOT_STARTED;
1730
1731 case EfiSimpleNetworkStarted:
1732 default:
1733 return EFI_DEVICE_ERROR;
1734 }
1735
1736 DEBUG ((DEBUG_NET, "Isr() IsrValid = %d\n", SimpleNetworkDevice->IsrValid));
1737
1738 if (!SimpleNetworkDevice->IsrValid) {
1739 //
1740 // Call 16 bit UNDI ROM to open the network interface
1741 //
1742 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));
1743 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
1744 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
1745
1746 DEBUG ((DEBUG_NET, "Isr() START\n"));
1747
1748 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
1749 if (EFI_ERROR (Status)) {
1750 return Status;
1751 }
1752 //
1753 // Check the status code from the 16 bit UNDI ROM
1754 //
1755 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
1756 return EFI_DEVICE_ERROR;
1757 }
1758 //
1759 // There have been no events on this UNDI interface, so return EFI_NOT_READY
1760 //
1761 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_NOT_OURS) {
1762 return EFI_SUCCESS;
1763 }
1764 //
1765 // There is data to process, so call until all events processed.
1766 //
1767 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));
1768 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
1769 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;
1770
1771 DEBUG ((DEBUG_NET, "Isr() PROCESS\n"));
1772
1773 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
1774 if (EFI_ERROR (Status)) {
1775 return Status;
1776 }
1777
1778 SimpleNetworkDevice->IsrValid = TRUE;
1779 }
1780 //
1781 // Call UNDI GET_NEXT until DONE
1782 //
1783 while (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_DONE) {
1784 //
1785 // Check the status code from the 16 bit UNDI ROM
1786 //
1787 if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
1788 return EFI_DEVICE_ERROR;
1789 }
1790 //
1791 // UNDI is busy. Caller will have to call again.
1792 // This should never happen with a polled mode driver.
1793 //
1794 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_BUSY) {
1795 DEBUG ((DEBUG_NET, " BUSY\n"));
1796 return EFI_SUCCESS;
1797 }
1798 //
1799 // Check for invalud UNDI FuncFlag
1800 //
1801 if (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE &&
1802 SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_TRANSMIT
1803 ) {
1804 DEBUG ((DEBUG_NET, " Invalid SimpleNetworkDevice->Isr.FuncFlag value %d\n", SimpleNetworkDevice->Isr.FuncFlag));
1805 return EFI_DEVICE_ERROR;
1806 }
1807 //
1808 // Check for Transmit Event
1809 //
1810 if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
1811 DEBUG ((DEBUG_NET, " TRANSMIT\n"));
1812 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
1813 }
1814 //
1815 // Check for Receive Event
1816 //
1817 else if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE) {
1818 //
1819 // note - this code will hang on a receive interrupt in a GetStatus loop
1820 //
1821 DEBUG ((DEBUG_NET, " RECEIVE\n"));
1822 SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
1823
1824 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.BufferLength = %d\n", SimpleNetworkDevice->Isr.BufferLength));
1825 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameLength = %d\n", SimpleNetworkDevice->Isr.FrameLength));
1826 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.FrameHeaderLength = %d\n", SimpleNetworkDevice->Isr.FrameHeaderLength));
1827 DEBUG (
1828 (
1829 DEBUG_NET, "SimpleNetworkDevice->Isr.Frame = %04x:%04x\n", SimpleNetworkDevice->Isr.FrameSegSel,
1830 SimpleNetworkDevice->Isr.FrameOffset
1831 )
1832 );
1833 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.ProtType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));
1834 DEBUG ((DEBUG_NET, "SimpleNetworkDevice->Isr.PktType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));
1835
1836 if (FrameReceived) {
1837 return EFI_SUCCESS;
1838 }
1839
1840 if ((Frame == NULL) || (SimpleNetworkDevice->Isr.FrameLength > *FrameLength)) {
1841 DEBUG ((DEBUG_NET, "return EFI_BUFFER_TOO_SMALL *FrameLength = %08x\n", *FrameLength));
1842 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;
1843 return EFI_BUFFER_TOO_SMALL;
1844 }
1845
1846 *FrameLength = SimpleNetworkDevice->Isr.FrameLength;
1847 if (FrameHeaderLength != NULL) {
1848 *FrameHeaderLength = SimpleNetworkDevice->Isr.FrameHeaderLength;
1849 }
1850
1851 if (ProtType != NULL) {
1852 *ProtType = SimpleNetworkDevice->Isr.ProtType;
1853 }
1854
1855 if (PktType != NULL) {
1856 *PktType = SimpleNetworkDevice->Isr.PktType;
1857 }
1858
1859 CopyMem (
1860 Frame,
1861 (VOID *)(UINTN) ((SimpleNetworkDevice->Isr.FrameSegSel << 4) + SimpleNetworkDevice->Isr.FrameOffset),
1862 SimpleNetworkDevice->Isr.BufferLength
1863 );
1864 Frame = Frame + SimpleNetworkDevice->Isr.BufferLength;
1865 if (SimpleNetworkDevice->Isr.BufferLength == SimpleNetworkDevice->Isr.FrameLength) {
1866 FrameReceived = TRUE;
1867 }
1868 }
1869 //
1870 // There is data to process, so call until all events processed.
1871 //
1872 ZeroMem (&SimpleNetworkDevice->Isr, sizeof (PXENV_UNDI_ISR_T));
1873 SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
1874 SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
1875
1876 DEBUG ((DEBUG_NET, "Isr() GET NEXT\n"));
1877
1878 Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
1879 if (EFI_ERROR (Status)) {
1880 return Status;
1881 }
1882 //
1883 // Check the status code from the 16 bit UNDI ROM
1884 //
1885 // if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
1886 // return EFI_DEVICE_ERROR;
1887 // }
1888 //
1889 }
1890
1891 SimpleNetworkDevice->IsrValid = FALSE;
1892 return EFI_SUCCESS;
1893 }
1894 //
1895 // ///////////////////////////////////////////////////////////////////////////////////////
1896 // Simple Network Protocol Interface Functions using 16 bit UNDI Option ROMs
1897 /////////////////////////////////////////////////////////////////////////////////////////
1898 //
1899 // Start()
1900 //
1901 /**
1902 Call 16 bit UNDI ROM to start the network interface
1903
1904 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1905
1906 @retval EFI_DEVICE_ERROR Network interface has not be initialized.
1907 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
1908 @retval EFI_SUCESS Success operation.
1909 **/
1910 EFI_STATUS
1911 EFIAPI
1912 Undi16SimpleNetworkStart (
1913 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1914 )
1915 {
1916 EFI_STATUS Status;
1917 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1918 PXENV_UNDI_STARTUP_T Startup;
1919
1920 if (This == NULL) {
1921 return EFI_INVALID_PARAMETER;
1922 }
1923
1924 Status = EFI_SUCCESS;
1925 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1926
1927 if (SimpleNetworkDevice == NULL) {
1928 return EFI_DEVICE_ERROR;
1929 }
1930 //
1931 // Verify that the current state of the adapter is valid for this call.
1932 //
1933 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
1934 case EfiSimpleNetworkStopped:
1935 break;
1936
1937 case EfiSimpleNetworkStarted:
1938 case EfiSimpleNetworkInitialized:
1939 return EFI_ALREADY_STARTED;
1940
1941 default:
1942 return EFI_DEVICE_ERROR;
1943 }
1944 //
1945 // Call 16 bit UNDI ROM to start the network interface
1946 //
1947 Startup.Status = INIT_PXE_STATUS;
1948
1949 Status = PxeUndiStartup (SimpleNetworkDevice, &Startup);
1950 if (EFI_ERROR (Status)) {
1951 return Status;
1952 }
1953 //
1954 // Check the status code from the 16 bit UNDI ROM
1955 //
1956 if (Startup.Status != PXENV_STATUS_SUCCESS) {
1957 return EFI_DEVICE_ERROR;
1958 }
1959 //
1960 // The UNDI interface has been started, so update the State.
1961 //
1962 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;
1963
1964 //
1965 //
1966 //
1967 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = 0;
1968 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = 0;
1969
1970 return Status;
1971 }
1972 //
1973 // Stop()
1974 //
1975 /**
1976 Call 16 bit UNDI ROM to stop the network interface
1977
1978 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
1979
1980 @retval EFI_DEVICE_ERROR Network interface has not be initialized.
1981 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
1982 @retval EFI_SUCESS Success operation.
1983 **/
1984 EFI_STATUS
1985 EFIAPI
1986 Undi16SimpleNetworkStop (
1987 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
1988 )
1989 {
1990 EFI_STATUS Status;
1991 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
1992
1993 if (This == NULL) {
1994 return EFI_INVALID_PARAMETER;
1995 }
1996
1997 Status = EFI_SUCCESS;
1998 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
1999
2000 if (SimpleNetworkDevice == NULL) {
2001 return EFI_DEVICE_ERROR;
2002 }
2003 //
2004 // Verify that the current state of the adapter is valid for this call.
2005 //
2006 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2007 case EfiSimpleNetworkStarted:
2008 break;
2009
2010 case EfiSimpleNetworkStopped:
2011 return EFI_NOT_STARTED;
2012
2013 case EfiSimpleNetworkInitialized:
2014 default:
2015 return EFI_DEVICE_ERROR;
2016 }
2017
2018 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;
2019
2020 return Status;
2021 }
2022
2023 //
2024 // Initialize()
2025 //
2026 /**
2027 Initialize network interface
2028
2029 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2030 @param ExtraRxBufferSize The size of extra request receive buffer.
2031 @param ExtraTxBufferSize The size of extra request transmit buffer.
2032
2033 @retval EFI_DEVICE_ERROR Fail to execute 16 bit ROM call.
2034 @retval EFI_SUCESS Success operation.
2035 **/
2036 EFI_STATUS
2037 EFIAPI
2038 Undi16SimpleNetworkInitialize (
2039 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
2040 IN UINTN ExtraRxBufferSize OPTIONAL,
2041 IN UINTN ExtraTxBufferSize OPTIONAL
2042 )
2043 {
2044 EFI_STATUS Status;
2045 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2046 PXENV_UNDI_INITIALIZE_T Initialize;
2047 PXENV_UNDI_OPEN_T Open;
2048
2049 if (This == NULL) {
2050 return EFI_INVALID_PARAMETER;
2051 }
2052
2053 Status = EFI_SUCCESS;
2054 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2055
2056 if (SimpleNetworkDevice == NULL) {
2057 return EFI_DEVICE_ERROR;
2058 }
2059 //
2060 // Verify that the current state of the adapter is valid for this call.
2061 //
2062 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2063 case EfiSimpleNetworkStopped:
2064 return EFI_NOT_STARTED;
2065
2066 case EfiSimpleNetworkStarted:
2067 break;
2068
2069 case EfiSimpleNetworkInitialized:
2070 default:
2071 return EFI_DEVICE_ERROR;
2072 }
2073 //
2074 // Call 16 bit UNDI ROM to start the network interface
2075 //
2076 Initialize.Status = INIT_PXE_STATUS;
2077 Initialize.ProtocolIni = 0;
2078
2079 Status = PxeUndiInitialize (SimpleNetworkDevice, &Initialize);
2080
2081 if (EFI_ERROR (Status)) {
2082 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Status = %r\n", Status));
2083 DEBUG ((DEBUG_ERROR, "Initialize.Status == %xh\n", Initialize.Status));
2084
2085 if (Initialize.Status == PXENV_STATUS_UNDI_MEDIATEST_FAILED) {
2086 Status = EFI_NO_MEDIA;
2087 }
2088
2089 return Status;
2090 }
2091 //
2092 // Check the status code from the 16 bit UNDI ROM
2093 //
2094 if (Initialize.Status != PXENV_STATUS_SUCCESS) {
2095 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiInitialize() - Initialize.Status = %04x\n", Initialize.Status));
2096 return EFI_DEVICE_ERROR;
2097 }
2098 //
2099 // Call 16 bit UNDI ROM to open the network interface
2100 //
2101 Open.Status = INIT_PXE_STATUS;
2102 Open.OpenFlag = 0;
2103 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);
2104 Undi16GetMCastFilters (
2105 &SimpleNetworkDevice->SimpleNetworkMode,
2106 &Open.McastBuffer,
2107 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2108 );
2109
2110 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);
2111
2112 if (EFI_ERROR (Status)) {
2113 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Status = %r\n", Status));
2114 return Status;
2115 }
2116 //
2117 // Check the status code from the 16 bit UNDI ROM
2118 //
2119 if (Open.Status != PXENV_STATUS_SUCCESS) {
2120 DEBUG ((DEBUG_ERROR, "ERROR : PxeUndiOpen() - Open.Status = %04x\n", Open.Status));
2121 return EFI_DEVICE_ERROR;
2122 }
2123 //
2124 // The UNDI interface has been initialized, so update the State.
2125 //
2126 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkInitialized;
2127
2128 //
2129 // If initialize succeeds, then assume that media is present.
2130 //
2131 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = TRUE;
2132
2133 //
2134 // Reset the recycled transmit buffer FIFO
2135 //
2136 SimpleNetworkDevice->TxBufferFifo.First = 0;
2137 SimpleNetworkDevice->TxBufferFifo.Last = 0;
2138 SimpleNetworkDevice->IsrValid = FALSE;
2139
2140 return Status;
2141 }
2142 //
2143 // Reset()
2144 //
2145 /**
2146 Reset network interface.
2147
2148 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2149 @param ExtendedVerification Need extended verfication.
2150
2151 @retval EFI_INVALID_PARAMETER Invalid This parameter.
2152 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2153 @retval EFI_NOT_STARTED Network device has been stopped.
2154 @retval EFI_DEVICE_ERROR Invalid status for network device
2155 @retval EFI_SUCCESS Success operation.
2156 **/
2157 EFI_STATUS
2158 EFIAPI
2159 Undi16SimpleNetworkReset (
2160 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
2161 IN BOOLEAN ExtendedVerification
2162 )
2163 {
2164 EFI_STATUS Status;
2165 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2166 PXENV_UNDI_RESET_T Reset;
2167 UINT16 Rx_filter;
2168
2169 if (This == NULL) {
2170 return EFI_INVALID_PARAMETER;
2171 }
2172
2173 Status = EFI_SUCCESS;
2174 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2175
2176 if (SimpleNetworkDevice == NULL) {
2177 return EFI_DEVICE_ERROR;
2178 }
2179 //
2180 // Verify that the current state of the adapter is valid for this call.
2181 //
2182 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2183 case EfiSimpleNetworkStopped:
2184 return EFI_NOT_STARTED;
2185
2186 case EfiSimpleNetworkInitialized:
2187 break;
2188
2189 case EfiSimpleNetworkStarted:
2190 default:
2191 return EFI_DEVICE_ERROR;
2192 }
2193
2194 Reset.Status = INIT_PXE_STATUS;
2195
2196 Rx_filter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);
2197
2198 Undi16GetMCastFilters (
2199 &SimpleNetworkDevice->SimpleNetworkMode,
2200 &Reset.R_Mcast_Buf,
2201 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2202 );
2203
2204 Status = PxeUndiResetNic (SimpleNetworkDevice, &Reset, Rx_filter);
2205
2206 if (EFI_ERROR (Status)) {
2207 return Status;
2208 }
2209 //
2210 // Check the status code from the 16 bit UNDI ROM
2211 //
2212 if (Reset.Status != PXENV_STATUS_SUCCESS) {
2213 return EFI_DEVICE_ERROR;
2214 }
2215 //
2216 // Reset the recycled transmit buffer FIFO
2217 //
2218 SimpleNetworkDevice->TxBufferFifo.First = 0;
2219 SimpleNetworkDevice->TxBufferFifo.Last = 0;
2220 SimpleNetworkDevice->IsrValid = FALSE;
2221
2222 return Status;
2223 }
2224 //
2225 // Shutdown()
2226 //
2227 /**
2228 Shutdown network interface.
2229
2230 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2231
2232 @retval EFI_INVALID_PARAMETER Invalid This parameter.
2233 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2234 @retval EFI_NOT_STARTED Network device has been stopped.
2235 @retval EFI_DEVICE_ERROR Invalid status for network device
2236 @retval EFI_SUCCESS Success operation.
2237 **/
2238 EFI_STATUS
2239 EFIAPI
2240 Undi16SimpleNetworkShutdown (
2241 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
2242 )
2243 {
2244 EFI_STATUS Status;
2245 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2246 PXENV_UNDI_CLOSE_T Close;
2247 PXENV_UNDI_SHUTDOWN_T Shutdown;
2248
2249 if (This == NULL) {
2250 return EFI_INVALID_PARAMETER;
2251 }
2252
2253 Status = EFI_SUCCESS;
2254 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2255
2256 if (SimpleNetworkDevice == NULL) {
2257 return EFI_DEVICE_ERROR;
2258 }
2259 //
2260 // Verify that the current state of the adapter is valid for this call.
2261 //
2262 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2263 case EfiSimpleNetworkStopped:
2264 return EFI_NOT_STARTED;
2265
2266 case EfiSimpleNetworkInitialized:
2267 break;
2268
2269 case EfiSimpleNetworkStarted:
2270 default:
2271 return EFI_DEVICE_ERROR;
2272 }
2273
2274 SimpleNetworkDevice->IsrValid = FALSE;
2275
2276 //
2277 // Call 16 bit UNDI ROM to start the network interface
2278 //
2279 Close.Status = INIT_PXE_STATUS;
2280
2281 Status = PxeUndiClose (SimpleNetworkDevice, &Close);
2282
2283 if (EFI_ERROR (Status)) {
2284 return Status;
2285 }
2286 //
2287 // Check the status code from the 16 bit UNDI ROM
2288 //
2289 if (Close.Status != PXENV_STATUS_SUCCESS) {
2290 return EFI_DEVICE_ERROR;
2291 }
2292 //
2293 // Call 16 bit UNDI ROM to open the network interface
2294 //
2295 Shutdown.Status = INIT_PXE_STATUS;
2296
2297 Status = PxeUndiShutdown (SimpleNetworkDevice, &Shutdown);
2298
2299 if (EFI_ERROR (Status)) {
2300 return Status;
2301 }
2302 //
2303 // Check the status code from the 16 bit UNDI ROM
2304 //
2305 if (Shutdown.Status != PXENV_STATUS_SUCCESS) {
2306 return EFI_DEVICE_ERROR;
2307 }
2308 //
2309 // The UNDI interface has been initialized, so update the State.
2310 //
2311 SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;
2312
2313 //
2314 // If shutdown succeeds, then assume that media is not present.
2315 //
2316 SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = FALSE;
2317
2318 //
2319 // Reset the recycled transmit buffer FIFO
2320 //
2321 SimpleNetworkDevice->TxBufferFifo.First = 0;
2322 SimpleNetworkDevice->TxBufferFifo.Last = 0;
2323
2324 //
2325 // A short delay. Without this an initialize immediately following
2326 // a shutdown will cause some versions of UNDI-16 to stop operating.
2327 //
2328 gBS->Stall (250000);
2329
2330 return Status;
2331 }
2332 //
2333 // ReceiveFilters()
2334 //
2335 /**
2336 Reset network interface.
2337
2338 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2339 @param Enable Enable mask value
2340 @param Disable Disable mask value
2341 @param ResetMCastFilter Whether reset multi cast filter or not
2342 @param MCastFilterCnt Count of mutli cast filter for different MAC address
2343 @param MCastFilter Buffer for mustli cast filter for different MAC address.
2344
2345 @retval EFI_INVALID_PARAMETER Invalid This parameter.
2346 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2347 @retval EFI_NOT_STARTED Network device has been stopped.
2348 @retval EFI_DEVICE_ERROR Invalid status for network device
2349 @retval EFI_SUCCESS Success operation.
2350 **/
2351 EFI_STATUS
2352 EFIAPI
2353 Undi16SimpleNetworkReceiveFilters (
2354 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
2355 IN UINT32 Enable,
2356 IN UINT32 Disable,
2357 IN BOOLEAN ResetMCastFilter,
2358 IN UINTN MCastFilterCnt OPTIONAL,
2359 IN EFI_MAC_ADDRESS * MCastFilter OPTIONAL
2360 )
2361 {
2362 EFI_STATUS Status;
2363 UINTN Index;
2364 UINT32 NewFilter;
2365 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2366 PXENV_UNDI_CLOSE_T Close;
2367 PXENV_UNDI_OPEN_T Open;
2368
2369 if (This == NULL) {
2370 return EFI_INVALID_PARAMETER;
2371 }
2372
2373 Status = EFI_SUCCESS;
2374 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2375
2376 if (SimpleNetworkDevice == NULL) {
2377 return EFI_DEVICE_ERROR;
2378 }
2379 //
2380 // Verify that the current state of the adapter is valid for this call.
2381 //
2382 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2383 case EfiSimpleNetworkStopped:
2384 return EFI_NOT_STARTED;
2385
2386 case EfiSimpleNetworkInitialized:
2387 break;
2388
2389 case EfiSimpleNetworkStarted:
2390 default:
2391 return EFI_DEVICE_ERROR;
2392 }
2393 //
2394 // First deal with possible filter setting changes
2395 //
2396 if ((Enable == 0) && (Disable == 0) && !ResetMCastFilter) {
2397 return EFI_SUCCESS;
2398 }
2399
2400 NewFilter = (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting | Enable) &~Disable;
2401
2402 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
2403 if ((MCastFilterCnt == 0) || (MCastFilter == 0) || MCastFilterCnt > SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount) {
2404 return EFI_INVALID_PARAMETER;
2405 }
2406 }
2407 //
2408 // Call 16 bit UNDI ROM to close the network interface
2409 //
2410 Close.Status = INIT_PXE_STATUS;
2411
2412 Status = PxeUndiClose (SimpleNetworkDevice, &Close);
2413
2414 if (EFI_ERROR (Status)) {
2415 return Status;
2416 }
2417 //
2418 // Check the status code from the 16 bit UNDI ROM
2419 //
2420 if (Close.Status != PXENV_STATUS_SUCCESS) {
2421 return EFI_DEVICE_ERROR;
2422 }
2423 //
2424 // Call 16 bit UNDI ROM to open the network interface
2425 //
2426 //
2427 // Reset the recycled transmit buffer FIFO
2428 //
2429 SimpleNetworkDevice->TxBufferFifo.First = 0;
2430 SimpleNetworkDevice->TxBufferFifo.Last = 0;
2431
2432 //
2433 // Call 16 bit UNDI ROM to open the network interface
2434 //
2435 ZeroMem (&Open, sizeof Open);
2436
2437 Open.Status = INIT_PXE_STATUS;
2438 Open.PktFilter = Undi16GetPacketFilterSetting (NewFilter);
2439
2440 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
2441 //
2442 // Copy the MAC addresses into the UNDI open parameter structure
2443 //
2444 Open.McastBuffer.MCastAddrCount = (UINT16) MCastFilterCnt;
2445 for (Index = 0; Index < MCastFilterCnt; ++Index) {
2446 CopyMem (
2447 Open.McastBuffer.MCastAddr[Index],
2448 &MCastFilter[Index],
2449 sizeof Open.McastBuffer.MCastAddr[Index]
2450 );
2451 }
2452 } else if (!ResetMCastFilter) {
2453 for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; ++Index) {
2454 CopyMem (
2455 Open.McastBuffer.MCastAddr[Index],
2456 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],
2457 sizeof Open.McastBuffer.MCastAddr[Index]
2458 );
2459 }
2460 }
2461
2462 Status = PxeUndiOpen (SimpleNetworkDevice, &Open);
2463
2464 if (EFI_ERROR (Status)) {
2465 return Status;
2466 }
2467 //
2468 // Check the status code from the 16 bit UNDI ROM
2469 //
2470 if (Open.Status != PXENV_STATUS_SUCCESS) {
2471 return EFI_DEVICE_ERROR;
2472 }
2473
2474 SimpleNetworkDevice->IsrValid = FALSE;
2475 SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = NewFilter;
2476
2477 if ((NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
2478 SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = (UINT32) MCastFilterCnt;
2479 for (Index = 0; Index < MCastFilterCnt; ++Index) {
2480 CopyMem (
2481 &SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index],
2482 &MCastFilter[Index],
2483 sizeof (EFI_MAC_ADDRESS)
2484 );
2485 }
2486 }
2487 //
2488 // Read back multicast addresses.
2489 //
2490 return EFI_SUCCESS;
2491 }
2492 //
2493 // StationAddress()
2494 //
2495 /**
2496 Set new MAC address.
2497
2498 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2499 @param Reset Whether reset station MAC address to permanent address
2500 @param New A pointer to New address
2501
2502 @retval EFI_INVALID_PARAMETER Invalid This parameter.
2503 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2504 @retval EFI_NOT_STARTED Network device has been stopped.
2505 @retval EFI_DEVICE_ERROR Invalid status for network device
2506 @retval EFI_SUCCESS Success operation.
2507 **/
2508 EFI_STATUS
2509 EFIAPI
2510 Undi16SimpleNetworkStationAddress (
2511 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
2512 IN BOOLEAN Reset,
2513 IN EFI_MAC_ADDRESS * New OPTIONAL
2514 )
2515 {
2516 EFI_STATUS Status;
2517 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2518 PXENV_UNDI_SET_STATION_ADDR_T SetStationAddr;
2519 //
2520 // EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;
2521 //
2522 PXENV_UNDI_CLOSE_T Close;
2523 PXENV_UNDI_OPEN_T Open;
2524
2525 if (This == NULL) {
2526 return EFI_INVALID_PARAMETER;
2527 }
2528
2529 Status = EFI_SUCCESS;
2530
2531 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2532
2533 if (SimpleNetworkDevice == NULL) {
2534 return EFI_DEVICE_ERROR;
2535 }
2536 //
2537 // Verify that the current state of the adapter is valid for this call.
2538 //
2539 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2540 case EfiSimpleNetworkInitialized:
2541 break;
2542
2543 case EfiSimpleNetworkStopped:
2544 return EFI_NOT_STARTED;
2545
2546 case EfiSimpleNetworkStarted:
2547 default:
2548 return EFI_DEVICE_ERROR;
2549 }
2550 //
2551 // Call 16 bit UNDI ROM to open the network interface
2552 //
2553 SetStationAddr.Status = INIT_PXE_STATUS;
2554
2555 if (Reset) {
2556 //
2557 // If we are resetting the Station Address to the permanent address, and the
2558 // Station Address is not programmable, then just return EFI_SUCCESS.
2559 //
2560 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {
2561 return EFI_SUCCESS;
2562 }
2563 //
2564 // If the address is already the permanent address, then just return success.
2565 //
2566 if (CompareMem (
2567 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
2568 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
2569 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2570 ) == 0) {
2571 return EFI_SUCCESS;
2572 }
2573 //
2574 // Copy the adapters permanent address to the new station address
2575 //
2576 CopyMem (
2577 &SetStationAddr.StationAddress,
2578 &SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
2579 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2580 );
2581 } else {
2582 //
2583 // If we are setting the Station Address, and the
2584 // Station Address is not programmable, return invalid parameter.
2585 //
2586 if (!SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable) {
2587 return EFI_INVALID_PARAMETER;
2588 }
2589 //
2590 // If the address is already the new address, then just return success.
2591 //
2592 if (CompareMem (
2593 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
2594 New,
2595 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2596 ) == 0) {
2597 return EFI_SUCCESS;
2598 }
2599 //
2600 // Copy New to the new station address
2601 //
2602 CopyMem (
2603 &SetStationAddr.StationAddress,
2604 New,
2605 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2606 );
2607
2608 }
2609 //
2610 // Call 16 bit UNDI ROM to stop the network interface
2611 //
2612 Close.Status = INIT_PXE_STATUS;
2613
2614 PxeUndiClose (SimpleNetworkDevice, &Close);
2615
2616 //
2617 // Call 16-bit UNDI ROM to set the station address
2618 //
2619 SetStationAddr.Status = PXENV_STATUS_SUCCESS;
2620
2621 Status = PxeUndiSetStationAddr (SimpleNetworkDevice, &SetStationAddr);
2622
2623 //
2624 // Call 16-bit UNDI ROM to start the network interface
2625 //
2626 Open.Status = PXENV_STATUS_SUCCESS;
2627 Open.OpenFlag = 0;
2628 Open.PktFilter = Undi16GetPacketFilterSetting (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);
2629 Undi16GetMCastFilters (
2630 &SimpleNetworkDevice->SimpleNetworkMode,
2631 &Open.McastBuffer,
2632 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2633 );
2634
2635 PxeUndiOpen (SimpleNetworkDevice, &Open);
2636
2637 //
2638 // Check status from station address change
2639 //
2640 if (EFI_ERROR (Status)) {
2641 return Status;
2642 }
2643 //
2644 // Check the status code from the 16 bit UNDI ROM
2645 //
2646 if (SetStationAddr.Status != PXENV_STATUS_SUCCESS) {
2647 return EFI_DEVICE_ERROR;
2648 }
2649
2650 CopyMem (
2651 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
2652 &SetStationAddr.StationAddress,
2653 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2654 );
2655
2656 #if 0 /* The device path is based on the permanent address not the current address. */
2657 //
2658 // The station address was changed, so update the device path with the new MAC address.
2659 //
2660 OldDevicePath = SimpleNetworkDevice->DevicePath;
2661 SimpleNetworkDevice->DevicePath = DuplicateDevicePath (SimpleNetworkDevice->BaseDevicePath);
2662 SimpleNetworkAppendMacAddressDevicePath (
2663 &SimpleNetworkDevice->DevicePath,
2664 &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress
2665 );
2666
2667 Status = LibReinstallProtocolInterfaces (
2668 SimpleNetworkDevice->Handle,
2669 &DevicePathProtocol,
2670 OldDevicePath,
2671 SimpleNetworkDevice->DevicePath,
2672 NULL
2673 );
2674
2675 if (EFI_ERROR (Status)) {
2676 DEBUG ((DEBUG_ERROR, "Failed to reinstall the DevicePath protocol for the Simple Network Device\n"));
2677 DEBUG ((DEBUG_ERROR, " Status = %r\n", Status));
2678 }
2679
2680 FreePool (OldDevicePath);
2681 #endif /* 0 */
2682
2683 return Status;
2684 }
2685 //
2686 // Statistics()
2687 //
2688 /**
2689 Resets or collects the statistics on a network interface.
2690
2691 @param This Protocol instance pointer.
2692 @param Reset Set to TRUE to reset the statistics for the network interface.
2693 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
2694 output the size, in bytes, of the resulting table of
2695 statistics.
2696 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
2697 contains the statistics.
2698
2699 @retval EFI_SUCCESS The statistics were collected from the network interface.
2700 @retval EFI_NOT_STARTED The network interface has not been started.
2701 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
2702 size needed to hold the statistics is returned in
2703 StatisticsSize.
2704 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2705 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2706 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
2707
2708 **/
2709 EFI_STATUS
2710 EFIAPI
2711 Undi16SimpleNetworkStatistics (
2712 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
2713 IN BOOLEAN Reset,
2714 IN OUT UINTN *StatisticsSize OPTIONAL,
2715 OUT EFI_NETWORK_STATISTICS * StatisticsTable OPTIONAL
2716 )
2717 {
2718 EFI_STATUS Status;
2719 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2720 PXENV_UNDI_CLEAR_STATISTICS_T ClearStatistics;
2721 PXENV_UNDI_GET_STATISTICS_T GetStatistics;
2722
2723 if (This == NULL) {
2724 return EFI_INVALID_PARAMETER;
2725 }
2726
2727 Status = EFI_SUCCESS;
2728 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2729
2730 if (SimpleNetworkDevice == NULL) {
2731 return EFI_DEVICE_ERROR;
2732 }
2733 //
2734 // Verify that the current state of the adapter is valid for this call.
2735 //
2736 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2737 case EfiSimpleNetworkInitialized:
2738 break;
2739
2740 case EfiSimpleNetworkStopped:
2741 return EFI_NOT_STARTED;
2742
2743 case EfiSimpleNetworkStarted:
2744 default:
2745 return EFI_DEVICE_ERROR;
2746 }
2747
2748 if ((StatisticsSize != NULL) && (*StatisticsSize != 0) && (StatisticsTable == NULL)) {
2749 return EFI_INVALID_PARAMETER;
2750 }
2751
2752 //
2753 // If Reset is TRUE, then clear all the statistics.
2754 //
2755 if (Reset) {
2756
2757 DEBUG ((DEBUG_NET, " RESET Statistics\n"));
2758
2759 //
2760 // Call 16 bit UNDI ROM to open the network interface
2761 //
2762 ClearStatistics.Status = INIT_PXE_STATUS;
2763
2764 Status = PxeUndiClearStatistics (SimpleNetworkDevice, &ClearStatistics);
2765
2766 if (EFI_ERROR (Status)) {
2767 return Status;
2768 }
2769 //
2770 // Check the status code from the 16 bit UNDI ROM
2771 //
2772 if (ClearStatistics.Status != PXENV_STATUS_SUCCESS) {
2773 return EFI_DEVICE_ERROR;
2774 }
2775
2776 DEBUG ((DEBUG_NET, " RESET Statistics Complete"));
2777 }
2778
2779 if (StatisticsSize != NULL) {
2780 EFI_NETWORK_STATISTICS LocalStatisticsTable;
2781
2782 DEBUG ((DEBUG_NET, " GET Statistics\n"));
2783
2784 //
2785 // If the size if valid, then see if the table is valid
2786 //
2787 if (StatisticsTable == NULL) {
2788 DEBUG ((DEBUG_NET, " StatisticsTable is NULL\n"));
2789 return EFI_INVALID_PARAMETER;
2790 }
2791 //
2792 // Call 16 bit UNDI ROM to open the network interface
2793 //
2794 GetStatistics.Status = INIT_PXE_STATUS;
2795 GetStatistics.XmtGoodFrames = 0;
2796 GetStatistics.RcvGoodFrames = 0;
2797 GetStatistics.RcvCRCErrors = 0;
2798 GetStatistics.RcvResourceErrors = 0;
2799
2800 Status = PxeUndiGetStatistics (SimpleNetworkDevice, &GetStatistics);
2801
2802 if (EFI_ERROR (Status)) {
2803 return Status;
2804 }
2805 //
2806 // Check the status code from the 16 bit UNDI ROM
2807 //
2808 if (GetStatistics.Status != PXENV_STATUS_SUCCESS) {
2809 return EFI_DEVICE_ERROR;
2810 }
2811 //
2812 // Fill in the Statistics Table with the collected values.
2813 //
2814 SetMem (&LocalStatisticsTable, sizeof LocalStatisticsTable, 0xff);
2815
2816 LocalStatisticsTable.TxGoodFrames = GetStatistics.XmtGoodFrames;
2817 LocalStatisticsTable.RxGoodFrames = GetStatistics.RcvGoodFrames;
2818 LocalStatisticsTable.RxCrcErrorFrames = GetStatistics.RcvCRCErrors;
2819 LocalStatisticsTable.RxDroppedFrames = GetStatistics.RcvResourceErrors;
2820
2821 CopyMem (StatisticsTable, &LocalStatisticsTable, *StatisticsSize);
2822
2823 DEBUG (
2824 (DEBUG_NET,
2825 " Statistics Collected : Size=%d Buf=%08x\n",
2826 *StatisticsSize,
2827 StatisticsTable)
2828 );
2829
2830 DEBUG ((DEBUG_NET, " GET Statistics Complete"));
2831
2832 if (*StatisticsSize < sizeof LocalStatisticsTable) {
2833 DEBUG ((DEBUG_NET, " BUFFER TOO SMALL\n"));
2834 Status = EFI_BUFFER_TOO_SMALL;
2835 }
2836
2837 *StatisticsSize = sizeof LocalStatisticsTable;
2838
2839 return Status;
2840
2841 }
2842
2843 return EFI_SUCCESS;
2844 }
2845 //
2846 // MCastIpToMac()
2847 //
2848 /**
2849 Translate IP address to MAC address.
2850
2851 @param This A pointer to EFI_SIMPLE_NETWORK_PROTOCOL structure.
2852 @param IPv6 IPv6 or IPv4
2853 @param IP A pointer to given Ip address.
2854 @param MAC On return, translated MAC address.
2855
2856 @retval EFI_INVALID_PARAMETER Invalid This parameter.
2857 @retval EFI_INVALID_PARAMETER Invalid IP address.
2858 @retval EFI_INVALID_PARAMETER Invalid return buffer for holding MAC address.
2859 @retval EFI_UNSUPPORTED Do not support IPv6
2860 @retval EFI_DEVICE_ERROR Network device has not been initialized.
2861 @retval EFI_NOT_STARTED Network device has been stopped.
2862 @retval EFI_DEVICE_ERROR Invalid status for network device
2863 @retval EFI_SUCCESS Success operation.
2864 **/
2865 EFI_STATUS
2866 EFIAPI
2867 Undi16SimpleNetworkMCastIpToMac (
2868 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
2869 IN BOOLEAN IPv6,
2870 IN EFI_IP_ADDRESS *IP,
2871 OUT EFI_MAC_ADDRESS *MAC
2872 )
2873 {
2874 EFI_STATUS Status;
2875 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
2876 PXENV_UNDI_GET_MCAST_ADDR_T GetMcastAddr;
2877
2878 if (This == NULL || IP == NULL || MAC == NULL) {
2879 return EFI_INVALID_PARAMETER;
2880 }
2881
2882 Status = EFI_SUCCESS;
2883 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2884
2885 if (SimpleNetworkDevice == NULL) {
2886 return EFI_DEVICE_ERROR;
2887 }
2888 //
2889 // Verify that the current state of the adapter is valid for this call.
2890 //
2891 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
2892 case EfiSimpleNetworkStopped:
2893 return EFI_NOT_STARTED;
2894
2895 case EfiSimpleNetworkInitialized:
2896 break;
2897
2898 case EfiSimpleNetworkStarted:
2899 default:
2900 return EFI_DEVICE_ERROR;
2901 }
2902 //
2903 // 16 bit UNDI Option ROMS do not support IPv6. Check for IPv6 usage.
2904 //
2905 if (IPv6) {
2906 return EFI_UNSUPPORTED;
2907 }
2908 //
2909 // Call 16 bit UNDI ROM to open the network interface
2910 //
2911 GetMcastAddr.Status = INIT_PXE_STATUS;
2912 CopyMem (&GetMcastAddr.InetAddr, IP, 4);
2913
2914 Status = PxeUndiGetMcastAddr (SimpleNetworkDevice, &GetMcastAddr);
2915
2916 if (EFI_ERROR (Status)) {
2917 return Status;
2918 }
2919 //
2920 // Check the status code from the 16 bit UNDI ROM
2921 //
2922 if (GetMcastAddr.Status != PXENV_STATUS_SUCCESS) {
2923 return EFI_DEVICE_ERROR;
2924 }
2925 //
2926 // Copy the MAC address from the returned data structure.
2927 //
2928 CopyMem (
2929 MAC,
2930 &GetMcastAddr.MediaAddr,
2931 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
2932 );
2933
2934 return Status;
2935 }
2936 //
2937 // NvData()
2938 //
2939 /**
2940 Performs read and write operations on the NVRAM device attached to a
2941 network interface.
2942
2943 @param This The protocol instance pointer.
2944 @param ReadWrite TRUE for read operations, FALSE for write operations.
2945 @param Offset Byte offset in the NVRAM device at which to start the read or
2946 write operation. This must be a multiple of NvRamAccessSize and
2947 less than NvRamSize.
2948 @param BufferSize The number of bytes to read or write from the NVRAM device.
2949 This must also be a multiple of NvramAccessSize.
2950 @param Buffer A pointer to the data buffer.
2951
2952 @retval EFI_SUCCESS The NVRAM access was performed.
2953 @retval EFI_NOT_STARTED The network interface has not been started.
2954 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2955 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2956 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
2957
2958 **/
2959 EFI_STATUS
2960 EFIAPI
2961 Undi16SimpleNetworkNvData (
2962 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
2963 IN BOOLEAN ReadWrite,
2964 IN UINTN Offset,
2965 IN UINTN BufferSize,
2966 IN OUT VOID *Buffer
2967 )
2968 {
2969 return EFI_UNSUPPORTED;
2970 }
2971 //
2972 // GetStatus()
2973 //
2974 /**
2975 Reads the current interrupt status and recycled transmit buffer status from
2976 a network interface.
2977
2978 @param This The protocol instance pointer.
2979 @param InterruptStatus A pointer to the bit mask of the currently active interrupts
2980 If this is NULL, the interrupt status will not be read from
2981 the device. If this is not NULL, the interrupt status will
2982 be read from the device. When the interrupt status is read,
2983 it will also be cleared. Clearing the transmit interrupt
2984 does not empty the recycled transmit buffer array.
2985 @param TxBuf Recycled transmit buffer address. The network interface will
2986 not transmit if its internal recycled transmit buffer array
2987 is full. Reading the transmit buffer does not clear the
2988 transmit interrupt. If this is NULL, then the transmit buffer
2989 status will not be read. If there are no transmit buffers to
2990 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
2991
2992 @retval EFI_SUCCESS The status of the network interface was retrieved.
2993 @retval EFI_NOT_STARTED The network interface has not been started.
2994 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
2995 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
2996 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
2997
2998 **/
2999 EFI_STATUS
3000 EFIAPI
3001 Undi16SimpleNetworkGetStatus (
3002 IN EFI_SIMPLE_NETWORK_PROTOCOL * This,
3003 OUT UINT32 *InterruptStatus OPTIONAL,
3004 OUT VOID **TxBuf OPTIONAL
3005 )
3006 {
3007 EFI_STATUS Status;
3008 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
3009 UINTN FrameLength;
3010
3011 if (This == NULL) {
3012 return EFI_INVALID_PARAMETER;
3013 }
3014
3015 Status = EFI_SUCCESS;
3016 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
3017
3018 if (SimpleNetworkDevice == NULL) {
3019 return EFI_DEVICE_ERROR;
3020 }
3021 //
3022 // Verify that the current state of the adapter is valid for this call.
3023 //
3024 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
3025 case EfiSimpleNetworkInitialized:
3026 break;
3027
3028 case EfiSimpleNetworkStopped:
3029 return EFI_NOT_STARTED;
3030
3031 case EfiSimpleNetworkStarted:
3032 default:
3033 return EFI_DEVICE_ERROR;
3034 }
3035
3036 if (InterruptStatus == NULL && TxBuf == NULL) {
3037 return EFI_INVALID_PARAMETER;
3038 }
3039
3040 FrameLength = 0;
3041 Status = Undi16SimpleNetworkIsr (This, &FrameLength, NULL, NULL, NULL, NULL);
3042
3043 if (Status != EFI_BUFFER_TOO_SMALL) {
3044 if (EFI_ERROR (Status)) {
3045 return Status;
3046 }
3047 }
3048 //
3049 // See if the caller wants interrupt info.
3050 //
3051 if (InterruptStatus != NULL) {
3052 *InterruptStatus = SimpleNetworkDevice->InterruptStatus;
3053 SimpleNetworkDevice->InterruptStatus = 0;
3054 }
3055 //
3056 // See if the caller wants transmit buffer status info.
3057 //
3058 if (TxBuf != NULL) {
3059 *TxBuf = 0;
3060 SimpleNetworkTransmitFifoRemove (&(SimpleNetworkDevice->TxBufferFifo), TxBuf);
3061 }
3062
3063 return EFI_SUCCESS;
3064 }
3065
3066 /**
3067 Places a packet in the transmit queue of a network interface.
3068
3069 @param This The protocol instance pointer.
3070 @param HeaderSize The size, in bytes, of the media header to be filled in by
3071 the Transmit() function. If HeaderSize is non-zero, then it
3072 must be equal to This->Mode->MediaHeaderSize and the DestAddr
3073 and Protocol parameters must not be NULL.
3074 @param BufferSize The size, in bytes, of the entire packet (media header and
3075 data) to be transmitted through the network interface.
3076 @param Buffer A pointer to the packet (media header followed by data) to be
3077 transmitted. This parameter cannot be NULL. If HeaderSize is zero,
3078 then the media header in Buffer must already be filled in by the
3079 caller. If HeaderSize is non-zero, then the media header will be
3080 filled in by the Transmit() function.
3081 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
3082 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
3083 This->Mode->CurrentAddress is used for the source HW MAC address.
3084 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
3085 parameter is ignored.
3086 @param Protocol The type of header to build. If HeaderSize is zero, then this
3087 parameter is ignored. See RFC 1700, section "Ether Types", for
3088 examples.
3089
3090 @retval EFI_SUCCESS The packet was placed on the transmit queue.
3091 @retval EFI_NOT_STARTED The network interface has not been started.
3092 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
3093 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3094 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3095 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3096 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3097
3098 **/
3099 EFI_STATUS
3100 EFIAPI
3101 Undi16SimpleNetworkTransmit (
3102 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
3103 IN UINTN HeaderSize,
3104 IN UINTN BufferSize,
3105 IN VOID *Buffer,
3106 IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
3107 IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
3108 IN UINT16 *Protocol OPTIONAL
3109 )
3110 {
3111 EFI_STATUS Status;
3112 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
3113 PXENV_UNDI_TRANSMIT_T XmitInfo;
3114
3115 if (This == NULL) {
3116 return EFI_INVALID_PARAMETER;
3117 }
3118
3119 Status = EFI_SUCCESS;
3120 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
3121
3122 if (SimpleNetworkDevice == NULL) {
3123 return EFI_DEVICE_ERROR;
3124 }
3125 //
3126 // Verify that the current state of the adapter is valid for this call.
3127 //
3128 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
3129 case EfiSimpleNetworkInitialized:
3130 break;
3131
3132 case EfiSimpleNetworkStopped:
3133 return EFI_NOT_STARTED;
3134
3135 case EfiSimpleNetworkStarted:
3136 default:
3137 return EFI_DEVICE_ERROR;
3138 }
3139
3140 if (Buffer == NULL) {
3141 return EFI_INVALID_PARAMETER;
3142 }
3143
3144 if (BufferSize < SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {
3145 return EFI_BUFFER_TOO_SMALL;
3146 }
3147
3148 if (HeaderSize != 0) {
3149 if (HeaderSize != SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize) {
3150 return EFI_INVALID_PARAMETER;
3151 }
3152
3153 if (DestAddr == NULL || Protocol == NULL) {
3154 return EFI_INVALID_PARAMETER;
3155 }
3156
3157 if (DestAddr != NULL) {
3158 CopyMem (
3159 Buffer,
3160 DestAddr,
3161 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
3162 );
3163 }
3164
3165 if (SrcAddr == NULL) {
3166 SrcAddr = &SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress;
3167 }
3168
3169 CopyMem (
3170 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize,
3171 SrcAddr,
3172 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
3173 );
3174
3175 if (Protocol != NULL) {
3176 *(UINT16 *) ((UINT8 *) Buffer + 2 * SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize) = (UINT16) (((*Protocol & 0xFF) << 8) | ((*Protocol >> 8) & 0xFF));
3177 }
3178 }
3179 //
3180 // See if the recycled transmit buffer FIFO is full.
3181 // If it is full, then we can not transmit until the caller calls GetStatus() to pull
3182 // off recycled transmit buffers.
3183 //
3184 if (SimpleNetworkTransmitFifoFull (&(SimpleNetworkDevice->TxBufferFifo))) {
3185 return EFI_NOT_READY;
3186 }
3187 //
3188 // Output debug trace message.
3189 //
3190 DEBUG ((DEBUG_NET, "Undi16SimpleNetworkTransmit\n\r "));
3191
3192 //
3193 // Initialize UNDI WRITE parameter structure.
3194 //
3195 XmitInfo.Status = INIT_PXE_STATUS;
3196 XmitInfo.Protocol = P_UNKNOWN;
3197 XmitInfo.XmitFlag = XMT_DESTADDR;
3198 XmitInfo.DestAddrOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr & 0x000f);
3199 XmitInfo.DestAddrSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->TxDestAddr >> 4);
3200 XmitInfo.TBDOffset = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit & 0x000f);
3201 XmitInfo.TBDSegment = (UINT16) ((UINT32)(UINTN) SimpleNetworkDevice->Xmit >> 4);
3202 XmitInfo.Reserved[0] = 0;
3203 XmitInfo.Reserved[1] = 0;
3204
3205 CopyMem (
3206 SimpleNetworkDevice->TxDestAddr,
3207 Buffer,
3208 SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize
3209 );
3210
3211 CopyMem (
3212 SimpleNetworkDevice->TxRealModeMediaHeader,
3213 Buffer,
3214 SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize
3215 );
3216
3217 SimpleNetworkDevice->Xmit->ImmedLength = (UINT16) SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize;
3218
3219 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen = (UINT16) (BufferSize - SimpleNetworkDevice->Xmit->ImmedLength);
3220
3221 CopyMem (
3222 SimpleNetworkDevice->TxRealModeDataBuffer,
3223 (UINT8 *) Buffer + SimpleNetworkDevice->SimpleNetworkMode.MediaHeaderSize,
3224 SimpleNetworkDevice->Xmit->DataBlock[0].TDDataLen
3225 );
3226
3227 //
3228 // Make API call to UNDI TRANSMIT
3229 //
3230 XmitInfo.Status = 0;
3231
3232 Status = PxeUndiTransmit (SimpleNetworkDevice, &XmitInfo);
3233
3234 if (EFI_ERROR (Status)) {
3235 return Status;
3236 }
3237 //
3238 // Check the status code from the 16 bit UNDI ROM
3239 //
3240 switch (XmitInfo.Status) {
3241 case PXENV_STATUS_OUT_OF_RESOURCES:
3242 return EFI_NOT_READY;
3243
3244 case PXENV_STATUS_SUCCESS:
3245 break;
3246
3247 default:
3248 return EFI_DEVICE_ERROR;
3249 }
3250 //
3251 // Add address of Buffer to the recycled transmit buffer FIFO
3252 //
3253 SimpleNetworkTransmitFifoAdd (&(SimpleNetworkDevice->TxBufferFifo), Buffer);
3254
3255 return EFI_SUCCESS;
3256 }
3257
3258 /**
3259 Receives a packet from a network interface.
3260
3261 @param This The protocol instance pointer.
3262 @param HeaderSize The size, in bytes, of the media header received on the network
3263 interface. If this parameter is NULL, then the media header size
3264 will not be returned.
3265 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
3266 bytes, of the packet that was received on the network interface.
3267 @param Buffer A pointer to the data buffer to receive both the media header and
3268 the data.
3269 @param SrcAddr The source HW MAC address. If this parameter is NULL, the
3270 HW MAC source address will not be extracted from the media
3271 header.
3272 @param DestAddr The destination HW MAC address. If this parameter is NULL,
3273 the HW MAC destination address will not be extracted from the
3274 media header.
3275 @param Protocol The media header type. If this parameter is NULL, then the
3276 protocol will not be extracted from the media header. See
3277 RFC 1700 section "Ether Types" for examples.
3278
3279 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
3280 been updated to the number of bytes received.
3281 @retval EFI_NOT_STARTED The network interface has not been started.
3282 @retval EFI_NOT_READY The network interface is too busy to accept this transmit
3283 request.
3284 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3285 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3286 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3287 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3288
3289 **/
3290 EFI_STATUS
3291 EFIAPI
3292 Undi16SimpleNetworkReceive (
3293 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
3294 OUT UINTN *HeaderSize OPTIONAL,
3295 IN OUT UINTN *BufferSize,
3296 OUT VOID *Buffer,
3297 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
3298 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
3299 OUT UINT16 *Protocol OPTIONAL
3300 )
3301 {
3302 EFI_STATUS Status;
3303 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
3304 UINTN MediaAddrSize;
3305 UINT8 ProtType;
3306
3307 if (This == NULL || BufferSize == NULL || Buffer == NULL) {
3308 return EFI_INVALID_PARAMETER;
3309 }
3310
3311 Status = EFI_SUCCESS;
3312 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
3313
3314 if (SimpleNetworkDevice == NULL) {
3315 return EFI_DEVICE_ERROR;
3316 }
3317 //
3318 // Verify that the current state of the adapter is valid for this call.
3319 //
3320 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
3321 case EfiSimpleNetworkInitialized:
3322 break;
3323
3324 case EfiSimpleNetworkStopped:
3325 return EFI_NOT_STARTED;
3326
3327 case EfiSimpleNetworkStarted:
3328 default:
3329 return EFI_DEVICE_ERROR;
3330 }
3331
3332 Status = Undi16SimpleNetworkIsr (
3333 This,
3334 BufferSize,
3335 HeaderSize,
3336 Buffer,
3337 &ProtType,
3338 NULL
3339 );
3340
3341 if (EFI_ERROR (Status)) {
3342 return Status;
3343 }
3344
3345 if ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) == 0) {
3346 return EFI_NOT_READY;
3347
3348 }
3349
3350 SimpleNetworkDevice->InterruptStatus &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
3351
3352 MediaAddrSize = This->Mode->HwAddressSize;
3353
3354 if (SrcAddr != NULL) {
3355 CopyMem (SrcAddr, (UINT8 *) Buffer + MediaAddrSize, MediaAddrSize);
3356 }
3357
3358 if (DestAddr != NULL) {
3359 CopyMem (DestAddr, Buffer, MediaAddrSize);
3360 }
3361
3362 if (Protocol != NULL) {
3363 *((UINT8 *) Protocol) = *((UINT8 *) Buffer + (2 * MediaAddrSize) + 1);
3364 *((UINT8 *) Protocol + 1) = *((UINT8 *) Buffer + (2 * MediaAddrSize));
3365 }
3366
3367 DEBUG ((DEBUG_NET, "Packet Received: BufferSize=%d HeaderSize = %d\n", *BufferSize, *HeaderSize));
3368
3369 return Status;
3370
3371 }
3372 //
3373 // WaitForPacket()
3374 //
3375 /**
3376 wait for a packet to be received.
3377
3378 @param Event Event used with WaitForEvent() to wait for a packet to be received.
3379 @param Context Event Context
3380
3381 **/
3382 VOID
3383 EFIAPI
3384 Undi16SimpleNetworkWaitForPacket (
3385 IN EFI_EVENT Event,
3386 IN VOID *Context
3387 )
3388 {
3389 //
3390 // Someone is waiting on the receive packet event, if there's
3391 // a packet pending, signal the event
3392 //
3393 if (!EFI_ERROR (Undi16SimpleNetworkCheckForPacket (Context))) {
3394 gBS->SignalEvent (Event);
3395 }
3396 }
3397 //
3398 // CheckForPacket()
3399 //
3400 /**
3401 Check whether packet is ready for receive.
3402
3403 @param This The protocol instance pointer.
3404
3405 @retval EFI_SUCCESS Receive data is ready.
3406 @retval EFI_NOT_STARTED The network interface has not been started.
3407 @retval EFI_NOT_READY The network interface is too busy to accept this transmit
3408 request.
3409 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
3410 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
3411 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
3412 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
3413 **/
3414 EFI_STATUS
3415 Undi16SimpleNetworkCheckForPacket (
3416 IN EFI_SIMPLE_NETWORK_PROTOCOL *This
3417 )
3418 {
3419 EFI_STATUS Status;
3420 EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
3421 UINTN FrameLength;
3422
3423 if (This == NULL) {
3424 return EFI_INVALID_PARAMETER;
3425 }
3426
3427 Status = EFI_SUCCESS;
3428 SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
3429
3430 if (SimpleNetworkDevice == NULL) {
3431 return EFI_DEVICE_ERROR;
3432 }
3433 //
3434 // Verify that the current state of the adapter is valid for this call.
3435 //
3436 switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
3437 case EfiSimpleNetworkInitialized:
3438 break;
3439
3440 case EfiSimpleNetworkStopped:
3441 return EFI_NOT_STARTED;
3442
3443 case EfiSimpleNetworkStarted:
3444 default:
3445 return EFI_DEVICE_ERROR;
3446 }
3447
3448 FrameLength = 0;
3449 Status = Undi16SimpleNetworkIsr (
3450 This,
3451 &FrameLength,
3452 NULL,
3453 NULL,
3454 NULL,
3455 NULL
3456 );
3457
3458 if (Status != EFI_BUFFER_TOO_SMALL) {
3459 if (EFI_ERROR (Status)) {
3460 return Status;
3461 }
3462 }
3463
3464 return ((SimpleNetworkDevice->InterruptStatus & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT) != 0) ? EFI_SUCCESS : EFI_NOT_READY;
3465 }
3466
3467 /**
3468 Signal handlers for ExitBootServices event.
3469
3470 Clean up any Real-mode UNDI residue from the system
3471
3472 @param Event ExitBootServices event
3473 @param Context
3474 **/
3475 VOID
3476 EFIAPI
3477 Undi16SimpleNetworkEvent (
3478 IN EFI_EVENT Event,
3479 IN VOID *Context
3480 )
3481 {
3482 //
3483 // NOTE: This is not the only way to effect this cleanup. The prescribed mechanism
3484 // would be to perform an UNDI STOP command. This strategam has been attempted
3485 // but results in problems making some of the EFI core services from TPL_CALLBACK.
3486 // This issue needs to be resolved, but the other alternative has been to perform
3487 // the unchain logic explicitly, as done below.
3488 //
3489 RestoreCachedVectorAddress (0x1A);
3490 }
3491
3492 /**
3493 Allocate buffer below 1M for real mode.
3494
3495 @param NumPages The number pages want to be allocated.
3496 @param Buffer On return, allocated buffer.
3497
3498 @return Status of allocating pages.
3499 **/
3500 EFI_STATUS
3501 BiosSnp16AllocatePagesBelowOneMb (
3502 UINTN NumPages,
3503 VOID **Buffer
3504 )
3505 {
3506 EFI_STATUS Status;
3507 EFI_PHYSICAL_ADDRESS PhysicalAddress;
3508
3509 PhysicalAddress = 0x000fffff;
3510 Status = gBS->AllocatePages (
3511 AllocateMaxAddress,
3512 EfiRuntimeServicesData,
3513 NumPages,
3514 &PhysicalAddress
3515 );
3516 if (EFI_ERROR (Status)) {
3517 return Status;
3518 }
3519
3520 *Buffer = (VOID *) (UINTN) PhysicalAddress;
3521 return EFI_SUCCESS;
3522 }