/*
 * 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 "qemu/osdep.h"
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "net/net.h"
#include "qemu/fifo8.h"
#include "hw/irq.h"
#include "hw/net/allwinner_emac.h"
#include "hw/qdev-properties.h"
#include "qemu/log.h"
#include "qemu/module.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_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_DRIVER_NIC,
    .size = sizeof(NICState),
    .can_receive = aw_emac_can_receive,
    .receive = aw_emac_receive,
    .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)
