iPXE
Data Structures | Macros | Functions
efi_snp.h File Reference

iPXE EFI SNP interface More...

#include <ipxe/list.h>
#include <ipxe/netdevice.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/SimpleNetwork.h>
#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
#include <ipxe/efi/Protocol/ComponentName2.h>
#include <ipxe/efi/Protocol/DevicePath.h>
#include <ipxe/efi/Protocol/HiiConfigAccess.h>
#include <ipxe/efi/Protocol/HiiDatabase.h>
#include <ipxe/efi/Protocol/LoadFile.h>
#include <ipxe/efi/Protocol/VlanConfig.h>

Go to the source code of this file.

Data Structures

struct  efi_snp_device
 An SNP device. More...
 

Macros

#define EFI_SNP_NUM_TX   32
 SNP transmit completion ring size. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
 FILE_SECBOOT (PERMITTED)
 
int efi_snp_hii_install (struct efi_snp_device *snpdev)
 Install HII protocol and packages for SNP device. More...
 
int efi_snp_hii_uninstall (struct efi_snp_device *snpdev)
 Uninstall HII protocol and package for SNP device. More...
 
struct efi_snp_devicefind_snpdev (EFI_HANDLE handle)
 Find SNP device by EFI device handle. More...
 
struct efi_snp_devicelast_opened_snpdev (void)
 Get most recently opened SNP device. More...
 
void efi_snp_add_claim (int delta)
 Add to SNP claimed/released count. More...
 
static void efi_snp_claim (void)
 Claim network devices for use by iPXE. More...
 
static void efi_snp_release (void)
 Release network devices for use via SNP. More...
 

Detailed Description

iPXE EFI SNP interface

Definition in file efi_snp.h.

Macro Definition Documentation

◆ EFI_SNP_NUM_TX

#define EFI_SNP_NUM_TX   32

SNP transmit completion ring size.

Definition at line 26 of file efi_snp.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ efi_snp_hii_install()

int efi_snp_hii_install ( struct efi_snp_device snpdev)

Install HII protocol and packages for SNP device.

Parameters
snpdevSNP device
Return values
rcReturn status code

Definition at line 659 of file efi_snp_hii.c.

