/*
 * QEMU Freescale eTSEC Emulator
 *
 * Copyright (c) 2011-2013 AdaCore
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "net/checksum.h"

#include "etsec.h"
#include "registers.h"

/* #define ETSEC_RING_DEBUG */
/* #define HEX_DUMP */
/* #define DEBUG_BD */

#ifdef ETSEC_RING_DEBUG
static const int debug_etsec = 1;
#else
static const int debug_etsec;
#endif

#define RING_DEBUG(fmt, ...) do {              \
 if (debug_etsec) {                            \
        qemu_log(fmt , ## __VA_ARGS__);        \
    }                                          \
    } while (0)

#ifdef DEBUG_BD

static void print_tx_bd_flags(uint16_t flags)
{
    qemu_log("      Ready: %d\n", !!(flags & BD_TX_READY));
    qemu_log("      PAD/CRC: %d\n", !!(flags & BD_TX_PADCRC));
    qemu_log("      Wrap: %d\n", !!(flags & BD_WRAP));
    qemu_log("      Interrupt: %d\n", !!(flags & BD_INTERRUPT));
    qemu_log("      Last in frame: %d\n", !!(flags & BD_LAST));
    qemu_log("      Tx CRC: %d\n", !!(flags & BD_TX_TC));
    qemu_log("      User-defined preamble / defer: %d\n",
           !!(flags & BD_TX_PREDEF));
    qemu_log("      Huge frame enable / Late collision: %d\n",
           !!(flags & BD_TX_HFELC));
    qemu_log("      Control frame / Retransmission Limit: %d\n",
           !!(flags & BD_TX_CFRL));
    qemu_log("      Retry count: %d\n",
           (flags >> BD_TX_RC_OFFSET) & BD_TX_RC_MASK);
    qemu_log("      Underrun / TCP/IP off-load enable: %d\n",
           !!(flags & BD_TX_TOEUN));
    qemu_log("      Truncation: %d\n", !!(flags & BD_TX_TR));
}

static void print_rx_bd_flags(uint16_t flags)
{
    qemu_log("      Empty: %d\n", !!(flags & BD_RX_EMPTY));
    qemu_log("      Receive software ownership: %d\n", !!(flags & BD_RX_RO1));
    qemu_log("      Wrap: %d\n", !!(flags & BD_WRAP));
    qemu_log("      Interrupt: %d\n", !!(flags & BD_INTERRUPT));
    qemu_log("      Last in frame: %d\n", !!(flags & BD_LAST));
    qemu_log("      First in frame: %d\n", !!(flags & BD_RX_FIRST));
    qemu_log("      Miss: %d\n", !!(flags & BD_RX_MISS));
    qemu_log("      Broadcast: %d\n", !!(flags & BD_RX_BROADCAST));
    qemu_log("      Multicast: %d\n", !!(flags & BD_RX_MULTICAST));
    qemu_log("      Rx frame length violation: %d\n", !!(flags & BD_RX_LG));
    qemu_log("      Rx non-octet aligned frame: %d\n", !!(flags & BD_RX_NO));
    qemu_log("      Short frame: %d\n", !!(flags & BD_RX_SH));
    qemu_log("      Rx CRC Error: %d\n", !!(flags & BD_RX_CR));
    qemu_log("      Overrun: %d\n", !!(flags & BD_RX_OV));
    qemu_log("      Truncation: %d\n", !!(flags & BD_RX_TR));
}


static void print_bd(eTSEC_rxtx_bd bd, int mode, uint32_t index)
{
    qemu_log("eTSEC %s Data Buffer Descriptor (%u)\n",
           mode == eTSEC_TRANSMIT ? "Transmit" : "Receive",
           index);
    qemu_log("   Flags   : 0x%04x\n", bd.flags);
    if (mode == eTSEC_TRANSMIT) {
        print_tx_bd_flags(bd.flags);
    } else {
        print_rx_bd_flags(bd.flags);
    }
    qemu_log("   Length  : 0x%04x\n", bd.length);
    qemu_log("   Pointer : 0x%08x\n", bd.bufptr);
}

#endif  /* DEBUG_BD */

