/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (C) 2022, Intel Corporation
 * Description:
 * 3504-0 Universal 10/100/1000 Ethernet MAC (DWC_gmac)
 * Driver specifically designed for Cyclone V SoC DevKit use only.
 *
 * based on Intel SOC FPGA HWLIB Repo
 * https://github.com/altera-opensource/intel-socfpga-hwlib
 */

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

#define DT_DRV_COMPAT snps_ethernet_cyclonev

#include "eth_cyclonev_priv.h"

#include <stdio.h>

#include <zephyr/devicetree.h>
#include <zephyr/kernel.h>
#include <zephyr/net/ethernet.h>

#include "phy_cyclonev.c"
#include <ethernet/eth_stats.h>
#include <sys/types.h>
#include <zephyr/irq.h>
#define TX_AVAIL_WAIT	    K_MSEC(1)
#define INC_WRAP(idx, size) ({ idx = (idx + 1) % size; })

static const uint8_t eth_cyclonev_mac_addr[6] = DT_INST_PROP(0, local_mac_address);

void eth_cyclonev_reset(uint32_t instance);
void eth_cyclonev_set_mac_addr(uint8_t *address, uint32_t instance, uint32_t n,
				struct eth_cyclonev_priv *p);
int eth_cyclonev_get_software_reset_status(uint32_t instance, struct eth_cyclonev_priv *p);
int eth_cyclonev_software_reset(uint32_t instance, struct eth_cyclonev_priv *p);
void eth_cyclonev_setup_rxdesc(struct eth_cyclonev_priv *p);
void eth_cyclonev_setup_txdesc(struct eth_cyclonev_priv *p);
static void eth_cyclonev_iface_init(struct net_if *iface);
static int eth_cyclonev_send(const struct device *dev, struct net_pkt *pkt);
void eth_cyclonev_isr(const struct device *dev);
int set_mac_conf_status(int instance, uint32_t *mac_config_reg_settings,
				struct eth_cyclonev_priv *p);
int eth_cyclonev_probe(const struct device *dev);
static int eth_cyclonev_start(const struct device *dev);
static int eth_cyclonev_stop(const struct device *dev);
static void eth_cyclonev_receive(struct eth_cyclonev_priv *p);
static void eth_cyclonev_tx_release(struct eth_cyclonev_priv *p);
static int eth_cyclonev_set_config(const struct device *dev, enum ethernet_config_type type,
				const struct ethernet_config *config);
static enum ethernet_hw_caps eth_cyclonev_caps(const struct device *dev);

/** Device config */
struct eth_cyclonev_config {
	/** BBRAM base address */
	uint8_t *base;
	/** BBRAM size (Unit:bytes) */
	int size;
	int inst_num;
	void (*irq_config)(void);
};

/**
 * @brief Reset gmac device function
 * Function initialise HPS interface, see
 * https://www.intel.com/content/dam/www/programmable
 * /us/en/pdfs/literature/hb/cyclone-v/cv_54001.pdf p. 1252
 *
 * @param instance Number of instance (0 or 1 in Cyclone V HPS)
 */

void eth_cyclonev_reset(uint32_t instance)
{
	/*	 1. After the HPS is released from cold or warm reset,
	 *reset the Ethernet Controller module by setting the appropriate
	 *emac bit in the permodrst register in the Reset Manager.
	 */

	sys_set_bits(RSTMGR_PERMODRST_ADDR, Rstmgr_Permodrst_Emac_Set_Msk[instance]);

	/*	 4a. Set the physel_* field in the ctrl register of the System Manager
	 *(EMAC Group) to 0x1 to select the RGMII PHY interface.
	 */

	alt_replbits_word(SYSMGR_EMAC_ADDR, Sysmgr_Core_Emac_Phy_Intf_Sel_Set_Msk[instance],
			  Sysmgr_Emac_Phy_Intf_Sel_E_Rgmii[instance]);

	/*	 4b. Disable the Ethernet Controller FPGA interfaces by clearing the
	 * emac_* bit in the module register of the System Manager (FPGA Interface
	 * group).
	 */

	sys_clear_bits(SYSMGR_FPGAINTF_INDIV_ADDR, Sysmgr_Fpgaintf_En_3_Emac_Set_Msk[instance]);

	/*	 7. After confirming the settings are valid, software can clear the emac
	 * bit in the permodrst register of the Reset Manager to bring the EMAC out of
	 * reset.
	 */

	sys_clear_bits(RSTMGR_PERMODRST_ADDR, Rstmgr_Permodrst_Emac_Set_Msk[instance]);
}

/**
 * @brief Set MAC Address function
 * Loads the selected MAC Address in device's registers.
 *
 * @param address Pointer to Mac Address table
 * @param instance Number of instance (0 or 1 in Cyclone V HPS)
 * @param n Selected index of MAC Address, n <= 15. There's no implementation
 * of setting MAC Addresses for n > 15.
 *
 */

void eth_cyclonev_set_mac_addr(uint8_t *address, uint32_t instance, uint32_t n,
	struct eth_cyclonev_priv *p)
{
	uint32_t tmpreg;

	if (instance > 1) {
		return;
	}
	if (n > 15) {
		LOG_ERR("Invalid index of MAC Address: %d", n);
		return;
	}

	/* Calculate the selected MAC address high register */
	tmpreg = ((uint32_t)address[5] << 8) | (uint32_t)address[4];

	/* Load the selected MAC address high register */
	sys_write32(tmpreg, EMAC_GMAC_MAC_ADDR_HIGH_ADDR(p->base_addr, n));

