/*
 * Xilinx Processor System Gigabit Ethernet controller (GEM) driver
 *
 * Copyright (c) 2021, Weidmueller Interface GmbH & Co. KG
 * SPDX-License-Identifier: Apache-2.0
 *
 * Known current limitations / TODOs:
 * - Only supports 32-bit addresses in buffer descriptors, therefore
 *   the ZynqMP APU (Cortex-A53 cores) may not be fully supported.
 * - Hardware timestamps not considered.
 * - VLAN tags not considered.
 * - Wake-on-LAN interrupt not supported.
 * - Send function is not SMP-capable (due to single TX done semaphore).
 * - Interrupt-driven PHY management not supported - polling only.
 * - No explicit placement of the DMA memory area(s) in either a
 *   specific memory section or at a fixed memory location yet. This
 *   is not an issue as long as the controller is used in conjunction
 *   with the Cortex-R5 QEMU target or an actual R5 running without the
 *   MPU enabled.
 * - No detailed error handling when evaluating the Interrupt Status,
 *   RX Status and TX Status registers.
 */

#include <zephyr/zephyr.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/sys/__assert.h>

#include <zephyr/net/net_if.h>
#include <zephyr/net/ethernet.h>
#include <ethernet/eth_stats.h>

#include "eth_xlnx_gem_priv.h"

#define LOG_MODULE_NAME eth_xlnx_gem
#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

static int  eth_xlnx_gem_dev_init(const struct device *dev);
static void eth_xlnx_gem_iface_init(struct net_if *iface);
static void eth_xlnx_gem_isr(const struct device *dev);
static int  eth_xlnx_gem_send(const struct device *dev, struct net_pkt *pkt);
static int  eth_xlnx_gem_start_device(const struct device *dev);
static int  eth_xlnx_gem_stop_device(const struct device *dev);
static enum ethernet_hw_caps
	eth_xlnx_gem_get_capabilities(const struct device *dev);
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
static struct net_stats_eth *eth_xlnx_gem_stats(const struct device *dev);
#endif

static void eth_xlnx_gem_reset_hw(const struct device *dev);
static void eth_xlnx_gem_configure_clocks(const struct device *dev);
static void eth_xlnx_gem_set_initial_nwcfg(const struct device *dev);
static void eth_xlnx_gem_set_nwcfg_link_speed(const struct device *dev);
static void eth_xlnx_gem_set_mac_address(const struct device *dev);
static void eth_xlnx_gem_set_initial_dmacr(const struct device *dev);
static void eth_xlnx_gem_init_phy(const struct device *dev);
static void eth_xlnx_gem_poll_phy(struct k_work *item);
static void eth_xlnx_gem_configure_buffers(const struct device *dev);
static void eth_xlnx_gem_rx_pending_work(struct k_work *item);
static void eth_xlnx_gem_handle_rx_pending(const struct device *dev);
static void eth_xlnx_gem_tx_done_work(struct k_work *item);
static void eth_xlnx_gem_handle_tx_done(const struct device *dev);

static const struct ethernet_api eth_xlnx_gem_apis = {
	.iface_api.init   = eth_xlnx_gem_iface_init,
	.get_capabilities = eth_xlnx_gem_get_capabilities,
	.send		  = eth_xlnx_gem_send,
	.start		  = eth_xlnx_gem_start_device,
	.stop		  = eth_xlnx_gem_stop_device,
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
	.get_stats	  = eth_xlnx_gem_stats,
#endif
};

/*
 * Insert the configuration & run-time data for all GEM instances which
 * are enabled in the device tree of the current target board.
 */
DT_INST_FOREACH_STATUS_OKAY(ETH_XLNX_GEM_INITIALIZE)

/**
 * @brief GEM device initialization function
 * Initializes the GEM itself, the DMA memory area used by the GEM and,
 * if enabled, an associated PHY attached to the GEM's MDIO interface.
 *
 * @param dev Pointer to the device data
 * @retval 0 if the device initialization completed successfully
 */
static int eth_xlnx_gem_dev_init(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	uint32_t reg_val;

	/* Precondition checks using assertions */

	/* Valid PHY address and polling interval, if PHY is to be managed */
	if (dev_conf->init_phy) {
		__ASSERT((dev_conf->phy_mdio_addr_fix >= 0 &&
			 dev_conf->phy_mdio_addr_fix <= 32),
			 "%s invalid PHY address %u, must be in range "
			 "1 to 32, or 0 for auto-detection",
			 dev->name, dev_conf->phy_mdio_addr_fix);
		__ASSERT(dev_conf->phy_poll_interval > 0,
			 "%s has an invalid zero PHY status polling "
			 "interval", dev->name);
	}

	/* Valid max. / nominal link speed value */
	__ASSERT((dev_conf->max_link_speed == LINK_10MBIT ||
		 dev_conf->max_link_speed == LINK_100MBIT ||
		 dev_conf->max_link_speed == LINK_1GBIT),
		 "%s invalid max./nominal link speed value %u",
		 dev->name, (uint32_t)dev_conf->max_link_speed);

	/* MDC clock divider validity check, SoC dependent */
#if defined(CONFIG_SOC_XILINX_ZYNQMP)
	__ASSERT(dev_conf->mdc_divider <= MDC_DIVIDER_48,
		 "%s invalid MDC clock divider value %u, must be in "
		 "range 0 to %u", dev->name, dev_conf->mdc_divider,
		 (uint32_t)MDC_DIVIDER_48);
#elif defined(CONFIG_SOC_FAMILY_XILINX_ZYNQ7000)
	__ASSERT(dev_conf->mdc_divider <= MDC_DIVIDER_224,
		 "%s invalid MDC clock divider value %u, must be in "
		 "range 0 to %u", dev->name, dev_conf->mdc_divider,
		 (uint32_t)MDC_DIVIDER_224);
#endif

	/* AMBA AHB configuration options */
	__ASSERT((dev_conf->amba_dbus_width == AMBA_AHB_DBUS_WIDTH_32BIT ||
		 dev_conf->amba_dbus_width == AMBA_AHB_DBUS_WIDTH_64BIT ||
		 dev_conf->amba_dbus_width == AMBA_AHB_DBUS_WIDTH_128BIT),
		 "%s AMBA AHB bus width configuration is invalid",
		 dev->name);
	__ASSERT((dev_conf->ahb_burst_length == AHB_BURST_SINGLE ||
		 dev_conf->ahb_burst_length == AHB_BURST_INCR4 ||
		 dev_conf->ahb_burst_length == AHB_BURST_INCR8 ||
		 dev_conf->ahb_burst_length == AHB_BURST_INCR16),
		 "%s AMBA AHB burst length configuration is invalid",
		 dev->name);

	/* HW RX buffer size */
	__ASSERT((dev_conf->hw_rx_buffer_size == HWRX_BUFFER_SIZE_8KB ||
		 dev_conf->hw_rx_buffer_size == HWRX_BUFFER_SIZE_4KB ||
		 dev_conf->hw_rx_buffer_size == HWRX_BUFFER_SIZE_2KB ||
		 dev_conf->hw_rx_buffer_size == HWRX_BUFFER_SIZE_1KB),
		 "%s hardware RX buffer size configuration is invalid",
		 dev->name);

	/* HW RX buffer offset */
	__ASSERT(dev_conf->hw_rx_buffer_offset <= 3,
		 "%s hardware RX buffer offset %u is invalid, must be in "
		 "range 0 to 3", dev->name, dev_conf->hw_rx_buffer_offset);

	/*
	 * RX & TX buffer sizes
	 * RX Buffer size must be a multiple of 64, as the size of the
	 * corresponding DMA receive buffer in AHB system memory is
	 * expressed as n * 64 bytes in the DMA configuration register.
	 */
	__ASSERT(dev_conf->rx_buffer_size % 64 == 0,
		 "%s RX buffer size %u is not a multiple of 64 bytes",
		 dev->name, dev_conf->rx_buffer_size);
	__ASSERT((dev_conf->rx_buffer_size != 0 &&
		 dev_conf->rx_buffer_size <= 16320),
		 "%s RX buffer size %u is invalid, should be >64, "
		 "must be 16320 bytes maximum.", dev->name,
		 dev_conf->rx_buffer_size);
	__ASSERT((dev_conf->tx_buffer_size != 0 &&
		 dev_conf->tx_buffer_size <= 16380),
		 "%s TX buffer size %u is invalid, should be >64, "
		 "must be 16380 bytes maximum.", dev->name,
		 dev_conf->tx_buffer_size);

	/* Checksum offloading limitations of the QEMU GEM implementation */
#ifdef CONFIG_QEMU_TARGET
	__ASSERT(!dev_conf->enable_rx_chksum_offload,
		 "TCP/UDP/IP hardware checksum offloading is not "
		 "supported by the QEMU GEM implementation");
	__ASSERT(!dev_conf->enable_tx_chksum_offload,
		 "TCP/UDP/IP hardware checksum offloading is not "
		 "supported by the QEMU GEM implementation");
#endif

	/*
	 * Initialization procedure as described in the Zynq-7000 TRM,
	 * chapter 16.3.x.
	 */
	eth_xlnx_gem_reset_hw(dev);		/* Chapter 16.3.1 */
	eth_xlnx_gem_set_initial_nwcfg(dev);	/* Chapter 16.3.2 */
	eth_xlnx_gem_set_mac_address(dev);	/* Chapter 16.3.2 */
	eth_xlnx_gem_set_initial_dmacr(dev);	/* Chapter 16.3.2 */

	/* Enable MDIO -> set gem.net_ctrl[mgmt_port_en] */
	if (dev_conf->init_phy) {
		reg_val  = sys_read32(dev_conf->base_addr +
				      ETH_XLNX_GEM_NWCTRL_OFFSET);
		reg_val |= ETH_XLNX_GEM_NWCTRL_MDEN_BIT;
		sys_write32(reg_val, dev_conf->base_addr +
			    ETH_XLNX_GEM_NWCTRL_OFFSET);
	}

	eth_xlnx_gem_configure_clocks(dev);	/* Chapter 16.3.3 */
	if (dev_conf->init_phy) {
		eth_xlnx_gem_init_phy(dev);	/* Chapter 16.3.4 */
	}
	eth_xlnx_gem_configure_buffers(dev);	/* Chapter 16.3.5 */

	return 0;
}

