#pragma once
#include <array>
#include <cheri.hh>
#include <cstddef>
#include <cstdint>
#include <debug.hh>
#include <futex.h>
#include <interrupt.h>
#include <optional>
#include <platform/concepts/ethernet.hh>
#include <thread.h>
#include <type_traits>

DECLARE_AND_DEFINE_INTERRUPT_CAPABILITY(EthernetReceive,
                                        EthernetReceiveInterrupt,
                                        true,
                                        true);

/**
 * The driver for Kunyan Liu's custom Ethernet MAC for the Arty A7.  This is
 * intended to run at 10Mb/s.  It provides two send and two receive buffers in
 * shared SRAM.
 *
 * WARNING: This is currently evolving and is not yet stable.
 */
class KunyanEthernet
{
	/**
	 * Flag set when we're debugging this driver.
	 */
	static constexpr bool DebugEthernet = false;

	/**
	 * Flag set to log messages when frames are dropped.
	 */
	static constexpr bool DebugDroppedFrames = false;

	/**
	 * Helper for conditional debug logs and assertions.
	 */
	using Debug = ConditionalDebug<DebugEthernet, "Ethernet driver">;

	/**
	 * Import the Capability helper from the CHERI namespace.
	 */
	template<typename T>
	using Capability = CHERI::Capability<T>;

	/**
	 * The location of registers
	 */
	enum class RegisterOffset : size_t
	{
		/**
		 * MAC control register.  Higher bits control filtering modes:
		 *
		 * 12: Drop frames with invalid CRC.
		 * 11: Allow incoming IPv6 multicast filtering
		 * 10: Allow incoming IPv4 multicast filtering
		 * 9: Allow incoming broadcast filtering
		 * 8: Allow incoming unicast filtering
		 *
		 *
		 * Write a 1 to reset the PHY.  This takes 167 ms.
		 */
		MACControl = 0,
		/**
		 * High 4 bytes of the MAC address.  Byte 2 is in bits 31:24, byte 5 is
		 * in 7:0.
		 */
		MACAddressHigh = 4,
		/**
		 * Low 2 bytes of the MAC address.  Byte 1 in bits 15:8, byte 0 in 7:0.
		 */
		MACAddressLow = 8,
		/**
		 * Scratch register, unused.
		 */
		Scratch = 12,
		/**
		 * MDIO address, controls which PHY register will be read or written.
		 */
		MDIOAddress = 0x10,
		/**
		 * MDIO Write, written to set the value to write to a PHY register.
		 */
		MDIODataWrite = 0x14,
		/**
		 * MDIO Read, set by the device to the value of a PHY register in
		 * response to an MDIO read.
		 */
		MDIODataRead = 0x18,
		/**
		 * MDIO control.  Used to control and report status of MDIO
		 * transactions.
		 */
		MDIOControl = 0x1c,
		/**
		 * Length of the frame written to the ping buffer for sending.
		 */
		TransmitFrameLengthPing = 0x20,
		/**
		 * Transmit control for the ping buffer.
		 */
		TransmitControlPing = 0x24,
		/**
		 * Length of the frame written to the pong buffer for sending.
		 */
		TransmitFrameLengthPong = 0x28,
		/**
		 * Transmit control for the pong buffer.
		 */
		TransmitControlPong = 0x2c,
		/**
		 * Receive control for the ping buffer.
		 */
		ReceiveControlPing = 0x30,
		/**
		 * Receive control for the pong buffer.
		 */
		ReceiveControlPong = 0x34,
		/**
		 * Interrupt enable.  Write 1 to enable, 0 to disable interrupts for
		 * each direction.  Bit 0 is transmit, bit 1 is receive.
		 */
		GlobalInterruptEnable = 0x38,
		/**
		 * Current interrupt status.  Bit 0 is transmit, bit 1 is receive.
		 *
		 * Write a 1 to each bit to clear.  The device will keep the interrupt
		 * asserted until it is explicitly cleared.
		 */
		InterruptStatus = 0x3c,
		/**
		 * Length of the frames in the ping and pong buffer, in the low and
		 * high 16 bits respectively.
		 */
		ReceiveFrameLength = 0x40,
		/**
		 * Saturating counter of the number of frames received.
		 */
		ReceivedFramesCount = 0x44,
		/**
		 * Saturating counter of the number of frames passed to software.
		 */
		ReceivedFramesPassedToSoftware = 0x48,
		/**
		 * Saturating counter of the number of frames dropped because the
		 * receive buffers were both full.
		 */
		ReceiveDroppedFramesBuffersFull = 0x4c,
		/**
		 * Saturating counter of the number of frames dropped because they had
		 * failed FCS checks.
		 */
		ReceiveDroppedFramesFCSFailed = 0x50,
		/**
		 * Saturating counter of the number of frames dropped because the
		 * target address was invalid.
		 */
		ReceiveDroppedFramesInvalidAddress = 0x54,
	};