659  {
661  VENDOR_DEVICE_PATH *vendor_path;
662  EFI_DEVICE_PATH_PROTOCOL *path_end;
663  size_t path_prefix_len;
664  int leak = 0;
665  EFI_STATUS efirc;
666  int rc;
667 
668  /* Do nothing if HII database protocol is not supported */
669  if ( ! efihii ) {
670  rc = -ENOTSUP;
671  goto err_no_hii;
672  }
673 
674  /* Initialise HII protocol */
675  memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
676 
677  /* Create HII package list */
678  snpdev->package_list = efi_snp_hii_package_list ( snpdev );
679  if ( ! snpdev->package_list ) {
680  DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
681  snpdev );
682  rc = -ENOMEM;
683  goto err_build_package_list;
684  }
685 
686  /* Allocate the new device path */
687  path_prefix_len = efi_path_len ( snpdev->path );
688  snpdev->hii_child_path = zalloc ( path_prefix_len +
689  sizeof ( *vendor_path ) +
690  sizeof ( *path_end ) );
691  if ( ! snpdev->hii_child_path ) {
692  DBGC ( snpdev,
693  "SNPDEV %p could not allocate HII child device path\n",
694  snpdev );
695  rc = -ENOMEM;
696  goto err_alloc_child_path;
697  }
698 
699  /* Populate the device path */
700  memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
701  vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
702  path_prefix_len );
703  vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
704  vendor_path->Header.SubType = HW_VENDOR_DP;
705  vendor_path->Header.Length[0] = sizeof ( *vendor_path );
706  efi_snp_hii_random_guid ( &vendor_path->Guid );
707  path_end = ( ( void * ) ( vendor_path + 1 ) );
708  efi_path_terminate ( path_end );
709 
710  /* Create device path and child handle for HII association */
711  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
712  &snpdev->hii_child_handle,
714  NULL ) ) != 0 ) {
715  rc = -EEFI ( efirc );
716  DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
717  "%s\n", snpdev, strerror ( rc ) );
718  goto err_hii_child_handle;
719  }
720 
721  /* Add HII packages */
722  if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
723  snpdev->hii_child_handle,
724  &snpdev->hii_handle ) ) != 0 ) {
725  rc = -EEFI ( efirc );
726  DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
727  snpdev, strerror ( rc ) );
728  goto err_new_package_list;
729  }
730 
731  /* Install HII protocol */
732  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
733  &snpdev->hii_child_handle,
735  NULL ) ) != 0 ) {
736  rc = -EEFI ( efirc );
737  DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
738  snpdev, strerror ( rc ) );
739  goto err_install_protocol;
740  }
741 
742  /* Add as child of handle with SNP instance */
743  if ( ( rc = efi_child_add ( snpdev->handle,
744  snpdev->hii_child_handle ) ) != 0 ) {
745  DBGC ( snpdev,
746  "SNPDEV %p could not adopt HII child handle: %s\n",
747  snpdev, strerror ( rc ) );
748  goto err_efi_child_add;
749  }
750 
751  return 0;
752 
753  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
754  err_efi_child_add:
755  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
756  snpdev->hii_child_handle,
758  NULL ) ) != 0 ) {
759  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
760  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
761  leak = 1;
762  }
763  efi_nullify_hii ( &snpdev->hii );
764  err_install_protocol:
765  if ( ! leak )
767  err_new_package_list:
768  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
769  snpdev->hii_child_handle,
771  NULL ) ) != 0 ) {
772  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
773  snpdev, strerror ( -EEFI ( efirc ) ) );
774  leak = 1;
775  }
776  err_hii_child_handle:
777  if ( ! leak ) {
778  free ( snpdev->hii_child_path );
779  snpdev->hii_child_path = NULL;
780  }
781  err_alloc_child_path:
782  if ( ! leak ) {
783  free ( snpdev->package_list );
784  snpdev->package_list = NULL;
785  }
786  err_build_package_list:
787  err_no_hii:
788  return rc;
789 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
Definition: efi_snp_hii.c:114
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:507
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:71
#define DBGC(...)
Definition: compiler.h:505
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2010
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:174
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition: efi_utils.c:111
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:67
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:63
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:37
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:221
#define ENOTSUP
Operation not supported.
Definition: errno.h:590
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:31
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:138
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:71
EFI_GUID Guid
Vendor-assigned GUID that defines the data that follows.
Definition: DevicePath.h:148
#define ENOMEM
Not enough space.
Definition: errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:144
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:65
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:136
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:143
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
EFI Boot Services Table.
Definition: UefiSpec.h:1931
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:344
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2011
static EFI_HII_PACKAGE_LIST_HEADER * efi_snp_hii_package_list(struct efi_snp_device *snpdev)
Build HII package list for SNP device.
Definition: efi_snp_hii.c:164
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:69
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
HII configuration access protocol.
Definition: efi_snp_hii.c:647
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:59
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition: DevicePath.h:54
EFI_HII_DATABASE_NEW_PACK NewPackageList
Definition: HiiDatabase.h:506
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:47
EFI_SYSTEM_TABLE * efi_systab
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:79
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:81

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_add(), efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_path_len(), efi_path_terminate(), efi_snp_device_hii, efi_snp_hii_package_list(), efi_snp_hii_random_guid(), efi_systab, efihii, ENOMEM, ENOTSUP, free, VENDOR_DEVICE_PATH::Guid, efi_snp_device::handle, HARDWARE_DEVICE_PATH, VENDOR_DEVICE_PATH::Header, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, HW_VENDOR_DP, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, EFI_DEVICE_PATH_PROTOCOL::Length, memcpy(), _EFI_HII_DATABASE_PROTOCOL::NewPackageList, NULL, efi_snp_device::package_list, efi_snp_device::path, rc, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and zalloc().

Referenced by efi_snp_probe().

◆ efi_snp_hii_uninstall()

int efi_snp_hii_uninstall ( struct efi_snp_device snpdev)

Uninstall HII protocol and package for SNP device.

Parameters
snpdevSNP device
Return values
leakUninstallation failed: leak memory

Definition at line 797 of file efi_snp_hii.c.

797  {
799  int leak = efi_shutdown_in_progress;
800  EFI_STATUS efirc;
801 
802  /* Do nothing if HII database protocol is not supported */
803  if ( ! efihii )
804  return 0;
805 
806  /* Uninstall protocols and remove package list */
807  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
808  if ( ( ! efi_shutdown_in_progress ) &&
809  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
810  snpdev->hii_child_handle,
812  NULL ) ) != 0 ) ) {
813  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
814  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
815  leak = 1;
816  }
817  efi_nullify_hii ( &snpdev->hii );
818  if ( ! leak )
820  if ( ( ! efi_shutdown_in_progress ) &&
821  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
822  snpdev->hii_child_handle,
824  NULL ) ) != 0 ) ) {
825  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
826  snpdev, strerror ( -EEFI ( efirc ) ) );
827  leak = 1;
828  }
829  if ( ! leak ) {
830  free ( snpdev->hii_child_path );
831  snpdev->hii_child_path = NULL;
832  free ( snpdev->package_list );
833  snpdev->package_list = NULL;
834  }
835 
836  /* Report leakage, if applicable */
837  if ( leak && ( ! efi_shutdown_in_progress ) )
838  DBGC ( snpdev, "SNPDEV %p HII nullified and leaked\n", snpdev );
839  return leak;
840 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:507
#define DBGC(...)
Definition: compiler.h:505
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:67
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:63
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:37
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:221
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:138
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:71
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
EFI Boot Services Table.
Definition: UefiSpec.h:1931
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:344
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2011
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:69
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
EFI_SYSTEM_TABLE * efi_systab
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:60
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:81

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_shutdown_in_progress, efi_systab, efihii, free, efi_snp_device::handle, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, NULL, efi_snp_device::package_list, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), and EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces.

