/*
 * i.MX Fast Ethernet Controller emulation.
 *
 * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
 *
 * Based on Coldfire Fast Ethernet Controller emulation.
 *
 * Copyright (c) 2007 CodeSourcery.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/net/imx_fec.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "sysemu/dma.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "net/checksum.h"
#include "net/eth.h"
#include "trace.h"

/* For crc32 */
#include <zlib.h>

#define IMX_MAX_DESC    1024

static const char *imx_default_reg_name(IMXFECState *s, uint32_t index)
{
    static char tmp[20];
    sprintf(tmp, "index %d", index);
    return tmp;
}

static const char *imx_fec_reg_name(IMXFECState *s, uint32_t index)
{
    switch (index) {
    case ENET_FRBR:
        return "FRBR";
    case ENET_FRSR:
        return "FRSR";
    case ENET_MIIGSK_CFGR:
        return "MIIGSK_CFGR";
    case ENET_MIIGSK_ENR:
        return "MIIGSK_ENR";
    default:
        return imx_default_reg_name(s, index);
    }
}

static const char *imx_enet_reg_name(IMXFECState *s, uint32_t index)
{
    switch (index) {
    case ENET_RSFL:
        return "RSFL";
    case ENET_RSEM:
        return "RSEM";
    case ENET_RAEM:
        return "RAEM";
    case ENET_RAFL:
        return "RAFL";
    case ENET_TSEM:
        return "TSEM";
    case ENET_TAEM:
        return "TAEM";
    case ENET_TAFL:
        return "TAFL";
    case ENET_TIPG:
        return "TIPG";
    case ENET_FTRL:
        return "FTRL";
    case ENET_TACC:
        return "TACC";
    case ENET_RACC:
        return "RACC";
    case ENET_ATCR:
        return "ATCR";
    case ENET_ATVR:
        return "ATVR";
    case ENET_ATOFF:
        return "ATOFF";
    case ENET_ATPER:
        return "ATPER";
    case ENET_ATCOR:
        return "ATCOR";
    case ENET_ATINC:
        return "ATINC";
    case ENET_ATSTMP:
        return "ATSTMP";
    case ENET_TGSR:
        return "TGSR";
    case ENET_TCSR0:
        return "TCSR0";
    case ENET_TCCR0:
        return "TCCR0";
    case ENET_TCSR1:
        return "TCSR1";
    case ENET_TCCR1:
        return "TCCR1";
    case ENET_TCSR2:
        return "TCSR2";
    case ENET_TCCR2:
        return "TCCR2";
    case ENET_TCSR3:
        return "TCSR3";
    case ENET_TCCR3:
        return "TCCR3";
    default:
        return imx_default_reg_name(s, index);
    }
}

static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
{
    switch (index) {
    case ENET_EIR:
        return "EIR";
    case ENET_EIMR:
        return "EIMR";
    case ENET_RDAR:
        return "RDAR";
    case ENET_TDAR:
        return "TDAR";
    case ENET_ECR:
        return "ECR";
    case ENET_MMFR:
        return "MMFR";
    case ENET_MSCR:
        return "MSCR";
    case ENET_MIBC:
        return "MIBC";
    case ENET_RCR:
        return "RCR";
    case ENET_TCR:
        return "TCR";
    case ENET_PALR:
        return "PALR";
    case ENET_PAUR:
        return "PAUR";
    case ENET_OPD:
        return "OPD";
    case ENET_IAUR:
        return "IAUR";
    case ENET_IALR:
        return "IALR";
    case ENET_GAUR:
        return "GAUR";
    case ENET_GALR:
        return "GALR";
    case ENET_TFWR:
        return "TFWR";
    case ENET_RDSR:
        return "RDSR";
    case ENET_TDSR:
        return "TDSR";
    case ENET_MRBR:
        return "MRBR";
    default:
        if (s->is_fec) {
            return imx_fec_reg_name(s, index);
        } else {
            return imx_enet_reg_name(s, index);
        }
    }
}

/*
 * Versions of this device with more than one TX descriptor save the
 * 2nd and 3rd descriptors in a subsection, to maintain migration
 * compatibility with previous versions of the device that only
 * supported a single descriptor.
 */
static bool imx_eth_is_multi_tx_ring(void *opaque)
{
    IMXFECState *s = IMX_FEC(opaque);

    return s->tx_ring_num > 1;
}