static void read_buffer_descriptor(eTSEC         *etsec,
                                   hwaddr         addr,
                                   eTSEC_rxtx_bd *bd)
{
    assert(bd != NULL);

    RING_DEBUG("READ Buffer Descriptor @ 0x" TARGET_FMT_plx"\n", addr);
    cpu_physical_memory_read(addr,
                             bd,
                             sizeof(eTSEC_rxtx_bd));

    if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
        bd->flags  = lduw_le_p(&bd->flags);
        bd->length = lduw_le_p(&bd->length);
        bd->bufptr = ldl_le_p(&bd->bufptr);
    } else {
        bd->flags  = lduw_be_p(&bd->flags);
        bd->length = lduw_be_p(&bd->length);
        bd->bufptr = ldl_be_p(&bd->bufptr);
    }
}

static void write_buffer_descriptor(eTSEC         *etsec,
                                    hwaddr         addr,
                                    eTSEC_rxtx_bd *bd)
{
    assert(bd != NULL);

    if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
        stw_le_p(&bd->flags, bd->flags);
        stw_le_p(&bd->length, bd->length);
        stl_le_p(&bd->bufptr, bd->bufptr);
    } else {
        stw_be_p(&bd->flags, bd->flags);
        stw_be_p(&bd->length, bd->length);
        stl_be_p(&bd->bufptr, bd->bufptr);
    }

    RING_DEBUG("Write Buffer Descriptor @ 0x" TARGET_FMT_plx"\n", addr);
    cpu_physical_memory_write(addr,
                              bd,
                              sizeof(eTSEC_rxtx_bd));
}

static void ievent_set(eTSEC    *etsec,
                       uint32_t  flags)
{
    etsec->regs[IEVENT].value |= flags;

    if ((flags & IEVENT_TXB && etsec->regs[IMASK].value & IMASK_TXBEN)
        || (flags & IEVENT_TXF && etsec->regs[IMASK].value & IMASK_TXFEN)) {
        qemu_irq_raise(etsec->tx_irq);
        RING_DEBUG("%s Raise Tx IRQ\n", __func__);
    }

    if ((flags & IEVENT_RXB && etsec->regs[IMASK].value & IMASK_RXBEN)
        || (flags & IEVENT_RXF && etsec->regs[IMASK].value & IMASK_RXFEN)) {
        qemu_irq_pulse(etsec->rx_irq);
        RING_DEBUG("%s Raise Rx IRQ\n", __func__);
    }
}

static void tx_padding_and_crc(eTSEC *etsec, uint32_t min_frame_len)
{
    int add = min_frame_len - etsec->tx_buffer_len;

    /* Padding */
    if (add > 0) {
        RING_DEBUG("pad:%u\n", add);
        etsec->tx_buffer = g_realloc(etsec->tx_buffer,
                                        etsec->tx_buffer_len + add);

        memset(etsec->tx_buffer + etsec->tx_buffer_len, 0x0, add);
        etsec->tx_buffer_len += add;
    }

    /* Never add CRC in QEMU */
}

static void process_tx_fcb(eTSEC *etsec)
{
    uint8_t flags = (uint8_t)(*etsec->tx_buffer);
    /* L3 header offset from start of frame */
    uint8_t l3_header_offset = (uint8_t)*(etsec->tx_buffer + 3);
    /* L4 header offset from start of L3 header */
    uint8_t l4_header_offset = (uint8_t)*(etsec->tx_buffer + 2);
    /* L3 header */
    uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset;
    /* L4 header */
    uint8_t *l4_header = l3_header + l4_header_offset;

    /* if packet is IP4 and IP checksum is requested */
    if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
        /* do IP4 checksum (TODO This funtion does TCP/UDP checksum but not sure
         * if it also does IP4 checksum. */
        net_checksum_calculate(etsec->tx_buffer + 8,
                etsec->tx_buffer_len - 8);
    }
    /* TODO Check the correct usage of the PHCS field of the FCB in case the NPH
     * flag is on */

    /* if packet is IP4 and TCP or UDP */
    if (flags & FCB_TX_IP && flags & FCB_TX_TUP) {
        /* if UDP */
        if (flags & FCB_TX_UDP) {
            /* if checksum is requested */
            if (flags & FCB_TX_CTU) {
                /* do UDP checksum */

                net_checksum_calculate(etsec->tx_buffer + 8,
                        etsec->tx_buffer_len - 8);
            } else {
                /* set checksum field to 0 */
                l4_header[6] = 0;
                l4_header[7] = 0;
            }
        } else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */
            /* do TCP checksum */
            net_checksum_calculate(etsec->tx_buffer + 8,
                                   etsec->tx_buffer_len - 8);
        }
    }
}