	/* Calculate the selected MAC address low register */
	tmpreg = ((uint32_t)address[3] << 24) | ((uint32_t)address[2] << 16) |
		 ((uint32_t)address[1] << 8) | address[0];

	/* Load the selected MAC address low register */
	sys_write32(tmpreg, EMAC_GMAC_MAC_ADDR_LOW_ADDR(p->base_addr, n));
}

/**
 * @brief Get software reset status function
 * Check status of SWR bit in DMA Controller Bus_Mode Register
 *
 * @param instance Number of instance (0 or 1 in Cyclone V HPS)
 * @retval 1 if DMA Controller Resets Logic, 0 otherwise
 */

int eth_cyclonev_get_software_reset_status(uint32_t instance, struct eth_cyclonev_priv *p)
{
	if (instance > 1) {
		return -1;
	}
	return EMAC_DMA_MODE_SWR_GET(sys_read32(EMAC_DMAGRP_BUS_MODE_ADDR(p->base_addr)));
}

/**
 * @brief Perform software reset
 * Resets all MAC subsystem registers and logic, wait for the software reset to
 * clear
 *
 * @param instance Number of instance (0 or 1 in Cyclone V HPS)
 * @retval 0 if Reset was successful, -1 otherwise
 */

int eth_cyclonev_software_reset(uint32_t instance, struct eth_cyclonev_priv *p)
{
	unsigned int i;

	if (instance > 1) {
		return -1;
	}

	/* Set the SWR bit: resets all MAC subsystem internal registers and logic */
	/* After reset all the registers holds their respective reset values */
	sys_set_bits(EMAC_DMAGRP_BUS_MODE_ADDR(p->base_addr), EMAC_DMA_MODE_SWR_SET_MSK);

	/* Wait for the software reset to clear */
	for (i = 0; i < 10; i++) {
		k_sleep(K_MSEC(10));
		if (eth_cyclonev_get_software_reset_status(instance, p) == 0) {
			break;
		}
	}

	if (i == 10) {
		return -1;
	}

	return 0;
}

/**
 * @brief RX descriptor ring initialisation function
 * Sets up RX descriptor ring with chained descriptors,
 * sets OWN bit in each descriptor, inits rx variables and stats
 *
 * @param p Pointer to device structure.
 */

void eth_cyclonev_setup_rxdesc(struct eth_cyclonev_priv *p)
{
	int32_t i;
	struct eth_cyclonev_dma_desc *rx_desc;

	/* For each descriptor where i = descriptor index do: */
	for (i = 0; i < NB_RX_DESCS; i++) {
		rx_desc = &p->rx_desc_ring[i];
		rx_desc->buffer1_addr = (uint32_t)&p->rx_buf[i * ETH_BUFFER_SIZE];
		rx_desc->control_buffer_size = ETH_DMARXDESC_RCH | ETH_BUFFER_SIZE;

		/*set own bit*/
		rx_desc->status = ETH_DMARXDESC_OWN;

		rx_desc->buffer2_next_desc_addr = (uint32_t)&p->rx_desc_ring[i + 1];
		if (i == (NB_RX_DESCS - 1)) {
			rx_desc->buffer2_next_desc_addr = (uint32_t)&p->rx_desc_ring[0];
		}
	}

	p->rx_current_desc_number = 0;
	p->rxints = 0;

	/* Set RX Descriptor List Address Register */
	sys_write32((uint32_t)&p->rx_desc_ring[0],
		    EMAC_DMA_RX_DESC_LIST_ADDR(p->base_addr));
}

/**
 * @brief TX descriptor ring initialisation function
 * Sets up TX descriptor ring with chained descriptors,
 * sets OWN bit in each descriptor, inits rx variables and stats
 *
 * @param p Pointer to device structure.
 */

void eth_cyclonev_setup_txdesc(struct eth_cyclonev_priv *p)
{
	int32_t i;

	struct eth_cyclonev_dma_desc *tx_desc;

	/* For each descriptor where i = descriptor index do: */
	for (i = 0; i < NB_TX_DESCS; i++) {
		tx_desc = &p->tx_desc_ring[i];
		tx_desc->buffer1_addr = (uint32_t)&p->tx_buf[i * ETH_BUFFER_SIZE];
		tx_desc->buffer2_next_desc_addr = (uint32_t)&p->tx_desc_ring[i + 1];
		tx_desc->status = 0;
		tx_desc->control_buffer_size = 0;

		if (i == (NB_TX_DESCS - 1)) {
			tx_desc->buffer2_next_desc_addr = (uint32_t)&p->tx_desc_ring[0];
		}
	}

	p->tx_current_desc_number = 0;
	p->txints = 0;
	p->tx_tail = 0;

	/* Set TX Descriptor List Address Register */
	sys_write32((uint32_t)&p->tx_desc_ring[0],
		    EMAC_DMA_TX_DESC_LIST_ADDR(p->base_addr));
}

/**
 * @brief Ethernet interface initialisation function
 * Inits interface, sets interface link MAC address
 *
 * @param iface Pointer to net_if structure
 */

/* Initialisation of interface */
static void eth_cyclonev_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	const struct eth_cyclonev_config *config = dev->config;
	struct eth_cyclonev_priv *p = dev->data;

	p->iface = iface;
	ethernet_init(iface);
	net_if_set_link_addr(iface, p->mac_addr, sizeof(p->mac_addr), NET_LINK_ETHERNET);

	/*
	 * Semaphores are used to represent number of available descriptors.
	 * The total is one less than ring size in order to always have
	 * at least one inactive slot for the hardware tail pointer to
	 * stop at and to prevent our head indexes from looping back
	 * onto our tail indexes.
	 */
	k_sem_init(&p->free_tx_descs, NB_TX_DESCS - 1, NB_TX_DESCS - 1);

	/* Initialize the ethernet irq handler */
	config->irq_config();

	p->initialised = 1;
	LOG_DBG("done");
}

