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)
 
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 25 of file efi_snp.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ 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 658 of file efi_snp_hii.c.

658  {
660  VENDOR_DEVICE_PATH *vendor_path;
661  EFI_DEVICE_PATH_PROTOCOL *path_end;
662  size_t path_prefix_len;
663  int leak = 0;
664  EFI_STATUS efirc;
665  int rc;
666 
667  /* Do nothing if HII database protocol is not supported */
668  if ( ! efihii ) {
669  rc = -ENOTSUP;
670  goto err_no_hii;
671  }
672 
673  /* Initialise HII protocol */
674  memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
675 
676  /* Create HII package list */
677  snpdev->package_list = efi_snp_hii_package_list ( snpdev );
678  if ( ! snpdev->package_list ) {
679  DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
680  snpdev );
681  rc = -ENOMEM;
682  goto err_build_package_list;
683  }
684 
685  /* Allocate the new device path */
686  path_prefix_len = efi_path_len ( snpdev->path );
687  snpdev->hii_child_path = zalloc ( path_prefix_len +
688  sizeof ( *vendor_path ) +
689  sizeof ( *path_end ) );
690  if ( ! snpdev->hii_child_path ) {
691  DBGC ( snpdev,
692  "SNPDEV %p could not allocate HII child device path\n",
693  snpdev );
694  rc = -ENOMEM;
695  goto err_alloc_child_path;
696  }
697 
698  /* Populate the device path */
699  memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
700  vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
701  path_prefix_len );
702  vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
703  vendor_path->Header.SubType = HW_VENDOR_DP;
704  vendor_path->Header.Length[0] = sizeof ( *vendor_path );
705  efi_snp_hii_random_guid ( &vendor_path->Guid );
706  path_end = ( ( void * ) ( vendor_path + 1 ) );
707  efi_path_terminate ( path_end );
708 
709  /* Create device path and child handle for HII association */
710  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
711  &snpdev->hii_child_handle,
713  NULL ) ) != 0 ) {
714  rc = -EEFI ( efirc );
715  DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
716  "%s\n", snpdev, strerror ( rc ) );
717  goto err_hii_child_handle;
718  }
719 
720  /* Add HII packages */
721  if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
722  snpdev->hii_child_handle,
723  &snpdev->hii_handle ) ) != 0 ) {
724  rc = -EEFI ( efirc );
725  DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
726  snpdev, strerror ( rc ) );
727  goto err_new_package_list;
728  }
729 
730  /* Install HII protocol */
731  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
732  &snpdev->hii_child_handle,
734  NULL ) ) != 0 ) {
735  rc = -EEFI ( efirc );
736  DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
737  snpdev, strerror ( rc ) );
738  goto err_install_protocol;
739  }
740 
741  /* Add as child of handle with SNP instance */
742  if ( ( rc = efi_child_add ( snpdev->handle,
743  snpdev->hii_child_handle ) ) != 0 ) {
744  DBGC ( snpdev,
745  "SNPDEV %p could not adopt HII child handle: %s\n",
746  snpdev, strerror ( rc ) );
747  goto err_efi_child_add;
748  }
749 
750  return 0;
751 
752  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
753  err_efi_child_add:
754  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
755  snpdev->hii_child_handle,
757  NULL ) ) != 0 ) {
758  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
759  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
760  leak = 1;
761  }
762  efi_nullify_hii ( &snpdev->hii );
763  err_install_protocol:
764  if ( ! leak )
766  err_new_package_list:
767  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
768  snpdev->hii_child_handle,
770  NULL ) ) != 0 ) {
771  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
772  snpdev, strerror ( -EEFI ( efirc ) ) );
773  leak = 1;
774  }
775  err_hii_child_handle:
776  if ( ! leak ) {
777  free ( snpdev->hii_child_path );
778  snpdev->hii_child_path = NULL;
779  }
780  err_alloc_child_path:
781  if ( ! leak ) {
782  free ( snpdev->package_list );
783  snpdev->package_list = NULL;
784  }
785  err_build_package_list:
786  err_no_hii:
787  return rc;
788 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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:171
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
Definition: efi_snp_hii.c:113
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:506
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:70
#define DBGC(...)
Definition: compiler.h:505
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1996
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:108
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition: efi_utils.c:122
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:66
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:191
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:70
EFI_GUID Guid
Vendor-assigned GUID that defines the data that follows.
Definition: DevicePath.h:147
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:143
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:135
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:142
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1917
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:343
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
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:163
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:68
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
HII configuration access protocol.
Definition: efi_snp_hii.c:646
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
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:53
EFI_HII_DATABASE_NEW_PACK NewPackageList
Definition: HiiDatabase.h:505
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
EFI_SYSTEM_TABLE * efi_systab
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:78
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

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 796 of file efi_snp_hii.c.