static void process_tx_bd(eTSEC         *etsec,
                          eTSEC_rxtx_bd *bd)
{
    uint8_t *tmp_buff = NULL;
    hwaddr tbdbth     = (hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32;

    if (bd->length == 0) {
        /* ERROR */
        return;
    }

    if (etsec->tx_buffer_len == 0) {
        /* It's the first BD */
        etsec->first_bd = *bd;
    }

    /* TODO: if TxBD[TOE/UN] skip the Tx Frame Control Block*/

    /* Load this Data Buffer */
    etsec->tx_buffer = g_realloc(etsec->tx_buffer,
                                    etsec->tx_buffer_len + bd->length);
    tmp_buff = etsec->tx_buffer + etsec->tx_buffer_len;
    cpu_physical_memory_read(bd->bufptr + tbdbth, tmp_buff, bd->length);

    /* Update buffer length */
    etsec->tx_buffer_len += bd->length;


    if (etsec->tx_buffer_len != 0 && (bd->flags & BD_LAST)) {
        if (etsec->regs[MACCFG1].value & MACCFG1_TX_EN) {
            /* MAC Transmit enabled */

            /* Process offload Tx FCB */
            if (etsec->first_bd.flags & BD_TX_TOEUN) {
                process_tx_fcb(etsec);
            }

            if (etsec->first_bd.flags & BD_TX_PADCRC
                || etsec->regs[MACCFG2].value & MACCFG2_PADCRC) {

                /* Padding and CRC (Padding implies CRC) */
                tx_padding_and_crc(etsec, 64);

            } else if (etsec->first_bd.flags & BD_TX_TC
                       || etsec->regs[MACCFG2].value & MACCFG2_CRC_EN) {

                /* Only CRC */
                /* Never add CRC in QEMU */
            }

#if defined(HEX_DUMP)
            qemu_log("eTSEC Send packet size:%d\n", etsec->tx_buffer_len);
            qemu_hexdump(etsec->tx_buffer, stderr, "", etsec->tx_buffer_len);
#endif  /* ETSEC_RING_DEBUG */

            if (etsec->first_bd.flags & BD_TX_TOEUN) {
                qemu_send_packet(qemu_get_queue(etsec->nic),
                        etsec->tx_buffer + 8,
                        etsec->tx_buffer_len - 8);
            } else {
                qemu_send_packet(qemu_get_queue(etsec->nic),
                        etsec->tx_buffer,
                        etsec->tx_buffer_len);
            }

        }

        etsec->tx_buffer_len = 0;

        if (bd->flags & BD_INTERRUPT) {
            ievent_set(etsec, IEVENT_TXF);
        }
    } else {
        if (bd->flags & BD_INTERRUPT) {
            ievent_set(etsec, IEVENT_TXB);
        }
    }

    /* Update DB flags */

    /* Clear Ready */
    bd->flags &= ~BD_TX_READY;

    /* Clear Defer */
    bd->flags &= ~BD_TX_PREDEF;

    /* Clear Late Collision */
    bd->flags &= ~BD_TX_HFELC;

    /* Clear Retransmission Limit */
    bd->flags &= ~BD_TX_CFRL;

    /* Clear Retry Count */
    bd->flags &= ~(BD_TX_RC_MASK << BD_TX_RC_OFFSET);

    /* Clear Underrun */
    bd->flags &= ~BD_TX_TOEUN;

    /* Clear Truncation */
    bd->flags &= ~BD_TX_TR;
}

void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr)
{
    hwaddr        ring_base = 0;
    hwaddr        bd_addr   = 0;
    eTSEC_rxtx_bd bd;
    uint16_t      bd_flags;

    if (!(etsec->regs[MACCFG1].value & MACCFG1_TX_EN)) {
        RING_DEBUG("%s: MAC Transmit not enabled\n", __func__);
        return;
    }

    ring_base = (hwaddr)(etsec->regs[TBASEH].value & 0xF) << 32;
    ring_base += etsec->regs[TBASE0 + ring_nbr].value & ~0x7;
    bd_addr    = etsec->regs[TBPTR0 + ring_nbr].value & ~0x7;

    do {
        read_buffer_descriptor(etsec, bd_addr, &bd);

#ifdef DEBUG_BD
        print_bd(bd,
                 eTSEC_TRANSMIT,
                 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));

#endif  /* DEBUG_BD */

        /* Save flags before BD update */
        bd_flags = bd.flags;

        if (bd_flags & BD_TX_READY) {
            process_tx_bd(etsec, &bd);

            /* Write back BD after update */
            write_buffer_descriptor(etsec, bd_addr, &bd);
        }

        /* Wrap or next BD */
        if (bd_flags & BD_WRAP) {
            bd_addr = ring_base;
        } else {
            bd_addr += sizeof(eTSEC_rxtx_bd);
        }

    } while (bd_addr != ring_base);

    bd_addr = ring_base;

    /* Save the Buffer Descriptor Pointers to current bd */
    etsec->regs[TBPTR0 + ring_nbr].value = bd_addr;

    /* Set transmit halt THLTx */
    etsec->regs[TSTAT].value |= 1 << (31 - ring_nbr);
}

