/*
 * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 NIC driver
 *
 */

#include <string.h>
#include <errno.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/cachedhcp.h>
#include <ipxe/efi/efi.h>
#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>

/** An MNP transmit or receive token */
struct mnp_token {
	/** MNP completion token */
	EFI_MANAGED_NETWORK_COMPLETION_TOKEN token;
	/** Token is owned by MNP */
	int busy;
};

/** An MNP NIC */
struct mnp_nic {
	/** EFI device */
	struct efi_device *efidev;
	/** Managed network protocol */
	EFI_MANAGED_NETWORK_PROTOCOL *mnp;
	/** Generic device */
	struct device dev;

	/** Transmit token */
	struct mnp_token tx;
	/** Transmit descriptor */
	EFI_MANAGED_NETWORK_TRANSMIT_DATA txdata;
	/** Transmit I/O buffer */
	struct io_buffer *txbuf;

	/** Receive token */
	struct mnp_token rx;
};

/**
 * Transmit or receive token event
 *
 * @v event		Event
 * @v context		Event context
 */
static VOID EFIAPI mnpnet_event ( EFI_EVENT event __unused, VOID *context ) {
	struct mnp_token *token = context;

	/* Sanity check */
	assert ( token->busy );

	/* Mark token as no longer owned by MNP */
	token->busy = 0;
}

/**
 * Transmit packet
 *
 * @v netdev		Network device
 * @v iobuf		I/O buffer
 * @ret rc		Return status code
 */
static int mnpnet_transmit ( struct net_device *netdev,
			     struct io_buffer *iobuf ) {
	struct mnp_nic *mnp = netdev->priv;
	struct ll_protocol *ll_protocol = netdev->ll_protocol;
	EFI_STATUS efirc;
	int rc;

	/* Do nothing if shutdown is in progress */
	if ( efi_shutdown_in_progress )
		return -ECANCELED;

	/* Defer the packet if there is already a transmission in progress */
	if ( mnp->txbuf ) {
		netdev_tx_defer ( netdev, iobuf );
		return 0;
	}

	/* Construct transmit token */
	mnp->txdata.DataLength =
		( iob_len ( iobuf ) - ll_protocol->ll_header_len );
	mnp->txdata.HeaderLength = ll_protocol->ll_header_len;
	mnp->txdata.FragmentCount = 1;
	mnp->txdata.FragmentTable[0].FragmentLength = iob_len ( iobuf );
	mnp->txdata.FragmentTable[0].FragmentBuffer = iobuf->data;
	mnp->tx.token.Packet.TxData = &mnp->txdata;

	/* Record as in use */
	mnp->tx.busy = 1;

	/* Transmit packet */
	if ( ( efirc = mnp->mnp->Transmit ( mnp->mnp, &mnp->tx.token ) ) != 0 ){
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not transmit: %s\n",
		       netdev->name, strerror ( rc ) );
		mnp->tx.busy = 0;
		return rc;
	}

	/* Record I/O buffer */
	mnp->txbuf = iobuf;

	return 0;
}

/**
 * Refill receive token
 *
 * @v netdev		Network device
 */