static const VMStateDescription vmstate_imx_eth_txdescs = {
    .name = "imx.fec/txdescs",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = imx_eth_is_multi_tx_ring,
    .fields = (VMStateField[]) {
         VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
         VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
         VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_imx_eth = {
    .name = TYPE_IMX_FEC,
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
        VMSTATE_UINT32(rx_descriptor, IMXFECState),
        VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
        VMSTATE_UINT32(phy_status, IMXFECState),
        VMSTATE_UINT32(phy_control, IMXFECState),
        VMSTATE_UINT32(phy_advertise, IMXFECState),
        VMSTATE_UINT32(phy_int, IMXFECState),
        VMSTATE_UINT32(phy_int_mask, IMXFECState),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_imx_eth_txdescs,
        NULL
    },
};

#define PHY_INT_ENERGYON            (1 << 7)
#define PHY_INT_AUTONEG_COMPLETE    (1 << 6)
#define PHY_INT_FAULT               (1 << 5)
#define PHY_INT_DOWN                (1 << 4)
#define PHY_INT_AUTONEG_LP          (1 << 3)
#define PHY_INT_PARFAULT            (1 << 2)
#define PHY_INT_AUTONEG_PAGE        (1 << 1)

static void imx_eth_update(IMXFECState *s);

/*
 * The MII phy could raise a GPIO to the processor which in turn
 * could be handled as an interrpt by the OS.
 * For now we don't handle any GPIO/interrupt line, so the OS will
 * have to poll for the PHY status.
 */
static void imx_phy_update_irq(IMXFECState *s)
{
    imx_eth_update(s);
}

static void imx_phy_update_link(IMXFECState *s)
{
    /* Autonegotiation status mirrors link status.  */
    if (qemu_get_queue(s->nic)->link_down) {
        trace_imx_phy_update_link("down");
        s->phy_status &= ~0x0024;
        s->phy_int |= PHY_INT_DOWN;
    } else {
        trace_imx_phy_update_link("up");
        s->phy_status |= 0x0024;
        s->phy_int |= PHY_INT_ENERGYON;
        s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
    }
    imx_phy_update_irq(s);
}

static void imx_eth_set_link(NetClientState *nc)
{
    imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
}

static void imx_phy_reset(IMXFECState *s)
{
    trace_imx_phy_reset();

    s->phy_status = 0x7809;
    s->phy_control = 0x3000;
    s->phy_advertise = 0x01e1;
    s->phy_int_mask = 0;
    s->phy_int = 0;
    imx_phy_update_link(s);
}

static uint32_t imx_phy_read(IMXFECState *s, int reg)
{
    uint32_t val;
    uint32_t phy = reg / 32;

    if (phy != s->phy_num) {
        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
                      TYPE_IMX_FEC, __func__, phy);
        return 0;
    }

    reg %= 32;

    switch (reg) {
    case 0:     /* Basic Control */
        val = s->phy_control;
        break;
    case 1:     /* Basic Status */
        val = s->phy_status;
        break;
    case 2:     /* ID1 */
        val = 0x0007;
        break;
    case 3:     /* ID2 */
        val = 0xc0d1;
        break;
    case 4:     /* Auto-neg advertisement */
        val = s->phy_advertise;
        break;
    case 5:     /* Auto-neg Link Partner Ability */
        val = 0x0f71;
        break;
    case 6:     /* Auto-neg Expansion */
        val = 1;
        break;
    case 29:    /* Interrupt source.  */
        val = s->phy_int;
        s->phy_int = 0;
        imx_phy_update_irq(s);
        break;
    case 30:    /* Interrupt mask */
        val = s->phy_int_mask;
        break;
    case 17:
    case 18:
    case 27:
    case 31:
        qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
                      TYPE_IMX_FEC, __func__, reg);
        val = 0;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
                      TYPE_IMX_FEC, __func__, reg);
        val = 0;
        break;
    }

    trace_imx_phy_read(val, phy, reg);

    return val;
}

static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
{
    uint32_t phy = reg / 32;

    if (phy != s->phy_num) {
        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
                      TYPE_IMX_FEC, __func__, phy);
        return;
    }

    reg %= 32;

    trace_imx_phy_write(val, phy, reg);

    switch (reg) {
    case 0:     /* Basic Control */
        if (val & 0x8000) {
            imx_phy_reset(s);
        } else {
            s->phy_control = val & 0x7980;
            /* Complete autonegotiation immediately.  */
            if (val & 0x1000) {
                s->phy_status |= 0x0020;
            }
        }
        break;
    case 4:     /* Auto-neg advertisement */
        s->phy_advertise = (val & 0x2d7f) | 0x80;
        break;
    case 30:    /* Interrupt mask */
        s->phy_int_mask = val & 0xff;
        imx_phy_update_irq(s);
        break;
    case 17:
    case 18:
    case 27:
    case 31:
        qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
                      TYPE_IMX_FEC, __func__, reg);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
                      TYPE_IMX_FEC, __func__, reg);
        break;
    }
}

static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
{
    dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd));

    trace_imx_fec_read_bd(addr, bd->flags, bd->length, bd->data);
}

static void imx_fec_write_bd(IMXFECBufDesc *bd, dma_addr_t addr)
{
    dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd));
}