/**
 * @brief GEM associated interface initialization function
 * Initializes the interface associated with a GEM device.
 *
 * @param iface Pointer to the associated interface data struct
 */
static void eth_xlnx_gem_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;

	/* Set the initial contents of the current instance's run-time data */
	dev_data->iface = iface;
	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
	ethernet_init(iface);
	net_if_flag_set(iface, NET_IF_NO_AUTO_START);

	/*
	 * Initialize the (delayed) work items for RX pending, TX done
	 * and PHY status polling handlers
	 */
	k_work_init(&dev_data->tx_done_work, eth_xlnx_gem_tx_done_work);
	k_work_init(&dev_data->rx_pend_work, eth_xlnx_gem_rx_pending_work);
	k_work_init_delayable(&dev_data->phy_poll_delayed_work,
			      eth_xlnx_gem_poll_phy);

	/* Initialize TX completion semaphore */
	k_sem_init(&dev_data->tx_done_sem, 0, 1);

	/*
	 * Initialize semaphores in the RX/TX BD rings which have not
	 * yet been initialized
	 */
	k_sem_init(&dev_data->txbd_ring.ring_sem, 1, 1);
	/* RX BD ring semaphore is not required at the time being */

	/* Initialize the device's interrupt */
	dev_conf->config_func(dev);

	/* Submit initial PHY status polling delayed work */
	k_work_reschedule(&dev_data->phy_poll_delayed_work, K_NO_WAIT);
}

/**
 * @brief GEM interrupt service routine
 * GEM interrupt service routine. Checks for indications of errors
 * and either immediately handles RX pending / TX complete notifications
 * or defers them to the system work queue.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_isr(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_val;

	/* Read the interrupt status register */
	reg_val = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);

	/*
	 * TODO: handling if one or more error flag(s) are set in the
	 * interrupt status register. -> For now, just log them
	 */
	if (reg_val & ETH_XLNX_GEM_IXR_ERRORS_MASK) {
		LOG_ERR("%s error bit(s) set in Interrupt Status Reg.: 0x%08X",
			dev->name, reg_val);
	}

	/*
	 * Check for the following indications by the controller:
	 * reg_val & 0x00000080 -> gem.intr_status bit [7] = Frame TX complete
	 * reg_val & 0x00000002 -> gem.intr_status bit [1] = Frame received
	 * comp. Zynq-7000 TRM, Chapter B.18, p. 1289/1290.
	 * If the respective condition's handling is configured to be deferred
	 * to the work queue thread, submit the corresponding job to the work
	 * queue, otherwise, handle the condition immediately.
	 */
	if ((reg_val & ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT) != 0) {
		sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);
		sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);
		if (dev_conf->defer_txd_to_queue) {
			k_work_submit(&dev_data->tx_done_work);
		} else {
			eth_xlnx_gem_handle_tx_done(dev);
		}
	}
	if ((reg_val & ETH_XLNX_GEM_IXR_FRAME_RX_BIT) != 0) {
		sys_write32(ETH_XLNX_GEM_IXR_FRAME_RX_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);
		sys_write32(ETH_XLNX_GEM_IXR_FRAME_RX_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);
		if (dev_conf->defer_rxp_to_queue) {
			k_work_submit(&dev_data->rx_pend_work);
		} else {
			eth_xlnx_gem_handle_rx_pending(dev);
		}
	}

	/*
	 * Clear all interrupt status bits so that the interrupt is de-asserted
	 * by the GEM. -> TXSR/RXSR are read/cleared by either eth_xlnx_gem_-
	 * handle_tx_done or eth_xlnx_gem_handle_rx_pending if those actions
	 * are not deferred to the system's work queue for the current inter-
	 * face. If the latter is the case, those registers will be read/
	 * cleared whenever the corresponding work item submitted from within
	 * this ISR is being processed.
	 */
	sys_write32((0xFFFFFFFF & ~(ETH_XLNX_GEM_IXR_FRAME_RX_BIT |
		    ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT)),
		    dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);
}

/**
 * @brief GEM data send function
 * GEM data send function. Blocks until a TX complete notification has been
 * received & processed.
 *
 * @param dev Pointer to the device data
 * @param pkt Pointer to the data packet to be sent
 * @retval -EINVAL in case of invalid parameters, e.g. zero data length
 * @retval -EIO in case of:
 *         (1) the attempt to TX data while the device is stopped,
 *             the interface is down or the link is down,
 *         (2) the attempt to TX data while no free buffers are available
 *             in the DMA memory area,
 *         (3) the transmission completion notification timing out
 * @retval 0 if the packet was transmitted successfully
 */
static int eth_xlnx_gem_send(const struct device *dev, struct net_pkt *pkt)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;

	uint16_t tx_data_length;
	uint16_t tx_data_remaining;
	void *tx_buffer_offs;

	uint8_t bds_reqd;
	uint8_t curr_bd_idx;
	uint8_t first_bd_idx;

	uint32_t reg_ctrl;
	uint32_t reg_val;
	int sem_status;

	if (!dev_data->started || dev_data->eff_link_speed == LINK_DOWN ||
			(!net_if_flag_is_set(dev_data->iface, NET_IF_UP))) {
#ifdef CONFIG_NET_STATISTICS_ETHERNET
		dev_data->stats.tx_dropped++;
#endif
		return -EIO;
	}

	tx_data_length = tx_data_remaining = net_pkt_get_len(pkt);
	if (tx_data_length == 0) {
		LOG_ERR("%s cannot TX, zero packet length", dev->name);
#ifdef CONFIG_NET_STATISTICS_ETHERNET
		dev_data->stats.errors.tx++;
#endif
		return -EINVAL;
	}

	/*
	 * Check if enough buffer descriptors are available for the amount
	 * of data to be transmitted, update the free BD count if this is
	 * the case. Update the 'next to use' BD index in the TX BD ring if
	 * sufficient space is available. If TX done handling, where the BD
	 * ring's data is accessed as well, is performed via the system work
	 * queue, protect against interruptions during the update of the BD
	 * ring's data by taking the ring's semaphore. If TX done handling
	 * is performed within the ISR, protect against interruptions by
	 * disabling the TX done interrupt source.
	 */
	bds_reqd = (uint8_t)((tx_data_length + (dev_conf->tx_buffer_size - 1)) /
		   dev_conf->tx_buffer_size);

	if (dev_conf->defer_txd_to_queue) {
		k_sem_take(&(dev_data->txbd_ring.ring_sem), K_FOREVER);
	} else {
		sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);
	}

	if (bds_reqd > dev_data->txbd_ring.free_bds) {
		LOG_ERR("%s cannot TX, packet length %hu requires "
			"%hhu BDs, current free count = %hhu",
			dev->name, tx_data_length, bds_reqd,
			dev_data->txbd_ring.free_bds);

		if (dev_conf->defer_txd_to_queue) {
			k_sem_give(&(dev_data->txbd_ring.ring_sem));
		} else {
			sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
				    dev_conf->base_addr + ETH_XLNX_GEM_IER_OFFSET);
		}
