/*
 * Emulation of Allwinner EMAC Fast Ethernet controller and
 * Realtek RTL8201CP PHY
 *
 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
 *
 * This model is based on reverse-engineering of Linux kernel driver.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 */
#include "hw/sysbus.h"
#include "net/net.h"
#include "qemu/fifo8.h"
#include "hw/net/allwinner_emac.h"
#include <zlib.h>

static uint8_t padding[60];

static void mii_set_link(RTL8201CPState *mii, bool link_ok)
{
    if (link_ok) {
        mii->bmsr |= MII_BMSR_LINK_ST | MII_BMSR_AN_COMP;
        mii->anlpar |= MII_ANAR_TXFD | MII_ANAR_10FD | MII_ANAR_10 |
                       MII_ANAR_CSMACD;
    } else {
        mii->bmsr &= ~(MII_BMSR_LINK_ST | MII_BMSR_AN_COMP);
        mii->anlpar = MII_ANAR_TX;
    }
}

static void mii_reset(RTL8201CPState *mii, bool link_ok)
{
    mii->bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED;
    mii->bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD |
                MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG;
    mii->anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 |
                MII_ANAR_CSMACD;
    mii->anlpar = MII_ANAR_TX;

    mii_set_link(mii, link_ok);
}

static uint16_t RTL8201CP_mdio_read(AwEmacState *s, uint8_t addr, uint8_t reg)
{
    RTL8201CPState *mii = &s->mii;
    uint16_t ret = 0xffff;

    if (addr == s->phy_addr) {
        switch (reg) {
        case MII_BMCR:
            return mii->bmcr;
        case MII_BMSR:
            return mii->bmsr;
        case MII_PHYID1:
            return RTL8201CP_PHYID1;
        case MII_PHYID2:
            return RTL8201CP_PHYID2;
        case MII_ANAR:
            return mii->anar;
        case MII_ANLPAR:
            return mii->anlpar;
        case MII_ANER:
        case MII_NSR:
        case MII_LBREMR:
        case MII_REC:
        case MII_SNRDR:
        case MII_TEST:
            qemu_log_mask(LOG_UNIMP,
                          "allwinner_emac: read from unimpl. mii reg 0x%x\n",
                          reg);
            return 0;
        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "allwinner_emac: read from invalid mii reg 0x%x\n",
                          reg);
            return 0;
        }
    }
    return ret;
}

static void RTL8201CP_mdio_write(AwEmacState *s, uint8_t addr, uint8_t reg,
                                 uint16_t value)
{
    RTL8201CPState *mii = &s->mii;
    NetClientState *nc;

    if (addr == s->phy_addr) {
        switch (reg) {
        case MII_BMCR:
            if (value & MII_BMCR_RESET) {
                nc = qemu_get_queue(s->nic);
                mii_reset(mii, !nc->link_down);
            } else {
                mii->bmcr = value;
            }
            break;
        case MII_ANAR:
            mii->anar = value;
            break;
        case MII_BMSR:
        case MII_PHYID1:
        case MII_PHYID2:
        case MII_ANLPAR:
        case MII_ANER:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "allwinner_emac: write to read-only mii reg 0x%x\n",
                          reg);
            break;
        case MII_NSR:
        case MII_LBREMR:
        case MII_REC:
        case MII_SNRDR:
        case MII_TEST:
            qemu_log_mask(LOG_UNIMP,
                          "allwinner_emac: write to unimpl. mii reg 0x%x\n",
                          reg);
            break;
        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "allwinner_emac: write to invalid mii reg 0x%x\n",
                          reg);
        }
    }
}

static void aw_emac_update_irq(AwEmacState *s)
{
    qemu_set_irq(s->irq, (s->int_sta & s->int_ctl) != 0);
}

static void aw_emac_tx_reset(AwEmacState *s, int chan)
{
    fifo8_reset(&s->tx_fifo[chan]);
    s->tx_length[chan] = 0;
}

static void aw_emac_rx_reset(AwEmacState *s)
{
    fifo8_reset(&s->rx_fifo);
    s->rx_num_packets = 0;
    s->rx_packet_size = 0;
    s->rx_packet_pos = 0;
}