/**
 * @brief Ethernet set config function usually called by
 *	Zephyr Ethernet stack. It supports currently two options:
 *	Set of Mac address and Enabling Promiscuous Mode
 *
 * @param dev Pointer to net_if structure
 * @param type Enumerated type of configuration to do
 * @param config Pointer to ethernet_config structure
 * @retval ret 0 if successful
 */

static int eth_cyclonev_set_config(const struct device *dev, enum ethernet_config_type type,
				   const struct ethernet_config *config)
{
	struct eth_cyclonev_priv *p = dev->data;
	uint32_t reg_val;
	int ret = 0;

	(void)reg_val; /* silence the "unused variable" warning */

	switch (type) {
	case ETHERNET_CONFIG_TYPE_MAC_ADDRESS:
		memcpy(p->mac_addr, config->mac_address.addr, sizeof(p->mac_addr));
		eth_cyclonev_set_mac_addr(p->mac_addr, p->instance, 0, p); /* Set MAC address */
		net_if_set_link_addr(p->iface, p->mac_addr, sizeof(p->mac_addr), NET_LINK_ETHERNET);
		break;
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
	case ETHERNET_CONFIG_TYPE_PROMISC_MODE:
		reg_val = sys_read32(EMAC_GMACGRP_MAC_FRAME_FILTER_ADDR(p->base_addr));
		if (config->promisc_mode && !(reg_val & EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK)) {
			/* Turn on Promisc Mode */
			sys_set_bits(EMAC_GMACGRP_MAC_FRAME_FILTER_ADDR(p->base_addr),
				     EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK);
		} else if (!config->promisc_mode &&
			   (reg_val & EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK)) {
			/* Turn off Promisc Mode */
			sys_clear_bits(EMAC_GMACGRP_MAC_FRAME_FILTER_ADDR(p->base_addr),
				       EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK);
		} else {
			ret = -EALREADY;
		}
		break;
#endif
	default:
		ret = -ENOTSUP;
		break;
	}
	LOG_DBG("set_config: ret = %d ", ret);
	return ret;
}

/**
 * @brief Get capabilities function usually called by
 *	Zephyr Ethernet stack.
 *
 * @param dev Pointer to net_if structure
 * @retval caps Enumerated capabilities of device
 */

static enum ethernet_hw_caps eth_cyclonev_caps(const struct device *dev)
{
	struct eth_cyclonev_priv *p = dev->data;
	enum ethernet_hw_caps caps = 0;

	if (p->feature & EMAC_DMA_HW_FEATURE_MIISEL) {
		caps |= ETHERNET_LINK_10BASE_T;
		caps |= ETHERNET_LINK_100BASE_T;
	}
	if (p->feature & EMAC_DMA_HW_FEATURE_GMIISEL) {
		caps |= ETHERNET_LINK_1000BASE_T;
	}
	if (p->feature & EMAC_DMA_HW_FEATURE_RXTYP2COE) {
		caps |= ETHERNET_HW_RX_CHKSUM_OFFLOAD;
	}
	if (p->feature & EMAC_DMA_HW_FEATURE_RXTYP1COE) {
		caps |= ETHERNET_HW_RX_CHKSUM_OFFLOAD;
	}

	caps |= ETHERNET_PROMISC_MODE;

	return caps;
}

/**
 * @brief Send packet function
 * Sends packet of data. See:
 * https://www.intel.com/content/dam/www/programmable/us/en/pdfs/
 * literature/hb/cyclone-v/cv_54001.pdf p.1254 and p.1206
 *
 * @param dev Pointer to device structure
 * @param pkt Pointer to net_pkt structure containing packet to sent
 * @retval 0 if successful, -1 otherwise
 */