static void imx_enet_read_bd(IMXENETBufDesc *bd, dma_addr_t addr)
{
    dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd));

    trace_imx_enet_read_bd(addr, bd->flags, bd->length, bd->data,
                   bd->option, bd->status);
}

static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
{
    dma_memory_write(&address_space_memory, addr, bd, sizeof(*bd));
}

static void imx_eth_update(IMXFECState *s)
{
    /*
     * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
     * interrupts swapped. This worked with older versions of Linux (4.14
     * and older) since Linux associated both interrupt lines with Ethernet
     * MAC interrupts. Specifically,
     * - Linux 4.15 and later have separate interrupt handlers for the MAC and
     *   timer interrupts. Those versions of Linux fail with versions of QEMU
     *   with swapped interrupt assignments.
     * - In linux 4.14, both interrupt lines were registered with the Ethernet
     *   MAC interrupt handler. As a result, all versions of qemu happen to
     *   work, though that is accidental.
     * - In Linux 4.9 and older, the timer interrupt was registered directly
     *   with the Ethernet MAC interrupt handler. The MAC interrupt was
     *   redirected to a GPIO interrupt to work around erratum ERR006687.
     *   This was implemented using the SOC's IOMUX block. In qemu, this GPIO
     *   interrupt never fired since IOMUX is currently not supported in qemu.
     *   Linux instead received MAC interrupts on the timer interrupt.
     *   As a result, qemu versions with the swapped interrupt assignment work,
     *   albeit accidentally, but qemu versions with the correct interrupt
     *   assignment fail.
     *
     * To ensure that all versions of Linux work, generate ENET_INT_MAC
     * interrrupts on both interrupt lines. This should be changed if and when
     * qemu supports IOMUX.
     */
    if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
        (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
        qemu_set_irq(s->irq[1], 1);
    } else {
        qemu_set_irq(s->irq[1], 0);
    }

    if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_MAC) {
        qemu_set_irq(s->irq[0], 1);
    } else {
        qemu_set_irq(s->irq[0], 0);
    }
}

static void imx_fec_do_tx(IMXFECState *s)
{
    int frame_size = 0, descnt = 0;
    uint8_t *ptr = s->frame;
    uint32_t addr = s->tx_descriptor[0];

    while (descnt++ < IMX_MAX_DESC) {
        IMXFECBufDesc bd;
        int len;

        imx_fec_read_bd(&bd, addr);
        if ((bd.flags & ENET_BD_R) == 0) {

            /* Run out of descriptors to transmit.  */
            trace_imx_eth_tx_bd_busy();

            break;
        }
        len = bd.length;
        if (frame_size + len > ENET_MAX_FRAME_SIZE) {
            len = ENET_MAX_FRAME_SIZE - frame_size;
            s->regs[ENET_EIR] |= ENET_INT_BABT;
        }
        dma_memory_read(&address_space_memory, bd.data, ptr, len);
        ptr += len;
        frame_size += len;
        if (bd.flags & ENET_BD_L) {
            /* Last buffer in frame.  */
            qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
            ptr = s->frame;
            frame_size = 0;
            s->regs[ENET_EIR] |= ENET_INT_TXF;
        }
        s->regs[ENET_EIR] |= ENET_INT_TXB;
        bd.flags &= ~ENET_BD_R;
        /* Write back the modified descriptor.  */
        imx_fec_write_bd(&bd, addr);
        /* Advance to the next descriptor.  */
        if ((bd.flags & ENET_BD_W) != 0) {
            addr = s->regs[ENET_TDSR];
        } else {
            addr += sizeof(bd);
        }
    }

    s->tx_descriptor[0] = addr;

    imx_eth_update(s);
}

