/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#include <autoconf.h>
#include <ethdrivers/gen_config.h>
#include <lwip/gen_config.h>

#ifdef CONFIG_LIB_LWIP

#include <ethdrivers/lwip.h>
#include <ethdrivers/helpers.h>
#include <string.h>
#include <lwip/netif.h>
#include <netif/etharp.h>
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "debug.h"

static void initialize_free_bufs(lwip_iface_t *iface)
{
    dma_addr_t *dma_bufs = NULL;
    dma_bufs = malloc(sizeof(dma_addr_t) * CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS);
    if (!dma_bufs) {
        goto error;
    }
    memset(dma_bufs, 0, sizeof(dma_addr_t) * CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS);
    iface->bufs = malloc(sizeof(dma_addr_t *) * CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS);
    if (!iface->bufs) {
        goto error;
    }
    for (int i = 0; i < CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS; i++) {
        dma_bufs[i] = dma_alloc_pin(&iface->dma_man, CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE, 1,
                                    iface->driver.dma_alignment);
        if (!dma_bufs[i].phys) {
            goto error;
        }
        ps_dma_cache_clean_invalidate(&iface->dma_man, dma_bufs[i].virt, CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE);
        iface->bufs[i] = &dma_bufs[i];
    }
    iface->num_free_bufs = CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS;
    return;
error:
    if (iface->bufs) {
        free(iface->bufs);
    }
    if (dma_bufs) {
        for (int i = 0; i < CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS; i++) {
            if (dma_bufs[i].virt) {
                dma_unpin_free(&iface->dma_man, dma_bufs[i].virt, CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE);
            }
        }
        free(dma_bufs);
    }
    iface->bufs = NULL;
}

static uintptr_t lwip_allocate_rx_buf(void *iface, size_t buf_size, void **cookie)
{
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;
    if (buf_size > CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE) {
        LOG_ERROR("Requested RX buffer of size %zu which can never be fullfilled by preallocated buffers of size %d", buf_size,
                  CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE);
        return 0;
    }
    if (lwip_iface->num_free_bufs == 0) {
        if (!lwip_iface->bufs) {
            initialize_free_bufs(lwip_iface);
            if (!lwip_iface->bufs) {
                LOG_ERROR("Failed lazy initialization of preallocated free buffers");
                return 0;
            }
        } else {
            return 0;
        }
    }
    lwip_iface->num_free_bufs--;
    dma_addr_t *buf = lwip_iface->bufs[lwip_iface->num_free_bufs];
    ps_dma_cache_invalidate(&lwip_iface->dma_man, buf->virt, buf_size);
    *cookie = (void *)buf;
    return buf->phys;
}

static void lwip_tx_complete(void *iface, void *cookie)
{
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;
    lwip_iface->bufs[lwip_iface->num_free_bufs] = cookie;
    lwip_iface->num_free_bufs++;
}

static void lwip_rx_complete(void *iface, unsigned int num_bufs, void **cookies, unsigned int *lens)
{
    struct pbuf *p;
    int len;
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;
    int i;
    len = 0;
    for (i = 0; i < num_bufs; i++) {
        ps_dma_cache_invalidate(&lwip_iface->dma_man, ((dma_addr_t *)cookies[i])->virt, lens[i]);
        len += lens[i];
    }
#if ETH_PAD_SIZE
    len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
    /* Get a buffer from the pool */
    p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
    if (p == NULL) {
        for (i = 0; i < num_bufs; i++) {
            lwip_tx_complete(iface, cookies[i]);
        }
        return;
    }

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
    len -= ETH_PAD_SIZE;
#endif

    /* fill the pbuf chain */
    struct pbuf *q = p;
    unsigned int copied = 0;
    unsigned int buf = 0;
    unsigned int buf_done = 0;
    unsigned int pbuf_done = 0;
    while (copied < len) {
        unsigned int next = MIN(q->len - pbuf_done, lens[buf] - buf_done);
        memcpy(q->payload + pbuf_done, ((dma_addr_t *)cookies[buf])->virt + buf_done, next);
        buf_done += next;
        pbuf_done += next;
        copied += next;
        if (buf_done == lens[buf]) {
            buf++;
            buf_done = 0;
        }
        if (pbuf_done == q->len) {
            q = q->next;
            pbuf_done = 0;
        }
    }

//    PKT_DEBUG(printf("Receiving packet\n"));
//    PKT_DEBUG(print_packet(COL_RX, p->payload, len));

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
    LINK_STATS_INC(link.recv);

    for (i = 0; i < num_bufs; i++) {
        lwip_tx_complete(iface, cookies[i]);
    }

    struct eth_hdr *ethhdr;
    ethhdr = p->payload;

    switch (htons(ethhdr->type)) {
    /* IP or ARP packet? */
    case ETHTYPE_IP:
    case ETHTYPE_ARP:
#if PPPOE_SUPPORT
    /* PPPoE packet? */
    case ETHTYPE_PPPOEDISC:
    case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
        /* full packet send to tcpip_thread to process */
        if (lwip_iface->netif->input(p, lwip_iface->netif) != ERR_OK) {
            LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
            pbuf_free(p);
            p = NULL;
        }
        break;

    default:
        pbuf_free(p);
        break;
    }
}

