/*
 * Copyright 2016, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(DATA61_GPL)
 */

#include <ethdrivers/raw.h>
#include <ethdrivers/helpers.h>
#include <string.h>
#include <utils/util.h>
#include <lwip/netif.h>
#include "cpsw/cpswif.h"
#include <ethdrivers/plat/cpsw.h>
#include <ethdrivers/plat/interrupt.h>
#include "lwiplib.h"

#define DEFAULT_MAC "\x00\x19\xb8\x00\xf0\xa3"

#define MAX_PKT_SIZE 1520
#define DMA_ALIGN 32

static void
low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu)
{
    struct beaglebone_eth_data *eth_data = (struct beaglebone_eth_data*)driver->eth_data;
    struct cpswportif *cpswif = (struct cpswportif*) eth_data->cpswPortIf;

    for (int temp = 0; temp < LEN_MAC_ADDRESS; temp++) {
        mac[temp] = cpswif->eth_addr[temp];
    }

    *mtu = MAX_PKT_SIZE;
}

static void fill_rx_bufs(struct eth_driver *driver)
{
    struct beaglebone_eth_data *dev = (struct beaglebone_eth_data*)driver->eth_data;

    THREAD_MEMORY_RELEASE();

    while (dev->rx_remain > 0) {
        /* request a buffer */
        void *cookie;
        int next_rdt = (dev->rdt + 1) % dev->rx_size;
        uintptr_t phys = driver->i_cb.allocate_rx_buf ? driver->i_cb.allocate_rx_buf(driver->cb_cookie, MAX_PKT_SIZE, &cookie) : 0;
        if (!phys) {
            break;
        }
        dev->rx_cookies[dev->rdt] = cookie;

        dev->rx_ring[dev->rdt].bufptr = phys;
        dev->rx_ring[dev->rdt].bufoff_len = PBUF_LEN_MAX;
        /* Mark the descriptor as owned by CPDMA to tell the CPSW hardware it can put
         * RX data into it
         */
        THREAD_MEMORY_RELEASE();

        dev->rx_ring[dev->rdt].flags_pktlen = CPDMA_BUF_DESC_OWNER;
        /* Set the next field in the hardware descriptor. The device will traverse the ring
         * using the next field to dump other RX data
         */
        THREAD_MEMORY_RELEASE();
        dev->rx_ring[dev->rdt].next = ((struct descriptor *) dev->rx_ring_phys) + next_rdt;

        dev->rdt = next_rdt;
        dev->rx_remain--;
    }

    THREAD_MEMORY_ACQUIRE();
}

static void free_desc_ring(struct beaglebone_eth_data *dev, ps_dma_man_t *dma_man)
{
    if (dev->rx_ring) {
        dma_unpin_free(dma_man, (void*)dev->rx_ring, sizeof(struct descriptor) * dev->rx_size);
        dev->rx_ring = NULL;
    }
    if (dev->tx_ring) {
        dma_unpin_free(dma_man, (void*)dev->tx_ring, sizeof(struct descriptor) * dev->tx_size);
        dev->tx_ring = NULL;
    }
    if (dev->rx_cookies) {
        free(dev->rx_cookies);
        dev->rx_cookies = NULL;
    }
    if (dev->tx_cookies) {
        free(dev->tx_cookies);
        dev->tx_cookies = NULL;
    }
    if (dev->tx_lengths) {
        free(dev->tx_lengths);
        dev->tx_lengths = NULL;
    }
}