static int eth_cyclonev_send(const struct device *dev, struct net_pkt *pkt)
{
	LOG_DBG("ethernet CVSX sending...\n");

	struct eth_cyclonev_priv *p = dev->data;
	struct eth_cyclonev_dma_desc *tx_desc;
	int32_t index = 0;
	uint16_t len = net_pkt_get_len(pkt);
	int first = 1;
	struct net_buf *frag;

	LOG_DBG("Pkt length: %d", len);
	frag = pkt->buffer;
	do {

		/* reserve a free descriptor for this fragment */
		if (k_sem_take(&p->free_tx_descs, TX_AVAIL_WAIT) != 0) {
			LOG_DBG("no more free tx descriptors");
			goto abort;
		}

		tx_desc = &p->tx_desc_ring[p->tx_current_desc_number];

		/* Check if it is a free descriptor.  */
		if (tx_desc->status & ETH_DMATXDESC_OWN) {
			/* Buffer is still owned by device.  */
			LOG_ERR("No free tx descriptors!\n");
			goto abort;
		}

		/* check if len is too large */
		if (len >= ETH_BUFFER_SIZE) {
			LOG_ERR("Length of packet is too long\n");
			goto abort;
		}

		/* Copy data to local buffer   */

		if (frag) {
			memcpy(&p->tx_buf[p->tx_current_desc_number * ETH_BUFFER_SIZE], frag->data,
			       len);
		}

		/* Set the buffer size.  */
		tx_desc->control_buffer_size = (frag->len & ETH_DMATXDESC_TBS1);

		LOG_DBG("Desc[%d] at address: 0x%08x: , Frag size: %d, Buffer Addr: %p",
			p->tx_current_desc_number,
			(unsigned int)&p->tx_desc_ring[p->tx_current_desc_number], frag->len,
			(void *)tx_desc->buffer1_addr);

		tx_desc->status = ETH_DMATXDESC_TCH;

		/* Set the Descriptor's FS bit.  */
		if (first) {
			tx_desc->status |= (ETH_DMATXDESC_FS | ETH_DMATXDESC_CIC_BYPASS);
			first = 0;
		}

		/* If Last: then (...) */
		if (!frag->frags) {
			/* set the Descriptor's LS and IC bit.  */
			tx_desc->status |= (ETH_DMATXDESC_LS | ETH_DMATXDESC_IC);
			index = p->tx_current_desc_number;
		}

		/* Set the current index to the next descriptor.  */
		p->tx_current_desc_number = (p->tx_current_desc_number + 1);
		if (p->tx_current_desc_number >= NB_TX_DESCS) {
			p->tx_current_desc_number = 0;
		}

		if (!frag->frags) {

			while (1) {

				tx_desc = &p->tx_desc_ring[index];

				if (tx_desc->status & ETH_DMATXDESC_OWN) {
					LOG_ERR("Send packet error!\n");
					/* Restart DMA transmission and re-initialise
					 * TX descriptors
					 */
					sys_clear_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(
							       p->base_addr),
						       EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK);
					sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(
							     p->base_addr),
						     EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK);
					eth_cyclonev_setup_txdesc(p);
					sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(
							     p->base_addr),
						     EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK);
					goto abort;
				}

				/* Set OWN bit.  */
				tx_desc->status |= ETH_DMATXDESC_OWN;

				if (tx_desc->status & ETH_DMATXDESC_FS) {
					break;
				}

				index--;
				if (index < 0) {
					index = NB_TX_DESCS - 1;
				}
			}

			LOG_DBG("Current Host Transmit Descriptor Register: 0x%08x",
				sys_read32(
					EMAC_DMA_CURR_HOST_TX_DESC_ADDR(p->base_addr)));
			LOG_DBG("Current Host Transmit Buffer Register: 0x%08x",
				sys_read32(
					EMAC_DMA_CURR_HOST_TX_BUFF_ADDR(p->base_addr)));

			/* If the DMA transmission is suspended, resume transmission.  */
			if (sys_read32(EMAC_DMAGRP_STATUS_ADDR(p->base_addr)) &
			    EMAC_DMAGRP_STATUS_TS_SET_MSK) {

				/* Clear TBUS ETHERNET DMA flag */
				sys_write32(EMAC_DMAGRP_STATUS_TS_SET_MSK,
					    EMAC_DMAGRP_STATUS_ADDR(p->base_addr));

				/* Resume DMA transmission */
				sys_write32(0,
					    EMAC_DMA_TX_POLL_DEMAND_ADDR(p->base_addr));
			}
		}
		frag = frag->frags;
	} while (frag);

	LOG_DBG("Sent");
	return 0;

abort:
	k_sem_give(&p->free_tx_descs); /* Multi-descriptor package release (?) */

	return -1;
}

/**
 * @brief Interrupt handling function
 * Detects interrupt status, invokes necessary actions
 * and clears interrupt status register
 *
 * @param dev Pointer to device structure
 */

void eth_cyclonev_isr(const struct device *dev)
{
	struct eth_cyclonev_priv *p = dev->data;
	uint32_t irq_status = 0;
	uint32_t irq_status_emac = 0;

	irq_status =
		sys_read32(EMAC_DMAGRP_STATUS_ADDR(p->base_addr)) & p->interrupt_mask;
	irq_status_emac = sys_read32(EMAC_GMAC_INT_STAT_ADDR(p->base_addr));
	LOG_DBG("DMA_IRQ_STATUS = 0x%08x, emac: 0x%08x", irq_status, irq_status_emac);

	if (irq_status & EMAC_DMA_INT_EN_NIE_SET_MSK) {
		sys_write32(EMAC_DMA_INT_EN_NIE_SET_MSK,
			    EMAC_DMAGRP_STATUS_ADDR(p->base_addr));
	}

	if (irq_status & EMAC_DMA_INT_EN_TIE_SET_MSK) {
		p->txints++;
		eth_cyclonev_tx_release(p);
		/* Clear the selected ETHERNET DMA bit(s) */
		sys_write32(EMAC_DMA_INT_EN_TIE_SET_MSK,
			    EMAC_DMAGRP_STATUS_ADDR(p->base_addr));
	}

	if (irq_status & EMAC_DMA_INT_EN_RIE_SET_MSK) {
		p->rxints++;
		eth_cyclonev_receive(p);
		/* Clear the selected ETHERNET DMA bit(s) */
		sys_write32(EMAC_DMA_INT_EN_RIE_SET_MSK,
			    EMAC_DMAGRP_STATUS_ADDR(p->base_addr));
	}

	if (irq_status_emac & EMAC_GMAC_INT_STAT_RGSMIIIS_SET_MSK) {
		/* Clear the selected ETHERNET GMAC bit(s) */
		uint32_t regval = sys_read32(GMACGRP_CONTROL_STATUS_ADDR(p->base_addr));

		if (EMAC_GMAC_MII_CTL_STAT_LNKSTS_GET(regval)) {
			LOG_INF("Link is up");
		} else {
			LOG_INF("Link is down");
			return;
		}

		if (EMAC_GMAC_MII_CTL_STAT_LNKMOD_GET(regval)) {
			LOG_INF("Full duplex");
		} else {
			LOG_INF("Half duplex");
		}

		switch (EMAC_GMAC_MII_CTL_STAT_LNKSPEED_GET(regval)) {
		case 0:
			LOG_INF("Link Speed 2.5MHz");
			break;
		case 1:
			LOG_INF("Link Speed 25MHz");
			break;
		case 2:
			LOG_INF("Link Speed 125MHz");
			break;
		default:
			LOG_ERR("LNKSPEED_GET_ERROR");
			break;
		}

		if (p->initialised) {
			uint32_t cfg_reg_set;

			cfg_reg_set = sys_read32(GMACGRP_MAC_CONFIG_ADDR(p->base_addr));

			if (eth_cyclonev_stop(dev) == -1) {
				LOG_ERR("Couldn't stop device: %s", dev->name);
				return;
			}

			set_mac_conf_status(p->instance, &cfg_reg_set, p);
			sys_write32(cfg_reg_set, GMACGRP_MAC_CONFIG_ADDR(p->base_addr));

			eth_cyclonev_start(dev);
		}
	}
}

