2 Copyright (c) 2006, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
45 InitializeSnpNiiDriver (
46 IN EFI_HANDLE image_handle
,
47 IN EFI_SYSTEM_TABLE
*system_table
52 SimpleNetworkDriverSupported (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
60 SimpleNetworkDriverStart (
61 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
62 IN EFI_HANDLE Controller
,
63 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
68 SimpleNetworkDriverStop (
69 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
70 IN EFI_HANDLE Controller
,
71 IN UINTN NumberOfChildren
,
72 IN EFI_HANDLE
*ChildHandleBuffer
76 // Simple Network Protocol Driver Global Variables
78 EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding
= {
79 SimpleNetworkDriverSupported
,
80 SimpleNetworkDriverStart
,
81 SimpleNetworkDriverStop
,
88 // Module global variables needed to support undi 3.0 interface
90 EFI_PCI_IO_PROTOCOL
*mPciIoFncs
;
91 struct s_v2p
*_v2p
= NULL
; // undi3.0 map_list head
92 // End Global variables
96 IN OUT
struct s_v2p
**v2p
,
97 EFI_PCI_IO_PROTOCOL_OPERATION type
,
104 This routine maps the given CPU address to a Device address. It creates a
105 an entry in the map list with the virtual and physical addresses and the
109 v2p - pointer to return a map list node pointer.
110 type - the direction in which the data flows from the given virtual address
111 device->cpu or cpu->device or both ways.
112 vaddr - virtual address (or CPU address) to be mapped
113 bsize - size of the buffer to be mapped.
117 EFI_SUCEESS - routine has completed the mapping
118 other - error as indicated.
124 if ((v2p
== NULL
) || (vaddr
== NULL
) || (bsize
== 0)) {
125 return EFI_INVALID_PARAMETER
;
128 Status
= gBS
->AllocatePool (
130 sizeof (struct s_v2p
),
134 if (Status
!= EFI_SUCCESS
) {
138 Status
= mPciIoFncs
->Map (
146 if (Status
!= EFI_SUCCESS
) {
147 gBS
->FreePool (*v2p
);
150 (*v2p
)->vaddr
= vaddr
;
151 (*v2p
)->bsize
= bsize
;
166 This routine searches the linked list of mapped address nodes (for undi3.0
167 interface) to find the node that corresponds to the given virtual address and
168 returns a pointer to that node.
171 v2p - pointer to return a map list node pointer.
172 vaddr - virtual address (or CPU address) to be searched in the map list
176 EFI_SUCEESS - if a match found!
177 Other - match not found
183 if (v2p
== NULL
|| vaddr
== NULL
) {
184 return EFI_INVALID_PARAMETER
;
187 for (v
= _v2p
; v
!= NULL
; v
= v
->next
) {
188 if (v
->vaddr
== vaddr
) {
194 return EFI_NOT_FOUND
;
204 This routine unmaps the given virtual address and frees the memory allocated
205 for the map list node corresponding to that address.
208 vaddr - virtual address (or CPU address) to be unmapped
211 EFI_SUCEESS - if successfully unmapped
212 Other - as indicated by the error
222 return EFI_INVALID_PARAMETER
;
226 return EFI_NOT_FOUND
;
229 // Is our node at the head of the list??
231 if ((v
= _v2p
)->vaddr
== vaddr
) {
234 Status
= mPciIoFncs
->Unmap (mPciIoFncs
, v
->unmap
);
240 Print (L
"Unmap failed with status = %x\n", Status
);
246 for (; v
->next
!= NULL
; v
= t
) {
247 if ((t
= v
->next
)->vaddr
== vaddr
) {
249 Status
= mPciIoFncs
->Unmap (mPciIoFncs
, t
->unmap
);
253 Print (L
"Unmap failed with status = %x\n", Status
);
260 return EFI_NOT_FOUND
;
271 Wait for a key stroke, used for debugging purposes
283 Aprint ("\nPress any key to continue\n");
285 while (gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &key
) == EFI_NOT_READY
) {
293 issue_hwundi_command (
307 Aprint ("\nissue_hwundi_command() - This should not be called!");
311 return EFI_INVALID_PARAMETER
;
315 // %%TBD - For now, nothing is done.
317 return EFI_UNSUPPORTED
;
329 Compute 8-bit checksum of a buffer.
332 ptr - Pointer to buffer.
333 len - Length of buffer in bytes.
336 8-bit checksum of all bytes in buffer.
337 If ptr is NULL or len is zero, zero is returned.
347 if (ptr
== NULL
|| len
== 0) {
352 cksum
= (UINT8
) (cksum
+*bptr
++);
360 SimpleNetworkDriverSupported (
361 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
362 IN EFI_HANDLE Controller
,
363 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
368 Test to see if this driver supports Controller. Any Controller
369 that contains a Nii protocol can be supported.
372 This - Protocol instance pointer.
373 Controller - Handle of device to test.
374 RemainingDevicePath - Not used.
377 EFI_SUCCESS - This driver supports this device.
378 EFI_ALREADY_STARTED - This driver is already running on this device.
379 other - This driver does not support this device.
384 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NiiProtocol
;
389 Status
= gBS
->OpenProtocol (
391 &gEfiDevicePathProtocolGuid
,
393 This
->DriverBindingHandle
,
395 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
397 if (EFI_ERROR (Status
)) {
401 Status
= gBS
->OpenProtocol (
403 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
404 (VOID
**) &NiiProtocol
,
405 This
->DriverBindingHandle
,
407 EFI_OPEN_PROTOCOL_BY_DRIVER
409 if (Status
== EFI_ALREADY_STARTED
)
412 Aprint ("Support(): Already Started. on handle %x\n", Controller
);
414 return EFI_ALREADY_STARTED
;
417 if (!EFI_ERROR (Status
))
421 Aprint ("Support(): UNDI3.1 found on handle %x\n", Controller
);
427 // try the older 3.0 driver
429 Status
= gBS
->OpenProtocol (
431 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
432 (VOID
**) &NiiProtocol
,
433 This
->DriverBindingHandle
,
435 EFI_OPEN_PROTOCOL_BY_DRIVER
437 if (EFI_ERROR (Status
)) {
442 Aprint ("Support(): UNDI3.0 found on handle %x\n", Controller
);
447 // check the version, we don't want to connect to the undi16
449 if (NiiProtocol
->Type
!= EfiNetworkInterfaceUndi
) {
450 Status
= EFI_UNSUPPORTED
;
454 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
456 if (NiiProtocol
->ID
& 0x0F) {
457 DEBUG ((EFI_D_NET
, "\n!PXE structure is not paragraph aligned.\n"));
458 Status
= EFI_UNSUPPORTED
;
462 pxe
= (PXE_UNDI
*) (UINTN
) (NiiProtocol
->ID
);
465 // Verify !PXE revisions.
467 if (pxe
->hw
.Signature
!= PXE_ROMID_SIGNATURE
) {
468 DEBUG ((EFI_D_NET
, "\n!PXE signature is not valid.\n"));
469 Status
= EFI_UNSUPPORTED
;
473 if (pxe
->hw
.Rev
< PXE_ROMID_REV
) {
474 DEBUG ((EFI_D_NET
, "\n!PXE.Rev is not supported.\n"));
475 Status
= EFI_UNSUPPORTED
;
479 if (pxe
->hw
.MajorVer
< PXE_ROMID_MAJORVER
) {
481 DEBUG ((EFI_D_NET
, "\n!PXE.MajorVer is not supported.\n"));
482 Status
= EFI_UNSUPPORTED
;
485 } else if (pxe
->hw
.MajorVer
== PXE_ROMID_MAJORVER
&& pxe
->hw
.MinorVer
< PXE_ROMID_MINORVER
) {
486 DEBUG ((EFI_D_NET
, "\n!PXE.MinorVer is not supported."));
487 Status
= EFI_UNSUPPORTED
;
491 // Do S/W UNDI specific checks.
493 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) == 0) {
494 if (pxe
->sw
.EntryPoint
< pxe
->sw
.Len
) {
495 DEBUG ((EFI_D_NET
, "\n!PXE S/W entry point is not valid."));
496 Status
= EFI_UNSUPPORTED
;
500 if (pxe
->sw
.BusCnt
== 0) {
501 DEBUG ((EFI_D_NET
, "\n!PXE.BusCnt is zero."));
502 Status
= EFI_UNSUPPORTED
;
507 Status
= EFI_SUCCESS
;
509 Aprint ("Support(): supported on %x\n", Controller
);
517 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
518 This
->DriverBindingHandle
,
525 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
526 This
->DriverBindingHandle
,
536 SimpleNetworkDriverStart (
537 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
538 IN EFI_HANDLE Controller
,
539 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
544 called for any handle that we said "supported" in the above call!
547 This - Protocol instance pointer.
548 Controller - Handle of device to start
549 RemainingDevicePath - Not used.
552 EFI_SUCCESS - This driver supports this device.
553 other - This driver failed to start this device.
557 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
558 EFI_DEVICE_PATH_PROTOCOL
*NiiDevicePath
;
564 EFI_PHYSICAL_ADDRESS paddr
;
568 PXE_PCI_CONFIG_INFO ConfigInfo
;
569 PCI_TYPE00
*ConfigHeader
;
572 PXE_STATFLAGS InitStatFlags
;
574 DEBUG ((EFI_D_NET
, "\nSnpNotifyNetworkInterfaceIdentifier() "));
576 Status
= gBS
->OpenProtocol (
578 &gEfiDevicePathProtocolGuid
,
579 (VOID
**) &NiiDevicePath
,
580 This
->DriverBindingHandle
,
582 EFI_OPEN_PROTOCOL_BY_DRIVER
585 if (EFI_ERROR (Status
)) {
589 Status
= gBS
->LocateDevicePath (
590 &gEfiPciIoProtocolGuid
,
595 if (EFI_ERROR (Status
)) {
599 Status
= gBS
->OpenProtocol (
601 &gEfiPciIoProtocolGuid
,
602 (VOID
**) &mPciIoFncs
,
603 This
->DriverBindingHandle
,
605 EFI_OPEN_PROTOCOL_GET_PROTOCOL
607 if (EFI_ERROR (Status
)) {
611 // Get the NII interface. look for 3.1 undi first, if it is not there
612 // then look for 3.0, validate the interface.
614 Status
= gBS
->OpenProtocol (
616 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
618 This
->DriverBindingHandle
,
620 EFI_OPEN_PROTOCOL_BY_DRIVER
622 if (Status
== EFI_ALREADY_STARTED
) {
625 &gEfiDevicePathProtocolGuid
,
626 This
->DriverBindingHandle
,
632 if (!EFI_ERROR (Status
)) {
634 // probably not a 3.1 UNDI
638 Aprint ("Start(): UNDI3.1 found\n");
643 Status
= gBS
->OpenProtocol (
645 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
647 This
->DriverBindingHandle
,
649 EFI_OPEN_PROTOCOL_BY_DRIVER
651 if (EFI_ERROR (Status
)) {
654 &gEfiDevicePathProtocolGuid
,
655 This
->DriverBindingHandle
,
663 Aprint ("Start(): UNDI3.0 found\n");
668 pxe
= (PXE_UNDI
*) (UINTN
) (Nii
->ID
);
670 if (calc_8bit_cksum (pxe
, pxe
->hw
.Len
) != 0) {
671 DEBUG ((EFI_D_NET
, "\n!PXE checksum is not correct.\n"));
675 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
677 // We can get any packets.
679 } else if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
681 // We need to be able to get broadcast packets for DHCP.
682 // If we do not have promiscuous support, we must at least have
683 // broadcast support or we cannot do DHCP!
686 DEBUG ((EFI_D_NET
, "\nUNDI does not have promiscuous or broadcast support."));
690 // OK, we like this UNDI, and we know snp is not already there on this handle
691 // Allocate and initialize a new simple network protocol structure.
693 Status
= mPciIoFncs
->AllocateBuffer (
697 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
702 if (Status
!= EFI_SUCCESS
) {
703 DEBUG ((EFI_D_NET
, "\nCould not allocate SNP_DRIVER structure.\n"));
707 snp
= (SNP_DRIVER
*) (UINTN
) addr
;
710 Size
= SNP_MEM_PAGES (sizeof (SNP_DRIVER
));
712 Status
= mPciIoFncs
->Map (
714 EfiPciIoOperationBusMasterCommonBuffer
,
723 DEBUG ((EFI_D_NET
, "\nSNP_DRIVER @ %Xh, sizeof(SNP_DRIVER) == %d", addr
, sizeof (SNP_DRIVER
)));
724 snp
= (SNP_DRIVER
*) (UINTN
) paddr
;
725 snp
->SnpDriverUnmap
= addrUnmap
;
728 ZeroMem (snp
, sizeof (SNP_DRIVER
));
730 snp
->IoFncs
= mPciIoFncs
;
731 snp
->IsOldUndi
= (BOOLEAN
) (!UndiNew
);
733 snp
->Signature
= SNP_DRIVER_SIGNATURE
;
735 EfiInitializeLock (&snp
->lock
, EFI_TPL_NOTIFY
);
737 snp
->snp
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
738 snp
->snp
.Start
= snp_undi32_start
;
739 snp
->snp
.Stop
= snp_undi32_stop
;
740 snp
->snp
.Initialize
= snp_undi32_initialize
;
741 snp
->snp
.Reset
= snp_undi32_reset
;
742 snp
->snp
.Shutdown
= snp_undi32_shutdown
;
743 snp
->snp
.ReceiveFilters
= snp_undi32_receive_filters
;
744 snp
->snp
.StationAddress
= snp_undi32_station_address
;
745 snp
->snp
.Statistics
= snp_undi32_statistics
;
746 snp
->snp
.MCastIpToMac
= snp_undi32_mcast_ip_to_mac
;
747 snp
->snp
.NvData
= snp_undi32_nvdata
;
748 snp
->snp
.GetStatus
= snp_undi32_get_status
;
749 snp
->snp
.Transmit
= snp_undi32_transmit
;
750 snp
->snp
.Receive
= snp_undi32_receive
;
751 snp
->snp
.WaitForPacket
= NULL
;
753 snp
->snp
.Mode
= &snp
->mode
;
755 snp
->tx_rx_bufsize
= 0;
756 snp
->tx_rx_buffer
= NULL
;
758 snp
->if_num
= Nii
->IfNum
;
760 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) != 0) {
761 snp
->is_swundi
= FALSE
;
762 snp
->issue_undi32_command
= &issue_hwundi_command
;
764 snp
->is_swundi
= TRUE
;
766 if ((pxe
->sw
.Implementation
& PXE_ROMID_IMP_SW_VIRT_ADDR
) != 0) {
767 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) pxe
->sw
.EntryPoint
;
769 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) ((UINT8
) (UINTN
) pxe
+ pxe
->sw
.EntryPoint
);
773 // Allocate a global CPB and DB buffer for this UNDI interface.
774 // we do this because:
776 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be
777 // within 2GB limit, create them here and map them so that when undi calls
778 // v2p callback to check if the physical address is < 2gb, we will pass.
780 // -This is not a requirement for 3.1 or later UNDIs but the code looks
781 // simpler if we use the same cpb, db variables for both old and new undi
782 // interfaces from all the SNP interface calls (we don't map the buffers
783 // for the newer undi interfaces though)
785 // -it is OK to allocate one global set of CPB, DB pair for each UNDI
786 // interface as EFI does not multi-task and so SNP will not be re-entered!
788 Status
= mPciIoFncs
->AllocateBuffer (
792 SNP_MEM_PAGES (4096),
797 if (Status
!= EFI_SUCCESS
) {
798 DEBUG ((EFI_D_NET
, "\nCould not allocate CPB and DB structures.\n"));
799 goto Error_DeleteSNP
;
802 if (snp
->IsOldUndi
) {
803 Size
= SNP_MEM_PAGES (4096);
805 Status
= mPciIoFncs
->Map (
807 EfiPciIoOperationBusMasterCommonBuffer
,
816 snp
->cpb
= (VOID
*) (UINTN
) paddr
;
817 snp
->db
= (VOID
*) ((UINTN
) paddr
+ 2048);
819 snp
->cpb
= (VOID
*) (UINTN
) addr
;
820 snp
->db
= (VOID
*) ((UINTN
) addr
+ 2048);
823 // pxe_start call is going to give the callback functions to UNDI, these callback
824 // functions use the BarIndex values from the snp structure, so these must be initialized
825 // with default values before doing a pxe_start. The correct values can be obtained after
826 // getting the config information from UNDI
828 snp
->MemoryBarIndex
= 0;
832 // we need the undi init information many times in this snp code, just get it
833 // once here and store it in the snp driver structure. to get Init Info
834 // from UNDI we have to start undi first.
836 Status
= pxe_start (snp
);
838 if (Status
!= EFI_SUCCESS
) {
839 goto Error_DeleteCPBDB
;
842 snp
->cdb
.OpCode
= PXE_OPCODE_GET_INIT_INFO
;
843 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
845 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
846 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
848 snp
->cdb
.DBsize
= sizeof snp
->init_info
;
849 snp
->cdb
.DBaddr
= (UINT64
) (UINTN
) &snp
->init_info
;
851 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
852 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
854 snp
->cdb
.IFnum
= snp
->if_num
;
855 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
857 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_init_info() "));
859 (*snp
->issue_undi32_command
) ((UINT64
) (UINTN
) &snp
->cdb
);
862 // Save the INIT Stat Code...
864 InitStatFlags
= snp
->cdb
.StatFlags
;
866 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
867 DEBUG ((EFI_D_NET
, "\nsnp->undi.init_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
869 goto Error_DeleteCPBDB
;
872 snp
->cdb
.OpCode
= PXE_OPCODE_GET_CONFIG_INFO
;
873 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
875 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
876 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
878 snp
->cdb
.DBsize
= sizeof ConfigInfo
;
879 snp
->cdb
.DBaddr
= (UINT64
) (UINTN
) &ConfigInfo
;
881 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
882 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
884 snp
->cdb
.IFnum
= snp
->if_num
;
885 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
887 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_config_info() "));
889 (*snp
->issue_undi32_command
) ((UINT64
) (UINTN
) &snp
->cdb
);
891 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
892 DEBUG ((EFI_D_NET
, "\nsnp->undi.config_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
894 goto Error_DeleteCPBDB
;
897 // Find the correct BAR to do IO.
900 // Enumerate through the PCI BARs for the device to determine which one is
901 // the IO BAR. Save the index of the BAR into the adapter info structure.
902 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
904 ConfigHeader
= (PCI_TYPE00
*) &ConfigInfo
.Config
.Byte
[0];
905 TempBar
= (UINT32
*) &ConfigHeader
->Device
.Bar
[0];
906 for (BarIndex
= 0; BarIndex
<= 5; BarIndex
++) {
907 if ((*TempBar
& PCI_BAR_MEM_MASK
) == PCI_BAR_MEM_64BIT
) {
909 // This is a 64-bit memory bar, skip this and the
915 if ((*TempBar
& PCI_BAR_IO_MASK
) == PCI_BAR_IO_MODE
) {
916 snp
->IoBarIndex
= BarIndex
;
924 // We allocate 2 more global buffers for undi 3.0 interface. We use these
925 // buffers to pass to undi when the user buffers are beyond 4GB.
926 // UNDI 3.0 wants all the addresses passed to it to be
927 // within 2GB limit, create them here and map them so that when undi calls
928 // v2p callback to check if the physical address is < 2gb, we will pass.
930 // For 3.1 and later UNDIs, we do not do this because undi is
931 // going to call the map() callback if and only if it wants to use the
932 // device address for any address it receives.
934 if (snp
->IsOldUndi
) {
936 // buffer for receive
938 Size
= SNP_MEM_PAGES (snp
->init_info
.MediaHeaderLen
+ snp
->init_info
.FrameDataLen
);
939 Status
= mPciIoFncs
->AllocateBuffer (
948 if (Status
!= EFI_SUCCESS
) {
949 DEBUG ((EFI_D_ERROR
, "\nCould not allocate receive buffer.\n"));
950 goto Error_DeleteCPBDB
;
953 Status
= mPciIoFncs
->Map (
955 EfiPciIoOperationBusMasterCommonBuffer
,
959 &snp
->ReceiveBufUnmap
964 snp
->receive_buf
= (UINT8
*) (UINTN
) paddr
;
967 // buffer for fill_header
969 Size
= SNP_MEM_PAGES (snp
->init_info
.MediaHeaderLen
);
970 Status
= mPciIoFncs
->AllocateBuffer (
979 if (Status
!= EFI_SUCCESS
) {
980 DEBUG ((EFI_D_ERROR
, "\nCould not allocate fill_header buffer.\n"));
981 goto Error_DeleteRCVBuf
;
984 Status
= mPciIoFncs
->Map (
986 EfiPciIoOperationBusMasterCommonBuffer
,
990 &snp
->FillHdrBufUnmap
994 snp
->fill_hdr_buf
= (UINT8
*) (UINTN
) paddr
;
997 // Initialize simple network protocol mode structure
999 snp
->mode
.State
= EfiSimpleNetworkStopped
;
1000 snp
->mode
.HwAddressSize
= snp
->init_info
.HWaddrLen
;
1001 snp
->mode
.MediaHeaderSize
= snp
->init_info
.MediaHeaderLen
;
1002 snp
->mode
.MaxPacketSize
= snp
->init_info
.FrameDataLen
;
1003 snp
->mode
.NvRamAccessSize
= snp
->init_info
.NvWidth
;
1004 snp
->mode
.NvRamSize
= snp
->init_info
.NvCount
* snp
->mode
.NvRamAccessSize
;
1005 snp
->mode
.IfType
= snp
->init_info
.IFtype
;
1006 snp
->mode
.MaxMCastFilterCount
= snp
->init_info
.MCastFilterCnt
;
1007 snp
->mode
.MCastFilterCount
= 0;
1009 switch (InitStatFlags
& PXE_STATFLAGS_CABLE_DETECT_MASK
) {
1010 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
:
1011 snp
->mode
.MediaPresentSupported
= TRUE
;
1014 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED
:
1016 snp
->mode
.MediaPresentSupported
= FALSE
;
1019 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_STATION_ADDR_SETTABLE
) != 0) {
1020 snp
->mode
.MacAddressChangeable
= TRUE
;
1022 snp
->mode
.MacAddressChangeable
= FALSE
;
1025 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED
) != 0) {
1026 snp
->mode
.MultipleTxSupported
= TRUE
;
1028 snp
->mode
.MultipleTxSupported
= FALSE
;
1031 snp
->mode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
1033 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
1034 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1038 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
1039 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1043 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
1044 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
1048 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
) != 0) {
1049 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
1053 if (pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) {
1054 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1058 snp
->mode
.ReceiveFilterSetting
= 0;
1061 // need to get the station address to save in the mode structure. we need to
1062 // initialize the UNDI first for this.
1064 snp
->tx_rx_bufsize
= snp
->init_info
.MemoryRequired
;
1065 Status
= pxe_init (snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
1069 goto Error_DeleteHdrBuf
;
1072 Status
= pxe_get_stn_addr (snp
);
1074 if (Status
!= EFI_SUCCESS
) {
1075 DEBUG ((EFI_D_ERROR
, "\nsnp->undi.get_station_addr() failed.\n"));
1078 goto Error_DeleteHdrBuf
;
1081 snp
->mode
.MediaPresent
= FALSE
;
1084 // We should not leave UNDI started and initialized here. this DriverStart()
1085 // routine must only find and attach the SNP interface to UNDI layer that it
1086 // finds on the given handle!
1087 // The UNDI layer will be started when upper layers call snp->start.
1088 // How ever, this DriverStart() must fill up the snp mode structure which
1089 // contains the MAC address of the NIC. For this reason we started and
1090 // initialized UNDI here, now we are done, do a shutdown and stop of the
1097 // add SNP to the undi handle
1099 Status
= gBS
->InstallProtocolInterface (
1101 &gEfiSimpleNetworkProtocolGuid
,
1102 EFI_NATIVE_INTERFACE
,
1106 if (!EFI_ERROR (Status
)) {
1111 if (snp
->IsOldUndi
) {
1112 Status
= mPciIoFncs
->Unmap (
1114 snp
->FillHdrBufUnmap
1116 Size
= SNP_MEM_PAGES (snp
->init_info
.MediaHeaderLen
);
1117 mPciIoFncs
->FreeBuffer (
1125 if (snp
->IsOldUndi
) {
1126 Status
= mPciIoFncs
->Unmap (
1128 snp
->ReceiveBufUnmap
1130 Size
= SNP_MEM_PAGES (snp
->init_info
.MediaHeaderLen
+ snp
->init_info
.FrameDataLen
);
1131 mPciIoFncs
->FreeBuffer (
1140 if (snp
->IsOldUndi
) {
1141 Status
= mPciIoFncs
->Unmap (
1147 Status
= mPciIoFncs
->FreeBuffer (
1149 SNP_MEM_PAGES (4096),
1154 if (snp
->IsOldUndi
) {
1155 Status
= mPciIoFncs
->Unmap (
1161 mPciIoFncs
->FreeBuffer (
1163 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
1168 gBS
->CloseProtocol (
1170 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
1171 This
->DriverBindingHandle
,
1175 gBS
->CloseProtocol (
1177 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1178 This
->DriverBindingHandle
,
1183 gBS
->CloseProtocol (
1185 &gEfiDevicePathProtocolGuid
,
1186 This
->DriverBindingHandle
,
1195 SimpleNetworkDriverStop (
1196 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1197 IN EFI_HANDLE Controller
,
1198 IN UINTN NumberOfChildren
,
1199 IN EFI_HANDLE
*ChildHandleBuffer
1203 Routine Description:
1212 EFI_SIMPLE_NETWORK_PROTOCOL
*SnpProtocol
;
1216 // Get our context back.
1218 Status
= gBS
->OpenProtocol (
1220 &gEfiSimpleNetworkProtocolGuid
,
1221 (VOID
**) &SnpProtocol
,
1222 This
->DriverBindingHandle
,
1224 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1227 if (EFI_ERROR (Status
)) {
1228 return EFI_UNSUPPORTED
;
1231 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol
);
1233 Status
= gBS
->UninstallProtocolInterface (
1235 &gEfiSimpleNetworkProtocolGuid
,
1239 if (EFI_ERROR (Status
)) {
1243 if (!Snp
->IsOldUndi
) {
1244 Status
= gBS
->CloseProtocol (
1246 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
1247 This
->DriverBindingHandle
,
1251 Status
= gBS
->CloseProtocol (
1253 &gEfiNetworkInterfaceIdentifierProtocolGuid
,
1254 This
->DriverBindingHandle
,
1259 Status
= gBS
->CloseProtocol (
1261 &gEfiDevicePathProtocolGuid
,
1262 This
->DriverBindingHandle
,
1269 if (Snp
->IsOldUndi
) {
1270 Status
= mPciIoFncs
->Unmap (
1272 Snp
->FillHdrBufUnmap
1275 mPciIoFncs
->FreeBuffer (
1277 SNP_MEM_PAGES (Snp
->init_info
.MediaHeaderLen
),
1280 Status
= mPciIoFncs
->Unmap (
1282 Snp
->ReceiveBufUnmap
1285 mPciIoFncs
->FreeBuffer (
1287 SNP_MEM_PAGES (Snp
->init_info
.MediaHeaderLen
+ Snp
->init_info
.FrameDataLen
),
1291 Status
= mPciIoFncs
->Unmap (
1295 Status
= mPciIoFncs
->Unmap (
1301 mPciIoFncs
->FreeBuffer (
1303 SNP_MEM_PAGES (4096),
1307 mPciIoFncs
->FreeBuffer (
1309 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),