static int initialize_desc_ring(struct beaglebone_eth_data *dev, ps_dma_man_t *dma_man)
{
    /* CPSW device has its own fixed memory area to save RX and TX ring descriptors */
    dma_addr_t tx_ring = {.virt = VPTR_CPSW_CPPI(dev->iomm_address.eth_mmio_cpsw_reg), .phys = CPSW0_CPPI_RAM_REGS};
    dma_addr_t rx_ring = {.virt = VPTR_CPSW_CPPI(dev->iomm_address.eth_mmio_cpsw_reg) + (SIZE_CPPI_RAM >> 1), .phys = CPSW0_CPPI_RAM_REGS + (SIZE_CPPI_RAM >> 1)};
    dev->rx_ring = rx_ring.virt;
    dev->rx_ring_phys = rx_ring.phys;

    ps_dma_cache_clean_invalidate(dma_man, rx_ring.virt, sizeof(struct descriptor) * dev->rx_size);
    ps_dma_cache_clean_invalidate(dma_man, tx_ring.virt, sizeof(struct descriptor) * dev->tx_size);

    dev->rx_cookies = malloc(sizeof(void*) * dev->rx_size);
    dev->tx_cookies = malloc(sizeof(void*) * dev->tx_size);
    dev->tx_lengths = malloc(sizeof(unsigned int) * dev->tx_size);
    if (!dev->rx_cookies || !dev->tx_cookies || !dev->tx_lengths) {
        if (dev->rx_cookies) {
            free(dev->rx_cookies);
        }
        if (dev->tx_cookies) {
            free(dev->tx_cookies);
        }
        if (dev->tx_lengths) {
            free(dev->tx_lengths);
        }
        ZF_LOGE("Failed to malloc");
        free_desc_ring(dev, dma_man);
        return -1;
    }
    dev->tx_ring = tx_ring.virt;
    dev->tx_ring_phys = tx_ring.phys;
    /* Remaining needs to be 2 less than size as we cannot actually enqueue size many descriptors,
     * since then the head and tail pointers would be equal, indicating empty. */
    dev->rx_remain = dev->rx_size - 2;
    dev->tx_remain = dev->tx_size - 2;

    dev->rdt = dev->rdh = dev->tdt = dev->tdh = 0;

    /* zero both rings */
    for (unsigned int i = 0; i < dev->tx_size; i++) {
        dev->tx_ring[i] = (struct descriptor) {
            .next = NULL,
            .bufptr = 0,
            .bufoff_len = 0,
            .flags_pktlen = 0
        };
    }
    for (unsigned int i = 0; i < dev->rx_size; i++) {
        dev->rx_ring[i] = (struct descriptor) {
            .next = NULL,
            .bufptr = 0,
            .bufoff_len = 0,
            .flags_pktlen = CPDMA_BUF_DESC_OWNER
        };
    }
    THREAD_MEMORY_FENCE();

    return 0;
}

static void complete_rx(struct eth_driver *eth_driver)
{
    struct beaglebone_eth_data *dev = (struct beaglebone_eth_data*)eth_driver->eth_data;
    unsigned int rdt = dev->rdt;

    while ((dev->rdh != rdt) && ((dev->rx_ring[dev->rdh].flags_pktlen & CPDMA_BUF_DESC_OWNER) != CPDMA_BUF_DESC_OWNER)) {
        int orig_rdh = dev->rdh;


        /* Ensure no memory references get ordered before we checked the descriptor was written back */
        THREAD_MEMORY_ACQUIRE();

        void *cookie = dev->rx_cookies[dev->rdh];
        unsigned int len = (dev->rx_ring[dev->rdh].flags_pktlen) & CPDMA_BD_PKTLEN_MASK;
        /* update rdh */
        dev->rdh = (dev->rdh + 1) % dev->rx_size;
        dev->rx_remain++;

        /* Give the buffers back */
        eth_driver->i_cb.rx_complete(eth_driver->cb_cookie, 1, &cookie, &len);

        /* Acknowledge that this packet is processed */
        CPSWCPDMARxCPWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg), 0, (uintptr_t)  (((volatile struct descriptor *) dev->rx_ring_phys) + (orig_rdh)));
        dev->rx_ring[orig_rdh].flags_pktlen = CPDMA_BUF_DESC_OWNER;
        CPSWCPDMARxHdrDescPtrWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg), ((struct descriptor *) dev->rx_ring_phys) + dev->rdh, 0);

    }
}