static err_t ethif_link_output(struct netif *netif, struct pbuf *p)
{
    lwip_iface_t *iface = (lwip_iface_t *)netif->state;
    dma_addr_t buf;
    struct pbuf *q;
    int status;

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

    if (p->tot_len > CONFIG_LIB_ETHDRIVER_PREALLOCATED_BUF_SIZE) {
        return ERR_MEM;
    }
    if (iface->num_free_bufs == 0) {
        return ERR_MEM;
    }
    iface->num_free_bufs--;
    dma_addr_t *orig_buf = iface->bufs[iface->num_free_bufs];
    buf = *orig_buf;

    char *pkt_pos = (char *)buf.virt;
    for (q = p; q != NULL; q = q->next) {
        memcpy(pkt_pos, q->payload, q->len);
        pkt_pos += q->len;
    }
    ps_dma_cache_clean(&iface->dma_man, buf.virt, p->tot_len);
//    PKT_DEBUG(cprintf(COL_TX, "Sending packet"));
//    PKT_DEBUG(print_packet(COL_TX, (void*)buf.virt, p->tot_len));

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    unsigned int length = p->tot_len;
    status = iface->driver.i_fn.raw_tx(&iface->driver, 1, &buf.phys, &length, orig_buf);
    switch (status) {
    case ETHIF_TX_FAILED:
        lwip_tx_complete(iface, orig_buf);
        return ERR_WOULDBLOCK;
    case ETHIF_TX_COMPLETE:
        lwip_tx_complete(iface, orig_buf);
    case ETHIF_TX_ENQUEUED:
        break;
    }

    LINK_STATS_INC(link.xmit);

    return ERR_OK;
}

static uintptr_t lwip_pbuf_allocate_rx_buf(void *iface, size_t buf_size, void **cookie)
{
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;
#if ETH_PAD_SIZE
    buf_size += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
    /* add space for alignment */
    buf_size += lwip_iface->driver.dma_alignment;
    struct pbuf *p = pbuf_alloc(PBUF_RAW, buf_size, PBUF_RAM);
    if (!p) {
        return 0;
    }
    /* we cannot support chained pbufs when doing this */
    if (p->next) {
        pbuf_free(p);
        return 0;
    }
#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
    uintptr_t new_payload = (uintptr_t)p->payload;
    /* round up to dma_alignment */
    new_payload = ROUND_UP(new_payload, lwip_iface->driver.dma_alignment);
    pbuf_header(p, -(new_payload - (uintptr_t)p->payload));
    uintptr_t phys = ps_dma_pin(&lwip_iface->dma_man, p->payload, buf_size);
    if (!phys) {
        pbuf_free(p);
        return 0;
    }
    ps_dma_cache_invalidate(&lwip_iface->dma_man, p->payload, buf_size);
    *cookie = p;
    return phys;
}

static void lwip_pbuf_tx_complete(void *iface, void *cookie)
{
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;
    struct pbuf *p = (struct pbuf *)cookie;
    for (; p; p = p->next) {
        uintptr_t loc = (uintptr_t)p->payload;
        uintptr_t end = (uintptr_t)p->payload + p->len;
        while (loc < end) {
            uintptr_t next = ROUND_UP(loc + 1, PAGE_SIZE_4K);
            if (next > end) {
                next = end;
            }
            ps_dma_unpin(&lwip_iface->dma_man, (void *)loc, next - loc);
            loc = next;
        }
    }
    pbuf_free(cookie);
}

static void lwip_pbuf_rx_complete(void *iface, unsigned int num_bufs, void **cookies, unsigned int *lens)
{
    struct pbuf *p = NULL;
    int i;
    lwip_iface_t *lwip_iface = (lwip_iface_t *)iface;

    assert(num_bufs > 0);
    /* staple all the bufs together, do it in reverse order for efficiency
     * of traversing pbuf chains */
    for (i = num_bufs - 1; i >= 0; i--) {
        struct pbuf *q = (struct pbuf *)cookies[i];
        ps_dma_cache_invalidate(&lwip_iface->dma_man, q->payload, lens[i]);
        pbuf_realloc(q, lens[i]);
        if (p) {
            pbuf_cat(q, p);
        }
        p = q;
    }

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    LINK_STATS_INC(link.recv);

    struct eth_hdr *ethhdr;
    ethhdr = p->payload;

    switch (htons(ethhdr->type)) {
    /* IP or ARP packet? */
    case ETHTYPE_IP:
    case ETHTYPE_ARP:
#if PPPOE_SUPPORT
    /* PPPoE packet? */
    case ETHTYPE_PPPOEDISC:
    case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
        /* full packet send to tcpip_thread to process */
        if (lwip_iface->netif->input(p, lwip_iface->netif) != ERR_OK) {
            LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
            LOG_INFO("failed to input\n");
            pbuf_free(p);
        }
        break;

    default:
        pbuf_free(p);
        break;
    }
}

