/*
 * 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.
 */

/*
 * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
 */

#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "hw/sysbus.h"
#include "hw/ptimer.h"
#include "etsec.h"
#include "registers.h"
#include "qemu/log.h"

/* #define HEX_DUMP */
/* #define DEBUG_REGISTER */

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

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

/* call after any change to IEVENT or IMASK */
void etsec_update_irq(eTSEC *etsec)
{
    uint32_t ievent = etsec->regs[IEVENT].value;
    uint32_t imask  = etsec->regs[IMASK].value;
    uint32_t active = ievent & imask;

    int tx  = !!(active & IEVENT_TX_MASK);
    int rx  = !!(active & IEVENT_RX_MASK);
    int err = !!(active & IEVENT_ERR_MASK);

    DPRINTF("%s IRQ ievent=%"PRIx32" imask=%"PRIx32" %c%c%c",
            __func__, ievent, imask,
            tx  ? 'T' : '_',
            rx  ? 'R' : '_',
            err ? 'E' : '_');

    qemu_set_irq(etsec->tx_irq, tx);
    qemu_set_irq(etsec->rx_irq, rx);
    qemu_set_irq(etsec->err_irq, err);
}

static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size)
{
    eTSEC          *etsec     = opaque;
    uint32_t        reg_index = addr / 4;
    eTSEC_Register *reg       = NULL;
    uint32_t        ret       = 0x0;

    assert(reg_index < ETSEC_REG_NUMBER);

    reg = &etsec->regs[reg_index];


    switch (reg->access) {
    case ACC_WO:
        ret = 0x00000000;
        break;

    case ACC_RW:
    case ACC_W1C:
    case ACC_RO:
    default:
        ret = reg->value;
        break;
    }

    DPRINTF("Read  0x%08x @ 0x" TARGET_FMT_plx
            "                            : %s (%s)\n",
            ret, addr, reg->name, reg->desc);

    return ret;
}

static void write_tstat(eTSEC          *etsec,
                        eTSEC_Register *reg,
                        uint32_t        reg_index,
                        uint32_t        value)
{
    int i = 0;

    for (i = 0; i < 8; i++) {
        /* Check THLTi flag in TSTAT */
        if (value & (1 << (31 - i))) {
            etsec_walk_tx_ring(etsec, i);
        }
    }

    /* Write 1 to clear */
    reg->value &= ~value;
}

static void write_rstat(eTSEC          *etsec,
                        eTSEC_Register *reg,
                        uint32_t        reg_index,
                        uint32_t        value)
{
    int i = 0;

    for (i = 0; i < 8; i++) {
        /* Check QHLTi flag in RSTAT */
        if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) {
            etsec_walk_rx_ring(etsec, i);
        }
    }

    /* Write 1 to clear */
    reg->value &= ~value;
}

static void write_tbasex(eTSEC          *etsec,
                         eTSEC_Register *reg,
                         uint32_t        reg_index,
                         uint32_t        value)
{
    reg->value = value & ~0x7;

    /* Copy this value in the ring's TxBD pointer */
    etsec->regs[TBPTR0 + (reg_index - TBASE0)].value = value & ~0x7;
}

static void write_rbasex(eTSEC          *etsec,
                         eTSEC_Register *reg,
                         uint32_t        reg_index,
                         uint32_t        value)
{
    reg->value = value & ~0x7;

    /* Copy this value in the ring's RxBD pointer */
    etsec->regs[RBPTR0 + (reg_index - RBASE0)].value = value & ~0x7;
}