static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
{
    int frame_size = 0, descnt = 0;

    uint8_t *ptr = s->frame;
    uint32_t addr, int_txb, int_txf, tdsr;
    size_t ring;

    switch (index) {
    case ENET_TDAR:
        ring    = 0;
        int_txb = ENET_INT_TXB;
        int_txf = ENET_INT_TXF;
        tdsr    = ENET_TDSR;
        break;
    case ENET_TDAR1:
        ring    = 1;
        int_txb = ENET_INT_TXB1;
        int_txf = ENET_INT_TXF1;
        tdsr    = ENET_TDSR1;
        break;
    case ENET_TDAR2:
        ring    = 2;
        int_txb = ENET_INT_TXB2;
        int_txf = ENET_INT_TXF2;
        tdsr    = ENET_TDSR2;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: bogus value for index %x\n",
                      __func__, index);
        abort();
        break;
    }

    addr = s->tx_descriptor[ring];

    while (descnt++ < IMX_MAX_DESC) {
        IMXENETBufDesc bd;
        int len;

        imx_enet_read_bd(&bd, addr);
        if ((bd.flags & ENET_BD_R) == 0) {
            /* Run out of descriptors to transmit.  */

            trace_imx_eth_tx_bd_busy();

            break;
        }
        len = bd.length;
        if (frame_size + len > ENET_MAX_FRAME_SIZE) {
            len = ENET_MAX_FRAME_SIZE - frame_size;
            s->regs[ENET_EIR] |= ENET_INT_BABT;
        }
        dma_memory_read(&address_space_memory, bd.data, ptr, len);
        ptr += len;
        frame_size += len;
        if (bd.flags & ENET_BD_L) {
            int csum = 0;

            if (bd.option & ENET_BD_PINS) {
                csum |= (CSUM_TCP | CSUM_UDP);
            }
            if (bd.option & ENET_BD_IINS) {
                csum |= CSUM_IP;
            }
            if (csum) {
                net_checksum_calculate(s->frame, frame_size, csum);
            }

            /* Last buffer in frame.  */

            qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
            ptr = s->frame;

            frame_size = 0;
            if (bd.option & ENET_BD_TX_INT) {
                s->regs[ENET_EIR] |= int_txf;
            }
            /* Indicate that we've updated the last buffer descriptor. */
            bd.last_buffer = ENET_BD_BDU;
        }
        if (bd.option & ENET_BD_TX_INT) {
            s->regs[ENET_EIR] |= int_txb;
        }
        bd.flags &= ~ENET_BD_R;
        /* Write back the modified descriptor.  */
        imx_enet_write_bd(&bd, addr);
        /* Advance to the next descriptor.  */
        if ((bd.flags & ENET_BD_W) != 0) {
            addr = s->regs[tdsr];
        } else {
            addr += sizeof(bd);
        }
    }

    s->tx_descriptor[ring] = addr;

    imx_eth_update(s);
}

static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
{
    if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
        imx_enet_do_tx(s, index);
    } else {
        imx_fec_do_tx(s);
    }
}

static void imx_eth_enable_rx(IMXFECState *s, bool flush)
{
    IMXFECBufDesc bd;

    imx_fec_read_bd(&bd, s->rx_descriptor);

    s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;

    if (!s->regs[ENET_RDAR]) {
        trace_imx_eth_rx_bd_full();
    } else if (flush) {
        qemu_flush_queued_packets(qemu_get_queue(s->nic));
    }
}

static void imx_eth_reset(DeviceState *d)
{
    IMXFECState *s = IMX_FEC(d);

    /* Reset the Device */
    memset(s->regs, 0, sizeof(s->regs));
    s->regs[ENET_ECR]   = 0xf0000000;
    s->regs[ENET_MIBC]  = 0xc0000000;
    s->regs[ENET_RCR]   = 0x05ee0001;
    s->regs[ENET_OPD]   = 0x00010000;

    s->regs[ENET_PALR]  = (s->conf.macaddr.a[0] << 24)
                          | (s->conf.macaddr.a[1] << 16)
                          | (s->conf.macaddr.a[2] << 8)
                          | s->conf.macaddr.a[3];
    s->regs[ENET_PAUR]  = (s->conf.macaddr.a[4] << 24)
                          | (s->conf.macaddr.a[5] << 16)
                          | 0x8808;

    if (s->is_fec) {
        s->regs[ENET_FRBR]  = 0x00000600;
        s->regs[ENET_FRSR]  = 0x00000500;
        s->regs[ENET_MIIGSK_ENR]  = 0x00000006;
    } else {
        s->regs[ENET_RAEM]  = 0x00000004;
        s->regs[ENET_RAFL]  = 0x00000004;
        s->regs[ENET_TAEM]  = 0x00000004;
        s->regs[ENET_TAFL]  = 0x00000008;
        s->regs[ENET_TIPG]  = 0x0000000c;
        s->regs[ENET_FTRL]  = 0x000007ff;
        s->regs[ENET_ATPER] = 0x3b9aca00;
    }

    s->rx_descriptor = 0;
    memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));

    /* We also reset the PHY */
    imx_phy_reset(s);
}

static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
{
    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
                  PRIx32 "\n", TYPE_IMX_FEC, __func__, index * 4);
    return 0;
}

static uint32_t imx_fec_read(IMXFECState *s, uint32_t index)
{
    switch (index) {
    case ENET_FRBR:
    case ENET_FRSR:
    case ENET_MIIGSK_CFGR:
    case ENET_MIIGSK_ENR:
        return s->regs[index];
    default:
        return imx_default_read(s, index);
    }
}

