iPXE
Functions
nii.h File Reference

NII driver. More...

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int nii_start (struct efi_device *efidev)
 Attach driver to device.
void nii_stop (struct efi_device *efidev)
 Detach driver from device.

Detailed Description

NII driver.

Definition in file nii.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int nii_start ( struct efi_device efidev)

Attach driver to device.

Parameters:
efidevEFI device
Return values:
rcReturn status code

Definition at line 1210 of file nii.c.

References alloc_netdev(), EFI_SYSTEM_TABLE::BootServices, nii_nic::broadcast, device::children, EFI_BOOT_SERVICES::CloseProtocol, DBGC, DBGC_EFI_OPENERS, efi_device::dev, nii_nic::dev, net_device::dev, efi_device::device, device::driver_name, EEFI, efi_device_info(), efi_handle_name(), efi_image_handle, efi_nii31_protocol_guid, EFI_OPEN_PROTOCOL_BY_DRIVER, EFI_OPEN_PROTOCOL_EXCLUSIVE, efi_systab, nii_nic::efidev, efidev_set_drvdata(), ENODEV, ENOMEM, ENOTSUP, s_pxe_sw_undi::EntryPoint, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::Id, s_pxe_sw_undi::Implementation, INIT_LIST_HEAD, nii_nic::issue, list_add, list_del, net_device::ll_broadcast, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::MajorVer, nii_nic::mappings, nii_nic::media, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::MinorVer, device::name, net_device::name, netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), nii_nic::nii, nii_get_init_info(), nii_get_station_address(), nii_pci_close(), nii_pci_open(), nii_start_undi(), nii_stop_undi(), EFI_BOOT_SERVICES::OpenProtocol, device::parent, net_device::priv, PXE_ROMID_IMP_HW_UNDI, PXE_ROMID_IMP_SW_VIRT_ADDR, rc, register_netdev(), device::siblings, strerror(), nii_nic::undi, and unregister_netdev().

                                            {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        EFI_HANDLE device = efidev->device;
        struct net_device *netdev;
        struct nii_nic *nii;
        void *interface;
        EFI_STATUS efirc;
        int rc;

        /* Allocate and initialise structure */
        netdev = alloc_netdev ( sizeof ( *nii ) );
        if ( ! netdev ) {
                rc = -ENOMEM;
                goto err_alloc;
        }
        netdev_init ( netdev, &nii_operations );
        nii = netdev->priv;
        nii->efidev = efidev;
        INIT_LIST_HEAD ( &nii->mappings );
        netdev->ll_broadcast = nii->broadcast;
        efidev_set_drvdata ( efidev, netdev );

        /* Populate underlying device information */
        efi_device_info ( device, "NII", &nii->dev );
        nii->dev.driver_name = "NII";
        nii->dev.parent = &efidev->dev;
        list_add ( &nii->dev.siblings, &efidev->dev.children );
        INIT_LIST_HEAD ( &nii->dev.children );
        netdev->dev = &nii->dev;

        /* Open NII protocol */
        if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
                                          &interface, efi_image_handle, device,
                                          ( EFI_OPEN_PROTOCOL_BY_DRIVER |
                                            EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
                rc = -EEFI ( efirc );
                DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
                       nii->dev.name, strerror ( rc ) );
                DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
                goto err_open_protocol;
        }
        nii->nii = interface;

        /* Locate UNDI and entry point */
        nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
        if ( ! nii->undi ) {
                DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
                rc = -ENODEV;
                goto err_no_undi;
        }
        if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
                DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
                       nii->dev.name );
                rc = -ENOTSUP;
                goto err_hw_undi;
        }
        if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
                nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
        } else {
                nii->issue = ( ( ( void * ) nii->undi ) +
                               nii->undi->EntryPoint );
        }
        DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
               nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
               nii->undi, nii->issue, nii->undi->Implementation );

        /* Open PCI I/O protocols and locate BARs */
        if ( ( rc = nii_pci_open ( nii ) ) != 0 )
                goto err_pci_open;

        /* Start UNDI */
        if ( ( rc = nii_start_undi ( nii ) ) != 0 )
                goto err_start_undi;

        /* Get initialisation information */
        if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
                goto err_get_init_info;

        /* Get MAC addresses */
        if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
                goto err_get_station_address;

        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
                goto err_register_netdev;
        DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
               netdev->name, efi_handle_name ( device ) );

        /* Set initial link state (if media detection is not supported) */
        if ( ! nii->media )
                netdev_link_up ( netdev );

        return 0;

        unregister_netdev ( netdev );
 err_register_netdev:
 err_get_station_address:
 err_get_init_info:
        nii_stop_undi ( nii );
 err_start_undi:
        nii_pci_close ( nii );
 err_pci_open:
 err_hw_undi:
 err_no_undi:
        bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
                            efi_image_handle, device );
 err_open_protocol:
        list_del ( &nii->dev.siblings );
        netdev_nullify ( netdev );
        netdev_put ( netdev );
 err_alloc:
        return rc;
}
void nii_stop ( struct efi_device efidev)

Detach driver from device.

Parameters:
efidevEFI device

Definition at line 1329 of file nii.c.

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, nii_nic::dev, efi_device::device, efi_image_handle, efi_nii31_protocol_guid, efi_systab, efidev_get_drvdata(), list_del, netdev, netdev_nullify(), netdev_put(), nii_nic::nii, nii_pci_close(), nii_stop_undi(), net_device::priv, device::siblings, and unregister_netdev().

                                            {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct net_device *netdev = efidev_get_drvdata ( efidev );
        struct nii_nic *nii = netdev->priv;
        EFI_HANDLE device = efidev->device;

        /* Unregister network device */
        unregister_netdev ( netdev );

        /* Stop UNDI */
        nii_stop_undi ( nii );

        /* Close PCI I/O protocols */
        nii_pci_close ( nii );

        /* Close NII protocol */
        bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
                            efi_image_handle, device );

        /* Free network device */
        list_del ( &nii->dev.siblings );
        netdev_nullify ( netdev );
        netdev_put ( netdev );
}