static void fifo8_push_word(Fifo8 *fifo, uint32_t val)
{
    fifo8_push(fifo, val);
    fifo8_push(fifo, val >> 8);
    fifo8_push(fifo, val >> 16);
    fifo8_push(fifo, val >> 24);
}

static uint32_t fifo8_pop_word(Fifo8 *fifo)
{
    uint32_t ret;

    ret = fifo8_pop(fifo);
    ret |= fifo8_pop(fifo) << 8;
    ret |= fifo8_pop(fifo) << 16;
    ret |= fifo8_pop(fifo) << 24;

    return ret;
}

static int aw_emac_can_receive(NetClientState *nc)
{
    AwEmacState *s = qemu_get_nic_opaque(nc);

    /*
     * To avoid packet drops, allow reception only when there is space
     * for a full frame: 1522 + 8 (rx headers) + 2 (padding).
     */
    return (s->ctl & EMAC_CTL_RX_EN) && (fifo8_num_free(&s->rx_fifo) >= 1532);
}

static ssize_t aw_emac_receive(NetClientState *nc, const uint8_t *buf,
                               size_t size)
{
    AwEmacState *s = qemu_get_nic_opaque(nc);
    Fifo8 *fifo = &s->rx_fifo;
    size_t padded_size, total_size;
    uint32_t crc;

    padded_size = size > 60 ? size : 60;
    total_size = QEMU_ALIGN_UP(RX_HDR_SIZE + padded_size + CRC_SIZE, 4);

    if (!(s->ctl & EMAC_CTL_RX_EN) || (fifo8_num_free(fifo) < total_size)) {
        return -1;
    }

    fifo8_push_word(fifo, EMAC_UNDOCUMENTED_MAGIC);
    fifo8_push_word(fifo, EMAC_RX_HEADER(padded_size + CRC_SIZE,
                                         EMAC_RX_IO_DATA_STATUS_OK));
    fifo8_push_all(fifo, buf, size);
    crc = crc32(~0, buf, size);

    if (padded_size != size) {
        fifo8_push_all(fifo, padding, padded_size - size);
        crc = crc32(crc, padding, padded_size - size);
    }

    fifo8_push_word(fifo, crc);
    fifo8_push_all(fifo, padding, QEMU_ALIGN_UP(padded_size, 4) - padded_size);
    s->rx_num_packets++;

    s->int_sta |= EMAC_INT_RX;
    aw_emac_update_irq(s);

    return size;
}

static void aw_emac_cleanup(NetClientState *nc)
{
    AwEmacState *s = qemu_get_nic_opaque(nc);

    s->nic = NULL;
}

static void aw_emac_reset(DeviceState *dev)
{
    AwEmacState *s = AW_EMAC(dev);
    NetClientState *nc = qemu_get_queue(s->nic);

    s->ctl = 0;
    s->tx_mode = 0;
    s->int_ctl = 0;
    s->int_sta = 0;
    s->tx_channel = 0;
    s->phy_target = 0;

    aw_emac_tx_reset(s, 0);
    aw_emac_tx_reset(s, 1);
    aw_emac_rx_reset(s);

    mii_reset(&s->mii, !nc->link_down);
}

static uint64_t aw_emac_read(void *opaque, hwaddr offset, unsigned size)
{
    AwEmacState *s = opaque;
    Fifo8 *fifo = &s->rx_fifo;
    NetClientState *nc;
    uint64_t ret;

    switch (offset) {
    case EMAC_CTL_REG:
        return s->ctl;
    case EMAC_TX_MODE_REG:
        return s->tx_mode;
    case EMAC_TX_INS_REG:
        return s->tx_channel;
    case EMAC_RX_CTL_REG:
        return s->rx_ctl;
    case EMAC_RX_IO_DATA_REG:
        if (!s->rx_num_packets) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "Read IO data register when no packet available");
            return 0;
        }

        ret = fifo8_pop_word(fifo);

        switch (s->rx_packet_pos) {
        case 0:     /* Word is magic header */
            s->rx_packet_pos += 4;
            break;
        case 4:     /* Word is rx info header */
            s->rx_packet_pos += 4;
            s->rx_packet_size = QEMU_ALIGN_UP(extract32(ret, 0, 16), 4);
            break;
        default:    /* Word is packet data */
            s->rx_packet_pos += 4;
            s->rx_packet_size -= 4;

            if (!s->rx_packet_size) {
                s->rx_packet_pos = 0;
                s->rx_num_packets--;
                nc = qemu_get_queue(s->nic);
                if (aw_emac_can_receive(nc)) {
                    qemu_flush_queued_packets(nc);
                }
            }
        }
        return ret;
    case EMAC_RX_FBC_REG:
        return s->rx_num_packets;
    case EMAC_INT_CTL_REG:
        return s->int_ctl;
    case EMAC_INT_STA_REG:
        return s->int_sta;
    case EMAC_MAC_MRDD_REG:
        return RTL8201CP_mdio_read(s,
                                   extract32(s->phy_target, PHY_ADDR_SHIFT, 8),
                                   extract32(s->phy_target, PHY_REG_SHIFT, 8));
    default:
        qemu_log_mask(LOG_UNIMP,
                      "allwinner_emac: read access to unknown register 0x"
                      TARGET_FMT_plx "\n", offset);
        ret = 0;
    }

    return ret;
}

