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 = %x\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 = %x\n", Status
));
242 return EFI_NOT_FOUND
;
247 issue_hwundi_command (
260 DEBUG ((EFI_D_ERROR
, "\nissue_hwundi_command() - This should not be called!"));
263 return EFI_INVALID_PARAMETER
;
267 // %%TBD - For now, nothing is done.
269 return EFI_UNSUPPORTED
;
274 Compute 8-bit checksum of a buffer.
276 @param ptr Pointer to buffer.
277 @param len Length of buffer in bytes.
279 @return 8-bit checksum of all bytes in buffer.
280 @return If ptr is NULL or len is zero, zero is returned.
296 if (ptr
== NULL
|| len
== 0) {
301 cksum
= (UINT8
) (cksum
+*bptr
++);
309 Test to see if this driver supports Controller. Any Controller
310 that contains a Nii protocol can be supported.
312 @param This Protocol instance pointer.
313 @param Controller Handle of device to test.
314 @param RemainingDevicePath Not used.
316 @retval EFI_SUCCESS This driver supports this device.
317 @retval EFI_ALREADY_STARTED This driver is already running on this device.
318 @retval other This driver does not support this device.
323 SimpleNetworkDriverSupported (
324 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
325 IN EFI_HANDLE Controller
,
326 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
330 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*NiiProtocol
;
333 Status
= gBS
->OpenProtocol (
335 &gEfiDevicePathProtocolGuid
,
337 This
->DriverBindingHandle
,
339 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
341 if (EFI_ERROR (Status
)) {
345 Status
= gBS
->OpenProtocol (
347 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
348 (VOID
**) &NiiProtocol
,
349 This
->DriverBindingHandle
,
351 EFI_OPEN_PROTOCOL_BY_DRIVER
354 if (EFI_ERROR (Status
)) {
355 if (Status
== EFI_ALREADY_STARTED
) {
356 DEBUG ((EFI_D_INFO
, "Support(): Already Started. on handle %x\n", Controller
));
361 DEBUG ((EFI_D_INFO
, "Support(): UNDI3.1 found on handle %x\n", Controller
));
364 // check the version, we don't want to connect to the undi16
366 if (NiiProtocol
->Type
!= EfiNetworkInterfaceUndi
) {
367 Status
= EFI_UNSUPPORTED
;
371 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
373 if (NiiProtocol
->ID
& 0x0F) {
374 DEBUG ((EFI_D_NET
, "\n!PXE structure is not paragraph aligned.\n"));
375 Status
= EFI_UNSUPPORTED
;
379 pxe
= (PXE_UNDI
*) (UINTN
) (NiiProtocol
->ID
);
382 // Verify !PXE revisions.
384 if (pxe
->hw
.Signature
!= PXE_ROMID_SIGNATURE
) {
385 DEBUG ((EFI_D_NET
, "\n!PXE signature is not valid.\n"));
386 Status
= EFI_UNSUPPORTED
;
390 if (pxe
->hw
.Rev
< PXE_ROMID_REV
) {
391 DEBUG ((EFI_D_NET
, "\n!PXE.Rev is not supported.\n"));
392 Status
= EFI_UNSUPPORTED
;
396 if (pxe
->hw
.MajorVer
< PXE_ROMID_MAJORVER
) {
398 DEBUG ((EFI_D_NET
, "\n!PXE.MajorVer is not supported.\n"));
399 Status
= EFI_UNSUPPORTED
;
402 } else if (pxe
->hw
.MajorVer
== PXE_ROMID_MAJORVER
&& pxe
->hw
.MinorVer
< PXE_ROMID_MINORVER
) {
403 DEBUG ((EFI_D_NET
, "\n!PXE.MinorVer is not supported."));
404 Status
= EFI_UNSUPPORTED
;
408 // Do S/W UNDI specific checks.
410 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) == 0) {
411 if (pxe
->sw
.EntryPoint
< pxe
->sw
.Len
) {
412 DEBUG ((EFI_D_NET
, "\n!PXE S/W entry point is not valid."));
413 Status
= EFI_UNSUPPORTED
;
417 if (pxe
->sw
.BusCnt
== 0) {
418 DEBUG ((EFI_D_NET
, "\n!PXE.BusCnt is zero."));
419 Status
= EFI_UNSUPPORTED
;
424 Status
= EFI_SUCCESS
;
425 DEBUG ((EFI_D_INFO
, "Support(): supported on %x\n", Controller
));
430 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
431 This
->DriverBindingHandle
,
440 called for any handle that we said "supported" in the above call!
442 @param This Protocol instance pointer.
443 @param Controller Handle of device to start
444 @param RemainingDevicePath Not used.
446 @retval EFI_SUCCESS This driver supports this device.
447 @retval other This driver failed to start this device.
452 SimpleNetworkDriverStart (
453 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
454 IN EFI_HANDLE Controller
,
455 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
458 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL
*Nii
;
459 EFI_DEVICE_PATH_PROTOCOL
*NiiDevicePath
;
465 PXE_PCI_CONFIG_INFO ConfigInfo
;
466 PCI_TYPE00
*ConfigHeader
;
469 PXE_STATFLAGS InitStatFlags
;
471 DEBUG ((EFI_D_NET
, "\nSnpNotifyNetworkInterfaceIdentifier() "));
473 Status
= gBS
->OpenProtocol (
475 &gEfiDevicePathProtocolGuid
,
476 (VOID
**) &NiiDevicePath
,
477 This
->DriverBindingHandle
,
479 EFI_OPEN_PROTOCOL_BY_DRIVER
482 if (EFI_ERROR (Status
)) {
486 Status
= gBS
->LocateDevicePath (
487 &gEfiPciIoProtocolGuid
,
492 if (EFI_ERROR (Status
)) {
496 Status
= gBS
->OpenProtocol (
498 &gEfiPciIoProtocolGuid
,
499 (VOID
**) &mPciIoFncs
,
500 This
->DriverBindingHandle
,
502 EFI_OPEN_PROTOCOL_GET_PROTOCOL
504 if (EFI_ERROR (Status
)) {
508 // Get the NII interface.
510 Status
= gBS
->OpenProtocol (
512 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
514 This
->DriverBindingHandle
,
516 EFI_OPEN_PROTOCOL_BY_DRIVER
518 if (EFI_ERROR (Status
)) {
521 &gEfiDevicePathProtocolGuid
,
522 This
->DriverBindingHandle
,
528 DEBUG ((EFI_D_INFO
, "Start(): UNDI3.1 found\n"));
530 pxe
= (PXE_UNDI
*) (UINTN
) (Nii
->ID
);
532 if (calc_8bit_cksum (pxe
, pxe
->hw
.Len
) != 0) {
533 DEBUG ((EFI_D_NET
, "\n!PXE checksum is not correct.\n"));
537 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
539 // We can get any packets.
541 } else if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
543 // We need to be able to get broadcast packets for DHCP.
544 // If we do not have promiscuous support, we must at least have
545 // broadcast support or we cannot do DHCP!
548 DEBUG ((EFI_D_NET
, "\nUNDI does not have promiscuous or broadcast support."));
552 // OK, we like this UNDI, and we know snp is not already there on this handle
553 // Allocate and initialize a new simple network protocol structure.
555 Status
= mPciIoFncs
->AllocateBuffer (
559 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
564 if (Status
!= EFI_SUCCESS
) {
565 DEBUG ((EFI_D_NET
, "\nCould not allocate SNP_DRIVER structure.\n"));
569 snp
= (SNP_DRIVER
*) (UINTN
) addr
;
571 ZeroMem (snp
, sizeof (SNP_DRIVER
));
573 snp
->IoFncs
= mPciIoFncs
;
574 snp
->Signature
= SNP_DRIVER_SIGNATURE
;
576 EfiInitializeLock (&snp
->lock
, TPL_NOTIFY
);
578 snp
->snp
.Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
579 snp
->snp
.Start
= snp_undi32_start
;
580 snp
->snp
.Stop
= snp_undi32_stop
;
581 snp
->snp
.Initialize
= snp_undi32_initialize
;
582 snp
->snp
.Reset
= snp_undi32_reset
;
583 snp
->snp
.Shutdown
= snp_undi32_shutdown
;
584 snp
->snp
.ReceiveFilters
= snp_undi32_receive_filters
;
585 snp
->snp
.StationAddress
= snp_undi32_station_address
;
586 snp
->snp
.Statistics
= snp_undi32_statistics
;
587 snp
->snp
.MCastIpToMac
= snp_undi32_mcast_ip_to_mac
;
588 snp
->snp
.NvData
= snp_undi32_nvdata
;
589 snp
->snp
.GetStatus
= snp_undi32_get_status
;
590 snp
->snp
.Transmit
= snp_undi32_transmit
;
591 snp
->snp
.Receive
= snp_undi32_receive
;
592 snp
->snp
.WaitForPacket
= NULL
;
594 snp
->snp
.Mode
= &snp
->mode
;
596 snp
->tx_rx_bufsize
= 0;
597 snp
->tx_rx_buffer
= NULL
;
599 snp
->if_num
= Nii
->IfNum
;
601 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_HW_UNDI
) != 0) {
602 snp
->is_swundi
= FALSE
;
603 snp
->issue_undi32_command
= &issue_hwundi_command
;
605 snp
->is_swundi
= TRUE
;
607 if ((pxe
->sw
.Implementation
& PXE_ROMID_IMP_SW_VIRT_ADDR
) != 0) {
608 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) pxe
->sw
.EntryPoint
;
610 snp
->issue_undi32_command
= (issue_undi32_command
) (UINTN
) ((UINT8
) (UINTN
) pxe
+ pxe
->sw
.EntryPoint
);
614 // Allocate a global CPB and DB buffer for this UNDI interface.
615 // we do this because:
617 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be
618 // within 2GB limit, create them here and map them so that when undi calls
619 // v2p callback to check if the physical address is < 2gb, we will pass.
621 // -This is not a requirement for 3.1 or later UNDIs but the code looks
622 // simpler if we use the same cpb, db variables for both old and new undi
623 // interfaces from all the SNP interface calls (we don't map the buffers
624 // for the newer undi interfaces though)
626 // -it is OK to allocate one global set of CPB, DB pair for each UNDI
627 // interface as EFI does not multi-task and so SNP will not be re-entered!
629 Status
= mPciIoFncs
->AllocateBuffer (
633 SNP_MEM_PAGES (4096),
638 if (Status
!= EFI_SUCCESS
) {
639 DEBUG ((EFI_D_NET
, "\nCould not allocate CPB and DB structures.\n"));
640 goto Error_DeleteSNP
;
643 snp
->cpb
= (VOID
*) (UINTN
) addr
;
644 snp
->db
= (VOID
*) ((UINTN
) addr
+ 2048);
647 // pxe_start call is going to give the callback functions to UNDI, these callback
648 // functions use the BarIndex values from the snp structure, so these must be initialized
649 // with default values before doing a pxe_start. The correct values can be obtained after
650 // getting the config information from UNDI
652 snp
->MemoryBarIndex
= 0;
656 // we need the undi init information many times in this snp code, just get it
657 // once here and store it in the snp driver structure. to get Init Info
658 // from UNDI we have to start undi first.
660 Status
= pxe_start (snp
);
662 if (Status
!= EFI_SUCCESS
) {
663 goto Error_DeleteSNP
;
666 snp
->cdb
.OpCode
= PXE_OPCODE_GET_INIT_INFO
;
667 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
669 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
670 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
672 snp
->cdb
.DBsize
= sizeof snp
->init_info
;
673 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) &snp
->init_info
;
675 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
676 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
678 snp
->cdb
.IFnum
= snp
->if_num
;
679 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
681 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_init_info() "));
683 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
686 // Save the INIT Stat Code...
688 InitStatFlags
= snp
->cdb
.StatFlags
;
690 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
691 DEBUG ((EFI_D_NET
, "\nsnp->undi.init_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
693 goto Error_DeleteSNP
;
696 snp
->cdb
.OpCode
= PXE_OPCODE_GET_CONFIG_INFO
;
697 snp
->cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
699 snp
->cdb
.CPBsize
= PXE_CPBSIZE_NOT_USED
;
700 snp
->cdb
.CPBaddr
= PXE_DBADDR_NOT_USED
;
702 snp
->cdb
.DBsize
= sizeof ConfigInfo
;
703 snp
->cdb
.DBaddr
= (UINT64
)(UINTN
) &ConfigInfo
;
705 snp
->cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
706 snp
->cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
708 snp
->cdb
.IFnum
= snp
->if_num
;
709 snp
->cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
711 DEBUG ((EFI_D_NET
, "\nsnp->undi.get_config_info() "));
713 (*snp
->issue_undi32_command
) ((UINT64
)(UINTN
) &snp
->cdb
);
715 if (snp
->cdb
.StatCode
!= PXE_STATCODE_SUCCESS
) {
716 DEBUG ((EFI_D_NET
, "\nsnp->undi.config_info() %xh:%xh\n", snp
->cdb
.StatFlags
, snp
->cdb
.StatCode
));
718 goto Error_DeleteSNP
;
721 // Find the correct BAR to do IO.
724 // Enumerate through the PCI BARs for the device to determine which one is
725 // the IO BAR. Save the index of the BAR into the adapter info structure.
726 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
728 ConfigHeader
= (PCI_TYPE00
*) &ConfigInfo
.Config
.Byte
[0];
729 TempBar
= (UINT32
*) &ConfigHeader
->Device
.Bar
[0];
730 for (BarIndex
= 0; BarIndex
<= 5; BarIndex
++) {
731 if ((*TempBar
& PCI_BAR_MEM_MASK
) == PCI_BAR_MEM_64BIT
) {
733 // This is a 64-bit memory bar, skip this and the
739 if ((*TempBar
& PCI_BAR_IO_MASK
) == PCI_BAR_IO_MODE
) {
740 snp
->IoBarIndex
= BarIndex
;
748 // Initialize simple network protocol mode structure
750 snp
->mode
.State
= EfiSimpleNetworkStopped
;
751 snp
->mode
.HwAddressSize
= snp
->init_info
.HWaddrLen
;
752 snp
->mode
.MediaHeaderSize
= snp
->init_info
.MediaHeaderLen
;
753 snp
->mode
.MaxPacketSize
= snp
->init_info
.FrameDataLen
;
754 snp
->mode
.NvRamAccessSize
= snp
->init_info
.NvWidth
;
755 snp
->mode
.NvRamSize
= snp
->init_info
.NvCount
* snp
->mode
.NvRamAccessSize
;
756 snp
->mode
.IfType
= snp
->init_info
.IFtype
;
757 snp
->mode
.MaxMCastFilterCount
= snp
->init_info
.MCastFilterCnt
;
758 snp
->mode
.MCastFilterCount
= 0;
760 switch (InitStatFlags
& PXE_STATFLAGS_CABLE_DETECT_MASK
) {
761 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
:
762 snp
->mode
.MediaPresentSupported
= TRUE
;
765 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED
:
767 snp
->mode
.MediaPresentSupported
= FALSE
;
770 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_STATION_ADDR_SETTABLE
) != 0) {
771 snp
->mode
.MacAddressChangeable
= TRUE
;
773 snp
->mode
.MacAddressChangeable
= FALSE
;
776 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED
) != 0) {
777 snp
->mode
.MultipleTxSupported
= TRUE
;
779 snp
->mode
.MultipleTxSupported
= FALSE
;
782 snp
->mode
.ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
784 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) != 0) {
785 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
789 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
) != 0) {
790 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
794 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
) != 0) {
795 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
799 if ((pxe
->hw
.Implementation
& PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED
) != 0) {
800 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
804 if (pxe
->hw
.Implementation
& PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
) {
805 snp
->mode
.ReceiveFilterMask
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
809 snp
->mode
.ReceiveFilterSetting
= 0;
812 // need to get the station address to save in the mode structure. we need to
813 // initialize the UNDI first for this.
815 snp
->tx_rx_bufsize
= snp
->init_info
.MemoryRequired
;
816 Status
= pxe_init (snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
820 goto Error_DeleteSNP
;
823 Status
= pxe_get_stn_addr (snp
);
825 if (Status
!= EFI_SUCCESS
) {
826 DEBUG ((EFI_D_ERROR
, "\nsnp->undi.get_station_addr() failed.\n"));
829 goto Error_DeleteSNP
;
832 snp
->mode
.MediaPresent
= FALSE
;
835 // We should not leave UNDI started and initialized here. this DriverStart()
836 // routine must only find and attach the SNP interface to UNDI layer that it
837 // finds on the given handle!
838 // The UNDI layer will be started when upper layers call snp->start.
839 // How ever, this DriverStart() must fill up the snp mode structure which
840 // contains the MAC address of the NIC. For this reason we started and
841 // initialized UNDI here, now we are done, do a shutdown and stop of the
848 // add SNP to the undi handle
850 Status
= gBS
->InstallProtocolInterface (
852 &gEfiSimpleNetworkProtocolGuid
,
853 EFI_NATIVE_INTERFACE
,
857 if (!EFI_ERROR (Status
)) {
861 Status
= mPciIoFncs
->FreeBuffer (
863 SNP_MEM_PAGES (4096),
869 mPciIoFncs
->FreeBuffer (
871 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
877 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
878 This
->DriverBindingHandle
,
884 &gEfiDevicePathProtocolGuid
,
885 This
->DriverBindingHandle
,
900 SimpleNetworkDriverStop (
901 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
902 IN EFI_HANDLE Controller
,
903 IN UINTN NumberOfChildren
,
904 IN EFI_HANDLE
*ChildHandleBuffer
908 EFI_SIMPLE_NETWORK_PROTOCOL
*SnpProtocol
;
912 // Get our context back.
914 Status
= gBS
->OpenProtocol (
916 &gEfiSimpleNetworkProtocolGuid
,
917 (VOID
**) &SnpProtocol
,
918 This
->DriverBindingHandle
,
920 EFI_OPEN_PROTOCOL_GET_PROTOCOL
923 if (EFI_ERROR (Status
)) {
924 return EFI_UNSUPPORTED
;
927 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol
);
929 Status
= gBS
->UninstallProtocolInterface (
931 &gEfiSimpleNetworkProtocolGuid
,
935 if (EFI_ERROR (Status
)) {
939 Status
= gBS
->CloseProtocol (
941 &gEfiNetworkInterfaceIdentifierProtocolGuid_31
,
942 This
->DriverBindingHandle
,
946 Status
= gBS
->CloseProtocol (
948 &gEfiDevicePathProtocolGuid
,
949 This
->DriverBindingHandle
,
956 mPciIoFncs
->FreeBuffer (
958 SNP_MEM_PAGES (4096),
962 mPciIoFncs
->FreeBuffer (
964 SNP_MEM_PAGES (sizeof (SNP_DRIVER
)),
973 Install all the driver protocol
975 @param entry EFI_IMAGE_ENTRY_POINT)
977 @retval EFI_SUCEESS Initialization routine has found UNDI hardware,
978 loaded it's ROM, and installed a notify event for
979 the Network Indentifier Interface Protocol
981 @retval Other Return value from HandleProtocol for
982 DeviceIoProtocol or LoadedImageProtocol
987 InitializeSnpNiiDriver (
988 IN EFI_HANDLE ImageHandle
,
989 IN EFI_SYSTEM_TABLE
*SystemTable
992 return EfiLibInstallDriverBindingComponentName2 (
995 &mSimpleNetworkDriverBinding
,
997 &gSimpleNetworkComponentName
,
998 &gSimpleNetworkComponentName2