/**
 * @brief Receive packet function (IRQ)
 * In the event of receive completion interrupt, this function
 * copies data from buffer to necessary net stack structures
 * performs general error checking and returns descriptor to hardware.
 *
 * @param p Pointer to device structure
 *
 */

static void eth_cyclonev_receive(struct eth_cyclonev_priv *p)
{
	struct eth_cyclonev_dma_desc *rx_desc;
	struct net_pkt *pkt;
	uint32_t index, frame_length, rx_search, wrap, data_remaining, last_desc_index, buf_size;

	index = p->rx_current_desc_number;
	rx_desc = &p->rx_desc_ring[index];

	while (!(rx_desc->status & ETH_DMARXDESC_OWN)) {

		LOG_DBG("RDES0[%d] = 0x%08x", index, rx_desc->status);
		/* Look for FS bit */
		if (!(rx_desc->status & ETH_DMARXDESC_FS)) {
			LOG_ERR("Unexpected missing FS bit");
			rx_desc->status |= ETH_DMARXDESC_OWN;
			goto cont;
		}
		/* Look for EOF bit, save frame length including multiple
		 * buffers and index of last descriptor
		 */
		rx_search = index;
		wrap = index;
		do {
			rx_desc = &p->rx_desc_ring[rx_search];
			/* Frame length */
			frame_length = data_remaining = (ETH_DMARXDESC_FL & rx_desc->status) >> 16;
			last_desc_index = rx_search;
			if (!(rx_desc->status & ETH_DMARXDESC_LS)) {
				INC_WRAP(rx_search, NB_RX_DESCS);
				if (rx_search == wrap) {
					LOG_ERR("Couldn't find EOF bit!");
					rx_desc = &p->rx_desc_ring[index];
					rx_desc->status |= ETH_DMARXDESC_OWN;
					goto cont;
				}
			}
		} while (!(rx_desc->status & ETH_DMARXDESC_LS));

		LOG_DBG("Frame length = %d, Last descriptor = %d", frame_length, last_desc_index);
		p->rx_current_desc_number = last_desc_index;

		/* Allocate packet with buffer */
		pkt = net_pkt_rx_alloc_with_buffer(p->iface, frame_length, AF_UNSPEC, 0, K_NO_WAIT);
		if (!pkt) {
			LOG_ERR("net_pkt_rx_alloc_with_buffer() failed");
			eth_stats_update_errors_rx(p->iface);
		}

		/* Copy data from multiple buffers and descriptors */
		rx_search = index;
		wrap = index;
		do {
			rx_desc = &p->rx_desc_ring[rx_search];
			if (data_remaining < ETH_BUFFER_SIZE) {
				buf_size = data_remaining;
			} else {
				buf_size = ETH_BUFFER_SIZE;
			}
			if (pkt) {
				net_pkt_write(pkt, &p->rx_buf[rx_search * ETH_BUFFER_SIZE],
					      buf_size);
			}
			data_remaining -= buf_size;
			rx_desc->status |= ETH_DMARXDESC_OWN;
			if (last_desc_index != rx_search) {
				INC_WRAP(rx_search, NB_RX_DESCS);
				if (rx_search == wrap) {
					LOG_ERR("Couldn't find last descriptor! Data remaining: %d",
						data_remaining);
					goto cont;
				}
				if (rx_search == last_desc_index) {
					/* One more iteration */
					rx_desc = &p->rx_desc_ring[rx_search];
					if (data_remaining < ETH_BUFFER_SIZE) {
						buf_size = data_remaining;
					} else {
						buf_size = ETH_BUFFER_SIZE;
					}
					if (pkt) {
						net_pkt_write(
							pkt,
							&p->rx_buf[rx_search * ETH_BUFFER_SIZE],
							buf_size);
					}
					data_remaining -= buf_size;

					rx_desc->status |= ETH_DMARXDESC_OWN;
				}
			}
		} while (last_desc_index != rx_search);

		/* Hand-over packet into IP stack */
		if (pkt) {
			if (net_recv_data(p->iface, pkt) < 0) {
				LOG_ERR("RX packet hand-over to IP stack failed");
				net_pkt_unref(pkt);
			}
			LOG_DBG("Received packet %p, len %d", pkt, frame_length);
		}

cont:
		p->rx_current_desc_number++;
		if (p->rx_current_desc_number == NB_RX_DESCS) {
			p->rx_current_desc_number = 0;
		}
		index = p->rx_current_desc_number;
		rx_desc = &p->rx_desc_ring[index];
	}
}

/**
 * @brief Release tx function
 * Main purpose of its function is to track current descriptor number
 * and give back succeding tx semaphore when it have been used.
 *
 * @param p Pointer to device structure
 */

