From dcad73ca5ad3e1fe011c52a24036f67ad69fadc1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 22 Mar 2024 15:30:45 +0000 Subject: [efi] Add support for driving EFI_MANAGED_NETWORK_PROTOCOL devices We want exclusive access to the network device, both for performance reasons and because we perform operations such as EAPoL that affect the entire link. We currently drive the network card via either a native hardware driver or via the SNP or NII/UNDI interfaces, both of which grant us this exclusive access. Add an alternative driver that drives the network card non-exclusively via the EFI_MANAGED_NETWORK_PROTOCOL interface. This can function as a fallback for situations where neither SNP nor NII/UNDI interfaces are functional, and also opens up the possibility of non-destructively installing a temporary network device over which to download the autoexec.ipxe script. Signed-off-by: Michael Brown --- src/drivers/net/efi/mnp.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/drivers/net/efi/mnp.c (limited to 'src/drivers/net/efi/mnp.c') diff --git a/src/drivers/net/efi/mnp.c b/src/drivers/net/efi/mnp.c new file mode 100644 index 00000000..b79fe188 --- /dev/null +++ b/src/drivers/net/efi/mnp.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 Michael Brown . + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** @file + * + * MNP driver + * + */ + +#include +#include +#include +#include "snpnet.h" +#include "mnpnet.h" + +/** + * Check to see if driver supports a device + * + * @v device EFI device handle + * @ret rc Return status code + */ +static int mnp_supported ( EFI_HANDLE device ) { + EFI_GUID *binding = &efi_managed_network_service_binding_protocol_guid; + + return snpnet_supported ( device, binding ); +} + +/** EFI MNP driver */ +struct efi_driver mnp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { + .name = "MNP", + .supported = mnp_supported, + .start = mnpnet_start, + .stop = mnpnet_stop, +}; -- cgit v1.2.3-55-g7522 From b66f6025fa50f929c8e6448c383ffec273d41e6c Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 29 Mar 2024 12:58:10 +0000 Subject: [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 --- src/drivers/net/efi/mnp.c | 2 +- src/drivers/net/efi/mnpnet.c | 57 ++++++++++++++++++++++++++++++++++++++++++- src/drivers/net/efi/mnpnet.h | 17 ------------- src/drivers/net/efi/snponly.c | 2 +- src/include/ipxe/efi/mnpnet.h | 20 +++++++++++++++ 5 files changed, 78 insertions(+), 20 deletions(-) delete mode 100644 src/drivers/net/efi/mnpnet.h create mode 100644 src/include/ipxe/efi/mnpnet.h (limited to 'src/drivers/net/efi/mnp.c') diff --git a/src/drivers/net/efi/mnp.c b/src/drivers/net/efi/mnp.c index b79fe188..33218fb1 100644 --- a/src/drivers/net/efi/mnp.c +++ b/src/drivers/net/efi/mnp.c @@ -32,8 +32,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include "snpnet.h" -#include "mnpnet.h" /** * Check to see if driver supports a device 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 #include #include +#include #include -#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 ); +} diff --git a/src/drivers/net/efi/mnpnet.h b/src/drivers/net/efi/mnpnet.h deleted file mode 100644 index afed62aa..00000000 --- a/src/drivers/net/efi/mnpnet.h +++ /dev/null @@ -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 */ diff --git a/src/drivers/net/efi/snponly.c b/src/drivers/net/efi/snponly.c index 6786f3e8..2ae63fc0 100644 --- a/src/drivers/net/efi/snponly.c +++ b/src/drivers/net/efi/snponly.c @@ -29,10 +29,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include #include "snpnet.h" -#include "mnpnet.h" #include "nii.h" /** @file diff --git a/src/include/ipxe/efi/mnpnet.h b/src/include/ipxe/efi/mnpnet.h new file mode 100644 index 00000000..99d6cf08 --- /dev/null +++ b/src/include/ipxe/efi/mnpnet.h @@ -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 */ -- cgit v1.2.3-55-g7522