static err_t ethif_pbuf_link_output(struct netif *netif, struct pbuf *p)
{
    lwip_iface_t *iface = (lwip_iface_t *)netif->state;
    struct pbuf *q;
    int status;

    /* grab a reference to the pbuf */
    pbuf_ref(p);

#if ETH_PAD_SIZE
    pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
    int max_frames = 0;

    /* work out how many pieces this buffer could potentially take up */
    for (q = p; q; q = q->next) {
        uintptr_t base = PAGE_ALIGN_4K((uintptr_t)q->payload);
        uintptr_t top = PAGE_ALIGN_4K((uintptr_t)q->payload + q->len - 1);
        max_frames += ((top - base) / PAGE_SIZE_4K) + 1;
    }
    int num_frames = 0;
    unsigned int lengths[max_frames];
    uintptr_t phys[max_frames];
    for (q = p; q; q = q->next) {
        uintptr_t loc = (uintptr_t)q->payload;
        uintptr_t end = (uintptr_t)q->payload + q->len;
        while (loc < end) {
            uintptr_t next = ROUND_UP(loc + 1, PAGE_SIZE_4K);
            if (next > end) {
                next = end;
            }
            lengths[num_frames] = next - loc;
            phys[num_frames] = ps_dma_pin(&iface->dma_man, (void *)loc, lengths[num_frames]);
            ps_dma_cache_clean(&iface->dma_man, (void *)loc, lengths[num_frames]);
            assert(phys[num_frames]);
            num_frames++;
            loc = next;
        }
    }

#if ETH_PAD_SIZE
    pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif

    status = iface->driver.i_fn.raw_tx(&iface->driver, num_frames, phys, lengths, p);
    switch (status) {
    case ETHIF_TX_FAILED:
        lwip_pbuf_tx_complete(iface, p);
        return ERR_WOULDBLOCK;
    case ETHIF_TX_COMPLETE:
        lwip_pbuf_tx_complete(iface, p);
    case ETHIF_TX_ENQUEUED:
        break;
    }

    LINK_STATS_INC(link.xmit);

    return ERR_OK;
}

static struct raw_iface_callbacks lwip_prealloc_callbacks = {
    .tx_complete = lwip_tx_complete,
    .rx_complete = lwip_rx_complete,
    .allocate_rx_buf = lwip_allocate_rx_buf
};

static struct raw_iface_callbacks lwip_pbuf_callbacks = {
    .tx_complete = lwip_pbuf_tx_complete,
    .rx_complete = lwip_pbuf_rx_complete,
    .allocate_rx_buf = lwip_pbuf_allocate_rx_buf
};

static err_t ethif_init(struct netif *netif)
{
    if (netif -> state == NULL) {
        return ERR_ARG;
    }

    lwip_iface_t *iface = (lwip_iface_t *)netif->state;
    int mtu;
    iface->driver.i_fn.low_level_init(&iface->driver, netif->hwaddr, &mtu);
    netif->mtu = mtu;

    netif->hwaddr_len = ETHARP_HWADDR_LEN;
    netif->output = etharp_output;
    if (iface->bufs == NULL) {
        netif->linkoutput = ethif_pbuf_link_output;
    } else {
        netif->linkoutput = ethif_link_output;
    }

    NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd,
                    LINK_SPEED_OF_YOUR_NETIF_IN_BPS);

    netif -> flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP |
                     NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;

    iface->netif = netif;
    return ERR_OK;
}

lwip_iface_t *ethif_new_lwip_driver_no_malloc(ps_io_ops_t io_ops, ps_dma_man_t *pbuf_dma, ethif_driver_init driver,
                                              void *driver_config, lwip_iface_t *iface)
{
    memset(iface, 0, sizeof(*iface));
    iface->driver.cb_cookie = iface;
    if (pbuf_dma) {
        iface->driver.i_cb = lwip_pbuf_callbacks;
        iface->dma_man = *pbuf_dma;
    } else {
        iface->driver.i_cb = lwip_prealloc_callbacks;
        iface->dma_man = io_ops.dma_manager;
    }
    int err;
    err = driver(&iface->driver, io_ops, driver_config);
    if (err) {
        goto error;
    }
    /* if the driver did not already cause it to happen, allocate the preallocated buffers */
    if (!pbuf_dma && !iface->bufs) {
        initialize_free_bufs(iface);
        if (iface->bufs == NULL) {
            LOG_ERROR("Fault preallocating bufs");
            goto error;
        }
    }
    iface->ethif_init = ethif_init;
    return iface;
error:
    return NULL;
}

lwip_iface_t *ethif_new_lwip_driver(ps_io_ops_t io_ops, ps_dma_man_t *pbuf_dma, ethif_driver_init driver,
                                    void *driver_config)
{
    lwip_iface_t *ret;
    lwip_iface_t *iface = malloc(sizeof(*iface));
    if (!iface) {
        LOG_ERROR("Failed to malloc");
        return NULL;
    }
    ret = ethif_new_lwip_driver_no_malloc(io_ops, pbuf_dma, driver, driver_config, iface);
    if (!ret) {
        free(iface);
    }
    return ret;
}

#endif /* CONFIG_LIB_LWIP */