static void write_dmactrl(eTSEC          *etsec,
                          eTSEC_Register *reg,
                          uint32_t        reg_index,
                          uint32_t        value)
{
    reg->value = value;

    if (value & DMACTRL_GRS) {

        if (etsec->rx_buffer_len != 0) {
            /* Graceful receive stop delayed until end of frame */
        } else {
            /* Graceful receive stop now */
            etsec->regs[IEVENT].value |= IEVENT_GRSC;
            etsec_update_irq(etsec);
        }
    }

    if (value & DMACTRL_GTS) {

        if (etsec->tx_buffer_len != 0) {
            /* Graceful transmit stop delayed until end of frame */
        } else {
            /* Graceful transmit stop now */
            etsec->regs[IEVENT].value |= IEVENT_GTSC;
            etsec_update_irq(etsec);
        }
    }

    if (!(value & DMACTRL_WOP)) {
        /* Start polling */
        ptimer_stop(etsec->ptimer);
        ptimer_set_count(etsec->ptimer, 1);
        ptimer_run(etsec->ptimer, 1);
    }
}

static void etsec_write(void     *opaque,
                        hwaddr    addr,
                        uint64_t  value,
                        unsigned  size)
{
    eTSEC          *etsec     = opaque;
    uint32_t        reg_index = addr / 4;
    eTSEC_Register *reg       = NULL;
    uint32_t        before    = 0x0;

    assert(reg_index < ETSEC_REG_NUMBER);

    reg = &etsec->regs[reg_index];
    before = reg->value;

    switch (reg_index) {
    case IEVENT:
        /* Write 1 to clear */
        reg->value &= ~value;

        etsec_update_irq(etsec);
        break;

    case IMASK:
        reg->value = value;

        etsec_update_irq(etsec);
        break;

    case DMACTRL:
        write_dmactrl(etsec, reg, reg_index, value);
        break;

    case TSTAT:
        write_tstat(etsec, reg, reg_index, value);
        break;

    case RSTAT:
        write_rstat(etsec, reg, reg_index, value);
        break;

    case TBASE0 ... TBASE7:
        write_tbasex(etsec, reg, reg_index, value);
        break;

    case RBASE0 ... RBASE7:
        write_rbasex(etsec, reg, reg_index, value);
        break;

    case MIIMCFG ... MIIMIND:
        etsec_write_miim(etsec, reg, reg_index, value);
        break;

    default:
        /* Default handling */
        switch (reg->access) {

        case ACC_RW:
        case ACC_WO:
            reg->value = value;
            break;

        case ACC_W1C:
            reg->value &= ~value;
            break;

        case ACC_RO:
        default:
            /* Read Only or Unknown register */
            break;
        }
    }

    DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx
            " val:0x%08x->0x%08x : %s (%s)\n",
            (unsigned int)value, addr, before, reg->value,
            reg->name, reg->desc);
}

static const MemoryRegionOps etsec_ops = {
    .read = etsec_read,
    .write = etsec_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void etsec_timer_hit(void *opaque)
{
    eTSEC *etsec = opaque;

    ptimer_stop(etsec->ptimer);

    if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) {

        if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) {
            etsec_walk_tx_ring(etsec, 0);
        }
        ptimer_set_count(etsec->ptimer, 1);
        ptimer_run(etsec->ptimer, 1);
    }
}

static void etsec_reset(DeviceState *d)
{
    eTSEC *etsec = ETSEC_COMMON(d);
    int i = 0;
    int reg_index = 0;

    /* Default value for all registers */
    for (i = 0; i < ETSEC_REG_NUMBER; i++) {
        etsec->regs[i].name   = "Reserved";
        etsec->regs[i].desc   = "";
        etsec->regs[i].access = ACC_UNKNOWN;
        etsec->regs[i].value  = 0x00000000;
    }

    /* Set-up known registers */
    for (i = 0; eTSEC_registers_def[i].name != NULL; i++) {

        reg_index = eTSEC_registers_def[i].offset / 4;

        etsec->regs[reg_index].name   = eTSEC_registers_def[i].name;
        etsec->regs[reg_index].desc   = eTSEC_registers_def[i].desc;
        etsec->regs[reg_index].access = eTSEC_registers_def[i].access;
        etsec->regs[reg_index].value  = eTSEC_registers_def[i].reset;
    }

    etsec->tx_buffer     = NULL;
    etsec->tx_buffer_len = 0;
    etsec->rx_buffer     = NULL;
    etsec->rx_buffer_len = 0;

    etsec->phy_status =
        MII_SR_EXTENDED_CAPS    | MII_SR_LINK_STATUS   | MII_SR_AUTONEG_CAPS  |
        MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
        MII_SR_EXTENDED_STATUS  | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
        MII_SR_10T_HD_CAPS      | MII_SR_10T_FD_CAPS   | MII_SR_100X_HD_CAPS  |
        MII_SR_100X_FD_CAPS     | MII_SR_100T4_CAPS;

    etsec_update_irq(etsec);
}