	using MACAddress = std::array<uint8_t, 6>;

	/**
	 * MAC filtering modes.
	 */
	enum class FilterMode : uint32_t
	{
		/**
		 * Allow incoming frames without doing any address filtering.
		 */
		EnableAddressFiltering = 1 << 13,
		/**
		 * Drop frames with invalid CRC.
		 */
		DropInvalidCRC = 1 << 12,
		/**
		 * Allow incoming IPv6 multicast filtering
		 */
		AllowIPv6Multicast = 1 << 11,
		/**
		 * Allow incoming IPv4 multicast filtering
		 */
		AllowIPv4Multicast = 1 << 10,
		/**
		 * Allow incoming broadcast filtering
		 */
		AllowBroadcast = 1 << 9,
		/**
		 * Allow incoming unicast filtering
		 */
		AllowUnicast = 1 << 8,
	};

	/**
	 * The futex used to wait for interrupts when packets are available to
	 * receive.
	 */
	const uint32_t *receiveInterruptFutex;

	/**
	 * Counter for dropped frames, intended to be extensible to support
	 * different debugging registers.
	 */
	struct DroppedFrameCount
	{
		/**
		 * The old value of the counter.
		 */
		uint32_t droppedFrameCount[3];
		/**
		 * Get a reference to one of the recorded counters.
		 */
		template<RegisterOffset Reg>
		uint32_t &get();
		template<>
		uint32_t &get<RegisterOffset::ReceiveDroppedFramesBuffersFull>()
		{
			return droppedFrameCount[0];
		}

		template<>
		uint32_t &get<RegisterOffset::ReceiveDroppedFramesFCSFailed>()
		{
			return droppedFrameCount[1];
		}

		template<>
		uint32_t &get<RegisterOffset::ReceiveDroppedFramesInvalidAddress>()
		{
			return droppedFrameCount[2];
		}
	};

	/**
	 * Empty class, for use with `std::conditional_t` to conditionally add a
	 * field.
	 */
	struct Empty
	{
	};

	/**
	 * If we're building with debugging support for dropped-frame counters,
	 * reserve space for them.
	 */
	[[no_unique_address]] std::
	  conditional_t<DebugDroppedFrames, DroppedFrameCount, Empty>
	    droppedFrames;

	/**
	 * Log a message if the dropped-frame counter identified by `Reg` has
	 * changed.
	 */
	template<RegisterOffset Reg, typename T = decltype(droppedFrames)>
	void dropped_frames_log_if_changed(T &droppedFrames)
	{
		if constexpr (std::is_same_v<T, DroppedFrameCount>)
		{
			auto &lastCount = droppedFrames.template get<Reg>();
			auto  count     = mmio_register<Reg>();
			if (count != lastCount)
			{
				ConditionalDebug<true, "Ethernet driver">::log(
				  "Dropped frames in counter {}: {}", Reg, count);
				lastCount = count;
			}
		}
	}