static void eth_cyclonev_tx_release(struct eth_cyclonev_priv *p)
{
	unsigned int d_idx;
	struct eth_cyclonev_dma_desc *d;
	uint32_t des3_val;

	for (d_idx = p->tx_tail; d_idx != p->tx_current_desc_number;
	     INC_WRAP(d_idx, NB_TX_DESCS), k_sem_give(&p->free_tx_descs)) {

		d = &p->tx_desc_ring[d_idx];
		des3_val = d->status;
		LOG_DBG("TDES3[%d] = 0x%08x", d_idx, des3_val);

		/* stop here if hardware still owns it */
		if (des3_val & ETH_DMATXDESC_OWN) {
			break;
		}

		/* last packet descriptor: */
		if (des3_val & ETH_DMATXDESC_LS) {
			/* log any errors */
			if (des3_val & ETH_DMATXDESC_ES) {
				LOG_ERR("tx error (DES3 = 0x%08x)", des3_val);
				eth_stats_update_errors_tx(p->iface);
			}
		}
	}
	p->tx_tail = d_idx;
}

/**
 * @brief Sets MAC Config Register (not implemented)
 * Detects PHY Mode and assigns MAC Config Register
 *
 * @param instance Number of instance (0 or 1 in Cyclone V HPS)
 * @param mac_config_reg_settings Mac_config register mask to set
 * @retval updated mac_config_reg mask (>=0), -1 otherwise
 */
/* Configure the MAC with the speed fixed by the auto-negotiation process */
int set_mac_conf_status(int instance, uint32_t *mac_config_reg_settings,
	struct eth_cyclonev_priv *p)
{
	uint16_t phy_duplex_status, phy_speed;
	int ret;

	ret = alt_eth_phy_get_duplex_and_speed(&phy_duplex_status, &phy_speed, instance, p);
	if (ret != 0) {
		LOG_ERR("alt_eth_phy_get_duplex_and_speed failure!");
		return ret;
	}

	/* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */
	if (phy_duplex_status != 0) {
		*mac_config_reg_settings |= EMAC_GMACGRP_MAC_CONFIGURATION_DM_SET_MSK;
	}
	/* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */
	else {
		*mac_config_reg_settings &= ~EMAC_GMACGRP_MAC_CONFIGURATION_DM_SET_MSK;
	}

	/* Set Ethernet speed to 10M following the auto-negotiation */
	if (phy_speed == 10) {
		*mac_config_reg_settings &= ~EMAC_GMACGRP_MAC_CONFIGURATION_FES_SET_MSK;
		*mac_config_reg_settings |= EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK;
	}

	/* Set Ethernet speed to 100M following the auto-negotiation */
	if (phy_speed == 100) {
		*mac_config_reg_settings |= EMAC_GMACGRP_MAC_CONFIGURATION_FES_SET_MSK;
		*mac_config_reg_settings |= EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK;
	}

	/* Set Ethernet speed to 1G following the auto-negotiation */
	if (phy_speed == 1000) {
		*mac_config_reg_settings &= ~EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK;
	}

	return 0;
}

/**
 * @brief Hardware initialisation function
 * Performs EMAC HPS interface initialisation, DMA initialisation,
 * EMAC initialisation and configuration. See:
 * https://www.intel.com/content/dam/
 * www/programmable/us/en/pdfs/literature/hb/cyclone-v/cv_54001.pdf p.1252-54
 *
 * @param dev Pointer to device structure
 * @retval 0 if successful, -1 otherwise
 */

