summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/efi/mnpnet.c
diff options
context:
space:
mode:
authorMichael Brown2024-03-29 13:58:10 +0100
committerMichael Brown2024-03-29 15:46:13 +0100
commitb66f6025fa50f929c8e6448c383ffec273d41e6c (patch)
tree000bc509e9980eab923104c2733827672fe29cd6 /src/drivers/net/efi/mnpnet.c
parent[efi] Allow for allocating EFI devices from arbitrary handles (diff)
downloadipxe-b66f6025fa50f929c8e6448c383ffec273d41e6c.tar.gz
ipxe-b66f6025fa50f929c8e6448c383ffec273d41e6c.tar.xz
ipxe-b66f6025fa50f929c8e6448c383ffec273d41e6c.zip
[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>
Diffstat (limited to 'src/drivers/net/efi/mnpnet.c')
-rw-r--r--src/drivers/net/efi/mnpnet.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/drivers/net/efi/mnpnet.c b/src/drivers/net/efi/mnpnet.c
index a07eae54..84f803f4 100644
--- a/src/drivers/net/efi/mnpnet.c
+++ b/src/drivers/net/efi/mnpnet.c
@@ -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 );
+}