#ifdef CONFIG_NET_STATISTICS_ETHERNET
		dev_data->stats.tx_dropped++;
#endif
		return -EIO;
	}

	curr_bd_idx = first_bd_idx = dev_data->txbd_ring.next_to_use;
	reg_ctrl = (uint32_t)(&dev_data->txbd_ring.first_bd[curr_bd_idx].ctrl);

	dev_data->txbd_ring.next_to_use = (first_bd_idx + bds_reqd) %
					  dev_conf->txbd_count;
	dev_data->txbd_ring.free_bds -= bds_reqd;

	if (dev_conf->defer_txd_to_queue) {
		k_sem_give(&(dev_data->txbd_ring.ring_sem));
	} else {
		sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
			    dev_conf->base_addr + ETH_XLNX_GEM_IER_OFFSET);
	}

	/*
	 * Scatter the contents of the network packet's buffer to
	 * one or more DMA buffers.
	 */
	net_pkt_cursor_init(pkt);
	do {
		/* Calculate the base pointer of the target TX buffer */
		tx_buffer_offs = (void *)(dev_data->first_tx_buffer +
				 (dev_conf->tx_buffer_size * curr_bd_idx));

		/* Copy packet data to DMA buffer */
		net_pkt_read(pkt, (void *)tx_buffer_offs,
			     (tx_data_remaining < dev_conf->tx_buffer_size) ?
			     tx_data_remaining : dev_conf->tx_buffer_size);

		/* Update current BD's control word */
		reg_val = sys_read32(reg_ctrl) & (ETH_XLNX_GEM_TXBD_WRAP_BIT |
			  ETH_XLNX_GEM_TXBD_USED_BIT);
		reg_val |= (tx_data_remaining < dev_conf->tx_buffer_size) ?
			   tx_data_remaining : dev_conf->tx_buffer_size;
		sys_write32(reg_val, reg_ctrl);

		if (tx_data_remaining > dev_conf->tx_buffer_size) {
			/* Switch to next BD */
			curr_bd_idx = (curr_bd_idx + 1) % dev_conf->txbd_count;
			reg_ctrl = (uint32_t)(&dev_data->txbd_ring.first_bd[curr_bd_idx].ctrl);
		}

		tx_data_remaining -= (tx_data_remaining < dev_conf->tx_buffer_size) ?
				     tx_data_remaining : dev_conf->tx_buffer_size;
	} while (tx_data_remaining > 0);

	/* Set the 'last' bit in the current BD's control word */
	reg_val |= ETH_XLNX_GEM_TXBD_LAST_BIT;

	/*
	 * Clear the 'used' bits of all BDs involved in the current
	 * transmission. In accordance with chapter 16.3.8 of the
	 * Zynq-7000 TRM, the 'used' bits shall be cleared in reverse
	 * order, so that the 'used' bit of the first BD is cleared
	 * last just before the transmission is started.
	 */
	reg_val &= ~ETH_XLNX_GEM_TXBD_USED_BIT;
	sys_write32(reg_val, reg_ctrl);

	while (curr_bd_idx != first_bd_idx) {
		curr_bd_idx = (curr_bd_idx != 0) ? (curr_bd_idx - 1) :
			      (dev_conf->txbd_count - 1);
		reg_ctrl = (uint32_t)(&dev_data->txbd_ring.first_bd[curr_bd_idx].ctrl);
		reg_val = sys_read32(reg_ctrl);
		reg_val &= ~ETH_XLNX_GEM_TXBD_USED_BIT;
		sys_write32(reg_val, reg_ctrl);
	}

	/* Set the start TX bit in the gem.net_ctrl register */
	reg_val  = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);
	reg_val |= ETH_XLNX_GEM_NWCTRL_STARTTX_BIT;
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);

#ifdef CONFIG_NET_STATISTICS_ETHERNET
	dev_data->stats.bytes.sent += tx_data_length;
	dev_data->stats.pkts.tx++;
#endif

	/* Block until TX has completed */
	sem_status = k_sem_take(&dev_data->tx_done_sem, K_MSEC(100));
	if (sem_status < 0) {
		LOG_ERR("%s TX confirmation timed out", dev->name);
#ifdef CONFIG_NET_STATISTICS_ETHERNET
		dev_data->stats.tx_timeout_count++;
#endif
		return -EIO;
	}

	return 0;
}

/**
 * @brief GEM device start function
 * GEM device start function. Clears all status registers and any
 * pending interrupts, enables RX and TX, enables interrupts. If
 * no PHY is managed by the current driver instance, this function
 * also declares the physical link up at the configured nominal
 * link speed.
 *
 * @param dev Pointer to the device data
 * @retval    0 upon successful completion
 */
static int eth_xlnx_gem_start_device(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_val;

	if (dev_data->started) {
		return 0;
	}
	dev_data->started = true;

	/* Disable & clear all the MAC interrupts */
	sys_write32(ETH_XLNX_GEM_IXR_ALL_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);
	sys_write32(ETH_XLNX_GEM_IXR_ALL_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);

	/* Clear RX & TX status registers */
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_TXSR_OFFSET);
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_RXSR_OFFSET);

	/* RX and TX enable */
	reg_val  = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);
	reg_val |= (ETH_XLNX_GEM_NWCTRL_RXEN_BIT | ETH_XLNX_GEM_NWCTRL_TXEN_BIT);
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);

	/* Enable all the MAC interrupts */
	sys_write32(ETH_XLNX_GEM_IXR_ALL_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_IER_OFFSET);

	/* Submit the delayed work for polling the link state */
	if (k_work_delayable_remaining_get(&dev_data->phy_poll_delayed_work) == 0) {
		k_work_reschedule(&dev_data->phy_poll_delayed_work, K_NO_WAIT);
	}

	LOG_DBG("%s started", dev->name);
	return 0;
}

/**
 * @brief GEM device stop function
 * GEM device stop function. Disables all interrupts, disables
 * RX and TX, clears all status registers. If no PHY is managed
 * by the current driver instance, this function also declares
 * the physical link down.
 *
 * @param dev Pointer to the device data
 * @retval    0 upon successful completion
 */
static int eth_xlnx_gem_stop_device(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_val;

	if (!dev_data->started) {
		return 0;
	}
	dev_data->started = false;

	/* Cancel the delayed work that polls the link state */
	if (k_work_delayable_remaining_get(&dev_data->phy_poll_delayed_work) != 0) {
		k_work_cancel_delayable(&dev_data->phy_poll_delayed_work);
	}

	/* RX and TX disable */
	reg_val  = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);
	reg_val &= (~(ETH_XLNX_GEM_NWCTRL_RXEN_BIT | ETH_XLNX_GEM_NWCTRL_TXEN_BIT));
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);

	/* Disable & clear all the MAC interrupts */
	sys_write32(ETH_XLNX_GEM_IXR_ALL_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);
	sys_write32(ETH_XLNX_GEM_IXR_ALL_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_ISR_OFFSET);

	/* Clear RX & TX status registers */
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_TXSR_OFFSET);
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_RXSR_OFFSET);

	LOG_DBG("%s stopped", dev->name);
	return 0;
}

/**
 * @brief GEM capability request function
 * Returns the capabilities of the GEM controller as an enumeration.
 * All of the data returned is derived from the device configuration
 * of the current GEM device instance.
 *
 * @param dev Pointer to the device data
 * @return Enumeration containing the current GEM device's capabilities
 */
