iPXE
snpnet.h File Reference

SNP NIC driver. More...

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (PERMITTED)
int snpnet_supported (EFI_HANDLE device, EFI_GUID *protocol, int inhibit_wifi)
 Check to see if driver supports a device.
int snpnet_exclude (EFI_HANDLE device)
 Exclude existing drivers.
int snpnet_start (struct efi_device *efidev)
 Attach driver to device.
void snpnet_stop (struct efi_device *efidev)
 Detach driver from device.

Detailed Description

SNP NIC driver.

Definition in file snpnet.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

References EFI_HANDLE, and protocol.

◆ snpnet_supported()

int snpnet_supported ( EFI_HANDLE device,
EFI_GUID * protocol,
int inhibit_wifi )
extern

Check to see if driver supports a device.

Parameters
deviceEFI device handle
protocolProtocol GUID
inhibit_wifiInhibit wireless devices
Return values
rcReturn status code

Definition at line 511 of file snpnet.c.

512 {
513 EFI_HANDLE parent;
514 int rc;
515
516 /* Check that this is not a device we are providing ourselves */
517 if ( find_snpdev ( device ) != NULL ) {
518 DBGCP ( device, "HANDLE %s is provided by this binary\n",
520 return -ENOTTY;
521 }
522
523 /* Test for presence of protocol */
524 if ( ( rc = efi_test ( device, protocol ) ) != 0 ) {
525 DBGCP ( device, "HANDLE %s is not a %s device\n",
528 return rc;
529 }
530
531 /* Check that there are no instances of this protocol further
532 * up this device path.
533 */
535 &parent, 1 ) ) == 0 ) {
536 DBGC2 ( device, "HANDLE %s has %s-supporting parent ",
539 DBGC2 ( device, "%s\n", efi_handle_name ( parent ) );
540 return -ENOTTY;
541 }
542 DBGC ( device, "HANDLE %s is a %s device\n",
544
545 /* Check for wireless devices, if applicable */
546 if ( inhibit_wifi &&
547 ( ( efi_test ( device, &efi_wifi2_protocol_guid ) ) == 0 ) ) {
548 DBGC ( device, "HANDLE %s is wireless: assuming vendor %s "
549 "driver is too unreliable to use\n",
552 return -ENOTTY;
553 }
554
555 return 0;
556}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition efi_guid.c:726
EFI_GUID efi_wifi2_protocol_guid
WiFi 2 protocol GUID.
Definition efi_guid.c:437
struct efi_snp_device * find_snpdev(EFI_HANDLE handle)
Find SNP device by EFI device handle.
Definition efi_snp.c:2104
int efi_locate_device(EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent, unsigned int skip)
Locate parent device supporting a given protocol.
Definition efi_utils.c:46
#define DBGC2(...)
Definition compiler.h:522
#define DBGCP(...)
Definition compiler.h:539
#define DBGC(...)
Definition compiler.h:505
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define EFI_HANDLE
Definition efi.h:53
#define efi_test(handle, protocol)
Test protocol existence.
Definition efi.h:433
uint16_t protocol
Protocol ID.
Definition stp.h:7
A hardware device.
Definition device.h:77

References DBGC, DBGC2, DBGCP, efi_guid_ntoa(), EFI_HANDLE, efi_handle_name(), efi_locate_device(), efi_test, efi_wifi2_protocol_guid, ENOTTY, find_snpdev(), NULL, protocol, and rc.

Referenced by mnp_supported(), nii_supported(), and snp_supported().

◆ snpnet_exclude()

int snpnet_exclude ( EFI_HANDLE device)
extern

Exclude existing drivers.

Parameters
deviceEFI device handle
Return values
rcReturn status code

Definition at line 693 of file snpnet.c.

693 {
695 struct snp_insomniac_patch patch;
696 int insomniac;
697 int rc;
698
699 /* Check if this is a device that must not ever be shut down */
700 insomniac = snpnet_is_insomniac ( device );
701
702 /* Inhibit calls to Shutdown() and Stop(), if applicable */
703 if ( insomniac &&
704 ( ( rc = snpnet_insomniac_patch ( device, &patch ) ) != 0 ) ) {
705 goto err_patch;
706 }
707
708 /* Exclude existing SNP drivers */
709 if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
710 DBGC ( device, "SNP %s could not exclude drivers: %s\n",
712 goto err_exclude;
713 }
714
715 err_exclude:
716 if ( insomniac )
718 err_patch:
719 return rc;
720}
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
int efi_driver_exclude(EFI_HANDLE device, EFI_GUID *protocol)
Try to disconnect an existing EFI driver.
Definition efi_driver.c:438
EFI_GUID efi_simple_network_protocol_guid
Simple network protocol GUID.
Definition efi_guid.c:341
static int snpnet_insomniac_restore(EFI_HANDLE device, struct snp_insomniac_patch *patch)
Restore patched SNP protocol interface.
Definition snpnet.c:654
static int snpnet_is_insomniac(EFI_HANDLE device)
Check if device must be insomniac.
Definition snpnet.c:564
static int snpnet_insomniac_patch(EFI_HANDLE device, struct snp_insomniac_patch *patch)
Patch SNP protocol interface to prevent shutdown.
Definition snpnet.c:616
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An SNP interface patch to inhibit shutdown for insomniac devices.
Definition snpnet.c:91

References DBGC, efi_driver_exclude(), EFI_HANDLE, efi_handle_name(), efi_simple_network_protocol_guid, protocol, rc, snpnet_insomniac_patch(), snpnet_insomniac_restore(), snpnet_is_insomniac(), and strerror().

Referenced by __efi_driver().

◆ snpnet_start()

int snpnet_start ( struct efi_device * efidev)
extern

Attach driver to device.

Parameters
efidevEFI device
Return values
rcReturn status code

Definition at line 728 of file snpnet.c.

728 {
729 EFI_HANDLE device = efidev->device;
732 struct net_device *netdev;
733 struct snp_nic *snp;
734 EFI_STATUS efirc;
735 int rc;
736
737 /* Open SNP protocol */
738 if ( ( rc = efi_open_by_driver ( device,
740 &interface ) ) != 0 ) {
741 DBGC ( device, "SNP %s cannot open SNP protocol: %s\n",
745 goto err_open_protocol;
746 }
747
748 /* Allocate and initialise structure */
749 netdev = alloc_etherdev ( sizeof ( *snp ) );
750 if ( ! netdev ) {
751 rc = -ENOMEM;
752 goto err_alloc;
753 }
755 snp = netdev->priv;
756 snp->efidev = efidev;
757 snp->snp = interface;
758 mode = snp->snp->Mode;
760
761 /* Populate underlying device information */
762 efi_device_info ( device, "SNP", &snp->dev );
763 snp->dev.driver_name = "SNP";
764 snp->dev.parent = &efidev->dev;
765 list_add ( &snp->dev.siblings, &efidev->dev.children );
766 INIT_LIST_HEAD ( &snp->dev.children );
767 netdev->dev = &snp->dev;
768
769 /* Check if device is insomniac */
770 if ( snpnet_is_insomniac ( device ) )
771 netdev->state |= NETDEV_INSOMNIAC;
772
773 /* Bring to the correct state for a closed interface */
774 if ( ( mode->State == EfiSimpleNetworkStopped ) &&
775 ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
776 rc = -EEFI ( efirc );
777 DBGC ( device, "SNP %s could not start: %s\n",
779 goto err_start;
780 }
781 if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
782 ( ! netdev_insomniac ( netdev ) ) &&
783 ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
784 rc = -EEFI ( efirc );
785 DBGC ( device, "SNP %s could not shut down: %s\n",
787 goto err_shutdown;
788 }
789
790 /* Populate network device parameters */
791 if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
792 DBGC ( device, "SNP %s has invalid hardware address length "
793 "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
794 rc = -ENOTSUP;
795 goto err_hw_addr_len;
796 }
797 memcpy ( netdev->hw_addr, &mode->PermanentAddress,
798 netdev->ll_protocol->hw_addr_len );
799 if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
800 DBGC ( device, "SNP %s has invalid link-layer address length "
801 "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
802 rc = -ENOTSUP;
803 goto err_ll_addr_len;
804 }
805 memcpy ( netdev->ll_addr, &mode->CurrentAddress,
806 netdev->ll_protocol->ll_addr_len );
807 snp->mtu = ( snp->snp->Mode->MaxPacketSize +
808 snp->snp->Mode->MediaHeaderSize );
809
810 /* Register network device */
811 if ( ( rc = register_netdev ( netdev ) ) != 0 )
812 goto err_register_netdev;
813 DBGC ( device, "SNP %s registered as %s\n",
814 efi_handle_name ( device ), netdev->name );
815
816 /* Set initial link state */
817 if ( snp->snp->Mode->MediaPresentSupported ) {
819 } else {
821 }
822
823 return 0;
824
826 err_register_netdev:
827 err_ll_addr_len:
828 err_hw_addr_len:
829 err_shutdown:
830 err_start:
831 list_del ( &snp->dev.siblings );
833 netdev_put ( netdev );
834 err_alloc:
836 err_open_protocol:
837 return rc;
838}
@ EfiSimpleNetworkInitialized
@ EfiSimpleNetworkStopped
struct _EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
Definition efi_driver.h:87
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279
void efi_device_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying device information.
Definition efi_utils.c:189
uint16_t mode
Acceleration mode.
Definition ena.h:15
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
static struct net_device * netdev
Definition gdbudp.c:53
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:474
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
#define DBGC_EFI_OPENERS(...)
Definition efi.h:345
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
#define NETDEV_INSOMNIAC
Network device must be polled even when closed.
Definition netdevice.h:462
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static int netdev_insomniac(struct net_device *netdev)
Check whether or not network device must be polled even while closed.
Definition netdevice.h:707
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static void snpnet_check_link(struct net_device *netdev)
Check link state.
Definition snpnet.c:162
static struct net_device_operations snpnet_operations
SNP network device operations.
Definition snpnet.c:496
UINT32 MediaHeaderSize
The size, in bytes, of the network interface's media header.
BOOLEAN MediaPresentSupported
TRUE if the presence of media can be determined; otherwise FALSE.
UINT32 MaxPacketSize
The maximum size, in bytes, of the packets supported by the network interface.
EFI_SIMPLE_NETWORK_START Start
EFI_SIMPLE_NETWORK_MODE * Mode
Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device.
EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown
struct list_head children
Devices attached to this device.
Definition device.h:87
EFI_HANDLE device
EFI device handle.
Definition efi_driver.h:22
struct device dev
Generic device.
Definition efi_driver.h:20
An object interface.
Definition interface.h:125
A network device.
Definition netdevice.h:353
An SNP NIC.
Definition snpnet.c:47
EFI_SIMPLE_NETWORK_PROTOCOL * snp
Simple network protocol.
Definition snpnet.c:51
struct efi_device * efidev
EFI device.
Definition snpnet.c:49

References alloc_etherdev(), device::children, DBGC, DBGC_EFI_OPENERS, efi_device::dev, efi_device::device, EEFI, efi_close_by_driver(), efi_device_info(), EFI_HANDLE, efi_handle_name(), efi_open_by_driver, efi_simple_network_protocol_guid, snp_nic::efidev, efidev_set_drvdata(), EfiSimpleNetworkInitialized, EfiSimpleNetworkStopped, ENOMEM, ENOTSUP, INIT_LIST_HEAD, list_add, list_del, EFI_SIMPLE_NETWORK_MODE::MaxPacketSize, EFI_SIMPLE_NETWORK_MODE::MediaHeaderSize, EFI_SIMPLE_NETWORK_MODE::MediaPresentSupported, memcpy(), _EFI_SIMPLE_NETWORK_PROTOCOL::Mode, mode, netdev, netdev_init(), NETDEV_INSOMNIAC, netdev_insomniac(), netdev_link_up(), netdev_nullify(), netdev_put(), rc, register_netdev(), _EFI_SIMPLE_NETWORK_PROTOCOL::Shutdown, snp_nic::snp, snpnet_check_link(), snpnet_is_insomniac(), snpnet_operations, _EFI_SIMPLE_NETWORK_PROTOCOL::Start, strerror(), and unregister_netdev().

Referenced by __efi_driver().

◆ snpnet_stop()

void snpnet_stop ( struct efi_device * efidev)
extern

Detach driver from device.

Parameters
efidevEFI device

Definition at line 845 of file snpnet.c.

845 {
846 struct net_device *netdev = efidev_get_drvdata ( efidev );
847 struct snp_nic *snp = netdev->priv;
849 EFI_STATUS efirc;
850 int rc;
851
852 /* Unregister network device */
854
855 /* Stop SNP protocol (unless whole system shutdown is in progress) */
856 if ( ( ! efi_shutdown_in_progress ) &&
857 ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) ) {
858 rc = -EEFI ( efirc );
859 DBGC ( device, "SNP %s could not stop: %s\n",
861 /* Nothing we can do about this */
862 }
863
864 /* Free network device */
865 list_del ( &snp->dev.siblings );
867 netdev_put ( netdev );
868
869 /* Close SNP protocol */
871}
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
Definition efi_driver.h:98
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60
EFI_SIMPLE_NETWORK_STOP Stop

References DBGC, efi_device::device, EEFI, efi_close_by_driver(), EFI_HANDLE, efi_handle_name(), efi_shutdown_in_progress, efi_simple_network_protocol_guid, snp_nic::efidev, efidev_get_drvdata(), list_del, netdev, netdev_nullify(), netdev_put(), rc, snp_nic::snp, _EFI_SIMPLE_NETWORK_PROTOCOL::Stop, strerror(), and unregister_netdev().

Referenced by __efi_driver().