	/**
	 * Set the state of one of the MAC filtering modes.  Returns the previous
	 * value of the mode.
	 */
	bool filter_mode_update(FilterMode mode, bool enable)
	{
		auto    &macControl = mmio_register<RegisterOffset::MACControl>();
		uint32_t modeBit    = static_cast<uint32_t>(mode);
		uint32_t oldMode    = macControl;
		Debug::log("Old filter mode {}: {}", mode, oldMode);
		if (enable)
		{
			macControl = oldMode | modeBit;
		}
		else
		{
			macControl = oldMode & ~modeBit;
		}
		return oldMode | modeBit;
	}

	/**
	 * The PHY registers are accessed through the MDIO interface.
	 */
	enum class PHYRegister
	{
		BasicControlRegister              = 0,
		BasicStatusRegister               = 1,
		Identifier1                       = 2,
		Identifier2                       = 3,
		AutoNegotiationAdvertisement      = 4,
		AutoNegotiationLinkPartnerAbility = 5,
	};

	enum BufferID
	{
		Ping = 0,
		Pong = 1,
	};

	bool receiveBufferInUse[2] = {false, false};
	bool sendBufferInUse[2]    = {false, false};

	BufferID nextReceiveBuffer = BufferID::Ping;

	constexpr static BufferID next_buffer_id(BufferID current)
	{
		return current == BufferID::Ping ? BufferID::Pong : BufferID::Ping;
	}

	/**
	 * Reset the PHY.  This must be done on initialisation.
	 */
	void phy_reset()
	{
		auto &macControl = mmio_register<RegisterOffset::MACControl>();
		macControl       = 1;
		// Wait for the PHY to reset.
		thread_millisecond_wait(167);
		// Initialise MDIO again after the PHY has been reset.
		mmio_register<RegisterOffset::MDIOControl>() = 0x10;
		// Wait to make sure MDIO initialisation has completed.
		thread_microsecond_spin(1);
	}

	/**
	 * Helper.  Returns a pointer to the device.
	 */
	[[nodiscard]] __always_inline Capability<volatile uint32_t>
	                              mmio_region() const
	{
		return MMIO_CAPABILITY(uint32_t, kunyan_ethernet);
	}

	/**
	 * Helper.  Returns a reference to a register in this device's MMIO region.
	 * The register is identified by a `RegisterOffset` value.
	 */
	template<RegisterOffset Offset>
	[[nodiscard]] volatile uint32_t &mmio_register() const
	{
		auto reg = mmio_region();
		reg.address() += static_cast<size_t>(Offset);
		reg.bounds() = sizeof(uint32_t);
		return *reg;
	}

	/**
	 * Poll the MDIO control register until a transaction is done.
	 *
	 * NOTE: This does no error handling.  It can infinite loop if the device
	 * is broken.  Normally, MDIO operations complete in fewer cycles than it
	 * takes to call this method and so it will return almost instantly.
	 */
	void mdio_wait_for_ready()
	{
		auto &mdioControl = mmio_register<RegisterOffset::MDIOControl>();
		while (mdioControl & 1) {}
	}

	/**
	 * Start an MDIO transaction.  This assumes that the MDIO control register
	 * and, for write operations, the MDIO data write register have been set up.
	 * A call to `mdio_wait_for_ready` is required for read transactions to
	 * ensure that the operation has completed before reading the MIDO data read
	 * register.
	 */
	void mdio_start_transaction()
	{
		auto &mdioControl = mmio_register<RegisterOffset::MDIOControl>();
		Debug::Assert(((mdioControl & ((1 << 3) | 1)) == 0), "MDIO is busy");
		// Write the MDIO enable bit and the start bit.
		mdioControl = (1 << 3) | 1;
	}