static enum ethernet_hw_caps eth_xlnx_gem_get_capabilities(
	const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	enum ethernet_hw_caps caps = (enum ethernet_hw_caps)0;

	if (dev_conf->max_link_speed == LINK_1GBIT) {
		if (dev_conf->phy_advertise_lower) {
			caps |= (ETHERNET_LINK_1000BASE_T |
				ETHERNET_LINK_100BASE_T |
				ETHERNET_LINK_10BASE_T);
		} else {
			caps |= ETHERNET_LINK_1000BASE_T;
		}
	} else if (dev_conf->max_link_speed == LINK_100MBIT) {
		if (dev_conf->phy_advertise_lower) {
			caps |= (ETHERNET_LINK_100BASE_T |
				ETHERNET_LINK_10BASE_T);
		} else {
			caps |= ETHERNET_LINK_100BASE_T;
		}
	} else {
		caps |= ETHERNET_LINK_10BASE_T;
	}

	if (dev_conf->enable_rx_chksum_offload) {
		caps |= ETHERNET_HW_RX_CHKSUM_OFFLOAD;
	}

	if (dev_conf->enable_tx_chksum_offload) {
		caps |= ETHERNET_HW_TX_CHKSUM_OFFLOAD;
	}

	if (dev_conf->enable_fdx) {
		caps |= ETHERNET_DUPLEX_SET;
	}

	if (dev_conf->copy_all_frames) {
		caps |= ETHERNET_PROMISC_MODE;
	}

	return caps;
}

#ifdef CONFIG_NET_STATISTICS_ETHERNET
/**
 * @brief GEM statistics data request function
 * Returns a pointer to the statistics data of the current GEM controller.
 *
 * @param dev Pointer to the device data
 * @return Pointer to the current GEM device's statistics data
 */
static struct net_stats_eth *eth_xlnx_gem_stats(const struct device *dev)
{
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;

	return &data->stats;
}
#endif

/**
 * @brief GEM Hardware reset function
 * Resets the current GEM device. Called from within the device
 * initialization function.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_reset_hw(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;

	/*
	 * Controller reset sequence as described in the Zynq-7000 TRM,
	 * chapter 16.3.1.
	 */

	/* Clear the NWCTRL register */
	sys_write32(0x00000000,
		    dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);

	/* Clear the statistics counters */
	sys_write32(ETH_XLNX_GEM_STATCLR_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_NWCTRL_OFFSET);

	/* Clear the RX/TX status registers */
	sys_write32(ETH_XLNX_GEM_TXSRCLR_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_TXSR_OFFSET);
	sys_write32(ETH_XLNX_GEM_RXSRCLR_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_RXSR_OFFSET);

	/* Disable all interrupts */
	sys_write32(ETH_XLNX_GEM_IDRCLR_MASK,
		    dev_conf->base_addr + ETH_XLNX_GEM_IDR_OFFSET);

	/* Clear the buffer queues */
	sys_write32(0x00000000,
		    dev_conf->base_addr + ETH_XLNX_GEM_RXQBASE_OFFSET);
	sys_write32(0x00000000,
		    dev_conf->base_addr + ETH_XLNX_GEM_TXQBASE_OFFSET);
}

/**
 * @brief GEM clock configuration function
 * Calculates the pre-scalers for the TX clock to match the current
 * (if an associated PHY is managed) or nominal link speed. Called
 * from within the device initialization function.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_configure_clocks(const struct device *dev)
{
	/*
	 * Clock source configuration for the respective GEM as described
	 * in the Zynq-7000 TRM, chapter 16.3.3, is not tackled here. This
	 * is performed by the PS7Init code. Only the DIVISOR and DIVISOR1
	 * values for the respective GEM's TX clock are calculated here.
	 */

	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;

	uint32_t div0;
	uint32_t div1;
	uint32_t target = 2500000; /* default prevents 'may be uninitialized' warning */
	uint32_t tmp;
	uint32_t clk_ctrl_reg;

	if ((!dev_conf->init_phy) || dev_data->eff_link_speed == LINK_DOWN) {
		/*
		 * Run-time data indicates 'link down' or PHY management
		 * is disabled for the current device -> this indicates the
		 * initial device initialization. Once the PHY status polling
		 * delayed work handler has picked up the result of the auto-
		 * negotiation (if enabled), this if-statement will evaluate
		 * to false.
		 */
		if (dev_conf->max_link_speed == LINK_10MBIT) {
			target = 2500000;   /* Target frequency: 2.5 MHz */
		} else if (dev_conf->max_link_speed == LINK_100MBIT) {
			target = 25000000;  /* Target frequency: 25 MHz */
		} else if (dev_conf->max_link_speed == LINK_1GBIT) {
			target = 125000000; /* Target frequency: 125 MHz */
		}
	} else if (dev_data->eff_link_speed != LINK_DOWN) {
		/*
		 * Use the effective link speed instead of the maximum/nominal
		 * link speed for clock configuration.
		 */
		if (dev_data->eff_link_speed == LINK_10MBIT) {
			target = 2500000;   /* Target frequency: 2.5 MHz */
		} else if (dev_data->eff_link_speed == LINK_100MBIT) {
			target = 25000000;  /* Target frequency: 25 MHz */
		} else if (dev_data->eff_link_speed == LINK_1GBIT) {
			target = 125000000; /* Target frequency: 125 MHz */
		}
	}

	/*
	 * Calculate the divisors for the target frequency.
	 * The frequency of the PLL to which the divisors shall be applied are
	 * provided in the respective GEM's device tree data.
	 */
	for (div0 = 1; div0 < 64; div0++) {
		for (div1 = 1; div1 < 64; div1++) {
			tmp = ((dev_conf->pll_clock_frequency / div0) / div1);
			if (tmp >= (target - 10) && tmp <= (target + 10)) {
				break;
			}
		}
		if (tmp >= (target - 10) && tmp <= (target + 10)) {
			break;
		}
	}

#if defined(CONFIG_SOC_XILINX_ZYNQMP)
	/*
	 * ZynqMP register crl_apb.GEMx_REF_CTRL:
	 * RX_CLKACT bit [26]
	 * CLKACT bit [25]
	 * div0 bits [13..8], div1 bits [21..16]
	 * Unlock CRL_APB write access if the write protect bit
	 * is currently set, restore it afterwards.
	 */
	clk_ctrl_reg  = sys_read32(dev_conf->clk_ctrl_reg_address);
	clk_ctrl_reg &= ~((ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR_MASK <<
			ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR0_SHIFT) |
			(ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR_MASK <<
			ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR1_SHIFT));
	clk_ctrl_reg |=	((div0 & ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR_MASK) <<
			ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR0_SHIFT) |
			((div1 & ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR_MASK) <<
			ETH_XLNX_CRL_APB_GEMX_REF_CTRL_DIVISOR1_SHIFT);
	clk_ctrl_reg |=	ETH_XLNX_CRL_APB_GEMX_REF_CTRL_RX_CLKACT_BIT |
			ETH_XLNX_CRL_APB_GEMX_REF_CTRL_CLKACT_BIT;

	/*
	 * Unlock CRL_APB write access if the write protect bit
	 * is currently set, restore it afterwards.
	 */
	tmp = sys_read32(ETH_XLNX_CRL_APB_WPROT_REGISTER_ADDRESS);
	if ((tmp & ETH_XLNX_CRL_APB_WPROT_BIT) > 0) {
		sys_write32((tmp & ~ETH_XLNX_CRL_APB_WPROT_BIT),
			    ETH_XLNX_CRL_APB_WPROT_REGISTER_ADDRESS);
	}
	sys_write32(clk_ctrl_reg, dev_conf->clk_ctrl_reg_address);
	if ((tmp & ETH_XLNX_CRL_APB_WPROT_BIT) > 0) {
		sys_write32(tmp, ETH_XLNX_CRL_APB_WPROT_REGISTER_ADDRESS);
	}
# elif defined(CONFIG_SOC_FAMILY_XILINX_ZYNQ7000)
	clk_ctrl_reg  = sys_read32(dev_conf->clk_ctrl_reg_address);
	clk_ctrl_reg &= ~((ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK <<
			ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT) |
			(ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK <<
			ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT));
	clk_ctrl_reg |= ((div0 & ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK) <<
			ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR0_SHIFT) |
			((div1 & ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR_MASK) <<
			ETH_XLNX_SLCR_GEMX_CLK_CTRL_DIVISOR1_SHIFT);

	sys_write32(clk_ctrl_reg, dev_conf->clk_ctrl_reg_address);
