/*
 *  QEMU model of the Milkymist minimac2 block.
 *
 *  Copyright (c) 2011 Michael Walle <michael@walle.cc>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Specification available at:
 *   not available yet
 *
 */

#include "hw.h"
#include "sysbus.h"
#include "trace.h"
#include "net/net.h"
#include "qemu/error-report.h"
#include "qdev-addr.h"

#include <zlib.h>

enum {
    R_SETUP = 0,
    R_MDIO,
    R_STATE0,
    R_COUNT0,
    R_STATE1,
    R_COUNT1,
    R_TXCOUNT,
    R_MAX
};

enum {
    SETUP_PHY_RST = (1<<0),
};

enum {
    MDIO_DO  = (1<<0),
    MDIO_DI  = (1<<1),
    MDIO_OE  = (1<<2),
    MDIO_CLK = (1<<3),
};

enum {
    STATE_EMPTY   = 0,
    STATE_LOADED  = 1,
    STATE_PENDING = 2,
};

enum {
    MDIO_OP_WRITE = 1,
    MDIO_OP_READ  = 2,
};

enum mdio_state {
    MDIO_STATE_IDLE,
    MDIO_STATE_READING,
    MDIO_STATE_WRITING,
};

enum {
    R_PHY_ID1  = 2,
    R_PHY_ID2  = 3,
    R_PHY_MAX  = 32
};

#define MINIMAC2_MTU 1530
#define MINIMAC2_BUFFER_SIZE 2048

struct MilkymistMinimac2MdioState {
    int last_clk;
    int count;
    uint32_t data;
    uint16_t data_out;
    int state;

    uint8_t phy_addr;
    uint8_t reg_addr;
};
typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState;

struct MilkymistMinimac2State {
    SysBusDevice busdev;
    NICState *nic;
    NICConf conf;
    char *phy_model;
    hwaddr buffers_base;
    MemoryRegion buffers;
    MemoryRegion regs_region;

    qemu_irq rx_irq;
    qemu_irq tx_irq;

    uint32_t regs[R_MAX];

    MilkymistMinimac2MdioState mdio;

    uint16_t phy_regs[R_PHY_MAX];

    uint8_t *rx0_buf;
    uint8_t *rx1_buf;
    uint8_t *tx_buf;
};
typedef struct MilkymistMinimac2State MilkymistMinimac2State;

static const uint8_t preamble_sfd[] = {
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5
};

static void minimac2_mdio_write_reg(MilkymistMinimac2State *s,
        uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
{
    trace_milkymist_minimac2_mdio_write(phy_addr, reg_addr, value);

    /* nop */
}

static uint16_t minimac2_mdio_read_reg(MilkymistMinimac2State *s,
        uint8_t phy_addr, uint8_t reg_addr)
{
    uint16_t r = s->phy_regs[reg_addr];

    trace_milkymist_minimac2_mdio_read(phy_addr, reg_addr, r);

    return r;
}

static void minimac2_update_mdio(MilkymistMinimac2State *s)
{
    MilkymistMinimac2MdioState *m = &s->mdio;

    /* detect rising clk edge */
    if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) {
        /* shift data in */
        int bit = ((s->regs[R_MDIO] & MDIO_DO)
                   && (s->regs[R_MDIO] & MDIO_OE)) ? 1 : 0;
        m->data = (m->data << 1) | bit;

        /* check for sync */
        if (m->data == 0xffffffff) {
            m->count = 32;
        }

        if (m->count == 16) {
            uint8_t start = (m->data >> 14) & 0x3;
            uint8_t op = (m->data >> 12) & 0x3;
            uint8_t ta = (m->data) & 0x3;

            if (start == 1 && op == MDIO_OP_WRITE && ta == 2) {
                m->state = MDIO_STATE_WRITING;
            } else if (start == 1 && op == MDIO_OP_READ && (ta & 1) == 0) {
                m->state = MDIO_STATE_READING;
            } else {
                m->state = MDIO_STATE_IDLE;
            }

            if (m->state != MDIO_STATE_IDLE) {
                m->phy_addr = (m->data >> 7) & 0x1f;
                m->reg_addr = (m->data >> 2) & 0x1f;
            }

            if (m->state == MDIO_STATE_READING) {
                m->data_out = minimac2_mdio_read_reg(s, m->phy_addr,
                        m->reg_addr);
            }
        }

        if (m->count < 16 && m->state == MDIO_STATE_READING) {
            int bit = (m->data_out & 0x8000) ? 1 : 0;
            m->data_out <<= 1;

            if (bit) {
                s->regs[R_MDIO] |= MDIO_DI;
            } else {
                s->regs[R_MDIO] &= ~MDIO_DI;
            }
        }

        if (m->count == 0 && m->state) {
            if (m->state == MDIO_STATE_WRITING) {
                uint16_t data = m->data & 0xffff;
                minimac2_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
            }
            m->state = MDIO_STATE_IDLE;
        }
        m->count--;
    }

    m->last_clk = (s->regs[R_MDIO] & MDIO_CLK) ? 1 : 0;
}