	/**
	 * Returns a pointer to one of the receive buffers, identified by the buffer
	 * identifier (ping or pong).
	 */
	uint8_t *receive_buffer_pointer(BufferID index = BufferID::Ping)
	{
		auto buffer = mmio_region();
		buffer.address() +=
		  static_cast<size_t>(index == BufferID::Ping ? 0x2000 : 0x2800);
		buffer.bounds() = 0x800;
		return const_cast<uint8_t *>(
		  reinterpret_cast<volatile uint8_t *>((buffer.get())));
	}

	/**
	 * Returns a pointer to one of the receive buffers, identified by the buffer
	 * identifier (ping or pong).
	 */
	uint8_t *transmit_buffer_pointer(BufferID index = BufferID::Ping)
	{
		auto buffer = mmio_region();
		buffer.address() +=
		  static_cast<size_t>(index == BufferID::Ping ? 0x1000 : 0x1800);
		buffer.bounds() = 0x800;
		return const_cast<uint8_t *>(
		  reinterpret_cast<volatile uint8_t *>((buffer.get())));
	}

	/**
	 * Write a value to a PHY register via MDIO.
	 */
	void
	mdio_write(uint8_t phyAddress, PHYRegister registerAddress, uint16_t data)
	{
		mdio_wait_for_ready();
		auto    &mdioAddress = mmio_register<RegisterOffset::MDIOAddress>();
		auto    &mdioWrite   = mmio_register<RegisterOffset::MDIODataWrite>();
		uint32_t writeCommand =
		  (0 << 10) | (phyAddress << 5) | uint32_t(registerAddress);
		mdioAddress = writeCommand;
		mdioWrite   = data;
		mdio_start_transaction();
	}

	/**
	 * Read a value from a PHY register via MDIO.
	 */
	uint16_t mdio_read(uint8_t phyAddress, PHYRegister registerAddress)
	{
		mdio_wait_for_ready();
		auto    &mdioAddress = mmio_register<RegisterOffset::MDIOAddress>();
		uint32_t readCommand =
		  (1 << 10) | (phyAddress << 5) | uint8_t(registerAddress);
		mdioAddress = readCommand;
		mdio_start_transaction();
		mdio_wait_for_ready();
		return mmio_register<RegisterOffset::MDIODataRead>();
	}

	public:
	/**
	 * Initialise a reference to the Ethernet device.  This will check the ID
	 * registers to make sure that this is the kind of device that we're
	 * expecting.
	 */
	KunyanEthernet()
	{
		phy_reset();
		// Check that this is the device that we're looking for
		Debug::Assert(
		  [&]() { return mdio_read(1, PHYRegister::Identifier1) == 0x2000; },
		  "PHY identifier 1 is not 0x2000");
		Debug::Assert(
		  [&]() {
			  return (mdio_read(1, PHYRegister::Identifier2) & 0xFFF0) ==
			         0x5c90;
		  },
		  "PHY identifier 1 is not 0x5c9x");
		autonegotiation_enable();
		filter_mode_update(FilterMode::DropInvalidCRC, true);
		filter_mode_update(FilterMode::EnableAddressFiltering, false);
		filter_mode_update(FilterMode::AllowUnicast, false);
		filter_mode_update(FilterMode::AllowIPv4Multicast, false);
		filter_mode_update(FilterMode::AllowIPv6Multicast, false);
		receiveInterruptFutex =
		  interrupt_futex_get(STATIC_SEALED_VALUE(EthernetReceive));
		// Enable receive interrupts
		mmio_register<RegisterOffset::GlobalInterruptEnable>() = 0b10;
		// Clear pending receive interrupts.
		mmio_register<RegisterOffset::InterruptStatus>() = 0b10;
	}

	KunyanEthernet(const KunyanEthernet &) = delete;
	KunyanEthernet(KunyanEthernet &&)      = delete;

	/**
	 * This device does not have a unique MAC address and so users must provide
	 * a locally administered MAC address if more than one device is present on
	 * the same network.
	 */
	static constexpr bool has_unique_mac_address()
	{
		return false;
	}