int eth_cyclonev_probe(const struct device *dev)
{
	struct eth_cyclonev_priv *p = dev->data;
	const struct eth_cyclonev_config *config = dev->config;
	uint32_t tmpreg = 0, interrupt_mask;
	uint32_t mac_config_reg_settings = 0;
	int ret;

	p->base_addr = (mem_addr_t)config->base;
	p->running = 0;
	p->initialised = 0;
	p->instance = config->inst_num;

	/* EMAC HPS Interface Initialization */

	/* Reset the EMAC */
	eth_cyclonev_reset(p->instance);

	/* Reset the PHY  */
	ret = alt_eth_phy_reset(p->instance, p);
	if (ret != 0) {
		LOG_ERR("alt_eth_phy_reset failure!\n");
		return ret;
	}

	/* Configure the PHY */
	ret = alt_eth_phy_config(p->instance, p);
	if (ret != 0) {
		LOG_ERR("alt_eth_phy_config failure!\n");
		return ret;
	}

	/* Read HW feature register */

	p->feature = sys_read32(EMAC_DMA_HW_FEATURE_ADDR(p->base_addr));

	/* DMA Initialisation */

	/* 1. Provide a software reset to reset all of the EMAC internal registers and
	 *logic. (DMA Register 0 (BusMode Register) – bit 0).
	 * 2. Wait for the completion of the reset process (poll bit 0 of the DMA
	 *Register 0 (Bus Mode Register), which is only cleared after the reset
	 *operation is completed).
	 */

	ret = eth_cyclonev_software_reset(p->instance, p);
	if (ret != 0) {
		LOG_ERR("eth_cyclonev_software_reset failure!\n");
		return ret;
	}

	/* 4. Program the following fields to initialize the Bus Mode Register by
	 * setting values in DMA Register 0 (Bus Mode Register):
	 */

	sys_write32((tmpreg | EMAC_DMA_MODE_FB_SET_MSK /* Fixed Burst */
		     ),
		    EMAC_DMAGRP_BUS_MODE_ADDR(p->base_addr));

	/*	 5. Program the interface options in Register 10 (AXI Bus Mode
	 * Register). If fixed burst-length is enabled, then select the maximum
	 * burst-length possible on the bus (bits[7:1]).(58)
	 */

	tmpreg = sys_read32(EMAC_DMAGRP_AXI_BUS_MODE_ADDR(p->base_addr));

	sys_write32(
		tmpreg | EMAC_DMAGRP_AXI_BUS_MODE_BLEN16_SET_MSK,
		EMAC_DMAGRP_AXI_BUS_MODE_ADDR(p->base_addr)); /* Set Burst Length = 16 */

	/* 6. Create a proper descriptor chain for transmit and receive. In addition,
	 * ensure that the receive descriptors are owned by DMA (bit 31 of descriptor
	 * should be set).
	 * 7. Make sure that your software creates three or more different transmit or
	 * receive descriptors in the chain before reusing any of the descriptors
	 * 8. Initialize receive and transmit descriptor list address with the base
	 * address of the transmit and receive descriptor (Register 3 (Receive
	 * Descriptor List Address Register) and Register 4 (Transmit Descriptor List
	 * Address Register) respectively).
	 */

	eth_cyclonev_setup_rxdesc(p);
	eth_cyclonev_setup_txdesc(p);

	/*	9. Program the following fields to initialize the mode of operation in
	 * Register 6 (Operation Mode Register):
	 */

	sys_write32((0 | EMAC_DMAGRP_OPERATION_MODE_TSF_SET_MSK /* Transmit Store and Forward */
		     | EMAC_DMAGRP_OPERATION_MODE_RSF_SET_MSK	/* Receive Store and Forward */
		     | EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK	/* Receive Store and Forward */
		     ),
		    EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr));

	/*	10.Clear the interrupt requests, by writing to those bits of the status
	 * register (interrupt bits only) that are set. For example, by writing 1 into
	 * bit 16, the normal interrupt summary clears this bit (DMA Register 5
	 * (Status Register)).
	 */

	interrupt_mask = EMAC_DMA_INT_EN_NIE_SET_MSK | EMAC_DMA_INT_EN_RIE_SET_MSK |
			 EMAC_DMA_INT_EN_TIE_SET_MSK;

	p->interrupt_mask = interrupt_mask;

	/* Clear the selected ETHERNET DMA bit(s) */
	sys_write32(interrupt_mask, EMAC_DMAGRP_STATUS_ADDR(p->base_addr));

	/*	11.Enable the interrupts by programming Register 7 (Interrupt Enable
	 * Register).
	 */

	sys_set_bits(EMAC_DMA_INT_EN_ADDR(p->base_addr), interrupt_mask);

	/* 12.Read Register 11 (AHB or AXI Status) to confirm that
	 * all previous transactions are complete.
	 */

	if (sys_read32(EMAC_DMAGRP_AHB_OR_AXI_STATUS_ADDR(p->base_addr)) != 0) {
		LOG_ERR("AHB_OR_AXI_STATUS Fail!\n");
		return -1;
	}

	/* EMAC Initialization and Configuration */

	/*	1. Program the GMII Address Register (offset 0x10) for controlling the
	 * management cycles for theexternal PHY. Bits[15:11] of the GMII Address
	 * Register are written with the Physical Layer Address of the PHY before
	 * reading or writing. Bit 0 indicates if the PHY is busy and is set before
	 * reading or writing to the PHY management interface.
	 * 2. Read the 16-bit data of the GMII Data Register from the PHY for link up,
	 * speed of operation, and mode of operation, by specifying the appropriate
	 * address value in bits[15:11] of the GMII Address Register.
	 */

	mac_config_reg_settings = (EMAC_GMACGRP_MAC_CONFIGURATION_IPC_SET_MSK
				   /* Checksum Offload */
				   | EMAC_GMACGRP_MAC_CONFIGURATION_JD_SET_MSK
				   /* Jabber Disable */
				   | EMAC_GMACGRP_MAC_CONFIGURATION_BE_SET_MSK
				   /* Frame Burst Enable */
				   | EMAC_GMACGRP_MAC_CONFIGURATION_WD_SET_MSK
				   /* Watchdog Disable */
				   | EMAC_GMACGRP_MAC_CONFIGURATION_TC_SET_MSK
				   /* Enable Transmission to PHY */
	);

	ret = set_mac_conf_status(p->instance, &mac_config_reg_settings, p);
	if (ret != 0) {
		return -1;
	}

	/*	3. Provide the MAC address registers (MAC Address0 High Register
	 * through MAC Address15 High Register and MAC Address0 Low Register
	 * through MAC Address15 Low Register).
	 */

	memcpy(p->mac_addr, eth_cyclonev_mac_addr, sizeof(p->mac_addr));
	eth_cyclonev_set_mac_addr(p->mac_addr, p->instance, 0, p);

	/* 5. Program the following fields to set the appropriate filters for the
	 * incoming frames in the MAC Frame Filter Register:
	 * • Receive All
	 * • Promiscuous mode
	 * • Hash or Perfect Filter
	 * • Unicast, multicast, broadcast, and control frames filter settings
	 */

	sys_clear_bits(EMAC_GMACGRP_MAC_FRAME_FILTER_ADDR(p->base_addr),
		       EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK); /* Disable promiscuous mode */

	/*	7. Program the Interrupt Mask Register bits,
	 * as required and if applicable for your configuration.
	 */

	sys_set_bits(EMAC_GMAC_INT_MSK_ADDR(p->base_addr),
		     EMAC_GMAC_INT_STAT_LPIIS_SET_MSK |	       /* Disable Low Power IRQ */
			     EMAC_GMAC_INT_STAT_TSIS_SET_MSK); /* Disable Timestamp IRQ */

	/* 8. Program the appropriate fields in MAC Configuration Register to
	 * configure receive and transmit operation modes...
	 */

	sys_write32(mac_config_reg_settings, GMACGRP_MAC_CONFIG_ADDR(p->base_addr));

	LOG_DBG("func_eth_cyclonev_probe Success!\n");
	return 0;
}