#endif /* CONFIG_SOC_XILINX_ZYNQMP / CONFIG_SOC_FAMILY_XILINX_ZYNQ7000 */

	LOG_DBG("%s set clock dividers div0/1 %u/%u for target "
		"frequency %u Hz", dev->name, div0, div1, target);
}

/**
 * @brief GEM initial Network Configuration Register setup function
 * Writes the contents of the current GEM device's Network Configuration
 * Register (NWCFG / gem.net_cfg). Called from within the device
 * initialization function. Implementation differs depending on whether
 * the current target is a Zynq-7000 or a ZynqMP.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_set_initial_nwcfg(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	uint32_t reg_val = 0;

	if (dev_conf->ignore_ipg_rxer) {
		/* [30]     ignore IPG rx_er */
		reg_val |= ETH_XLNX_GEM_NWCFG_IGNIPGRXERR_BIT;
	}
	if (dev_conf->disable_reject_nsp) {
		/* [29]     disable rejection of non-standard preamble */
		reg_val |= ETH_XLNX_GEM_NWCFG_BADPREAMBEN_BIT;
	}
	if (dev_conf->enable_ipg_stretch) {
		/* [28]     enable IPG stretch */
		reg_val |= ETH_XLNX_GEM_NWCFG_IPG_STRETCH_BIT;
	}
	if (dev_conf->enable_sgmii_mode) {
		/* [27]     SGMII mode enable */
		reg_val |= ETH_XLNX_GEM_NWCFG_SGMIIEN_BIT;
	}
	if (dev_conf->disable_reject_fcs_crc_errors) {
		/* [26]     disable rejection of FCS/CRC errors */
		reg_val |= ETH_XLNX_GEM_NWCFG_FCSIGNORE_BIT;
	}
	if (dev_conf->enable_rx_halfdup_while_tx) {
		/* [25]     RX half duplex while TX enable */
		reg_val |= ETH_XLNX_GEM_NWCFG_HDRXEN_BIT;
	}
	if (dev_conf->enable_rx_chksum_offload) {
		/* [24]     enable RX IP/TCP/UDP checksum offload */
		reg_val |= ETH_XLNX_GEM_NWCFG_RXCHKSUMEN_BIT;
	}
	if (dev_conf->disable_pause_copy) {
		/* [23]     Do not copy pause Frames to memory */
		reg_val |= ETH_XLNX_GEM_NWCFG_PAUSECOPYDI_BIT;
	}
	/* [22..21] Data bus width */
	reg_val |= (((uint32_t)(dev_conf->amba_dbus_width) &
		   ETH_XLNX_GEM_NWCFG_DBUSW_MASK) <<
		   ETH_XLNX_GEM_NWCFG_DBUSW_SHIFT);
	/* [20..18] MDC clock divider */
	reg_val |= (((uint32_t)dev_conf->mdc_divider &
		   ETH_XLNX_GEM_NWCFG_MDC_MASK) <<
		   ETH_XLNX_GEM_NWCFG_MDC_SHIFT);
	if (dev_conf->discard_rx_fcs) {
		/* [17]     Discard FCS from received frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_FCSREM_BIT;
	}
	if (dev_conf->discard_rx_length_errors) {
		/* [16]     RX length error discard */
		reg_val |= ETH_XLNX_GEM_NWCFG_LENGTHERRDSCRD_BIT;
	}
	/* [15..14] RX buffer offset */
	reg_val |= (((uint32_t)dev_conf->hw_rx_buffer_offset &
		   ETH_XLNX_GEM_NWCFG_RXOFFS_MASK) <<
		   ETH_XLNX_GEM_NWCFG_RXOFFS_SHIFT);
	if (dev_conf->enable_pause) {
		/* [13]     Enable pause TX */
		reg_val |= ETH_XLNX_GEM_NWCFG_PAUSEEN_BIT;
	}
	if (dev_conf->enable_tbi) {
		/* [11]     enable TBI instead of GMII/MII */
		reg_val |= ETH_XLNX_GEM_NWCFG_TBIINSTEAD_BIT;
	}
	if (dev_conf->ext_addr_match) {
		/* [09]     External address match enable */
		reg_val |= ETH_XLNX_GEM_NWCFG_EXTADDRMATCHEN_BIT;
	}
	if (dev_conf->enable_1536_frames) {
		/* [08]     Enable 1536 byte frames reception */
		reg_val |= ETH_XLNX_GEM_NWCFG_1536RXEN_BIT;
	}
	if (dev_conf->enable_ucast_hash) {
		/* [07]     Receive unicast hash frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_UCASTHASHEN_BIT;
	}
	if (dev_conf->enable_mcast_hash) {
		/* [06]     Receive multicast hash frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_MCASTHASHEN_BIT;
	}
	if (dev_conf->disable_bcast) {
		/* [05]     Do not receive broadcast frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_BCASTDIS_BIT;
	}
	if (dev_conf->copy_all_frames) {
		/* [04]     Copy all frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_COPYALLEN_BIT;
	}
	if (dev_conf->discard_non_vlan) {
		/* [02]     Receive only VLAN frames */
		reg_val |= ETH_XLNX_GEM_NWCFG_NVLANDISC_BIT;
	}
	if (dev_conf->enable_fdx) {
		/* [01]     enable Full duplex */
		reg_val |= ETH_XLNX_GEM_NWCFG_FDEN_BIT;
	}
	if (dev_conf->max_link_speed == LINK_100MBIT) {
		/* [00]     10 or 100 Mbps */
		reg_val |= ETH_XLNX_GEM_NWCFG_100_BIT;
	} else if (dev_conf->max_link_speed == LINK_1GBIT) {
		/* [10]     Gigabit mode enable */
		reg_val |= ETH_XLNX_GEM_NWCFG_1000_BIT;
	}
	/*
	 * No else-branch for 10Mbit/s mode:
	 * in 10 Mbit/s mode, both bits [00] and [10] remain 0
	 */

	/* Write the assembled register contents to gem.net_cfg */
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_NWCFG_OFFSET);
}

/**
 * @brief GEM Network Configuration Register link speed update function
 * Updates only the link speed-related bits of the Network Configuration
 * register. This is called from within #eth_xlnx_gem_poll_phy.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_set_nwcfg_link_speed(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_val;

	/*
	 * Read the current gem.net_cfg register contents and mask out
	 * the link speed-related bits
	 */
	reg_val  = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_NWCFG_OFFSET);
	reg_val &= ~(ETH_XLNX_GEM_NWCFG_1000_BIT | ETH_XLNX_GEM_NWCFG_100_BIT);

	/* No bits to set for 10 Mbps. 100 Mbps and 1 Gbps set one bit each. */
	if (dev_data->eff_link_speed == LINK_100MBIT) {
		reg_val |= ETH_XLNX_GEM_NWCFG_100_BIT;
	} else if (dev_data->eff_link_speed == LINK_1GBIT) {
		reg_val |= ETH_XLNX_GEM_NWCFG_1000_BIT;
	}

	/* Write the assembled register contents to gem.net_cfg */
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_NWCFG_OFFSET);
}