	static constexpr MACAddress mac_address_default()
	{
		return {0x60, 0x6A, 0x6A, 0x37, 0x47, 0x88};
	}

	void mac_address_set(MACAddress address = mac_address_default())
	{
		auto &macAddressHigh = mmio_register<RegisterOffset::MACAddressHigh>();
		auto &macAddressLow  = mmio_register<RegisterOffset::MACAddressLow>();
		macAddressHigh       = (address[2] << 24) | (address[3] << 16) |
		                 (address[4] << 8) | address[5];
		macAddressLow = (address[1] << 8) | address[0];
	}

	uint32_t receive_interrupt_value()
	{
		return *receiveInterruptFutex;
	}

	int receive_interrupt_complete(Timeout *timeout,
	                               uint32_t lastInterruptValue)
	{
		// Clear the interrupt on the device.
		auto &interruptStatus =
		  mmio_register<RegisterOffset::InterruptStatus>();
		interruptStatus = 0b10;
		// There's a small window in between finishing checking the receive
		// buffers and clearing the interrupt where we could miss the
		// interrupt.  Check that the receive buffers are empty *after*
		// reenabling the interrupt to ensure that we don't sleep in this
		// period.
		if (check_frame(BufferID::Ping) || check_frame(BufferID::Pong))
		{
			Debug::log("Packets already ready, not waiting for interrupt");
			return 0;
		}
		// Acknowledge the interrupt in the scheduler.
		interrupt_complete(STATIC_SEALED_VALUE(EthernetReceive));
		if (*receiveInterruptFutex == lastInterruptValue)
		{
			Debug::log("Acknowledged interrupt, sleeping on futex {}",
			           receiveInterruptFutex);
			return futex_timed_wait(
			  timeout, receiveInterruptFutex, lastInterruptValue);
		}
		Debug::log("Scheduler announces interrupt has fired");
		return 0;
	}

	/**
	 * Enable autonegotiation on the PHY.
	 *
	 * FIXME: This blocks forever if the cable is disconnected!
	 */
	void autonegotiation_enable(uint8_t phyAddress = 1)
	{
		Debug::log("Starting autonegotiation");
		// Advertise 802.3, 10Base-T full and half duplex
		mdio_write(phyAddress,
		           PHYRegister::AutoNegotiationAdvertisement,
		           (1 << 5) | (1 << 6) | 1);
		// Enable and restart autonegitiation
		mdio_write(
		  phyAddress, PHYRegister::BasicControlRegister, (1 << 12) | (1 << 9));
		Debug::log("Waiting for autonegotiation to complete");
		uint32_t loops = 0;
		while ((mdio_read(phyAddress, PHYRegister::BasicStatusRegister) &
		        (1 << 5)) == 0)
		{
			if ((loops++ & 0xfffff) == 0)
			{
				Debug::log(
				  "Waiting for autonegotiation to complete ({} loops): status: "
				  "{}",
				  loops,
				  mdio_read(phyAddress, PHYRegister::BasicStatusRegister));
			}
			yield();
		}
		Debug::Assert(
		  [&]() {
			  return (mdio_read(phyAddress, PHYRegister::BasicStatusRegister) &
			          (1 << 2)) != 0;
		  },
		  "Autonegotiation completed but link is down");
		Debug::log("Autonegotiation complete, status: {}",
		           mdio_read(phyAddress, PHYRegister::BasicStatusRegister));
		// Write 1 to clear the receive status.
		mmio_register<RegisterOffset::ReceiveControlPing>() = 1;
		mmio_register<RegisterOffset::ReceiveControlPong>() = 1;
	}

	/**
	 * Check the link status of the PHY.
	 */
	bool phy_link_status()
	{
		return (mdio_read(1, PHYRegister::BasicStatusRegister) & (1 << 2)) != 0;
	}