796  {
798  int leak = efi_shutdown_in_progress;
799  EFI_STATUS efirc;
800 
801  /* Do nothing if HII database protocol is not supported */
802  if ( ! efihii )
803  return 0;
804 
805  /* Uninstall protocols and remove package list */
806  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
807  if ( ( ! efi_shutdown_in_progress ) &&
808  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
809  snpdev->hii_child_handle,
811  NULL ) ) != 0 ) ) {
812  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
813  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
814  leak = 1;
815  }
816  efi_nullify_hii ( &snpdev->hii );
817  if ( ! leak )
819  if ( ( ! efi_shutdown_in_progress ) &&
820  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
821  snpdev->hii_child_handle,
823  NULL ) ) != 0 ) ) {
824  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
825  snpdev, strerror ( -EEFI ( efirc ) ) );
826  leak = 1;
827  }
828  if ( ! leak ) {
829  free ( snpdev->hii_child_path );
830  snpdev->hii_child_path = NULL;
831  free ( snpdev->package_list );
832  snpdev->package_list = NULL;
833  }
834 
835  /* Report leakage, if applicable */
836  if ( leak && ( ! efi_shutdown_in_progress ) )
837  DBGC ( snpdev, "SNPDEV %p HII nullified and leaked\n", snpdev );
838  return leak;
839 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:506
#define DBGC(...)
Definition: compiler.h:505
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:66
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:62
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:191
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:70
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI Boot Services Table.
Definition: UefiSpec.h:1917
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:343
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:68
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
EFI_SYSTEM_TABLE * efi_systab
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

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 2118 of file efi_snp.c.

2118  {
2119  struct efi_snp_device *snpdev;
2120 
2121  list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
2122  if ( snpdev->handle == handle )
2123  return snpdev;
2124  }
2125  return NULL;
2126 }
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
An SNP device.
Definition: efi_snp.h:28
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30

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

Referenced by snp_nii_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 2133 of file efi_snp.c.

2133  {
2134  struct net_device *netdev;
2135 
2137  if ( ! netdev )
2138  return NULL;
2139 
2140  return efi_snp_demux ( netdev );
2141 }
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:1047
A network device.
Definition: netdevice.h:352
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1766

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 2148 of file efi_snp.c.

2148  {
2149  struct efi_snp_device *snpdev;
2150 
2151  /* Raise TPL if we are about to claim devices */
2152  if ( ! efi_snp_claimed )
2154 
2155  /* Claim SNP devices */
2156  efi_snp_claimed += delta;
2157  assert ( efi_snp_claimed >= 0 );
2158 
2159  /* Update SNP mode state for each interface */
2160  list_for_each_entry ( snpdev, &efi_snp_devices, list )
2161  efi_snp_set_state ( snpdev );
2162 
2163  /* Restore TPL if we have released devices */
2164  if ( ! efi_snp_claimed )
2166 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
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:431
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition: efi_snp.c:51
An SNP device.
Definition: efi_snp.h:28
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30

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 91 of file efi_snp.h.

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

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 99 of file efi_snp.h.

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

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().