/**
 * @brief GEM MAC address setup function
 * Acquires the MAC address to be assigned to the current GEM device
 * from the device configuration data which in turn acquires it from
 * the device tree data, then writes it to the gem.spec_addr1_bot/LADDR1L
 * and gem.spec_addr1_top/LADDR1H registers. Called from within the device
 * initialization function.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_set_mac_address(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t regval_top;
	uint32_t regval_bot;

	regval_bot  = (dev_data->mac_addr[0] & 0xFF);
	regval_bot |= (dev_data->mac_addr[1] & 0xFF) << 8;
	regval_bot |= (dev_data->mac_addr[2] & 0xFF) << 16;
	regval_bot |= (dev_data->mac_addr[3] & 0xFF) << 24;

	regval_top  = (dev_data->mac_addr[4] & 0xFF);
	regval_top |= (dev_data->mac_addr[5] & 0xFF) << 8;

	sys_write32(regval_bot, dev_conf->base_addr + ETH_XLNX_GEM_LADDR1L_OFFSET);
	sys_write32(regval_top, dev_conf->base_addr + ETH_XLNX_GEM_LADDR1H_OFFSET);

	LOG_DBG("%s MAC %02X:%02X:%02X:%02X:%02X:%02X",
		dev->name,
		dev_data->mac_addr[0],
		dev_data->mac_addr[1],
		dev_data->mac_addr[2],
		dev_data->mac_addr[3],
		dev_data->mac_addr[4],
		dev_data->mac_addr[5]);
}

/**
 * @brief GEM initial DMA Control Register setup function
 * Writes the contents of the current GEM device's DMA Control Register
 * (DMACR / gem.dma_cfg). Called from within the device initialization
 * function.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_set_initial_dmacr(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	uint32_t reg_val = 0;

	/*
	 * gem.dma_cfg register bit (field) definitions:
	 * comp. Zynq-7000 TRM, p. 1278 ff.
	 */

	if (dev_conf->disc_rx_ahb_unavail) {
		/* [24] Discard RX packet when AHB unavailable */
		reg_val |= ETH_XLNX_GEM_DMACR_DISCNOAHB_BIT;
	}
	/*
	 * [23..16] DMA RX buffer size in AHB system memory
	 *    e.g.: 0x02 = 128, 0x18 = 1536, 0xA0 = 10240
	 */
	reg_val |= (((dev_conf->rx_buffer_size / 64) &
		   ETH_XLNX_GEM_DMACR_RX_BUF_MASK) <<
		   ETH_XLNX_GEM_DMACR_RX_BUF_SHIFT);
	if (dev_conf->enable_tx_chksum_offload) {
		/* [11] TX TCP/UDP/IP checksum offload to GEM */
		reg_val |= ETH_XLNX_GEM_DMACR_TCP_CHKSUM_BIT;
	}
	if (dev_conf->tx_buffer_size_full) {
		/* [10] TX buffer memory size select */
		reg_val |= ETH_XLNX_GEM_DMACR_TX_SIZE_BIT;
	}
	/*
	 * [09..08] RX packet buffer memory size select
	 *          0 = 1kB, 1 = 2kB, 2 = 4kB, 3 = 8kB
	 */
	reg_val |= (((uint32_t)dev_conf->hw_rx_buffer_size <<
		   ETH_XLNX_GEM_DMACR_RX_SIZE_SHIFT) &
		   ETH_XLNX_GEM_DMACR_RX_SIZE_MASK);
	if (dev_conf->enable_ahb_packet_endian_swap) {
		/* [07] AHB packet data endian swap enable */
		reg_val |= ETH_XLNX_GEM_DMACR_ENDIAN_BIT;
	}
	if (dev_conf->enable_ahb_md_endian_swap) {
		/* [06] AHB mgmt descriptor endian swap enable */
		reg_val |= ETH_XLNX_GEM_DMACR_DESCR_ENDIAN_BIT;
	}
	/*
	 * [04..00] AHB fixed burst length for DMA ops.
	 *          00001 = single AHB bursts,
	 *          001xx = attempt to use INCR4  bursts,
	 *          01xxx = attempt to use INCR8  bursts,
	 *          1xxxx = attempt to use INCR16 bursts
	 */
	reg_val |= ((uint32_t)dev_conf->ahb_burst_length &
		   ETH_XLNX_GEM_DMACR_AHB_BURST_LENGTH_MASK);

	/* Write the assembled register contents */
	sys_write32(reg_val, dev_conf->base_addr + ETH_XLNX_GEM_DMACR_OFFSET);
}

/**
 * @brief GEM associated PHY detection and setup function
 * If the current GEM device shall manage an associated PHY, its detection
 * and configuration is performed from within this function. Called from
 * within the device initialization function. This function refers to
 * functionality implemented in the phy_xlnx_gem module.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_init_phy(const struct device *dev)
{
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	int detect_rc;

	LOG_DBG("%s attempting to initialize associated PHY", dev->name);

	/*
	 * The phy_xlnx_gem_detect function checks if a valid PHY
	 * ID is returned when reading the corresponding high / low
	 * ID registers for all valid MDIO addresses. If a compatible
	 * PHY is detected, the function writes a pointer to the
	 * vendor-specific implementations of the PHY management
	 * functions to the run-time device data struct, along with
	 * the ID and the MDIO address of the detected PHY (dev_data->
	 * phy_id, dev_data->phy_addr, dev_data->phy_access_api).
	 */
	detect_rc = phy_xlnx_gem_detect(dev);

	if (detect_rc == 0 && dev_data->phy_id != 0x00000000 &&
			dev_data->phy_id != 0xFFFFFFFF &&
			dev_data->phy_access_api != NULL) {
		/* A compatible PHY was detected -> reset & configure it */
		dev_data->phy_access_api->phy_reset_func(dev);
		dev_data->phy_access_api->phy_configure_func(dev);
	} else {
		LOG_WRN("%s no compatible PHY detected", dev->name);
	}
}

/**
 * @brief GEM associated PHY status polling function
 * This handler of a delayed work item is called from the context of
 * the system work queue. It is always scheduled at least once during the
 * interface initialization. If the current driver instance manages a
 * PHY, the delayed work item will be re-scheduled in order to continuously
 * monitor the link state and speed while the device is active. Link state
 * and link speed changes are polled, which may result in the link state
 * change being propagated (carrier on/off) and / or the TX clock being
 * reconfigured to match the current link speed. If PHY management is dis-
 * abled for the current driver instance or no compatible PHY was detected,
 * the work item will not be re-scheduled and default link speed and link
 * state values are applied. This function refers to functionality imple-
 * mented in the phy_xlnx_gem module.
 *
 * @param work Pointer to the delayed work item which facilitates
 *             access to the current device's configuration data
 */
static void eth_xlnx_gem_poll_phy(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct eth_xlnx_gem_dev_data *dev_data = CONTAINER_OF(dwork,
		struct eth_xlnx_gem_dev_data, phy_poll_delayed_work);
	const struct device *dev = net_if_get_device(dev_data->iface);
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;

	uint16_t phy_status;
	uint8_t link_status;

	if (dev_data->phy_access_api != NULL) {
		/* A supported PHY is managed by the driver */
		phy_status = dev_data->phy_access_api->phy_poll_status_change_func(dev);

		if ((phy_status & (
			PHY_XLNX_GEM_EVENT_LINK_SPEED_CHANGED |
			PHY_XLNX_GEM_EVENT_LINK_STATE_CHANGED |
			PHY_XLNX_GEM_EVENT_AUTONEG_COMPLETE)) != 0) {

			/*
			 * Get the PHY's link status. Handling a 'link down'
			 * event the simplest possible case.
			 */
			link_status = dev_data->phy_access_api->phy_poll_link_status_func(dev);

			if (link_status == 0) {
				/*
				 * Link is down -> propagate to the Ethernet
				 * layer that the link has gone down.
				 */
				dev_data->eff_link_speed = LINK_DOWN;
				net_eth_carrier_off(dev_data->iface);

				LOG_WRN("%s link down", dev->name);
			} else {
				/*
				 * A link has been detected, which, depending
				 * on the driver's configuration, might have
				 * a different speed than the previous link.
				 * Therefore, the clock dividers must be ad-
				 * justed accordingly.
				 */
				dev_data->eff_link_speed =
					dev_data->phy_access_api->phy_poll_link_speed_func(dev);

				eth_xlnx_gem_configure_clocks(dev);
				eth_xlnx_gem_set_nwcfg_link_speed(dev);
				net_eth_carrier_on(dev_data->iface);

				LOG_INF("%s link up, %s", dev->name,
					(dev_data->eff_link_speed   == LINK_1GBIT)
					? "1 GBit/s"
					: (dev_data->eff_link_speed == LINK_100MBIT)
					? "100 MBit/s"
					: (dev_data->eff_link_speed == LINK_10MBIT)
					? "10 MBit/s" : "undefined / link down");
			}
		}

		/*
		 * Re-submit the delayed work using the interval from the device
		 * configuration data.
		 */
		k_work_reschedule(&dev_data->phy_poll_delayed_work,
				  K_MSEC(dev_conf->phy_poll_interval));
	} else {
		/*
		 * The current driver instance doesn't manage a PHY or no
		 * supported PHY was detected -> pretend the configured max.
		 * link speed is the effective link speed and that the link
		 * is up. The delayed work item won't be re-scheduled, as
		 * there isn't anything to poll for.
		 */
		dev_data->eff_link_speed = dev_conf->max_link_speed;

		eth_xlnx_gem_configure_clocks(dev);
		eth_xlnx_gem_set_nwcfg_link_speed(dev);
		net_eth_carrier_on(dev_data->iface);

		LOG_WRN("%s PHY not managed by the driver or no compatible "
			"PHY detected, assuming link up at %s", dev->name,
			(dev_conf->max_link_speed == LINK_1GBIT)
			? "1 GBit/s"
			: (dev_conf->max_link_speed == LINK_100MBIT)
			? "100 MBit/s"
			: (dev_conf->max_link_speed == LINK_10MBIT)
			? "10 MBit/s" : "undefined");
	}
}