static void mnpnet_refill_rx ( struct net_device *netdev ) {
	struct mnp_nic *mnp = netdev->priv;
	EFI_STATUS efirc;
	int rc;

	/* Do nothing if receive token is still in use */
	if ( mnp->rx.busy )
		return;

	/* Mark as in use */
	mnp->rx.busy = 1;

	/* Queue receive token */
	if ( ( efirc = mnp->mnp->Receive ( mnp->mnp, &mnp->rx.token ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not receive: %s\n",
		       netdev->name, strerror ( rc ) );
		/* Wait for next refill */
		mnp->rx.busy = 0;
		return;
	}
}

/**
 * Poll for completed packets
 *
 * @v netdev		Network device
 */
static void mnpnet_poll_tx ( struct net_device *netdev ) {
	struct mnp_nic *mnp = netdev->priv;
	struct io_buffer *iobuf;
	EFI_STATUS efirc;
	int rc;

	/* Do nothing if transmit token is still in use */
	if ( mnp->tx.busy )
		return;

	/* Do nothing unless we have a completion */
	if ( ! mnp->txbuf )
		return;

	/* Get completion status */
	efirc = mnp->tx.token.Status;
	rc = ( efirc ? -EEFI ( efirc ) : 0 );

	/* Complete transmission */
	iobuf = mnp->txbuf;
	mnp->txbuf = NULL;
	netdev_tx_complete_err ( netdev, iobuf, rc );
}

/**
 * Poll for received packets
 *
 * @v netdev		Network device
 */
static void mnpnet_poll_rx ( struct net_device *netdev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	struct mnp_nic *mnp = netdev->priv;
	EFI_MANAGED_NETWORK_RECEIVE_DATA *rxdata;
	struct io_buffer *iobuf;
	size_t len;
	EFI_STATUS efirc;
	int rc;

	/* Do nothing unless we have a completion */
	if ( mnp->rx.busy )
		return;
	rxdata = mnp->rx.token.Packet.RxData;

	/* Get completion status */
	if ( ( efirc = mnp->rx.token.Status ) != 0 ) {
		rc = -EEFI ( efirc );
		netdev_rx_err ( netdev, NULL, rc );
		goto recycle;
	}

	/* Allocate and fill I/O buffer */
	len = rxdata->PacketLength;
	iobuf = alloc_iob ( len );
	if ( ! iobuf ) {
		netdev_rx_err ( netdev, NULL, -ENOMEM );
		goto recycle;
	}
	memcpy ( iob_put ( iobuf, len ), rxdata->MediaHeader, len );

	/* Hand off to network stack */
	netdev_rx ( netdev, iobuf );

 recycle:
	/* Recycle token */
	bs->SignalEvent ( rxdata->RecycleEvent );
}

/**
 * Poll for completed packets
 *
 * @v netdev		Network device
 */
static void mnpnet_poll ( struct net_device *netdev ) {
	struct mnp_nic *mnp = netdev->priv;

	/* Do nothing if shutdown is in progress */
	if ( efi_shutdown_in_progress )
		return;

	/* Poll interface */
	mnp->mnp->Poll ( mnp->mnp );

	/* Process any transmit completions */
	mnpnet_poll_tx ( netdev );

	/* Process any receive completions */
	mnpnet_poll_rx ( netdev );

	/* Refill receive token */
	mnpnet_refill_rx ( netdev );
}

/**
 * Open network device
 *
 * @v netdev		Network device
 * @ret rc		Return status code
 */
static int mnpnet_open ( struct net_device *netdev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	static EFI_MANAGED_NETWORK_CONFIG_DATA config = {
		.EnableUnicastReceive = TRUE,
		.EnableMulticastReceive = TRUE,
		.EnableBroadcastReceive = TRUE,
		.EnablePromiscuousReceive = TRUE,
		.FlushQueuesOnReset = TRUE,
		.DisableBackgroundPolling = TRUE,
	};
	struct mnp_nic *mnp = netdev->priv;
	EFI_STATUS efirc;
	int rc;

	/* Create transmit event */
	if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
					 mnpnet_event, &mnp->tx,
					 &mnp->tx.token.Event ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not create TX event: %s\n",
		       netdev->name, strerror ( rc ) );
		goto err_tx_event;
	}

	/* Create receive event */
	if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
					 mnpnet_event, &mnp->rx,
					 &mnp->rx.token.Event ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not create RX event: %s\n",
		       netdev->name, strerror ( rc ) );
		goto err_rx_event;
	}

	/* Configure MNP */
	if ( ( efirc = mnp->mnp->Configure ( mnp->mnp, &config ) ) != 0 ) {
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not configure: %s\n",
		       netdev->name, strerror ( rc ) );
		goto err_configure;
	}

	/* Refill receive token */
	mnpnet_refill_rx ( netdev );

	return 0;

	mnp->mnp->Configure ( mnp->mnp, NULL );
 err_configure:
	bs->CloseEvent ( mnp->rx.token.Event );
 err_rx_event:
	bs->CloseEvent ( mnp->tx.token.Event );
 err_tx_event:
	return rc;
}

/**
 * Close network device
 *
 * @v netdev		Network device
 */
static void mnpnet_close ( struct net_device *netdev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	struct mnp_nic *mnp = netdev->priv;

	/* Reset MNP (unless whole system shutdown is in progress) */
	if ( ! efi_shutdown_in_progress )
		mnp->mnp->Configure ( mnp->mnp, NULL );

	/* Close events */
	bs->CloseEvent ( mnp->rx.token.Event );
	bs->CloseEvent ( mnp->tx.token.Event );

	/* Reset tokens */
	mnp->tx.busy = 0;
	mnp->rx.busy = 0;

	/* Discard any incomplete I/O buffer */
	if ( mnp->txbuf ) {
		netdev_tx_complete_err ( netdev, mnp->txbuf, -ECANCELED );
		mnp->txbuf = NULL;
	}
}

/** MNP network device operations */
static struct net_device_operations mnpnet_operations = {
	.open = mnpnet_open,
	.close = mnpnet_close,
	.transmit = mnpnet_transmit,
	.poll = mnpnet_poll,
};