static uint32_t imx_enet_read(IMXFECState *s, uint32_t index)
{
    switch (index) {
    case ENET_RSFL:
    case ENET_RSEM:
    case ENET_RAEM:
    case ENET_RAFL:
    case ENET_TSEM:
    case ENET_TAEM:
    case ENET_TAFL:
    case ENET_TIPG:
    case ENET_FTRL:
    case ENET_TACC:
    case ENET_RACC:
    case ENET_ATCR:
    case ENET_ATVR:
    case ENET_ATOFF:
    case ENET_ATPER:
    case ENET_ATCOR:
    case ENET_ATINC:
    case ENET_ATSTMP:
    case ENET_TGSR:
    case ENET_TCSR0:
    case ENET_TCCR0:
    case ENET_TCSR1:
    case ENET_TCCR1:
    case ENET_TCSR2:
    case ENET_TCCR2:
    case ENET_TCSR3:
    case ENET_TCCR3:
        return s->regs[index];
    default:
        return imx_default_read(s, index);
    }
}

static uint64_t imx_eth_read(void *opaque, hwaddr offset, unsigned size)
{
    uint32_t value = 0;
    IMXFECState *s = IMX_FEC(opaque);
    uint32_t index = offset >> 2;

    switch (index) {
    case ENET_EIR:
    case ENET_EIMR:
    case ENET_RDAR:
    case ENET_TDAR:
    case ENET_ECR:
    case ENET_MMFR:
    case ENET_MSCR:
    case ENET_MIBC:
    case ENET_RCR:
    case ENET_TCR:
    case ENET_PALR:
    case ENET_PAUR:
    case ENET_OPD:
    case ENET_IAUR:
    case ENET_IALR:
    case ENET_GAUR:
    case ENET_GALR:
    case ENET_TFWR:
    case ENET_RDSR:
    case ENET_TDSR:
    case ENET_MRBR:
        value = s->regs[index];
        break;
    default:
        if (s->is_fec) {
            value = imx_fec_read(s, index);
        } else {
            value = imx_enet_read(s, index);
        }
        break;
    }

    trace_imx_eth_read(index, imx_eth_reg_name(s, index), value);

    return value;
}

static void imx_default_write(IMXFECState *s, uint32_t index, uint32_t value)
{
    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                  PRIx32 "\n", TYPE_IMX_FEC, __func__, index * 4);
    return;
}

static void imx_fec_write(IMXFECState *s, uint32_t index, uint32_t value)
{
    switch (index) {
    case ENET_FRBR:
        /* FRBR is read only */
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Register FRBR is read only\n",
                      TYPE_IMX_FEC, __func__);
        break;
    case ENET_FRSR:
        s->regs[index] = (value & 0x000003fc) | 0x00000400;
        break;
    case ENET_MIIGSK_CFGR:
        s->regs[index] = value & 0x00000053;
        break;
    case ENET_MIIGSK_ENR:
        s->regs[index] = (value & 0x00000002) ? 0x00000006 : 0;
        break;
    default:
        imx_default_write(s, index, value);
        break;
    }
}

static void imx_enet_write(IMXFECState *s, uint32_t index, uint32_t value)
{
    switch (index) {
    case ENET_RSFL:
    case ENET_RSEM:
    case ENET_RAEM:
    case ENET_RAFL:
    case ENET_TSEM:
    case ENET_TAEM:
    case ENET_TAFL:
        s->regs[index] = value & 0x000001ff;
        break;
    case ENET_TIPG:
        s->regs[index] = value & 0x0000001f;
        break;
    case ENET_FTRL:
        s->regs[index] = value & 0x00003fff;
        break;
    case ENET_TACC:
        s->regs[index] = value & 0x00000019;
        break;
    case ENET_RACC:
        s->regs[index] = value & 0x000000C7;
        break;
    case ENET_ATCR:
        s->regs[index] = value & 0x00002a9d;
        break;
    case ENET_ATVR:
    case ENET_ATOFF:
    case ENET_ATPER:
        s->regs[index] = value;
        break;
    case ENET_ATSTMP:
        /* ATSTMP is read only */
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Register ATSTMP is read only\n",
                      TYPE_IMX_FEC, __func__);
        break;
    case ENET_ATCOR:
        s->regs[index] = value & 0x7fffffff;
        break;
    case ENET_ATINC:
        s->regs[index] = value & 0x00007f7f;
        break;
    case ENET_TGSR:
        /* implement clear timer flag */
        s->regs[index] &= ~(value & 0x0000000f); /* all bits W1C */
        break;
    case ENET_TCSR0:
    case ENET_TCSR1:
    case ENET_TCSR2:
    case ENET_TCSR3:
        s->regs[index] &= ~(value & 0x00000080); /* W1C bits */
        s->regs[index] &= ~0x0000007d; /* writable fields */
        s->regs[index] |= (value & 0x0000007d);
        break;
    case ENET_TCCR0:
    case ENET_TCCR1:
    case ENET_TCCR2:
    case ENET_TCCR3:
        s->regs[index] = value;
        break;
    default:
        imx_default_write(s, index, value);
        break;
    }
}