static size_t assemble_frame(uint8_t *buf, size_t size,
        const uint8_t *payload, size_t payload_size)
{
    uint32_t crc;

    if (size < payload_size + 12) {
        error_report("milkymist_minimac2: received too big ethernet frame");
        return 0;
    }

    /* prepend preamble and sfd */
    memcpy(buf, preamble_sfd, 8);

    /* now copy the payload */
    memcpy(buf + 8, payload, payload_size);

    /* pad frame if needed */
    if (payload_size < 60) {
        memset(buf + payload_size + 8, 0, 60 - payload_size);
        payload_size = 60;
    }

    /* append fcs */
    crc = cpu_to_le32(crc32(0, buf + 8, payload_size));
    memcpy(buf + payload_size + 8, &crc, 4);

    return payload_size + 12;
}

static void minimac2_tx(MilkymistMinimac2State *s)
{
    uint32_t txcount = s->regs[R_TXCOUNT];
    uint8_t *buf = s->tx_buf;

    if (txcount < 64) {
        error_report("milkymist_minimac2: ethernet frame too small (%u < %u)",
                txcount, 64);
        goto err;
    }

    if (txcount > MINIMAC2_MTU) {
        error_report("milkymist_minimac2: MTU exceeded (%u > %u)",
                txcount, MINIMAC2_MTU);
        goto err;
    }

    if (memcmp(buf, preamble_sfd, 8) != 0) {
        error_report("milkymist_minimac2: frame doesn't contain the preamble "
                "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)",
                buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
        goto err;
    }

    trace_milkymist_minimac2_tx_frame(txcount - 12);

    /* send packet, skipping preamble and sfd */
    qemu_send_packet_raw(&s->nic->nc, buf + 8, txcount - 12);

    s->regs[R_TXCOUNT] = 0;

err:
    trace_milkymist_minimac2_pulse_irq_tx();
    qemu_irq_pulse(s->tx_irq);
}

static void update_rx_interrupt(MilkymistMinimac2State *s)
{
    if (s->regs[R_STATE0] == STATE_PENDING
            || s->regs[R_STATE1] == STATE_PENDING) {
        trace_milkymist_minimac2_raise_irq_rx();
        qemu_irq_raise(s->rx_irq);
    } else {
        trace_milkymist_minimac2_lower_irq_rx();
        qemu_irq_lower(s->rx_irq);
    }
}

static ssize_t minimac2_rx(NetClientState *nc, const uint8_t *buf, size_t size)
{
    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;

    uint32_t r_count;
    uint32_t r_state;
    uint8_t *rx_buf;

    size_t frame_size;

    trace_milkymist_minimac2_rx_frame(buf, size);

    /* choose appropriate slot */
    if (s->regs[R_STATE0] == STATE_LOADED) {
        r_count = R_COUNT0;
        r_state = R_STATE0;
        rx_buf = s->rx0_buf;
    } else if (s->regs[R_STATE1] == STATE_LOADED) {
        r_count = R_COUNT1;
        r_state = R_STATE1;
        rx_buf = s->rx1_buf;
    } else {
        trace_milkymist_minimac2_drop_rx_frame(buf);
        return size;
    }

    /* assemble frame */
    frame_size = assemble_frame(rx_buf, MINIMAC2_BUFFER_SIZE, buf, size);

    if (frame_size == 0) {
        return size;
    }

    trace_milkymist_minimac2_rx_transfer(rx_buf, frame_size);

    /* update slot */
    s->regs[r_count] = frame_size;
    s->regs[r_state] = STATE_PENDING;

    update_rx_interrupt(s);

    return size;
}

static uint64_t
minimac2_read(void *opaque, hwaddr addr, unsigned size)
{
    MilkymistMinimac2State *s = opaque;
    uint32_t r = 0;

    addr >>= 2;
    switch (addr) {
    case R_SETUP:
    case R_MDIO:
    case R_STATE0:
    case R_COUNT0:
    case R_STATE1:
    case R_COUNT1:
    case R_TXCOUNT:
        r = s->regs[addr];
        break;

    default:
        error_report("milkymist_minimac2: read access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        break;
    }

    trace_milkymist_minimac2_memory_read(addr << 2, r);

    return r;
}

static void
minimac2_write(void *opaque, hwaddr addr, uint64_t value,
               unsigned size)
{
    MilkymistMinimac2State *s = opaque;

    trace_milkymist_minimac2_memory_read(addr, value);

    addr >>= 2;
    switch (addr) {
    case R_MDIO:
    {
        /* MDIO_DI is read only */
        int mdio_di = (s->regs[R_MDIO] & MDIO_DI);
        s->regs[R_MDIO] = value;
        if (mdio_di) {
            s->regs[R_MDIO] |= mdio_di;
        } else {
            s->regs[R_MDIO] &= ~mdio_di;
        }

        minimac2_update_mdio(s);
    } break;
    case R_TXCOUNT:
        s->regs[addr] = value;
        if (value > 0) {
            minimac2_tx(s);
        }
        break;
    case R_STATE0:
    case R_STATE1:
        s->regs[addr] = value;
        update_rx_interrupt(s);
        break;
    case R_SETUP:
    case R_COUNT0:
    case R_COUNT1:
        s->regs[addr] = value;
        break;

    default:
        error_report("milkymist_minimac2: write access to unknown register 0x"
                TARGET_FMT_plx, addr << 2);
        break;
    }
}

static const MemoryRegionOps minimac2_ops = {
    .read = minimac2_read,
    .write = minimac2_write,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static int minimac2_can_rx(NetClientState *nc)
{
    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;

    if (s->regs[R_STATE0] == STATE_LOADED) {
        return 1;
    }
    if (s->regs[R_STATE1] == STATE_LOADED) {
        return 1;
    }

    return 0;
}

static void minimac2_cleanup(NetClientState *nc)
{
    MilkymistMinimac2State *s = DO_UPCAST(NICState, nc, nc)->opaque;

    s->nic = NULL;
}

static void milkymist_minimac2_reset(DeviceState *d)
{
    MilkymistMinimac2State *s =
            container_of(d, MilkymistMinimac2State, busdev.qdev);
    int i;

    for (i = 0; i < R_MAX; i++) {
        s->regs[i] = 0;
    }
    for (i = 0; i < R_PHY_MAX; i++) {
        s->phy_regs[i] = 0;
    }

    /* defaults */
    s->phy_regs[R_PHY_ID1] = 0x0022; /* Micrel KSZ8001L */
    s->phy_regs[R_PHY_ID2] = 0x161a;
}

static NetClientInfo net_milkymist_minimac2_info = {
    .type = NET_CLIENT_OPTIONS_KIND_NIC,
    .size = sizeof(NICState),
    .can_receive = minimac2_can_rx,
    .receive = minimac2_rx,
    .cleanup = minimac2_cleanup,
};

static int milkymist_minimac2_init(SysBusDevice *dev)
{
    MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
    size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);

    sysbus_init_irq(dev, &s->rx_irq);
    sysbus_init_irq(dev, &s->tx_irq);

    memory_region_init_io(&s->regs_region, &minimac2_ops, s,
                          "milkymist-minimac2", R_MAX * 4);
    sysbus_init_mmio(dev, &s->regs_region);

    /* register buffers memory */
    memory_region_init_ram(&s->buffers, "milkymist-minimac2.buffers",
                           buffers_size);
    vmstate_register_ram_global(&s->buffers);
    s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
    s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
    s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;

    sysbus_add_memory(dev, s->buffers_base, &s->buffers);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);
    s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);

    return 0;
}