static void aw_emac_write(void *opaque, hwaddr offset, uint64_t value,
                          unsigned size)
{
    AwEmacState *s = opaque;
    Fifo8 *fifo;
    NetClientState *nc = qemu_get_queue(s->nic);
    int chan;

    switch (offset) {
    case EMAC_CTL_REG:
        if (value & EMAC_CTL_RESET) {
            aw_emac_reset(DEVICE(s));
            value &= ~EMAC_CTL_RESET;
        }
        s->ctl = value;
        if (aw_emac_can_receive(nc)) {
            qemu_flush_queued_packets(nc);
        }
        break;
    case EMAC_TX_MODE_REG:
        s->tx_mode = value;
        break;
    case EMAC_TX_CTL0_REG:
    case EMAC_TX_CTL1_REG:
        chan = (offset == EMAC_TX_CTL0_REG ? 0 : 1);
        if ((value & 1) && (s->ctl & EMAC_CTL_TX_EN)) {
            uint32_t len, ret;
            const uint8_t *data;

            fifo = &s->tx_fifo[chan];
            len = s->tx_length[chan];

            if (len > fifo8_num_used(fifo)) {
                len = fifo8_num_used(fifo);
                qemu_log_mask(LOG_GUEST_ERROR,
                              "allwinner_emac: TX length > fifo data length\n");
            }
            if (len > 0) {
                data = fifo8_pop_buf(fifo, len, &ret);
                qemu_send_packet(nc, data, ret);
                aw_emac_tx_reset(s, chan);
                /* Raise TX interrupt */
                s->int_sta |= EMAC_INT_TX_CHAN(chan);
                aw_emac_update_irq(s);
            }
        }
        break;
    case EMAC_TX_INS_REG:
        s->tx_channel = value < NUM_TX_FIFOS ? value : 0;
        break;
    case EMAC_TX_PL0_REG:
    case EMAC_TX_PL1_REG:
        chan = (offset == EMAC_TX_PL0_REG ? 0 : 1);
        if (value > TX_FIFO_SIZE) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "allwinner_emac: invalid TX frame length %d\n",
                          (int)value);
            value = TX_FIFO_SIZE;
        }
        s->tx_length[chan] = value;
        break;
    case EMAC_TX_IO_DATA_REG:
        fifo = &s->tx_fifo[s->tx_channel];
        if (fifo8_num_free(fifo) < 4) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "allwinner_emac: TX data overruns fifo\n");
            break;
        }
        fifo8_push_word(fifo, value);
        break;
    case EMAC_RX_CTL_REG:
        s->rx_ctl = value;
        break;
    case EMAC_RX_FBC_REG:
        if (value == 0) {
            aw_emac_rx_reset(s);
        }
        break;
    case EMAC_INT_CTL_REG:
        s->int_ctl = value;
        aw_emac_update_irq(s);
        break;
    case EMAC_INT_STA_REG:
        s->int_sta &= ~value;
        aw_emac_update_irq(s);
        break;
    case EMAC_MAC_MADR_REG:
        s->phy_target = value;
        break;
    case EMAC_MAC_MWTD_REG:
        RTL8201CP_mdio_write(s, extract32(s->phy_target, PHY_ADDR_SHIFT, 8),
                             extract32(s->phy_target, PHY_REG_SHIFT, 8), value);
        break;
    default:
        qemu_log_mask(LOG_UNIMP,
                      "allwinner_emac: write access to unknown register 0x"
                      TARGET_FMT_plx "\n", offset);
    }
}