static void fill_rx_bd(eTSEC          *etsec,
                       eTSEC_rxtx_bd  *bd,
                       const uint8_t **buf,
                       size_t         *size)
{
    uint16_t to_write;
    hwaddr   bufptr = bd->bufptr +
        ((hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32);
    uint8_t  padd[etsec->rx_padding];
    uint8_t  rem;

    RING_DEBUG("eTSEC fill Rx buffer @ 0x%016" HWADDR_PRIx
               " size:%zu(padding + crc:%u) + fcb:%u\n",
               bufptr, *size, etsec->rx_padding, etsec->rx_fcb_size);

    bd->length = 0;

    /* This operation will only write FCB */
    if (etsec->rx_fcb_size != 0) {

        cpu_physical_memory_write(bufptr, etsec->rx_fcb, etsec->rx_fcb_size);

        bufptr             += etsec->rx_fcb_size;
        bd->length         += etsec->rx_fcb_size;
        etsec->rx_fcb_size  = 0;

    }

    /* We remove padding from the computation of to_write because it is not
     * allocated in the buffer.
     */
    to_write = MIN(*size - etsec->rx_padding,
                   etsec->regs[MRBLR].value - etsec->rx_fcb_size);

    /* This operation can only write packet data and no padding */
    if (to_write > 0) {
        cpu_physical_memory_write(bufptr, *buf, to_write);

        *buf   += to_write;
        bufptr += to_write;
        *size  -= to_write;

        bd->flags  &= ~BD_RX_EMPTY;
        bd->length += to_write;
    }

    if (*size == etsec->rx_padding) {
        /* The remaining bytes are only for padding which is not actually
         * allocated in the data buffer.
         */

        rem = MIN(etsec->regs[MRBLR].value - bd->length, etsec->rx_padding);

        if (rem > 0) {
            memset(padd, 0x0, sizeof(padd));
            etsec->rx_padding -= rem;
            *size             -= rem;
            bd->length        += rem;
            cpu_physical_memory_write(bufptr, padd, rem);
        }
    }
}

static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
{
    uint32_t fcb_size = 0;
    uint8_t  prsdep   = (etsec->regs[RCTRL].value >> RCTRL_PRSDEP_OFFSET)
        & RCTRL_PRSDEP_MASK;

    if (prsdep != 0) {
        /* Prepend FCB (FCB size + RCTRL[PAL]) */
        fcb_size = 8 + ((etsec->regs[RCTRL].value >> 16) & 0x1F);

        etsec->rx_fcb_size = fcb_size;

        /* TODO: fill_FCB(etsec); */
        memset(etsec->rx_fcb, 0x0, sizeof(etsec->rx_fcb));

    } else {
        etsec->rx_fcb_size = 0;
    }

    if (etsec->rx_buffer != NULL) {
        g_free(etsec->rx_buffer);
    }

    /* Do not copy the frame for now */
    etsec->rx_buffer     = (uint8_t *)buf;
    etsec->rx_buffer_len = size;

    /* CRC padding (We don't have to compute the CRC) */
    etsec->rx_padding = 4;

    etsec->rx_first_in_frame = 1;
    etsec->rx_remaining_data = etsec->rx_buffer_len;
    RING_DEBUG("%s: rx_buffer_len:%u rx_padding+crc:%u\n", __func__,
               etsec->rx_buffer_len, etsec->rx_padding);
}

void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
{
    int ring_nbr = 0;           /* Always use ring0 (no filer) */

    if (etsec->rx_buffer_len != 0) {
        RING_DEBUG("%s: We can't receive now,"
                   " a buffer is already in the pipe\n", __func__);
        return;
    }

    if (etsec->regs[RSTAT].value & 1 << (23 - ring_nbr)) {
        RING_DEBUG("%s: The ring is halted\n", __func__);
        return;
    }

    if (etsec->regs[DMACTRL].value & DMACTRL_GRS) {
        RING_DEBUG("%s: Graceful receive stop\n", __func__);
        return;
    }

    if (!(etsec->regs[MACCFG1].value & MACCFG1_RX_EN)) {
        RING_DEBUG("%s: MAC Receive not enabled\n", __func__);
        return;
    }

    if ((etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
        /* CRC is not in the packet yet, so short frame is below 60 bytes */
        RING_DEBUG("%s: Drop short frame\n", __func__);
        return;
    }

    rx_init_frame(etsec, buf, size);

    etsec_walk_rx_ring(etsec, ring_nbr);
}

void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
{
    hwaddr         ring_base     = 0;
    hwaddr         bd_addr       = 0;
    hwaddr         start_bd_addr = 0;
    eTSEC_rxtx_bd  bd;
    uint16_t       bd_flags;
    size_t         remaining_data;
    const uint8_t *buf;
    uint8_t       *tmp_buf;
    size_t         size;

    if (etsec->rx_buffer_len == 0) {
        /* No frame to send */
        RING_DEBUG("No frame to send\n");
        return;
    }

    remaining_data = etsec->rx_remaining_data + etsec->rx_padding;
    buf            = etsec->rx_buffer
        + (etsec->rx_buffer_len - etsec->rx_remaining_data);
    size           = etsec->rx_buffer_len + etsec->rx_padding;

    ring_base = (hwaddr)(etsec->regs[RBASEH].value & 0xF) << 32;
    ring_base += etsec->regs[RBASE0 + ring_nbr].value & ~0x7;
    start_bd_addr  = bd_addr = etsec->regs[RBPTR0 + ring_nbr].value & ~0x7;

    do {
        read_buffer_descriptor(etsec, bd_addr, &bd);

#ifdef DEBUG_BD
        print_bd(bd,
                 eTSEC_RECEIVE,
                 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));

#endif  /* DEBUG_BD */

        /* Save flags before BD update */
        bd_flags = bd.flags;

        if (bd_flags & BD_RX_EMPTY) {
            fill_rx_bd(etsec, &bd, &buf, &remaining_data);

            if (etsec->rx_first_in_frame) {
                bd.flags |= BD_RX_FIRST;
                etsec->rx_first_in_frame = 0;
                etsec->rx_first_bd = bd;
            }

            /* Last in frame */
            if (remaining_data == 0) {

                /* Clear flags */

                bd.flags &= ~0x7ff;

                bd.flags |= BD_LAST;

                /* NOTE: non-octet aligned frame is impossible in qemu */

                if (size >= etsec->regs[MAXFRM].value) {
                    /* frame length violation */
                    qemu_log("%s frame length violation: size:%zu MAXFRM:%d\n",
                           __func__, size, etsec->regs[MAXFRM].value);

                    bd.flags |= BD_RX_LG;
                }

                if (size  < 64) {
                    /* Short frame */
                    bd.flags |= BD_RX_SH;
                }

                /* TODO: Broadcast and Multicast */

                if (bd.flags | BD_INTERRUPT) {
                    /* Set RXFx */
                    etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);

                    /* Set IEVENT */
                    ievent_set(etsec, IEVENT_RXF);
                }

            } else {
                if (bd.flags | BD_INTERRUPT) {
                    /* Set IEVENT */
                    ievent_set(etsec, IEVENT_RXB);
                }
            }

            /* Write back BD after update */
            write_buffer_descriptor(etsec, bd_addr, &bd);
        }

        /* Wrap or next BD */
        if (bd_flags & BD_WRAP) {
            bd_addr = ring_base;
        } else {
            bd_addr += sizeof(eTSEC_rxtx_bd);
        }
    } while (remaining_data != 0
             && (bd_flags & BD_RX_EMPTY)
             && bd_addr != start_bd_addr);

    /* Reset ring ptr */
    etsec->regs[RBPTR0 + ring_nbr].value = bd_addr;

    /* The frame is too large to fit in the Rx ring */
    if (remaining_data > 0) {

        /* Set RSTAT[QHLTx] */
        etsec->regs[RSTAT].value |= 1 << (23 - ring_nbr);

        /* Save remaining data to send the end of the frame when the ring will
         * be restarted
         */
        etsec->rx_remaining_data = remaining_data;

        /* Copy the frame */
        tmp_buf = g_malloc(size);
        memcpy(tmp_buf, etsec->rx_buffer, size);
        etsec->rx_buffer = tmp_buf;

        RING_DEBUG("no empty RxBD available any more\n");
    } else {
        etsec->rx_buffer_len = 0;
        etsec->rx_buffer     = NULL;
    }

    RING_DEBUG("eTSEC End of ring_write: remaining_data:%zu\n", remaining_data);
}