static ssize_t etsec_receive(NetClientState *nc,
                             const uint8_t  *buf,
                             size_t          size)
{
    ssize_t ret;
    eTSEC *etsec = qemu_get_nic_opaque(nc);

#if defined(HEX_DUMP)
    fprintf(stderr, "%s receive size:%zd\n", nc->name, size);
    qemu_hexdump((void *)buf, stderr, "", size);
#endif
    /* Flush is unnecessary as are already in receiving path */
    etsec->need_flush = false;
    ret = etsec_rx_ring_write(etsec, buf, size);
    if (ret == 0) {
        /* The packet will be queued, let's flush it when buffer is available
         * again. */
        etsec->need_flush = true;
    }
    return ret;
}


static void etsec_set_link_status(NetClientState *nc)
{
    eTSEC *etsec = qemu_get_nic_opaque(nc);

    etsec_miim_link_status(etsec, nc);
}

static NetClientInfo net_etsec_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .receive = etsec_receive,
    .link_status_changed = etsec_set_link_status,
};

static void etsec_realize(DeviceState *dev, Error **errp)
{
    eTSEC        *etsec = ETSEC_COMMON(dev);

    etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
                              object_get_typename(OBJECT(dev)), dev->id, etsec);
    qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);


    etsec->bh     = qemu_bh_new(etsec_timer_hit, etsec);
    etsec->ptimer = ptimer_init(etsec->bh, PTIMER_POLICY_DEFAULT);
    ptimer_set_freq(etsec->ptimer, 100);
}

static void etsec_instance_init(Object *obj)
{
    eTSEC        *etsec = ETSEC_COMMON(obj);
    SysBusDevice *sbd   = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&etsec->io_area, OBJECT(etsec), &etsec_ops, etsec,
                          "eTSEC", 0x1000);
    sysbus_init_mmio(sbd, &etsec->io_area);

    sysbus_init_irq(sbd, &etsec->tx_irq);
    sysbus_init_irq(sbd, &etsec->rx_irq);
    sysbus_init_irq(sbd, &etsec->err_irq);
}

static Property etsec_properties[] = {
    DEFINE_NIC_PROPERTIES(eTSEC, conf),
    DEFINE_PROP_END_OF_LIST(),
};

static void etsec_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = etsec_realize;
    dc->reset = etsec_reset;
    dc->props = etsec_properties;
    /* Supported by ppce500 machine */
    dc->user_creatable = true;
}

static TypeInfo etsec_info = {
    .name                  = "eTSEC",
    .parent                = TYPE_SYS_BUS_DEVICE,
    .instance_size         = sizeof(eTSEC),
    .class_init            = etsec_class_init,
    .instance_init         = etsec_instance_init,
};

static void etsec_register_types(void)
{
    type_register_static(&etsec_info);
}

type_init(etsec_register_types)

DeviceState *etsec_create(hwaddr         base,
                          MemoryRegion * mr,
                          NICInfo      * nd,
                          qemu_irq       tx_irq,
                          qemu_irq       rx_irq,
                          qemu_irq       err_irq)
{
    DeviceState *dev;

    dev = qdev_create(NULL, "eTSEC");
    qdev_set_nic_properties(dev, nd);
    qdev_init_nofail(dev);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq);
    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);

    memory_region_add_subregion(mr, base,
                                SYS_BUS_DEVICE(dev)->mmio[0].memory);

    return dev;
}
