2 Copyright (c) 2004 - 2005, 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 This routine maps the given CPU address to a Device address. It creates a
97 an entry in the map list with the virtual and physical addresses and the
100 @param v2p pointer to return a map list node pointer.
101 @param type the direction in which the data flows from the given
102 virtual address device->cpu or cpu->device or both
104 @param vaddr virtual address (or CPU address) to be mapped
105 @param bsize size of the buffer to be mapped.
107 @retval EFI_SUCEESS routine has completed the mapping
108 @retval other error as indicated.
113 IN OUT
struct s_v2p
**v2p
,
114 EFI_PCI_IO_PROTOCOL_OPERATION type
,
121 if ((v2p
== NULL
) || (vaddr
== NULL
) || (bsize
== 0)) {
122 return EFI_INVALID_PARAMETER
;
125 *v2p
= AllocatePool (sizeof (struct s_v2p
));
127 return EFI_OUT_OF_RESOURCES
;
130 Status
= mPciIoFncs
->Map (
138 if (Status
!= EFI_SUCCESS
) {
142 (*v2p
)->vaddr
= vaddr
;
143 (*v2p
)->bsize
= bsize
;
152 This routine searches the linked list of mapped address nodes (for undi3.0
153 interface) to find the node that corresponds to the given virtual address and
154 returns a pointer to that node.
156 @param v2p pointer to return a map list node pointer.
157 @param vaddr virtual address (or CPU address) to be searched in
160 @retval EFI_SUCEESS if a match found!
161 @retval Other match not found
172 if (v2p
== NULL
|| vaddr
== NULL
) {
173 return EFI_INVALID_PARAMETER
;
176 for (v
= _v2p
; v
!= NULL
; v
= v
->next
) {
177 if (v
->vaddr
== vaddr
) {
183 return EFI_NOT_FOUND
;
188 This routine unmaps the given virtual address and frees the memory allocated
189 for the map list node corresponding to that address.
191 @param vaddr virtual address (or CPU address) to be unmapped
193 @retval EFI_SUCEESS if successfully unmapped
194 @retval Other as indicated by the error
207 return EFI_INVALID_PARAMETER
;
211 return EFI_NOT_FOUND
;
214 // Is our node at the head of the list??
216 if ((v
= _v2p
)->vaddr
== vaddr
) {
219 Status
= mPciIoFncs
->Unmap (mPciIoFncs
, v
->unmap
);
224 DEBUG ((EFI_D_ERROR
, "Unmap failed with status = %r\n", Status
));
229 for (; v
->next
!= NULL
; v
= t
) {
230 if ((t
= v
->next
)->vaddr
== vaddr
) {
232 Status
= mPciIoFncs
->Unmap (mPciIoFncs
, t
->unmap
);
236 DEBUG ((EFI_D_ERROR
, "Unmap failed with status = %r\n", Status
));
242 return EFI_NOT_FOUND
;
246 issue_hwundi_command (
259 DEBUG ((EFI_D_ERROR
, "\nissue_hwundi_command() - This should not be called!"));
262 return EFI_INVALID_PARAMETER
;
266 // %%TBD - For now, nothing is done.
268 return EFI_UNSUPPORTED
;
273 Compute 8-bit checksum of a buffer.
275 @param ptr Pointer to buffer.
276 @param len Length of buffer in bytes.
278 @return 8-bit checksum of all bytes in buffer.
279 @return If ptr is NULL or len is zero, zero is returned.
294 if (ptr
== NULL
|| len
== 0) {
299 cksum
= (UINT8
) (cksum
+*bptr
++);
307 Test to see if this driver supports Controller. Any Controller
308 that contains a Nii protocol can be supported.
310 @param This Protocol instance pointer.
311 @param Controller Handle of device to test.
312 @param RemainingDevicePath Not used.
314 @retval EFI_SUCCESS This driver supports this device.
315 @retval EFI_ALREADY_STARTED This driver is already running on this device.
316 @retval other This driver does not support this device.
321 SimpleNetworkDriverSupported (
322 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
323 IN EFI_HANDLE Controller
,
324 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
328 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NiiProtocol
;
331 Status
= gBS
->OpenProtocol (
333 &gEfiDevicePathProtocolGuid
,
335 This
->DriverBindingHandle
,
337 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
339 if (EFI_ERROR (Status
)) {
343 Status
= gBS
->OpenProtocol (
345 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
346 (VOID
**) &NiiProtocol
,
347 This
->DriverBindingHandle
,
349 EFI_OPEN_PROTOCOL_BY_DRIVER
352 if (EFI_ERROR (Status
)) {
353 if (Status
== EFI_ALREADY_STARTED
) {
354 DEBUG ((EFI_D_INFO
, "Support(): Already Started. on handle %p\n", Controller
));
359 DEBUG ((EFI_D_INFO
, "Support(): UNDI3.1 found on handle %p\n", Controller
));
362 // check the version, we don't want to connect to the undi16
364 if (NiiProtocol
->Type
!= EfiNetworkInterfaceUndi
) {
365 Status
= EFI_UNSUPPORTED
;
369 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
371 if (NiiProtocol
->ID
& 0x0F) {
372 DEBUG ((EFI_D_NET
, "\n!PXE structure is not paragraph aligned.\n"));
373 Status
= EFI_UNSUPPORTED
;
377 pxe
= (PXE_UNDI
*) (UINTN
) (NiiProtocol
->ID
);
380 // Verify !PXE revisions.
382 if (pxe
->hw
.Signature
!= PXE_ROMID_SIGNATURE
) {
383 DEBUG ((EFI_D_NET
, "\n!PXE signature is not valid.\n"));
384 Status
= EFI_UNSUPPORTED
;
388 if (pxe
->hw
.Rev
< PXE_ROMID_REV
) {
389 DEBUG ((EFI_D_NET
, "\n!PXE.Rev is not supported.\n"));
390 Status
= EFI_UNSUPPORTED
;
394 if (pxe
->hw
.MajorVer
< PXE_ROMID_MAJORVER
) {
396 DEBUG ((EFI_D_NET
, "\n!PXE.MajorVer is not supported.\n"));
397 Status
= EFI_UNSUPPORTED
;
400 } else if (pxe
->hw
.MajorVer
== PXE_ROMID_MAJORVER
&& pxe
->hw
.MinorVer
< PXE_ROMID_MINORVER
) {
401 DEBUG ((EFI_D_NET
, "\n!PXE.MinorVer is not supported."));
402 Status
= EFI_UNSUPPORTED
;
406 // Do S/W UNDI specific checks.
408 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) == 0) {
409 if (pxe
->sw
.EntryPoint
< pxe
->sw
.Len
) {
410 DEBUG ((EFI_D_NET
, "\n!PXE S/W entry point is not valid."));
411 Status
= EFI_UNSUPPORTED
;
415 if (pxe
->sw
.BusCnt
== 0) {
416 DEBUG ((EFI_D_NET
, "\n!PXE.BusCnt is zero."));
417 Status
= EFI_UNSUPPORTED
;
422 Status
= EFI_SUCCESS
;
423 DEBUG ((EFI_D_INFO
, "Support(): supported on %p\n", Controller
));
428 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
429 This
->DriverBindingHandle
,
438 called for any handle that we said "supported" in the above call!
440 @param This Protocol instance pointer.
441 @param Controller Handle of device to start
442 @param RemainingDevicePath Not used.
444 @retval EFI_SUCCESS This driver supports this device.
445 @retval other This driver failed to start this device.
450 SimpleNetworkDriverStart (
451 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
452 IN EFI_HANDLE Controller
,
453 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
456 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
457 EFI_DEVICE_PATH_PROTOCOL
*NiiDevicePath
;
463 PXE_PCI_CONFIG_INFO ConfigInfo
;
464 PCI_TYPE00
*ConfigHeader
;
467 PXE_STATFLAGS InitStatFlags
;
469 DEBUG ((EFI_D_NET
, "\nSnpNotifyNetworkInterfaceIdentifier() "));
471 Status
= gBS
->OpenProtocol (
473 &gEfiDevicePathProtocolGuid
,
474 (VOID
**) &NiiDevicePath
,
475 This
->DriverBindingHandle
,
477 EFI_OPEN_PROTOCOL_BY_DRIVER
480 if (EFI_ERROR (Status
)) {
484 Status
= gBS
->LocateDevicePath (
485 &gEfiPciIoProtocolGuid
,
490 if (EFI_ERROR (Status
)) {
494 Status
= gBS
->OpenProtocol (
496 &gEfiPciIoProtocolGuid
,
497 (VOID
**) &mPciIoFncs
,
498 This
->DriverBindingHandle
,
500 EFI_OPEN_PROTOCOL_GET_PROTOCOL
502 if (EFI_ERROR (Status
)) {
506 // Get the NII interface.
508 Status
= gBS
->OpenProtocol (
510 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
512 This
->DriverBindingHandle
,
514 EFI_OPEN_PROTOCOL_BY_DRIVER
516 if (EFI_ERROR (Status
)) {
519 &gEfiDevicePathProtocolGuid
,
520 This
->DriverBindingHandle
,
526 DEBUG ((EFI_D_INFO
, "Start(): UNDI3.1 found\n"));
528 pxe
= (PXE_UNDI
*) (UINTN
) (Nii
->ID
);
530 if (calc_8bit_cksum (pxe
, pxe
->hw
.Len
) != 0) {
531 DEBUG ((EFI_D_NET
, "\n!PXE checksum is not correct.\n"));
535 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
537 // We can get any packets.
539 } else if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
541 // We need to be able to get broadcast packets for DHCP.
542 // If we do not have promiscuous support, we must at least have
543 // broadcast support or we cannot do DHCP!
546 DEBUG ((EFI_D_NET
, "\nUNDI does not have promiscuous or broadcast support."));
550 // OK, we like this UNDI, and we know snp is not already there on this handle
551 // Allocate and initialize a new simple network protocol structure.
553 Status
= mPciIoFncs
->AllocateBuffer (
557 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
562 if (Status
!= EFI_SUCCESS
) {
563 DEBUG ((EFI_D_NET
, "\nCould not allocate SNP_DRIVER structure.\n"));
567 snp
= (SNP_DRIVER
*) (UINTN
) addr
;
569 ZeroMem (snp
, sizeof (SNP_DRIVER
));
571 snp
->IoFncs
= mPciIoFncs
;
572 snp
->Signature
= SNP_DRIVER_SIGNATURE
;
574 EfiInitializeLock (&snp
->lock
, TPL_NOTIFY
);
576 snp
->snp
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
577 snp
->snp
.Start
= snp_undi32_start
;
578 snp
->snp
.Stop
= snp_undi32_stop
;
579 snp
->snp
.Initialize
= snp_undi32_initialize
;
580 snp
->snp
.Reset
= snp_undi32_reset
;
581 snp
->snp
.Shutdown
= snp_undi32_shutdown
;
582 snp
->snp
.ReceiveFilters
= snp_undi32_receive_filters
;
583 snp
->snp
.StationAddress
= snp_undi32_station_address
;
584 snp
->snp
.Statistics
= snp_undi32_statistics
;
585 snp
->snp
.MCastIpToMac
= snp_undi32_mcast_ip_to_mac
;
586 snp
->snp
.NvData
= snp_undi32_nvdata
;
587 snp
->snp
.GetStatus
= snp_undi32_get_status
;
588 snp
->snp
.Transmit
= snp_undi32_transmit
;
589 snp
->snp
.Receive
= snp_undi32_receive
;
590 snp
->snp
.WaitForPacket
= NULL
;
592 snp
->snp
.Mode
= &snp
->mode
;
594 snp
->tx_rx_bufsize
= 0;
595 snp
->tx_rx_buffer
= NULL
;
597 snp
->if_num
= Nii
->IfNum
;
599 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) != 0) {
600 snp
->is_swundi
= FALSE
;
601 snp
->issue_undi32_command
= &issue_hwundi_command
;
603 snp
->is_swundi
= TRUE
;
605 if ((pxe
->sw
.Implementation
& PXE_ROMID_IMP_SW_VIRT_ADDR
) != 0) {
606 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) pxe
->sw
.EntryPoint
;
608 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) ((UINT8
) (UINTN
) pxe
+ pxe
->sw
.EntryPoint
);
612 // Allocate a global CPB and DB buffer for this UNDI interface.
613 // we do this because:
615 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be
616 // within 2GB limit, create them here and map them so that when undi calls
617 // v2p callback to check if the physical address is < 2gb, we will pass.
619 // -This is not a requirement for 3.1 or later UNDIs but the code looks
620 // simpler if we use the same cpb, db variables for both old and new undi
621 // interfaces from all the SNP interface calls (we don't map the buffers
622 // for the newer undi interfaces though)
624 // -it is OK to allocate one global set of CPB, DB pair for each UNDI
625 // interface as EFI does not multi-task and so SNP will not be re-entered!
627 Status
= mPciIoFncs
->AllocateBuffer (
631 SNP_MEM_PAGES (4096),
636 if (Status
!= EFI_SUCCESS
) {
637 DEBUG ((EFI_D_NET
, "\nCould not allocate CPB and DB structures.\n"));
638 goto Error_DeleteSNP
;
641 snp
->cpb
= (VOID
*) (UINTN
) addr
;
642 snp
->db
= (VOID
*) ((UINTN
) addr
+ 2048);
645 // pxe_start call is going to give the callback functions to UNDI, these callback
646 // functions use the BarIndex values from the snp structure, so these must be initialized
647 // with default values before doing a pxe_start. The correct values can be obtained after
648 // getting the config information from UNDI
650 snp
->MemoryBarIndex
= 0;
654 // we need the undi init information many times in this snp code, just get it
655 // once here and store it in the snp driver structure. to get Init Info
656 // from UNDI we have to start undi first.
658 Status
= pxe_start (snp
);
660 if (Status
!= EFI_SUCCESS
) {
661 goto Error_DeleteSNP
;
664 snp
->cdb
.OpCode
= PXE_OPCODE_GET_INIT_INFO
;
665 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
667 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
668 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
670 snp
->cdb
.DBsize
= sizeof snp
->init_info
;
671 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) &snp
->init_info
;
673 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
674 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
676 snp
->cdb
.IFnum
= snp
->if_num
;
677 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
679 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_init_info() "));
681 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
684 // Save the INIT Stat Code...
686 InitStatFlags
= snp
->cdb
.StatFlags
;
688 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
689 DEBUG ((EFI_D_NET
, "\nsnp->undi.init_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
691 goto Error_DeleteSNP
;
694 snp
->cdb
.OpCode
= PXE_OPCODE_GET_CONFIG_INFO
;
695 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
697 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
698 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
700 snp
->cdb
.DBsize
= sizeof ConfigInfo
;
701 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) &ConfigInfo
;
703 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
704 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
706 snp
->cdb
.IFnum
= snp
->if_num
;
707 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
709 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_config_info() "));
711 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
713 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
714 DEBUG ((EFI_D_NET
, "\nsnp->undi.config_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
716 goto Error_DeleteSNP
;
719 // Find the correct BAR to do IO.
722 // Enumerate through the PCI BARs for the device to determine which one is
723 // the IO BAR. Save the index of the BAR into the adapter info structure.
724 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
726 ConfigHeader
= (PCI_TYPE00
*) &ConfigInfo
.Config
.Byte
[0];
727 TempBar
= (UINT32
*) &ConfigHeader
->Device
.Bar
[0];
728 for (BarIndex
= 0; BarIndex
<= 5; BarIndex
++) {
729 if ((*TempBar
& PCI_BAR_MEM_MASK
) == PCI_BAR_MEM_64BIT
) {
731 // This is a 64-bit memory bar, skip this and the
737 if ((*TempBar
& PCI_BAR_IO_MASK
) == PCI_BAR_IO_MODE
) {
738 snp
->IoBarIndex
= BarIndex
;
746 // Initialize simple network protocol mode structure
748 snp
->mode
.State
= EfiSimpleNetworkStopped
;
749 snp
->mode
.HwAddressSize
= snp
->init_info
.HWaddrLen
;
750 snp
->mode
.MediaHeaderSize
= snp
->init_info
.MediaHeaderLen
;
751 snp
->mode
.MaxPacketSize
= snp
->init_info
.FrameDataLen
;
752 snp
->mode
.NvRamAccessSize
= snp
->init_info
.NvWidth
;
753 snp
->mode
.NvRamSize
= snp
->init_info
.NvCount
* snp
->mode
.NvRamAccessSize
;
754 snp
->mode
.IfType
= snp
->init_info
.IFtype
;
755 snp
->mode
.MaxMCastFilterCount
= snp
->init_info
.MCastFilterCnt
;
756 snp
->mode
.MCastFilterCount
= 0;
758 switch (InitStatFlags
& PXE_STATFLAGS_CABLE_DETECT_MASK
) {
759 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
:
760 snp
->mode
.MediaPresentSupported
= TRUE
;
763 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED
:
765 snp
->mode
.MediaPresentSupported
= FALSE
;
768 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_STATION_ADDR_SETTABLE
) != 0) {
769 snp
->mode
.MacAddressChangeable
= TRUE
;
771 snp
->mode
.MacAddressChangeable
= FALSE
;
774 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED
) != 0) {
775 snp
->mode
.MultipleTxSupported
= TRUE
;
777 snp
->mode
.MultipleTxSupported
= FALSE
;
780 snp
->mode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
782 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
783 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
787 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
788 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
792 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
793 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
797 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
) != 0) {
798 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
802 if (pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) {
803 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
807 snp
->mode
.ReceiveFilterSetting
= 0;
810 // need to get the station address to save in the mode structure. we need to
811 // initialize the UNDI first for this.
813 snp
->tx_rx_bufsize
= snp
->init_info
.MemoryRequired
;
814 Status
= pxe_init (snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
818 goto Error_DeleteSNP
;
821 Status
= pxe_get_stn_addr (snp
);
823 if (Status
!= EFI_SUCCESS
) {
824 DEBUG ((EFI_D_ERROR
, "\nsnp->undi.get_station_addr() failed.\n"));
827 goto Error_DeleteSNP
;
830 snp
->mode
.MediaPresent
= FALSE
;
833 // We should not leave UNDI started and initialized here. this DriverStart()
834 // routine must only find and attach the SNP interface to UNDI layer that it
835 // finds on the given handle!
836 // The UNDI layer will be started when upper layers call snp->start.
837 // How ever, this DriverStart() must fill up the snp mode structure which
838 // contains the MAC address of the NIC. For this reason we started and
839 // initialized UNDI here, now we are done, do a shutdown and stop of the
846 // add SNP to the undi handle
848 Status
= gBS
->InstallProtocolInterface (
850 &gEfiSimpleNetworkProtocolGuid
,
851 EFI_NATIVE_INTERFACE
,
855 if (!EFI_ERROR (Status
)) {
859 Status
= mPciIoFncs
->FreeBuffer (
861 SNP_MEM_PAGES (4096),
867 mPciIoFncs
->FreeBuffer (
869 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
875 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
876 This
->DriverBindingHandle
,
882 &gEfiDevicePathProtocolGuid
,
883 This
->DriverBindingHandle
,
898 SimpleNetworkDriverStop (
899 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
900 IN EFI_HANDLE Controller
,
901 IN UINTN NumberOfChildren
,
902 IN EFI_HANDLE
*ChildHandleBuffer
906 EFI_SIMPLE_NETWORK_PROTOCOL
*SnpProtocol
;
910 // Get our context back.
912 Status
= gBS
->OpenProtocol (
914 &gEfiSimpleNetworkProtocolGuid
,
915 (VOID
**) &SnpProtocol
,
916 This
->DriverBindingHandle
,
918 EFI_OPEN_PROTOCOL_GET_PROTOCOL
921 if (EFI_ERROR (Status
)) {
922 return EFI_UNSUPPORTED
;
925 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol
);
927 Status
= gBS
->UninstallProtocolInterface (
929 &gEfiSimpleNetworkProtocolGuid
,
933 if (EFI_ERROR (Status
)) {
937 Status
= gBS
->CloseProtocol (
939 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
940 This
->DriverBindingHandle
,
944 Status
= gBS
->CloseProtocol (
946 &gEfiDevicePathProtocolGuid
,
947 This
->DriverBindingHandle
,
954 mPciIoFncs
->FreeBuffer (
956 SNP_MEM_PAGES (4096),
960 mPciIoFncs
->FreeBuffer (
962 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
971 Install all the driver protocol
973 @param entry EFI_IMAGE_ENTRY_POINT)
975 @retval EFI_SUCEESS Initialization routine has found UNDI hardware,
976 loaded it's ROM, and installed a notify event for
977 the Network Indentifier Interface Protocol
979 @retval Other Return value from HandleProtocol for
980 DeviceIoProtocol or LoadedImageProtocol
985 InitializeSnpNiiDriver (
986 IN EFI_HANDLE ImageHandle
,
987 IN EFI_SYSTEM_TABLE
*SystemTable
990 return EfiLibInstallDriverBindingComponentName2 (
993 &mSimpleNetworkDriverBinding
,
995 &gSimpleNetworkComponentName
,
996 &gSimpleNetworkComponentName2