static void complete_tx(struct eth_driver *driver)
{
    struct beaglebone_eth_data *dev = (struct beaglebone_eth_data*)driver->eth_data;
    volatile u32_t cnt = 0xFFFF;

    int orig_tdh = dev->tdh;

    while (dev->tdh != dev->tdt && (((dev->tx_ring[dev->tdh].flags_pktlen) & CPDMA_BUF_DESC_SOP))) {
        unsigned int i;

        /* Make sure that the transmission is over */
        while (((dev->tx_ring[dev->tdh].flags_pktlen & CPDMA_BUF_DESC_OWNER)
                == CPDMA_BUF_DESC_OWNER) && ((--cnt) != 0));

        /* If CPDMA failed to transmit, give it a chance once more */
        if (0 == cnt) {
            CPSWCPDMATxHdrDescPtrWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg),
                                       (uintptr_t)  (((volatile struct descriptor *) dev->tx_ring_phys) + (dev->tdh)), 0);
            return;
        }

        /* do not let memory loads happen before our checking of the descriptor write back */
        THREAD_MEMORY_RELEASE();
        /* increase where we believe tdh to be */
        void *cookie = dev->tx_cookies[dev->tdh];
        dev->tx_remain += dev->tx_lengths[dev->tdh];
        dev->tdh = (dev->tdh + dev->tx_lengths[dev->tdh]) % dev->tx_size;
        /* give the buffer back */
        driver->i_cb.tx_complete(driver->cb_cookie, cookie);

        dev->tx_ring[orig_tdh].flags_pktlen &= ~(CPDMA_BUF_DESC_SOP);
        dev->tx_ring[orig_tdh].flags_pktlen &= ~(CPDMA_BUF_DESC_EOP);

        /* Acknowledge CPSW */
        CPSWCPDMATxCPWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg), 0, (uintptr_t)  (((volatile struct descriptor *) dev->tx_ring_phys) + (dev->tdh - 1)));

    }
}

static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys, unsigned int *len, void *cookie)
{
    struct beaglebone_eth_data *dev = (struct beaglebone_eth_data*)driver->eth_data;

    /* Ensure we have room */
    if (num > dev->tx_remain) {
        return ETHIF_TX_FAILED;
    }

    if (len[0] < MIN_PKT_LEN) {
        len[0] = MIN_PKT_LEN;
    }

    dev->tx_ring[dev->tdt].flags_pktlen = len[0];
    dev->tx_ring[dev->tdt].flags_pktlen |= (CPDMA_BUF_DESC_SOP | CPDMA_BUF_DESC_OWNER);

    unsigned int i, ring;
    THREAD_MEMORY_RELEASE();
    for (i = 0; i < num; i++) {
        ring = (dev->tdt + i) % dev->tx_size;
        dev->tx_ring[ring].bufoff_len = len[i] & CPDMA_BD_LEN_MASK;
        dev->tx_ring[ring].bufptr = phys[i];
        dev->tx_ring[ring].next = ((volatile struct descriptor *) dev->tx_ring_phys) + (ring + 1);
        THREAD_MEMORY_RELEASE();
    }

    /* Indicate the end of the packet */
    dev->tx_ring[ring].next = NULL;
    dev->tx_ring[ring].flags_pktlen |= CPDMA_BUF_DESC_EOP;
    dev->tx_ring[ring].flags_pktlen &= ~CPDMA_BUF_DESC_EOQ;

    dev->tx_cookies[dev->tdt] = cookie;
    dev->tx_lengths[dev->tdt] = num;
    dev->tdt = (dev->tdt + num) % dev->tx_size;
    dev->tx_remain -= num;

    THREAD_MEMORY_RELEASE();

    /* For the first time, write the HDP with the filled bd */
    if (dev->tdt - num == 0) {
        CPSWCPDMATxHdrDescPtrWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg),
                                   (uintptr_t) ((volatile struct descriptor *) dev->tx_ring_phys) + (dev->tdt - num) , 0);
    } else {
        /**
         * Chain the bd's. If the DMA engine, already reached the end of the chain,
         * the EOQ will be set. In that case, the HDP shall be written again.
         */
        if (dev->tx_ring[ring].flags_pktlen & CPDMA_BUF_DESC_EOQ) {
            CPSWCPDMATxHdrDescPtrWrite(VPTR_CPSW_CPDMA(dev->iomm_address.eth_mmio_cpsw_reg),
                                       (uintptr_t) ((volatile struct descriptor *) dev->tx_ring_phys) + (dev->tdt - num) , 0);

        }

    }

    return ETHIF_TX_ENQUEUED;
}

static void handle_irq(struct eth_driver *driver, int irq)
{

    struct beaglebone_eth_data *eth_data = (struct beaglebone_eth_data*)driver->eth_data;

    if (irq == SYS_INT_3PGSWRXINT0) {
        complete_rx(driver);
        fill_rx_bufs(driver);
    } else if (irq == SYS_INT_3PGSWTXINT0) {
        complete_tx(driver);
    } else {
        ZF_LOGE("Unrecognised interrupt number %d\n", irq);
    }

}