/**
 * Attach driver to device
 *
 * @v efidev		EFI device
 * @ret rc		Return status code
 */
int mnpnet_start ( struct efi_device *efidev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_HANDLE device = efidev->device;
	EFI_GUID *binding = &efi_managed_network_service_binding_protocol_guid;
	EFI_SIMPLE_NETWORK_MODE mode;
	union {
		EFI_MANAGED_NETWORK_PROTOCOL *mnp;
		void *interface;
	} u;
	struct net_device *netdev;
	struct mnp_nic *mnp;
	EFI_STATUS efirc;
	int rc;

	/* Allocate and initalise structure */
	netdev = alloc_etherdev ( sizeof ( *mnp ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &mnpnet_operations );
	mnp = netdev->priv;
	mnp->efidev = efidev;
	efidev_set_drvdata ( efidev, netdev );

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

	/* Create MNP child */
	if ( ( rc = efi_service_add ( device, binding,
				      &efidev->child ) ) != 0 ) {
		DBGC ( mnp, "MNP %s could not create child: %s\n",
		       efi_handle_name ( device ), strerror ( rc ) );
		goto err_service;
	}

	/* Open MNP protocol */
	if ( ( efirc = bs->OpenProtocol ( efidev->child,
					  &efi_managed_network_protocol_guid,
					  &u.interface, efi_image_handle,
					  efidev->child,
					  ( EFI_OPEN_PROTOCOL_BY_DRIVER |
					    EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not open MNP protocol: %s\n",
		       efi_handle_name ( device ), strerror ( rc ) );
		goto err_open;
	}
	mnp->mnp = u.mnp;

	/* Get configuration */
	efirc = mnp->mnp->GetModeData ( mnp->mnp, NULL, &mode );
	if ( ( efirc != 0 ) && ( efirc != EFI_NOT_STARTED ) ) {
		rc = -EEFI ( efirc );
		DBGC ( mnp, "MNP %s could not get mode data: %s\n",
		       efi_handle_name ( device ), strerror ( rc ) );
		goto err_mode;
	}

	/* Populate network device parameters */
	if ( mode.HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
		DBGC ( device, "MNP %s has invalid hardware address length "
		       "%d\n", efi_handle_name ( device ), mode.HwAddressSize );
		rc = -ENOTSUP;
		goto err_hw_addr_len;
	}
	memcpy ( netdev->hw_addr, &mode.PermanentAddress,
		 netdev->ll_protocol->hw_addr_len );
	if ( mode.HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
		DBGC ( device, "MNP %s has invalid link-layer address length "
		       "%d\n", efi_handle_name ( device ), mode.HwAddressSize );
		rc = -ENOTSUP;
		goto err_ll_addr_len;
	}
	memcpy ( netdev->ll_addr, &mode.CurrentAddress,
		 netdev->ll_protocol->ll_addr_len );

	/* Register network device */
	if ( ( rc = register_netdev ( netdev ) ) != 0 )
		goto err_register;
	DBGC ( mnp, "MNP %s registered as %s\n",
	       efi_handle_name ( device ), netdev->name );

	/* Mark as link up: we don't handle link state */
	netdev_link_up ( netdev );

	return 0;

	unregister_netdev ( netdev );
 err_register:
 err_ll_addr_len:
 err_hw_addr_len:
 err_mode:
	bs->CloseProtocol ( efidev->child, &efi_managed_network_protocol_guid,
			    efi_image_handle, efidev->child );
 err_open:
	efi_service_del ( device, binding, efidev->child );
 err_service:
	list_del ( &mnp->dev.siblings );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc:
	return rc;
}

/**
 * Detach driver from device
 *
 * @v efidev		EFI device
  */
void mnpnet_stop ( struct efi_device *efidev ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_GUID *binding = &efi_managed_network_service_binding_protocol_guid;
	struct net_device *netdev = efidev_get_drvdata ( efidev );
	struct mnp_nic *mnp = netdev->priv;

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

	/* Close MNP protocol */
	bs->CloseProtocol ( efidev->child, &efi_managed_network_protocol_guid,
			    efi_image_handle, efidev->child );

	/* Remove MNP child (unless whole system shutdown is in progress) */
	if ( ! efi_shutdown_in_progress )
		efi_service_del ( efidev->device, binding, efidev->child );

	/* Free network device */
	list_del ( &mnp->dev.siblings );
	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;

	/* Recycle any cached DHCP packet */
	cachedhcp_recycle ( netdev );

	/* Stop temporary network device */
	mnpnet_stop ( efidev );

	/* Free temporary EFI device */
	efidev_free ( efidev );
}