Referenced by efi_snp_probe(), and efi_snp_remove().

◆ find_snpdev()

struct efi_snp_device* find_snpdev ( EFI_HANDLE  handle)

Find SNP device by EFI device handle.

Parameters
handleEFI device handle
Return values
snpdevSNP device, or NULL

Definition at line 2104 of file efi_snp.c.

2104  {
2105  struct efi_snp_device *snpdev;
2106 
2107  list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
2108  if ( snpdev->handle == handle )
2109  return snpdev;
2110  }
2111  return NULL;
2112 }
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:37
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
An SNP device.
Definition: efi_snp.h:29
uint16_t handle
Handle.
Definition: smbios.h:17
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
struct list_head list
List of SNP devices.
Definition: efi_snp.h:31

References handle, efi_snp_device::handle, efi_snp_device::list, list_for_each_entry, and NULL.

Referenced by snpnet_supported().

◆ last_opened_snpdev()

struct efi_snp_device* last_opened_snpdev ( void  )

Get most recently opened SNP device.

Return values
snpdevMost recently opened SNP device, or NULL

Definition at line 2119 of file efi_snp.c.

2119  {
2120  struct net_device *netdev;
2121 
2123  if ( ! netdev )
2124  return NULL;
2125 
2126  return efi_snp_demux ( netdev );
2127 }
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:1048
A network device.
Definition: netdevice.h:353
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1767

References efi_snp_demux(), last_opened_netdev(), netdev, and NULL.

Referenced by efi_image_exec().

◆ efi_snp_add_claim()

void efi_snp_add_claim ( int  delta)

Add to SNP claimed/released count.

Parameters
deltaClaim count change

Definition at line 2134 of file efi_snp.c.

2134  {
2135  struct efi_snp_device *snpdev;
2136 
2137  /* Raise TPL if we are about to claim devices */
2138  if ( ! efi_snp_claimed )
2140 
2141  /* Claim SNP devices */
2142  efi_snp_claimed += delta;
2143  assert ( efi_snp_claimed >= 0 );
2144 
2145  /* Update SNP mode state for each interface */
2146  list_for_each_entry ( snpdev, &efi_snp_devices, list )
2147  efi_snp_set_state ( snpdev );
2148 
2149  /* Restore TPL if we have released devices */
2150  if ( ! efi_snp_claimed )
2152 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:383
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:92
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:49
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition: efi_snp.c:52
An SNP device.
Definition: efi_snp.h:29
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:399
struct list_head list
List of SNP devices.
Definition: efi_snp.h:31

References assert(), efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_saved_tpl, efi_snp_set_state(), efi_snp_device::list, and list_for_each_entry.

Referenced by efi_snp_claim(), and efi_snp_release().

◆ efi_snp_claim()

static void efi_snp_claim ( void  )
inlinestatic

Claim network devices for use by iPXE.

Definition at line 92 of file efi_snp.h.

92  {
93  efi_snp_add_claim ( +1 );
94 }
void efi_snp_add_claim(int delta)
Add to SNP claimed/released count.
Definition: efi_snp.c:2134

References efi_snp_add_claim().

Referenced by _efi_start(), efi_block_boot(), efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_download_start(), efi_image_exec(), efi_pxe_dhcp(), efi_pxe_mtftp(), efi_pxe_udp_open(), and efi_snp_load_file().

◆ efi_snp_release()

static void efi_snp_release ( void  )
inlinestatic

Release network devices for use via SNP.

Definition at line 100 of file efi_snp.h.

100  {
101  efi_snp_add_claim ( -1 );
102 }
void efi_snp_add_claim(int delta)
Add to SNP claimed/released count.
Definition: efi_snp.c:2134

References efi_snp_add_claim().

Referenced by _efi_start(), efi_block_boot(), efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_download_close(), efi_download_start(), efi_image_exec(), efi_pxe_dhcp(), efi_pxe_mtftp(), efi_pxe_udp_close(), and efi_snp_load_file().