static void print_state(void)
{
    /* TODO */
}

static void raw_poll(struct eth_driver *driver)
{
    complete_tx(driver);
    complete_rx(driver);
    fill_rx_bufs(driver);
}

static struct raw_iface_funcs iface_fns = {
    .raw_handleIRQ = handle_irq,
    .print_state = print_state,
    .low_level_init = low_level_init,
    .raw_tx = raw_tx,
    .raw_poll = raw_poll
};

int ethif_am335x_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config)
{
    uint8_t mac[LEN_MAC_ADDRESS];
    /* Number if tx and rx buffers is limited by the CPSW/CPPI buffer size */
    uint32_t max_rx_cppi = (SIZE_CPPI_RAM >> 1) / sizeof(struct descriptor);
    uint32_t max_tx_cppi = (SIZE_CPPI_RAM >> 1) / sizeof(struct descriptor);

    struct cpswinst *cpswinst_data = NULL;
    struct cpswportif *cpswPortIf = NULL;
    struct beaglebone_eth_data *eth_data = NULL;

    int err;
    struct EthVirtAddr *eth_addresses = (struct EthVirtAddr *) config;

    eth_data = (struct beaglebone_eth_data*)malloc(sizeof(struct beaglebone_eth_data));
    if (eth_data == NULL) {
        ZF_LOGE("Failed to allocate eth data struct");
        return -1;
    }

    cpswPortIf = (struct cpswportif*) calloc(MAX_CPSW_INST * MAX_SLAVEPORT_PER_INST, sizeof(struct cpswportif));
    if (cpswPortIf == NULL) {
        ZF_LOGE("Failed to allocate cpswPortIf");
        return -1;
    }

    cpswinst_data = (struct cpswinst_data*) calloc(MAX_CPSW_INST, sizeof(struct cpswinst));
    if (cpswinst_data == NULL) {
        ZF_LOGE("Failed to allocate cpswinst");
        return -1;
    }

    compile_time_assert("CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT  <= max_rx_cppi", CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT <= (SIZE_CPPI_RAM >> 1) / sizeof(struct descriptor));
    compile_time_assert("CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT  <= max_tx_cppi", CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT <= (SIZE_CPPI_RAM >> 1) / sizeof(struct descriptor));

    /* Trim the number of buffers requested to the maximum count the hardware can support */
    eth_data->rx_size = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
    eth_data->tx_size = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;

    eth_driver->eth_data = eth_data;
    eth_driver->dma_alignment = DMA_ALIGN;
    eth_driver->i_fn = iface_fns;

    /* Tell the driver the mapped virtual addresses of the CPSW device */
    eth_data->iomm_address.eth_mmio_ctr_reg = eth_addresses->eth_mmio_ctr_reg;
    eth_data->iomm_address.eth_mmio_prcm_reg = eth_addresses->eth_mmio_prcm_reg;
    eth_data->iomm_address.eth_mmio_cpsw_reg = eth_addresses->eth_mmio_cpsw_reg;

    err = initialize_desc_ring(eth_data, &io_ops.dma_manager);
    if (err) {
        ZF_LOGE("Failed to allocate descriptor rings");
        return -1;
    }

    CPSWPinMuxSetup((uintptr_t) eth_addresses->eth_mmio_ctr_reg);

    CPSWClkEnable((uintptr_t) eth_addresses->eth_mmio_prcm_reg);

    EVMPortMIIModeSelect((uintptr_t) eth_addresses->eth_mmio_ctr_reg);

    /* Only need one port (port0) */
    EVMMACAddrGet((uintptr_t) eth_addresses->eth_mmio_ctr_reg, 0, mac);

    /* set MAC hardware address */
    for (int temp = 0; temp < LEN_MAC_ADDRESS; temp++) {
        cpswPortIf[0].eth_addr[temp] =
            mac[(LEN_MAC_ADDRESS - 1) - temp];
    }

    eth_data->cpswPortIf = cpswPortIf;
    eth_data->cpswinst   = cpswinst_data;

    fill_rx_bufs(eth_driver);

    /* Initialise CPSW interface */
    if (cpswif_init(eth_driver)) {
        ZF_LOGE("Failed to initialise cpswif\n");
        return -1;
    }

    /* done */
    return 0;
}
