/*
 * 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 "qemu/osdep.h"
#include "net/checksum.h"
#include "qemu/log.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;

    etsec_update_irq(etsec);
}

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 function 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)) {
            break;
        }

        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 (TRUE);

    /* Save the Buffer Descriptor Pointers to last bd that was not
     * succesfully closed */
    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;
    }

    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;

    /*
     * Ensure that payload length + CRC length is at least 802.3
     * minimum MTU size bytes long (64)
     */
    if (etsec->rx_buffer_len < 60) {
        etsec->rx_padding += 60 - etsec->rx_buffer_len;
    }

    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);
}

ssize_t 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 0;
    }

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

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

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

    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 -1;
    }

    rx_init_frame(etsec, buf, size);

    etsec_walk_rx_ring(etsec, ring_nbr);

    return size;
}

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;
        if (etsec->need_flush) {
            qemu_flush_queued_packets(qemu_get_queue(etsec->nic));
        }
    }

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