iPXE
Data Structures | Defines | 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>

Go to the source code of this file.

Data Structures

struct  efi_snp_device
 An SNP device. More...

Defines

#define EFI_SNP_NUM_TX   32
 SNP transmit completion ring size.

Functions

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

Detailed Description

iPXE EFI SNP interface

Definition in file efi_snp.h.


Define Documentation

#define EFI_SNP_NUM_TX   32

SNP transmit completion ring size.

Definition at line 24 of file efi_snp.h.

Referenced by efi_snp_get_status(), and efi_snp_transmit().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER  )
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 655 of file efi_snp_hii.c.

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_add(), efi_child_del(), efi_device_path_protocol_guid, efi_devpath_len(), efi_hii_config_access_protocol_guid, efi_snp_hii_package_list(), efi_snp_hii_random_guid(), efi_systab, END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, 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_BOOT_SERVICES *bs = efi_systab->BootServices;
        VENDOR_DEVICE_PATH *vendor_path;
        EFI_DEVICE_PATH_PROTOCOL *path_end;
        size_t path_prefix_len;
        int efirc;
        int rc;

        /* Do nothing if HII database protocol is not supported */
        if ( ! efihii ) {
                rc = -ENOTSUP;
                goto err_no_hii;
        }

        /* Initialise HII protocol */
        memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );

        /* Create HII package list */
        snpdev->package_list = efi_snp_hii_package_list ( snpdev );
        if ( ! snpdev->package_list ) {
                DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
                       snpdev );
                rc = -ENOMEM;
                goto err_build_package_list;
        }

        /* Allocate the new device path */
        path_prefix_len = efi_devpath_len ( snpdev->path );
        snpdev->hii_child_path = zalloc ( path_prefix_len +
                                          sizeof ( *vendor_path ) +
                                          sizeof ( *path_end ) );
        if ( ! snpdev->hii_child_path ) {
                DBGC ( snpdev,
                       "SNPDEV %p could not allocate HII child device path\n",
                       snpdev );
                rc = -ENOMEM;
                goto err_alloc_child_path;
        }

        /* Populate the device path */
        memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
        vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
                        path_prefix_len );
        vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
        vendor_path->Header.SubType = HW_VENDOR_DP;
        vendor_path->Header.Length[0] = sizeof ( *vendor_path );
        efi_snp_hii_random_guid ( &vendor_path->Guid );
        path_end = ( ( void * ) ( vendor_path + 1 ) );
        path_end->Type = END_DEVICE_PATH_TYPE;
        path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
        path_end->Length[0] = sizeof ( *path_end );

        /* Create device path and child handle for HII association */
        if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
                        &snpdev->hii_child_handle,
                        &efi_device_path_protocol_guid, snpdev->hii_child_path,
                        NULL ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
                       "%s\n", snpdev, strerror ( rc ) );
                goto err_hii_child_handle;
        }

        /* Add HII packages */
        if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
                                                snpdev->hii_child_handle,
                                                &snpdev->hii_handle ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
                       snpdev, strerror ( rc ) );
                goto err_new_package_list;
        }

        /* Install HII protocol */
        if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
                         &snpdev->hii_child_handle,
                         &efi_hii_config_access_protocol_guid, &snpdev->hii,
                         NULL ) ) != 0 ) {
                rc = -EEFI ( efirc );
                DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
                       snpdev, strerror ( rc ) );
                goto err_install_protocol;
        }

        /* Add as child of handle with SNP instance */
        if ( ( rc = efi_child_add ( snpdev->handle,
                                    snpdev->hii_child_handle ) ) != 0 ) {
                DBGC ( snpdev,
                       "SNPDEV %p could not adopt HII child handle: %s\n",
                       snpdev, strerror ( rc ) );
                goto err_efi_child_add;
        }

        return 0;

        efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
 err_efi_child_add:
        bs->UninstallMultipleProtocolInterfaces (
                        snpdev->hii_child_handle,
                        &efi_hii_config_access_protocol_guid, &snpdev->hii,
                        NULL );
 err_install_protocol:
        efihii->RemovePackageList ( efihii, snpdev->hii_handle );
 err_new_package_list:
        bs->UninstallMultipleProtocolInterfaces (
                        snpdev->hii_child_handle,
                        &efi_device_path_protocol_guid, snpdev->hii_child_path,
                        NULL );
 err_hii_child_handle:
        free ( snpdev->hii_child_path );
        snpdev->hii_child_path = NULL;
 err_alloc_child_path:
        free ( snpdev->package_list );
        snpdev->package_list = NULL;
 err_build_package_list:
 err_no_hii:
        return rc;
}
void efi_snp_hii_uninstall ( struct efi_snp_device snpdev)
struct efi_snp_device* find_snpdev ( EFI_HANDLE  handle) [read]

Find SNP device by EFI device handle.

Parameters:
handleEFI device handle
Return values:
snpdevSNP device, or NULL

Definition at line 1939 of file efi_snp.c.

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

Referenced by nii_supported(), and snp_supported().

                                                          {
        struct efi_snp_device *snpdev;

        list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
                if ( snpdev->handle == handle )
                        return snpdev;
        }
        return NULL;
}
struct efi_snp_device* last_opened_snpdev ( void  ) [read]

Get most recently opened SNP device.

Return values:
snpdevMost recently opened SNP device, or NULL

Definition at line 1954 of file efi_snp.c.

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

Referenced by efi_block_hook(), and efi_image_exec().

                                                    {
        struct net_device *netdev;

        netdev = last_opened_netdev();
        if ( ! netdev )
                return NULL;

        return efi_snp_demux ( netdev );
}
void efi_snp_add_claim ( int  delta)

Add to SNP claimed/released count.

Parameters:
deltaClaim count change

Definition at line 1969 of file efi_snp.c.

References assert, EFI_SYSTEM_TABLE::BootServices, efi_snp_claimed, efi_snp_old_tpl, efi_snp_set_state(), efi_systab, efi_snp_device::list, list_for_each_entry, EFI_BOOT_SERVICES::RaiseTPL, EFI_BOOT_SERVICES::RestoreTPL, and TPL_CALLBACK.

Referenced by efi_snp_claim(), and efi_snp_release().

                                     {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct efi_snp_device *snpdev;

        /* Raise TPL if we are about to claim devices */
        if ( ! efi_snp_claimed )
                efi_snp_old_tpl = bs->RaiseTPL ( TPL_CALLBACK );

        /* Claim SNP devices */
        efi_snp_claimed += delta;
        assert ( efi_snp_claimed >= 0 );

        /* Update SNP mode state for each interface */
        list_for_each_entry ( snpdev, &efi_snp_devices, list )
                efi_snp_set_state ( snpdev );

        /* Restore TPL if we have released devices */
        if ( ! efi_snp_claimed )
                bs->RestoreTPL ( efi_snp_old_tpl );
}
static void efi_snp_claim ( void  ) [inline, static]
static void efi_snp_release ( void  ) [inline, static]