/**
 * @brief GEM DMA memory area setup function
 * Sets up the DMA memory area to be used by the current GEM device.
 * Called from within the device initialization function or from within
 * the context of the PHY status polling delayed work handler.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_configure_buffers(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	struct eth_xlnx_gem_bd *bdptr;
	uint32_t buf_iter;

	/* Initial configuration of the RX/TX BD rings */
	DT_INST_FOREACH_STATUS_OKAY(ETH_XLNX_GEM_INIT_BD_RING)

	/*
	 * Set initial RX BD data -> comp. Zynq-7000 TRM, Chapter 16.3.5,
	 * "Receive Buffer Descriptor List". The BD ring data other than
	 * the base RX/TX buffer pointers will be set in eth_xlnx_gem_-
	 * iface_init()
	 */
	bdptr = dev_data->rxbd_ring.first_bd;

	for (buf_iter = 0; buf_iter < (dev_conf->rxbd_count - 1); buf_iter++) {
		/* Clear 'used' bit -> BD is owned by the controller */
		bdptr->ctrl = 0;
		bdptr->addr = (uint32_t)dev_data->first_rx_buffer +
			      (buf_iter * (uint32_t)dev_conf->rx_buffer_size);
		++bdptr;
	}

	/*
	 * For the last BD, bit [1] must be OR'ed in the buffer memory
	 * address -> this is the 'wrap' bit indicating that this is the
	 * last BD in the ring. This location is used as bits [1..0] can't
	 * be part of the buffer address due to alignment requirements
	 * anyways. Watch out: TX BDs handle this differently, their wrap
	 * bit is located in the BD's control word!
	 */
	bdptr->ctrl = 0; /* BD is owned by the controller */
	bdptr->addr = ((uint32_t)dev_data->first_rx_buffer +
		      (buf_iter * (uint32_t)dev_conf->rx_buffer_size)) |
		      ETH_XLNX_GEM_RXBD_WRAP_BIT;

	/*
	 * Set initial TX BD data -> comp. Zynq-7000 TRM, Chapter 16.3.5,
	 * "Transmit Buffer Descriptor List". TX BD ring data has already
	 * been set up in eth_xlnx_gem_iface_init()
	 */
	bdptr = dev_data->txbd_ring.first_bd;

	for (buf_iter = 0; buf_iter < (dev_conf->txbd_count - 1); buf_iter++) {
		/* Set up the control word -> 'used' flag must be set. */
		bdptr->ctrl = ETH_XLNX_GEM_TXBD_USED_BIT;
		bdptr->addr = (uint32_t)dev_data->first_tx_buffer +
			      (buf_iter * (uint32_t)dev_conf->tx_buffer_size);
		++bdptr;
	}

	/*
	 * For the last BD, set the 'wrap' bit indicating to the controller
	 * that this BD is the last one in the ring. -> For TX BDs, the 'wrap'
	 * bit isn't located in the address word, but in the control word
	 * instead
	 */
	bdptr->ctrl = (ETH_XLNX_GEM_TXBD_WRAP_BIT | ETH_XLNX_GEM_TXBD_USED_BIT);
	bdptr->addr = (uint32_t)dev_data->first_tx_buffer +
		      (buf_iter * (uint32_t)dev_conf->tx_buffer_size);

	/* Set free count/current index in the RX/TX BD ring data */
	dev_data->rxbd_ring.next_to_process = 0;
	dev_data->rxbd_ring.next_to_use     = 0;
	dev_data->rxbd_ring.free_bds        = dev_conf->rxbd_count;
	dev_data->txbd_ring.next_to_process = 0;
	dev_data->txbd_ring.next_to_use     = 0;
	dev_data->txbd_ring.free_bds        = dev_conf->txbd_count;

	/* Write pointers to the first RX/TX BD to the controller */
	sys_write32((uint32_t)dev_data->rxbd_ring.first_bd,
		    dev_conf->base_addr + ETH_XLNX_GEM_RXQBASE_OFFSET);
	sys_write32((uint32_t)dev_data->txbd_ring.first_bd,
		    dev_conf->base_addr + ETH_XLNX_GEM_TXQBASE_OFFSET);
}

/**
 * @brief GEM RX data pending handler wrapper for the work queue
 * Wraps the RX data pending handler, eth_xlnx_gem_handle_rx_pending,
 * for the scenario in which the current GEM device is configured
 * to defer RX pending / TX done indication handling to the system
 * work queue. In this case, the work item received by this wrapper
 * function will be enqueued from within the ISR if the corresponding
 * bit is set within the controller's interrupt status register
 * (gem.intr_status).
 *
 * @param item Pointer to the work item enqueued by the ISR which
 *             facilitates access to the current device's data
 */
static void eth_xlnx_gem_rx_pending_work(struct k_work *item)
{
	struct eth_xlnx_gem_dev_data *dev_data = CONTAINER_OF(item,
		struct eth_xlnx_gem_dev_data, rx_pend_work);
	const struct device *dev = net_if_get_device(dev_data->iface);

	eth_xlnx_gem_handle_rx_pending(dev);
}