static void aw_emac_set_link(NetClientState *nc)
{
    AwEmacState *s = qemu_get_nic_opaque(nc);

    mii_set_link(&s->mii, !nc->link_down);
}

static const MemoryRegionOps aw_emac_mem_ops = {
    .read = aw_emac_read,
    .write = aw_emac_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static NetClientInfo net_aw_emac_info = {
    .type = NET_CLIENT_OPTIONS_KIND_NIC,
    .size = sizeof(NICState),
    .can_receive = aw_emac_can_receive,
    .receive = aw_emac_receive,
    .cleanup = aw_emac_cleanup,
    .link_status_changed = aw_emac_set_link,
};

static void aw_emac_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    AwEmacState *s = AW_EMAC(obj);

    memory_region_init_io(&s->iomem, OBJECT(s), &aw_emac_mem_ops, s,
                          "aw_emac", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq);
}

static void aw_emac_realize(DeviceState *dev, Error **errp)
{
    AwEmacState *s = AW_EMAC(dev);

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

    fifo8_create(&s->rx_fifo, RX_FIFO_SIZE);
    fifo8_create(&s->tx_fifo[0], TX_FIFO_SIZE);
    fifo8_create(&s->tx_fifo[1], TX_FIFO_SIZE);
}

static Property aw_emac_properties[] = {
    DEFINE_NIC_PROPERTIES(AwEmacState, conf),
    DEFINE_PROP_UINT8("phy-addr", AwEmacState, phy_addr, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_mii = {
    .name = "rtl8201cp",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT16(bmcr, RTL8201CPState),
        VMSTATE_UINT16(bmsr, RTL8201CPState),
        VMSTATE_UINT16(anar, RTL8201CPState),
        VMSTATE_UINT16(anlpar, RTL8201CPState),
        VMSTATE_END_OF_LIST()
    }
};

static int aw_emac_post_load(void *opaque, int version_id)
{
    AwEmacState *s = opaque;

    aw_emac_set_link(qemu_get_queue(s->nic));

    return 0;
}

static const VMStateDescription vmstate_aw_emac = {
    .name = "allwinner_emac",
    .version_id = 1,
    .minimum_version_id = 1,
    .post_load = aw_emac_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(mii, AwEmacState, 1, vmstate_mii, RTL8201CPState),
        VMSTATE_UINT32(ctl, AwEmacState),
        VMSTATE_UINT32(tx_mode, AwEmacState),
        VMSTATE_UINT32(rx_ctl, AwEmacState),
        VMSTATE_UINT32(int_ctl, AwEmacState),
        VMSTATE_UINT32(int_sta, AwEmacState),
        VMSTATE_UINT32(phy_target, AwEmacState),
        VMSTATE_FIFO8(rx_fifo, AwEmacState),
        VMSTATE_UINT32(rx_num_packets, AwEmacState),
        VMSTATE_UINT32(rx_packet_size, AwEmacState),
        VMSTATE_UINT32(rx_packet_pos, AwEmacState),
        VMSTATE_STRUCT_ARRAY(tx_fifo, AwEmacState, NUM_TX_FIFOS, 1,
                             vmstate_fifo8, Fifo8),
        VMSTATE_UINT32_ARRAY(tx_length, AwEmacState, NUM_TX_FIFOS),
        VMSTATE_UINT32(tx_channel, AwEmacState),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->realize = aw_emac_realize;
    dc->props = aw_emac_properties;
    dc->reset = aw_emac_reset;
    dc->vmsd = &vmstate_aw_emac;
}

static const TypeInfo aw_emac_info = {
    .name           = TYPE_AW_EMAC,
    .parent         = TYPE_SYS_BUS_DEVICE,
    .instance_size  = sizeof(AwEmacState),
    .instance_init   = aw_emac_init,
    .class_init     = aw_emac_class_init,
};

static void aw_emac_register_types(void)
{
    type_register_static(&aw_emac_info);
}

type_init(aw_emac_register_types)