static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
    .name = "milkymist-minimac2-mdio",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_INT32(last_clk, MilkymistMinimac2MdioState),
        VMSTATE_INT32(count, MilkymistMinimac2MdioState),
        VMSTATE_UINT32(data, MilkymistMinimac2MdioState),
        VMSTATE_UINT16(data_out, MilkymistMinimac2MdioState),
        VMSTATE_INT32(state, MilkymistMinimac2MdioState),
        VMSTATE_UINT8(phy_addr, MilkymistMinimac2MdioState),
        VMSTATE_UINT8(reg_addr, MilkymistMinimac2MdioState),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_milkymist_minimac2 = {
    .name = "milkymist-minimac2",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, MilkymistMinimac2State, R_MAX),
        VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimac2State, R_PHY_MAX),
        VMSTATE_STRUCT(mdio, MilkymistMinimac2State, 0,
                vmstate_milkymist_minimac2_mdio, MilkymistMinimac2MdioState),
        VMSTATE_END_OF_LIST()
    }
};

static Property milkymist_minimac2_properties[] = {
    DEFINE_PROP_TADDR("buffers_base", MilkymistMinimac2State,
    buffers_base, 0),
    DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
    DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
    DEFINE_PROP_END_OF_LIST(),
};

static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = milkymist_minimac2_init;
    dc->reset = milkymist_minimac2_reset;
    dc->vmsd = &vmstate_milkymist_minimac2;
    dc->props = milkymist_minimac2_properties;
}

static const TypeInfo milkymist_minimac2_info = {
    .name          = "milkymist-minimac2",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MilkymistMinimac2State),
    .class_init    = milkymist_minimac2_class_init,
};

static void milkymist_minimac2_register_types(void)
{
    type_register_static(&milkymist_minimac2_info);
}

type_init(milkymist_minimac2_register_types)