/**
 * @brief GEM RX data pending handler
 * This handler is called either from within the ISR or from the
 * context of the system work queue whenever the RX data pending bit
 * is set in the controller's interrupt status register (gem.intr_status).
 * No further RX data pending interrupts will be triggered until this
 * handler has been executed, which eventually clears the corresponding
 * interrupt status bit. This function acquires the incoming packet
 * data from the DMA memory area via the RX buffer descriptors and copies
 * the data to a packet which will then be handed over to the network
 * stack.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_handle_rx_pending(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_addr;
	uint32_t reg_ctrl;
	uint32_t reg_val;
	uint32_t reg_val_rxsr;
	uint8_t first_bd_idx;
	uint8_t last_bd_idx;
	uint8_t	curr_bd_idx;
	uint32_t rx_data_length;
	uint32_t rx_data_remaining;
	struct net_pkt *pkt;

	/* Read the RX status register */
	reg_val_rxsr = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_RXSR_OFFSET);

	/*
	 * TODO Evaluate error flags from RX status register word
	 * here for proper error handling.
	 */

	while (1) {
		curr_bd_idx = dev_data->rxbd_ring.next_to_process;
		first_bd_idx = last_bd_idx = curr_bd_idx;
		reg_addr = (uint32_t)(&dev_data->rxbd_ring.first_bd[first_bd_idx].addr);
		reg_ctrl = (uint32_t)(&dev_data->rxbd_ring.first_bd[first_bd_idx].ctrl);

		/*
		 * Basic precondition checks for the current BD's
		 * address and control words
		 */
		reg_val = sys_read32(reg_addr);
		if ((reg_val & ETH_XLNX_GEM_RXBD_USED_BIT) == 0) {
			/*
			 * No new data contained in the current BD
			 * -> break out of the RX loop
			 */
			break;
		}
		reg_val = sys_read32(reg_ctrl);
		if ((reg_val & ETH_XLNX_GEM_RXBD_START_OF_FRAME_BIT) == 0) {
			/*
			 * Although the current BD is marked as 'used', it
			 * doesn't contain the SOF bit.
			 */
			LOG_ERR("%s unexpected missing SOF bit in RX BD [%u]",
				dev->name, first_bd_idx);
			break;
		}

		/*
		 * As long as the current BD doesn't have the EOF bit set,
		 * iterate forwards until the EOF bit is encountered. Only
		 * the BD containing the EOF bit also contains the length
		 * of the received packet which spans multiple buffers.
		 */
		do {
			reg_ctrl = (uint32_t)(&dev_data->rxbd_ring.first_bd[last_bd_idx].ctrl);
			reg_val  = sys_read32(reg_ctrl);
			rx_data_length = rx_data_remaining =
					 (reg_val & ETH_XLNX_GEM_RXBD_FRAME_LENGTH_MASK);
			if ((reg_val & ETH_XLNX_GEM_RXBD_END_OF_FRAME_BIT) == 0) {
				last_bd_idx = (last_bd_idx + 1) % dev_conf->rxbd_count;
			}
		} while ((reg_val & ETH_XLNX_GEM_RXBD_END_OF_FRAME_BIT) == 0);

		/*
		 * Store the position of the first BD behind the end of the
		 * frame currently being processed as 'next to process'
		 */
		dev_data->rxbd_ring.next_to_process = (last_bd_idx + 1) %
						      dev_conf->rxbd_count;

		/*
		 * Allocate a destination packet from the network stack
		 * now that the total frame length is known.
		 */
		pkt = net_pkt_rx_alloc_with_buffer(dev_data->iface, rx_data_length,
						   AF_UNSPEC, 0, K_NO_WAIT);
		if (pkt == NULL) {
			LOG_ERR("RX packet buffer alloc failed: %u bytes",
				rx_data_length);
#ifdef CONFIG_NET_STATISTICS_ETHERNET
			dev_data->stats.errors.rx++;
			dev_data->stats.error_details.rx_no_buffer_count++;
#endif
		}

		/*
		 * Copy data from all involved RX buffers into the allocated
		 * packet's data buffer. If we don't have a packet buffer be-
		 * cause none are available, we still have to iterate over all
		 * involved BDs in order to properly release them for re-use
		 * by the controller.
		 */
		do {
			if (pkt != NULL) {
				net_pkt_write(pkt, (const void *)
					      (dev_data->rxbd_ring.first_bd[curr_bd_idx].addr &
					      ETH_XLNX_GEM_RXBD_BUFFER_ADDR_MASK),
					      (rx_data_remaining < dev_conf->rx_buffer_size) ?
					      rx_data_remaining : dev_conf->rx_buffer_size);
			}
			rx_data_remaining -= (rx_data_remaining < dev_conf->rx_buffer_size) ?
					     rx_data_remaining : dev_conf->rx_buffer_size;

			/*
			 * The entire packet data of the current BD has been
			 * processed, on to the next BD -> preserve the RX BD's
			 * 'wrap' bit & address, but clear the 'used' bit.
			 */
			reg_addr = (uint32_t)(&dev_data->rxbd_ring.first_bd[curr_bd_idx].addr);
			reg_val	 = sys_read32(reg_addr);
			reg_val &= ~ETH_XLNX_GEM_RXBD_USED_BIT;
			sys_write32(reg_val, reg_addr);

			curr_bd_idx = (curr_bd_idx + 1) % dev_conf->rxbd_count;
		} while (curr_bd_idx != ((last_bd_idx + 1) % dev_conf->rxbd_count));

		/* Propagate the received packet to the network stack */
		if (pkt != NULL) {
			if (net_recv_data(dev_data->iface, pkt) < 0) {
				LOG_ERR("%s RX packet hand-over to IP stack failed",
					dev->name);
				net_pkt_unref(pkt);
			}
#ifdef CONFIG_NET_STATISTICS_ETHERNET
			else {
				dev_data->stats.bytes.received += rx_data_length;
				dev_data->stats.pkts.rx++;
			}
#endif
		}
	}

	/* Clear the RX status register */
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_RXSR_OFFSET);
	/* Re-enable the frame received interrupt source */
	sys_write32(ETH_XLNX_GEM_IXR_FRAME_RX_BIT,
		    dev_conf->base_addr + ETH_XLNX_GEM_IER_OFFSET);
}

/**
 * @brief GEM TX done handler wrapper for the work queue
 * Wraps the TX done handler, eth_xlnx_gem_handle_tx_done,
 * for the scenario in which the current GEM device is configured
 * to defer RX pending / TX done indication handling to the system
 * work queue. In this case, the work item received by this wrapper
 * function will be enqueued from within the ISR if the corresponding
 * bit is set within the controller's interrupt status register
 * (gem.intr_status).
 *
 * @param item Pointer to the work item enqueued by the ISR which
 *             facilitates access to the current device's data
 */
static void eth_xlnx_gem_tx_done_work(struct k_work *item)
{
	struct eth_xlnx_gem_dev_data *dev_data = CONTAINER_OF(item,
		struct eth_xlnx_gem_dev_data, tx_done_work);
	const struct device *dev = net_if_get_device(dev_data->iface);

	eth_xlnx_gem_handle_tx_done(dev);
}

/**
 * @brief GEM TX done handler
 * This handler is called either from within the ISR or from the
 * context of the system work queue whenever the TX done bit is set
 * in the controller's interrupt status register (gem.intr_status).
 * No further TX done interrupts will be triggered until this handler
 * has been executed, which eventually clears the corresponding
 * interrupt status bit. Once this handler reaches the end of its
 * execution, the eth_xlnx_gem_send call which effectively triggered
 * it is unblocked by posting to the current GEM's TX done semaphore
 * on which the send function is blocking.
 *
 * @param dev Pointer to the device data
 */
static void eth_xlnx_gem_handle_tx_done(const struct device *dev)
{
	const struct eth_xlnx_gem_dev_cfg *dev_conf = dev->config;
	struct eth_xlnx_gem_dev_data *dev_data = dev->data;
	uint32_t reg_ctrl;
	uint32_t reg_val;
	uint32_t reg_val_txsr;
	uint8_t curr_bd_idx;
	uint8_t first_bd_idx;
	uint8_t bds_processed = 0;
	uint8_t bd_is_last;

	/* Read the TX status register */
	reg_val_txsr = sys_read32(dev_conf->base_addr + ETH_XLNX_GEM_TXSR_OFFSET);

	/*
	 * TODO Evaluate error flags from TX status register word
	 * here for proper error handling
	 */

	if (dev_conf->defer_txd_to_queue) {
		k_sem_take(&(dev_data->txbd_ring.ring_sem), K_FOREVER);
	}

	curr_bd_idx = first_bd_idx = dev_data->txbd_ring.next_to_process;
	reg_ctrl = (uint32_t)(&dev_data->txbd_ring.first_bd[curr_bd_idx].ctrl);
	reg_val  = sys_read32(reg_ctrl);

	do {
		++bds_processed;

		/*
		 * TODO Evaluate error flags from current BD control word
		 * here for proper error handling
		 */

		/*
		 * Check if the BD we're currently looking at is the last BD
		 * of the current transmission
		 */
		bd_is_last = ((reg_val & ETH_XLNX_GEM_TXBD_LAST_BIT) != 0) ? 1 : 0;

		/*
		 * Reset control word of the current BD, clear everything but
		 * the 'wrap' bit, then set the 'used' bit
		 */
		reg_val &= ETH_XLNX_GEM_TXBD_WRAP_BIT;
		reg_val |= ETH_XLNX_GEM_TXBD_USED_BIT;
		sys_write32(reg_val, reg_ctrl);

		/* Move on to the next BD or break out of the loop */
		if (bd_is_last == 1) {
			break;
		}
		curr_bd_idx = (curr_bd_idx + 1) % dev_conf->txbd_count;
		reg_ctrl = (uint32_t)(&dev_data->txbd_ring.first_bd[curr_bd_idx].ctrl);
		reg_val  = sys_read32(reg_ctrl);
	} while (bd_is_last == 0 && curr_bd_idx != first_bd_idx);

	if (curr_bd_idx == first_bd_idx && bd_is_last == 0) {
		LOG_WRN("%s TX done handling wrapped around", dev->name);
	}

	dev_data->txbd_ring.next_to_process =
		(dev_data->txbd_ring.next_to_process + bds_processed) %
		dev_conf->txbd_count;
	dev_data->txbd_ring.free_bds += bds_processed;

	if (dev_conf->defer_txd_to_queue) {
		k_sem_give(&(dev_data->txbd_ring.ring_sem));
	}

	/* Clear the TX status register */
	sys_write32(0xFFFFFFFF, dev_conf->base_addr + ETH_XLNX_GEM_TXSR_OFFSET);

	/* Re-enable the TX complete interrupt source */
	sys_write32(ETH_XLNX_GEM_IXR_TX_COMPLETE_BIT,
		    dev_conf->base_addr + ETH_XLNX_GEM_IER_OFFSET);

	/* Indicate completion to a blocking eth_xlnx_gem_send() call */
	k_sem_give(&dev_data->tx_done_sem);
}