/**
 * @brief Start device function
 * Starts DMA and EMAC transmitter and receiver. See:
 * https://www.intel.com/content/dam/
 * www/programmable/us/en/pdfs/literature/hb/cyclone-v/cv_54001.pdf p.1255-56
 *
 * @param dev Pointer to device structure
 * @retval 0
 */

static int eth_cyclonev_start(const struct device *dev)
{

	struct eth_cyclonev_priv *p = dev->data;

	if (p->running) {
		LOG_DBG("Device already running!");
		return 0;
	}

	/*6. To re-start the operation, first start the DMA and then enable
	 * the EMAC transmitter and receiver.
	 */

	/* Start the DMA */
	sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		     EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK);
	sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		     EMAC_DMAGRP_OPERATION_MODE_SR_SET_MSK);

	/* Enable the EMAC transmitter and receiver */
	sys_set_bits(GMACGRP_MAC_CONFIG_ADDR(p->base_addr),
		     EMAC_GMACGRP_MAC_CONFIGURATION_TE_SET_MSK);
	sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		     EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK); /* Flush Transmit FIFO */
	sys_set_bits(GMACGRP_MAC_CONFIG_ADDR(p->base_addr),
		     EMAC_GMACGRP_MAC_CONFIGURATION_RE_SET_MSK);

	p->running = 1;
	LOG_DBG("Starting Device...");
	return 0;
}

/**
 * @brief Stop device function
 * Stops DMA and EMAC transmitter and receiver. See:
 * https://www.intel.com/content/dam/www/
 * programmable/us/en/pdfs/literature/hb/cyclone-v/cv_54001.pdf p.1255-56
 *
 * @param dev Pointer to device structure
 * @retval 0 if successful, -1 otherwise
 */

static int eth_cyclonev_stop(const struct device *dev)
{

	struct eth_cyclonev_priv *p = dev->data;

	if (!p->running) {
		LOG_DBG("Device is not running!");
		return 0;
	}
	/* 1. Disable the transmit DMA (if applicable), by clearing bit 13
	 * (Start or Stop Transmission Command) of Register 6 (Operation Mode
	 * Register).
	 */

	sys_clear_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		       EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK);

	/* 3. Disable the EMAC transmitter and EMAC receiver by clearing Bit 3
	 * (TE) and Bit 2 (RE) in Register 0 (MAC Configuration Register).
	 */
	sys_clear_bits(GMACGRP_MAC_CONFIG_ADDR(p->base_addr),
		       EMAC_GMACGRP_MAC_CONFIGURATION_TE_SET_MSK);
	sys_set_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		     EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK); /* Flush Transmit FIFO */
	sys_clear_bits(GMACGRP_MAC_CONFIG_ADDR(p->base_addr),
		       EMAC_GMACGRP_MAC_CONFIGURATION_RE_SET_MSK);

	/* 4. Disable the receive DMA (if applicable), after making sure that the data
	 * in the RX FIFO buffer is transferred to the system memory
	 * (by reading Register 9 (Debug Register).
	 */

	sys_clear_bits(EMAC_DMAGRP_OPERATION_MODE_ADDR(p->base_addr),
		       EMAC_DMAGRP_OPERATION_MODE_SR_SET_MSK);

	/* 5. Make sure that both the TX FIFO buffer and RX FIFO buffer are empty. */

	if (EMAC_DMAGRP_DEBUG_RXFSTS_GET(
		    sys_read32(EMAC_DMAGRP_DEBUG_ADDR(p->base_addr))) != 0x0) {
		return -1;
	}

	p->running = 0;
	LOG_DBG("Stopping Device...");
	return 0;
}

const struct ethernet_api eth_cyclonev_api = {.iface_api.init = eth_cyclonev_iface_init,
					      .get_capabilities = eth_cyclonev_caps,
					      .send = eth_cyclonev_send,
					      .start = eth_cyclonev_start,
					      .stop = eth_cyclonev_stop,
					      .set_config = eth_cyclonev_set_config};

#define CYCLONEV_ETH_INIT(inst)                                                                    \
                                              \
	static struct eth_cyclonev_priv eth_cyclonev_##inst##_data;                                \
	static void eth_cyclonev_##inst##_irq_config(void);			\
	\
		static const struct eth_cyclonev_config eth_cyclonev_##inst##_cfg = {            \
			.base = (uint8_t *)(DT_INST_REG_ADDR(inst)),               \
			.size = DT_INST_REG_SIZE(inst),                           \
			.inst_num = inst,                                     \
			.irq_config = eth_cyclonev_##inst##_irq_config,         \
	};   \
	ETH_NET_DEVICE_DT_INST_DEFINE(inst, eth_cyclonev_probe, NULL,			\
					&eth_cyclonev_##inst##_data, \
					&eth_cyclonev_##inst##_cfg,		\
					CONFIG_ETH_INIT_PRIORITY,		\
					&eth_cyclonev_api,           \
					NET_ETH_MTU);                   \
					\
	static void eth_cyclonev_##inst##_irq_config(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(inst),				\
			    DT_INST_IRQ(inst, priority), eth_cyclonev_isr,	\
			    DEVICE_DT_INST_GET(inst),			\
			    0);			\
		irq_enable(DT_INST_IRQN(inst));				\
	}
DT_INST_FOREACH_STATUS_OKAY(CYCLONEV_ETH_INIT)