static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
                           unsigned size)
{
    IMXFECState *s = IMX_FEC(opaque);
    const bool single_tx_ring = !imx_eth_is_multi_tx_ring(s);
    uint32_t index = offset >> 2;

    trace_imx_eth_write(index, imx_eth_reg_name(s, index), value);

    switch (index) {
    case ENET_EIR:
        s->regs[index] &= ~value;
        break;
    case ENET_EIMR:
        s->regs[index] = value;
        break;
    case ENET_RDAR:
        if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
            if (!s->regs[index]) {
                imx_eth_enable_rx(s, true);
            }
        } else {
            s->regs[index] = 0;
        }
        break;
    case ENET_TDAR1:
    case ENET_TDAR2:
        if (unlikely(single_tx_ring)) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "[%s]%s: trying to access TDAR2 or TDAR1\n",
                          TYPE_IMX_FEC, __func__);
            return;
        }
        /* fall through */
    case ENET_TDAR:
        if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
            s->regs[index] = ENET_TDAR_TDAR;
            imx_eth_do_tx(s, index);
        }
        s->regs[index] = 0;
        break;
    case ENET_ECR:
        if (value & ENET_ECR_RESET) {
            return imx_eth_reset(DEVICE(s));
        }
        s->regs[index] = value;
        if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
            s->regs[ENET_RDAR] = 0;
            s->rx_descriptor = s->regs[ENET_RDSR];
            s->regs[ENET_TDAR]  = 0;
            s->regs[ENET_TDAR1] = 0;
            s->regs[ENET_TDAR2] = 0;
            s->tx_descriptor[0] = s->regs[ENET_TDSR];
            s->tx_descriptor[1] = s->regs[ENET_TDSR1];
            s->tx_descriptor[2] = s->regs[ENET_TDSR2];
        }
        break;
    case ENET_MMFR:
        s->regs[index] = value;
        if (extract32(value, 29, 1)) {
            /* This is a read operation */
            s->regs[ENET_MMFR] = deposit32(s->regs[ENET_MMFR], 0, 16,
                                           imx_phy_read(s,
                                                       extract32(value,
                                                                 18, 10)));
        } else {
            /* This is a write operation */
            imx_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 16));
        }
        /* raise the interrupt as the PHY operation is done */
        s->regs[ENET_EIR] |= ENET_INT_MII;
        break;
    case ENET_MSCR:
        s->regs[index] = value & 0xfe;
        break;
    case ENET_MIBC:
        /* TODO: Implement MIB.  */
        s->regs[index] = (value & 0x80000000) ? 0xc0000000 : 0;
        break;
    case ENET_RCR:
        s->regs[index] = value & 0x07ff003f;
        /* TODO: Implement LOOP mode.  */
        break;
    case ENET_TCR:
        /* We transmit immediately, so raise GRA immediately.  */
        s->regs[index] = value;
        if (value & 1) {
            s->regs[ENET_EIR] |= ENET_INT_GRA;
        }
        break;
    case ENET_PALR:
        s->regs[index] = value;
        s->conf.macaddr.a[0] = value >> 24;
        s->conf.macaddr.a[1] = value >> 16;
        s->conf.macaddr.a[2] = value >> 8;
        s->conf.macaddr.a[3] = value;
        break;
    case ENET_PAUR:
        s->regs[index] = (value | 0x0000ffff) & 0xffff8808;
        s->conf.macaddr.a[4] = value >> 24;
        s->conf.macaddr.a[5] = value >> 16;
        break;
    case ENET_OPD:
        s->regs[index] = (value & 0x0000ffff) | 0x00010000;
        break;
    case ENET_IAUR:
    case ENET_IALR:
    case ENET_GAUR:
    case ENET_GALR:
        /* TODO: implement MAC hash filtering.  */
        break;
    case ENET_TFWR:
        if (s->is_fec) {
            s->regs[index] = value & 0x3;
        } else {
            s->regs[index] = value & 0x13f;
        }
        break;
    case ENET_RDSR:
        if (s->is_fec) {
            s->regs[index] = value & ~3;
        } else {
            s->regs[index] = value & ~7;
        }
        s->rx_descriptor = s->regs[index];
        break;
    case ENET_TDSR:
        if (s->is_fec) {
            s->regs[index] = value & ~3;
        } else {
            s->regs[index] = value & ~7;
        }
        s->tx_descriptor[0] = s->regs[index];
        break;
    case ENET_TDSR1:
        if (unlikely(single_tx_ring)) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "[%s]%s: trying to access TDSR1\n",
                          TYPE_IMX_FEC, __func__);
            return;
        }

        s->regs[index] = value & ~7;
        s->tx_descriptor[1] = s->regs[index];
        break;
    case ENET_TDSR2:
        if (unlikely(single_tx_ring)) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "[%s]%s: trying to access TDSR2\n",
                          TYPE_IMX_FEC, __func__);
            return;
        }

        s->regs[index] = value & ~7;
        s->tx_descriptor[2] = s->regs[index];
        break;
    case ENET_MRBR:
        s->regs[index] = value & 0x00003ff0;
        break;
    default:
        if (s->is_fec) {
            imx_fec_write(s, index, value);
        } else {
            imx_enet_write(s, index, value);
        }
        return;
    }

    imx_eth_update(s);
}