	std::optional<uint16_t> check_frame(BufferID index = BufferID::Ping)
	{
		// Debug::log("Checking for frame in buffer {}", index);
		auto receiveControl =
		  index == BufferID::Ping
		    ? mmio_register<RegisterOffset::ReceiveControlPing>()
		    : mmio_register<RegisterOffset::ReceiveControlPong>();
		if ((receiveControl & 1) == 0)
		{
			return std::nullopt;
		}
		Debug::log("Buffer has a frame.  Error? {}", receiveControl & 2);
		Debug::log("Buffer length: {}", receiveControl >> 16);
		return {receiveControl >> 16};
	}

	void complete_receive(BufferID index = BufferID::Ping)
	{
		Debug::log("Completing receive in buffer {}", index);
		// This buffer is now free to receive another frame.
		receiveBufferInUse[index] = false;
		if (index == BufferID::Ping)
		{
			mmio_register<RegisterOffset::ReceiveControlPing>() = 1;
		}
		else
		{
			mmio_register<RegisterOffset::ReceiveControlPong>() = 1;
		}
	}

	/**
	 * Class encapsulating a frame that has been received.  This holds a
	 * reference to the internal state of the buffer and will mark the buffer
	 * as free when it is destroyed.
	 */
	class BufferedFrame
	{
		friend class KunyanEthernet;
		KunyanEthernet &ethernetAdaptor;
		BufferID        owningBuffer;

		private:
		BufferedFrame(KunyanEthernet     &ethernetAdaptor,
		              BufferID            owningBuffer,
		              Capability<uint8_t> buffer,
		              uint16_t            length)

		  : ethernetAdaptor(ethernetAdaptor),
		    owningBuffer(owningBuffer),
		    buffer(buffer),
		    length(length)
		{
			// Mark this buffer as in use and try to advance the next buffer
			ethernetAdaptor.receiveBufferInUse[owningBuffer] = true;
			if (!ethernetAdaptor.receiveBufferInUse[next_buffer_id(
			      ethernetAdaptor.nextReceiveBuffer)])
			{
				ethernetAdaptor.nextReceiveBuffer =
				  next_buffer_id(ethernetAdaptor.nextReceiveBuffer);
			}
		}

		public:
		uint16_t            length;
		Capability<uint8_t> buffer;
		BufferedFrame(const BufferedFrame &) = delete;
		BufferedFrame(BufferedFrame &&other)
		  : ethernetAdaptor(other.ethernetAdaptor),
		    owningBuffer(other.owningBuffer),
		    buffer(other.buffer),
		    length(other.length)
		{
			other.buffer = nullptr;
			other.length = 0;
		}
		~BufferedFrame()
		{
			if (buffer != nullptr)
			{
				ethernetAdaptor.complete_receive(owningBuffer);
			}
		}
	};

	std::optional<BufferedFrame> receive_frame()
	{
		// To avoid processing the same packet twice, we must not use
		// the current receive buffer if it is already in use. In that
		// case, check the next receive buffer. If it is not in use,
		// rotate the buffers.  Otherwise, abandon.
		if (receiveBufferInUse[nextReceiveBuffer])
		{
			if (!receiveBufferInUse[next_buffer_id(nextReceiveBuffer)])
			{
				// The next receive buffer is not in use. Rotate.
				nextReceiveBuffer = next_buffer_id(nextReceiveBuffer);
			}
			else
			{
				// The next receive buffer is in use too. Abandon.
				return std::nullopt;
			}
		}

		auto maybeLength = check_frame(nextReceiveBuffer);

		if (!maybeLength)
		{
			// The current receive buffer is empty. However, the next
			// receive buffer, if not in use, may have a packet ready for
			// us. Check that one as well.

			if (!receiveBufferInUse[next_buffer_id(nextReceiveBuffer)])
			{
				// The next receive buffer is not in use. Check
				// for packets there as well.
				nextReceiveBuffer = next_buffer_id(nextReceiveBuffer);
				maybeLength       = check_frame(nextReceiveBuffer);
			}

			if (!maybeLength)
			{
				// None of the buffers has packets that we can
				// process. Abandon.
				return std::nullopt;
			}
		}

		auto length = *maybeLength;
		// Strip the FCS from the length.
		length -= 4;
		auto                buffer = receive_buffer_pointer(nextReceiveBuffer);
		Capability<uint8_t> boundedBuffer{buffer};
		boundedBuffer.bounds() = length;
		// Remove all permissions except load.  This also removes global, so
		// that this cannot be captured.
		boundedBuffer.permissions() &=
		  CHERI::PermissionSet{CHERI::Permission::Load};
		Debug::log("Received frame from buffer {}", nextReceiveBuffer);
		return {{*this, nextReceiveBuffer, buffer, length}};
	}

