[efi] Add the ability to create a temporary MNP network device

An MNP network device may be temporarily and non-destructively
installed on top of an existing UEFI network stack without having to
disconnect existing drivers.

Add the ability to create such a temporary network device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/1180/head
Michael Brown 2024-03-29 12:58:10 +00:00
parent b52b4a46d9
commit b66f6025fa
5 changed files with 78 additions and 20 deletions

View File

@ -32,8 +32,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <errno.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/mnpnet.h>
#include "snpnet.h"
#include "mnpnet.h"
/**
* Check to see if driver supports a device

View File

@ -38,8 +38,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_service.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/mnpnet.h>
#include <ipxe/efi/Protocol/ManagedNetwork.h>
#include "mnpnet.h"
/** An MNP transmit or receive token */
struct mnp_token {
@ -502,3 +502,58 @@ void mnpnet_stop ( struct efi_device *efidev ) {
netdev_nullify ( netdev );
netdev_put ( netdev );
}
/**
* Create temporary MNP network device
*
* @v handle MNP service binding handle
* @v netdev Network device to fill in
* @ret rc Return status code
*/
int mnptemp_create ( EFI_HANDLE handle, struct net_device **netdev ) {
struct efi_device *efidev;
int rc;
/* Create temporary EFI device */
efidev = efidev_alloc ( handle );
if ( ! efidev ) {
DBGC ( handle, "MNP %s could not create temporary device\n",
efi_handle_name ( handle ) );
rc = -ENOMEM;
goto err_alloc;
}
/* Start temporary network device */
if ( ( rc = mnpnet_start ( efidev ) ) != 0 ) {
DBGC ( handle, "MNP %s could not start MNP: %s\n",
efi_handle_name ( handle ), strerror ( rc ) );
goto err_start;
}
/* Fill in network device */
*netdev = efidev_get_drvdata ( efidev );
return 0;
mnpnet_stop ( efidev );
err_start:
efidev_free ( efidev );
err_alloc:
return rc;
}
/**
* Destroy temporary MNP network device
*
* @v netdev Network device
*/
void mnptemp_destroy ( struct net_device *netdev ) {
struct mnp_nic *mnp = netdev->priv;
struct efi_device *efidev = mnp->efidev;
/* Stop temporary network device */
mnpnet_stop ( efidev );
/* Free temporary EFI device */
efidev_free ( efidev );
}

View File

@ -1,17 +0,0 @@
#ifndef _MNPNET_H
#define _MNPNET_H
/** @file
*
* MNP NIC driver
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct efi_device;
extern int mnpnet_start ( struct efi_device *efidev );
extern void mnpnet_stop ( struct efi_device *efidev );
#endif /* _MNPNET_H */

View File

@ -29,10 +29,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/mnpnet.h>
#include <ipxe/efi/Protocol/SimpleNetwork.h>
#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
#include "snpnet.h"
#include "mnpnet.h"
#include "nii.h"
/** @file

View File

@ -0,0 +1,20 @@
#ifndef _IPXE_EFI_MNPNET_H
#define _IPXE_EFI_MNPNET_H
/** @file
*
* MNP NIC driver
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct efi_device;
struct net_device;
extern int mnpnet_start ( struct efi_device *efidev );
extern void mnpnet_stop ( struct efi_device *efidev );
extern int mnptemp_create ( EFI_HANDLE handle, struct net_device **netdev );
extern void mnptemp_destroy ( struct net_device *netdev );
#endif /* _IPXE_EFI_MNPNET_H */