static bool imx_eth_can_receive(NetClientState *nc)
{
    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    return !!s->regs[ENET_RDAR];
}

static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
                               size_t len)
{
    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
    IMXFECBufDesc bd;
    uint32_t flags = 0;
    uint32_t addr;
    uint32_t crc;
    uint32_t buf_addr;
    uint8_t *crc_ptr;
    unsigned int buf_len;
    size_t size = len;

    trace_imx_fec_receive(size);

    if (!s->regs[ENET_RDAR]) {
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",
                      TYPE_IMX_FEC, __func__);
        return 0;
    }

    /* 4 bytes for the CRC.  */
    size += 4;
    crc = cpu_to_be32(crc32(~0, buf, size));
    crc_ptr = (uint8_t *) &crc;

    /* Huge frames are truncated.  */
    if (size > ENET_MAX_FRAME_SIZE) {
        size = ENET_MAX_FRAME_SIZE;
        flags |= ENET_BD_TR | ENET_BD_LG;
    }

    /* Frames larger than the user limit just set error flags.  */
    if (size > (s->regs[ENET_RCR] >> 16)) {
        flags |= ENET_BD_LG;
    }

    addr = s->rx_descriptor;
    while (size > 0) {
        imx_fec_read_bd(&bd, addr);
        if ((bd.flags & ENET_BD_E) == 0) {
            /* No descriptors available.  Bail out.  */
            /*
             * FIXME: This is wrong. We should probably either
             * save the remainder for when more RX buffers are
             * available, or flag an error.
             */
            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",
                          TYPE_IMX_FEC, __func__);
            break;
        }
        buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
        bd.length = buf_len;
        size -= buf_len;

        trace_imx_fec_receive_len(addr, bd.length);

        /* The last 4 bytes are the CRC.  */
        if (size < 4) {
            buf_len += size - 4;
        }
        buf_addr = bd.data;
        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
        buf += buf_len;
        if (size < 4) {
            dma_memory_write(&address_space_memory, buf_addr + buf_len,
                             crc_ptr, 4 - size);
            crc_ptr += 4 - size;
        }
        bd.flags &= ~ENET_BD_E;
        if (size == 0) {
            /* Last buffer in frame.  */
            bd.flags |= flags | ENET_BD_L;

            trace_imx_fec_receive_last(bd.flags);

            s->regs[ENET_EIR] |= ENET_INT_RXF;
        } else {
            s->regs[ENET_EIR] |= ENET_INT_RXB;
        }
        imx_fec_write_bd(&bd, addr);
        /* Advance to the next descriptor.  */
        if ((bd.flags & ENET_BD_W) != 0) {
            addr = s->regs[ENET_RDSR];
        } else {
            addr += sizeof(bd);
        }
    }
    s->rx_descriptor = addr;
    imx_eth_enable_rx(s, false);
    imx_eth_update(s);
    return len;
}