	/**
	 * Send a packet.  This is synchronous and will block until the packet has
	 * been sent.  A better version would use the next available ping or pong
	 * buffer and return as soon as the send operation had been enqueued.
	 *
	 * The third argument is a callback that allows the caller to check the
	 * frame before it's sent but after it's copied into memory that isn't
	 * shared with other compartments.
	 */
	bool send_frame(const uint8_t *buffer, uint16_t length, auto &&check)
	{
		auto &transmitControl =
		  mmio_register<RegisterOffset::TransmitControlPing>();
		// Spin waiting for the transmit buffer to be free.
		while (transmitControl & 1) {}
		// Write the frame to the transmit buffer.
		auto transmitBuffer = transmit_buffer_pointer();
		// We must check the frame pointer and its length. Although it
		// is supplied by the firewall which is trusted, the firewall
		// does not check the pointer which is coming from external
		// untrusted components.
		Timeout t{10};
		if ((heap_claim_fast(&t, buffer) < 0) ||
		    (!CHERI::check_pointer<CHERI::PermissionSet{
		       CHERI::Permission::Load}>(buffer, length)))
		{
			return false;
		}
		memcpy(transmitBuffer, buffer, length);
		if (!check(transmitBuffer, length))
		{
			return false;
		}
		// The Ethernet standard requires frames to be at least 60 bytes long.
		// If we're asked to send anything shorter, pad it with zeroes.
		// (It would be nice if the MAC did this automatically).
		if (length < 60)
		{
			memset(transmitBuffer + length, 0, 60 - length);
			length = 60;
		}
		// Write the length of the frame to the transmit length register.
		mmio_register<RegisterOffset::TransmitFrameLengthPing>() = length;
		// Start the transmit.
		transmitControl = 1;
		Debug::log("Sent frame, waiting for completion");
		while (transmitControl & 1) {}
		// Return if the frame was sent successfully.
		Debug::log("Transmit control register: {}", transmitControl);
		if ((transmitControl & 2) != 0)
		{
			Debug::log("Error sending frame");
		}
		return (transmitControl & 2) == 0;
	}

	/**
	 * If debugging dropped frames is enabled, log any counter values that have
	 * changed since the last call to this function.
	 */
	void dropped_frames_log_all_if_changed()
	{
		if constexpr (DebugDroppedFrames)
		{
			dropped_frames_log_if_changed<
			  RegisterOffset::ReceiveDroppedFramesBuffersFull>(droppedFrames);
			dropped_frames_log_if_changed<
			  RegisterOffset::ReceiveDroppedFramesFCSFailed>(droppedFrames);
			dropped_frames_log_if_changed<
			  RegisterOffset::ReceiveDroppedFramesInvalidAddress>(
			  droppedFrames);
		}
	}

	void received_frames_log()
	{
		auto count = mmio_register<RegisterOffset::ReceivedFramesCount>();
		ConditionalDebug<true, "Ethernet driver">::log("Received frames: {}",
		                                               count);
	}
};

using EthernetDevice = KunyanEthernet;

static_assert(EthernetAdaptor<EthernetDevice>);