static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
                                size_t len)
{
    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));
    IMXENETBufDesc bd;
    uint32_t flags = 0;
    uint32_t addr;
    uint32_t crc;
    uint32_t buf_addr;
    uint8_t *crc_ptr;
    unsigned int buf_len;
    size_t size = len;
    bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;

    trace_imx_enet_receive(size);

    if (!s->regs[ENET_RDAR]) {
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Unexpected packet\n",
                      TYPE_IMX_FEC, __func__);
        return 0;
    }

    /* 4 bytes for the CRC.  */
    size += 4;
    crc = cpu_to_be32(crc32(~0, buf, size));
    crc_ptr = (uint8_t *) &crc;

    if (shift16) {
        size += 2;
    }

    /* Huge frames are truncated. */
    if (size > s->regs[ENET_FTRL]) {
        size = s->regs[ENET_FTRL];
        flags |= ENET_BD_TR | ENET_BD_LG;
    }

    /* Frames larger than the user limit just set error flags.  */
    if (size > (s->regs[ENET_RCR] >> 16)) {
        flags |= ENET_BD_LG;
    }

    addr = s->rx_descriptor;
    while (size > 0) {
        imx_enet_read_bd(&bd, addr);
        if ((bd.flags & ENET_BD_E) == 0) {
            /* No descriptors available.  Bail out.  */
            /*
             * FIXME: This is wrong. We should probably either
             * save the remainder for when more RX buffers are
             * available, or flag an error.
             */
            qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Lost end of frame\n",
                          TYPE_IMX_FEC, __func__);
            break;
        }
        buf_len = MIN(size, s->regs[ENET_MRBR]);
        bd.length = buf_len;
        size -= buf_len;

        trace_imx_enet_receive_len(addr, bd.length);

        /* The last 4 bytes are the CRC.  */
        if (size < 4) {
            buf_len += size - 4;
        }
        buf_addr = bd.data;

        if (shift16) {
            /*
             * If SHIFT16 bit of ENETx_RACC register is set we need to
             * align the payload to 4-byte boundary.
             */
            const uint8_t zeros[2] = { 0 };

            dma_memory_write(&address_space_memory, buf_addr,
                             zeros, sizeof(zeros));

            buf_addr += sizeof(zeros);
            buf_len  -= sizeof(zeros);

            /* We only do this once per Ethernet frame */
            shift16 = false;
        }

        dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
        buf += buf_len;
        if (size < 4) {
            dma_memory_write(&address_space_memory, buf_addr + buf_len,
                             crc_ptr, 4 - size);
            crc_ptr += 4 - size;
        }
        bd.flags &= ~ENET_BD_E;
        if (size == 0) {
            /* Last buffer in frame.  */
            bd.flags |= flags | ENET_BD_L;

            trace_imx_enet_receive_last(bd.flags);

            /* Indicate that we've updated the last buffer descriptor. */
            bd.last_buffer = ENET_BD_BDU;
            if (bd.option & ENET_BD_RX_INT) {
                s->regs[ENET_EIR] |= ENET_INT_RXF;
            }
        } else {
            if (bd.option & ENET_BD_RX_INT) {
                s->regs[ENET_EIR] |= ENET_INT_RXB;
            }
        }
        imx_enet_write_bd(&bd, addr);
        /* Advance to the next descriptor.  */
        if ((bd.flags & ENET_BD_W) != 0) {
            addr = s->regs[ENET_RDSR];
        } else {
            addr += sizeof(bd);
        }
    }
    s->rx_descriptor = addr;
    imx_eth_enable_rx(s, false);
    imx_eth_update(s);
    return len;
}

static ssize_t imx_eth_receive(NetClientState *nc, const uint8_t *buf,
                                size_t len)
{
    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
        return imx_enet_receive(nc, buf, len);
    } else {
        return imx_fec_receive(nc, buf, len);
    }
}

static const MemoryRegionOps imx_eth_ops = {
    .read                  = imx_eth_read,
    .write                 = imx_eth_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness            = DEVICE_NATIVE_ENDIAN,
};

static void imx_eth_cleanup(NetClientState *nc)
{
    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    s->nic = NULL;
}

static NetClientInfo imx_eth_net_info = {
    .type                = NET_CLIENT_DRIVER_NIC,
    .size                = sizeof(NICState),
    .can_receive         = imx_eth_can_receive,
    .receive             = imx_eth_receive,
    .cleanup             = imx_eth_cleanup,
    .link_status_changed = imx_eth_set_link,
};


static void imx_eth_realize(DeviceState *dev, Error **errp)
{
    IMXFECState *s = IMX_FEC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
                          TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq[0]);
    sysbus_init_irq(sbd, &s->irq[1]);

    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    s->nic = qemu_new_nic(&imx_eth_net_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);
}

static Property imx_eth_properties[] = {
    DEFINE_NIC_PROPERTIES(IMXFECState, conf),
    DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
    DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->vmsd    = &vmstate_imx_eth;
    dc->reset   = imx_eth_reset;
    device_class_set_props(dc, imx_eth_properties);
    dc->realize = imx_eth_realize;
    dc->desc    = "i.MX FEC/ENET Ethernet Controller";
}

static void imx_fec_init(Object *obj)
{
    IMXFECState *s = IMX_FEC(obj);

    s->is_fec = true;
}

static void imx_enet_init(Object *obj)
{
    IMXFECState *s = IMX_FEC(obj);

    s->is_fec = false;
}

static const TypeInfo imx_fec_info = {
    .name          = TYPE_IMX_FEC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IMXFECState),
    .instance_init = imx_fec_init,
    .class_init    = imx_eth_class_init,
};

static const TypeInfo imx_enet_info = {
    .name          = TYPE_IMX_ENET,
    .parent        = TYPE_IMX_FEC,
    .instance_init = imx_enet_init,
};

static void imx_eth_register_types(void)
{
    type_register_static(&imx_fec_info);
    type_register_static(&imx_enet_info);
}

type_init(imx_eth_register_types)
