/*
 * Nuvoton NPCM7xx EMC Module
 *
 * Copyright 2020 Google LLC
 *
 * 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.
 *
 * Unsupported/unimplemented features:
 * - MCMDR.FDUP (full duplex) is ignored, half duplex is not supported
 * - Only CAM0 is supported, CAM[1-15] are not
 *   - writes to CAMEN.[1-15] are ignored, these bits always read as zeroes
 * - MII is not implemented, MIIDA.BUSY and MIID always return zero
 * - MCMDR.LBK is not implemented
 * - MCMDR.{OPMOD,ENSQE,AEP,ARP} are not supported
 * - H/W FIFOs are not supported, MCMDR.FFTCR is ignored
 * - MGSTA.SQE is not supported
 * - pause and control frames are not implemented
 * - MGSTA.CCNT is not supported
 * - MPCNT, DMARFS are not implemented
 */

#include "qemu/osdep.h"

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

#include "hw/irq.h"
#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/net/npcm7xx_emc.h"
#include "net/eth.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "sysemu/dma.h"
#include "trace.h"

#define CRC_LENGTH 4

/*
 * The maximum size of a (layer 2) ethernet frame as defined by 802.3.
 * 1518 = 6(dest macaddr) + 6(src macaddr) + 2(proto) + 4(crc) + 1500(payload)
 * This does not include an additional 4 for the vlan field (802.1q).
 */
#define MAX_ETH_FRAME_SIZE 1518

static const char *emc_reg_name(int regno)
{
#define REG(name) case REG_ ## name: return #name;
    switch (regno) {
    REG(CAMCMR)
    REG(CAMEN)
    REG(TXDLSA)
    REG(RXDLSA)
    REG(MCMDR)
    REG(MIID)
    REG(MIIDA)
    REG(FFTCR)
    REG(TSDR)
    REG(RSDR)
    REG(DMARFC)
    REG(MIEN)
    REG(MISTA)
    REG(MGSTA)
    REG(MPCNT)
    REG(MRPC)
    REG(MRPCC)
    REG(MREPC)
    REG(DMARFS)
    REG(CTXDSA)
    REG(CTXBSA)
    REG(CRXDSA)
    REG(CRXBSA)
    case REG_CAMM_BASE + 0: return "CAM0M";
    case REG_CAML_BASE + 0: return "CAM0L";
    case REG_CAMM_BASE + 2 ... REG_CAMML_LAST:
        /* Only CAM0 is supported, fold the others into something simple. */
        if (regno & 1) {
            return "CAM<n>L";
        } else {
            return "CAM<n>M";
        }
    default: return "UNKNOWN";
    }
#undef REG
}

static void emc_reset(NPCM7xxEMCState *emc)
{
    trace_npcm7xx_emc_reset(emc->emc_num);

    memset(&emc->regs[0], 0, sizeof(emc->regs));

    /* These regs have non-zero reset values. */
    emc->regs[REG_TXDLSA] = 0xfffffffc;
    emc->regs[REG_RXDLSA] = 0xfffffffc;
    emc->regs[REG_MIIDA] = 0x00900000;
    emc->regs[REG_FFTCR] = 0x0101;
    emc->regs[REG_DMARFC] = 0x0800;
    emc->regs[REG_MPCNT] = 0x7fff;

    emc->tx_active = false;
    emc->rx_active = false;
}

static void npcm7xx_emc_reset(DeviceState *dev)
{
    NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
    emc_reset(emc);
}

static void emc_soft_reset(NPCM7xxEMCState *emc)
{
    /*
     * The docs say at least MCMDR.{LBK,OPMOD} bits are not changed during a
     * soft reset, but does not go into further detail. For now, KISS.
     */
    uint32_t mcmdr = emc->regs[REG_MCMDR];
    emc_reset(emc);
    emc->regs[REG_MCMDR] = mcmdr & (REG_MCMDR_LBK | REG_MCMDR_OPMOD);

    qemu_set_irq(emc->tx_irq, 0);
    qemu_set_irq(emc->rx_irq, 0);
}

static void emc_set_link(NetClientState *nc)
{
    /* Nothing to do yet. */
}

/* MISTA.TXINTR is the union of the individual bits with their enables. */
static void emc_update_mista_txintr(NPCM7xxEMCState *emc)
{
    /* Only look at the bits we support. */
    uint32_t mask = (REG_MISTA_TXBERR |
                     REG_MISTA_TDU |
                     REG_MISTA_TXCP);
    if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
        emc->regs[REG_MISTA] |= REG_MISTA_TXINTR;
    } else {
        emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR;
    }
}

/* MISTA.RXINTR is the union of the individual bits with their enables. */
static void emc_update_mista_rxintr(NPCM7xxEMCState *emc)
{
    /* Only look at the bits we support. */
    uint32_t mask = (REG_MISTA_RXBERR |
                     REG_MISTA_RDU |
                     REG_MISTA_RXGD);
    if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
        emc->regs[REG_MISTA] |= REG_MISTA_RXINTR;
    } else {
        emc->regs[REG_MISTA] &= ~REG_MISTA_RXINTR;
    }
}

/* N.B. emc_update_mista_txintr must have already been called. */
static void emc_update_tx_irq(NPCM7xxEMCState *emc)
{
    int level = !!(emc->regs[REG_MISTA] &
                   emc->regs[REG_MIEN] &
                   REG_MISTA_TXINTR);
    trace_npcm7xx_emc_update_tx_irq(level);
    qemu_set_irq(emc->tx_irq, level);
}

/* N.B. emc_update_mista_rxintr must have already been called. */
static void emc_update_rx_irq(NPCM7xxEMCState *emc)
{
    int level = !!(emc->regs[REG_MISTA] &
                   emc->regs[REG_MIEN] &
                   REG_MISTA_RXINTR);
    trace_npcm7xx_emc_update_rx_irq(level);
    qemu_set_irq(emc->rx_irq, level);
}

/* Update IRQ states due to changes in MIEN,MISTA. */
static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc)
{
    emc_update_mista_txintr(emc);
    emc_update_tx_irq(emc);

    emc_update_mista_rxintr(emc);
    emc_update_rx_irq(emc);
}

static int emc_read_tx_desc(dma_addr_t addr, NPCM7xxEMCTxDesc *desc)
{
    if (dma_memory_read(&address_space_memory, addr, desc,
                        sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
                      HWADDR_PRIx "\n", __func__, addr);
        return -1;
    }
    desc->flags = le32_to_cpu(desc->flags);
    desc->txbsa = le32_to_cpu(desc->txbsa);
    desc->status_and_length = le32_to_cpu(desc->status_and_length);
    desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
    return 0;
}

static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr)
{
    NPCM7xxEMCTxDesc le_desc;

    le_desc.flags = cpu_to_le32(desc->flags);
    le_desc.txbsa = cpu_to_le32(desc->txbsa);
    le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
    le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
    if (dma_memory_write(&address_space_memory, addr, &le_desc,
                         sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
                      HWADDR_PRIx "\n", __func__, addr);
        return -1;
    }
    return 0;
}

static int emc_read_rx_desc(dma_addr_t addr, NPCM7xxEMCRxDesc *desc)
{
    if (dma_memory_read(&address_space_memory, addr, desc,
                        sizeof(*desc), MEMTXATTRS_UNSPECIFIED)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
                      HWADDR_PRIx "\n", __func__, addr);
        return -1;
    }
    desc->status_and_length = le32_to_cpu(desc->status_and_length);
    desc->rxbsa = le32_to_cpu(desc->rxbsa);
    desc->reserved = le32_to_cpu(desc->reserved);
    desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
    return 0;
}

static int emc_write_rx_desc(const NPCM7xxEMCRxDesc *desc, dma_addr_t addr)
{
    NPCM7xxEMCRxDesc le_desc;

    le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
    le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
    le_desc.reserved = cpu_to_le32(desc->reserved);
    le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
    if (dma_memory_write(&address_space_memory, addr, &le_desc,
                         sizeof(le_desc), MEMTXATTRS_UNSPECIFIED)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
                      HWADDR_PRIx "\n", __func__, addr);
        return -1;
    }
    return 0;
}

static void emc_set_mista(NPCM7xxEMCState *emc, uint32_t flags)
{
    trace_npcm7xx_emc_set_mista(flags);
    emc->regs[REG_MISTA] |= flags;
    if (extract32(flags, 16, 16)) {
        emc_update_mista_txintr(emc);
    }
    if (extract32(flags, 0, 16)) {
        emc_update_mista_rxintr(emc);
    }
}

static void emc_halt_tx(NPCM7xxEMCState *emc, uint32_t mista_flag)
{
    emc->tx_active = false;
    emc_set_mista(emc, mista_flag);
}

static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
{
    emc->rx_active = false;
    emc_set_mista(emc, mista_flag);
}

static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
{
    emc->rx_active = true;
    qemu_flush_queued_packets(qemu_get_queue(emc->nic));
}

static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
                                       const NPCM7xxEMCTxDesc *tx_desc,
                                       uint32_t desc_addr)
{
    /* Update the current descriptor, if only to reset the owner flag. */
    if (emc_write_tx_desc(tx_desc, desc_addr)) {
        /*
         * We just read it so this shouldn't generally happen.
         * Error already reported.
         */
        emc_set_mista(emc, REG_MISTA_TXBERR);
    }
    emc->regs[REG_CTXDSA] = TX_DESC_NTXDSA(tx_desc->ntxdsa);
}

static void emc_set_next_rx_descriptor(NPCM7xxEMCState *emc,
                                       const NPCM7xxEMCRxDesc *rx_desc,
                                       uint32_t desc_addr)
{
    /* Update the current descriptor, if only to reset the owner flag. */
    if (emc_write_rx_desc(rx_desc, desc_addr)) {
        /*
         * We just read it so this shouldn't generally happen.
         * Error already reported.
         */
        emc_set_mista(emc, REG_MISTA_RXBERR);
    }
    emc->regs[REG_CRXDSA] = RX_DESC_NRXDSA(rx_desc->nrxdsa);
}

static void emc_try_send_next_packet(NPCM7xxEMCState *emc)
{
    /* Working buffer for sending out packets. Most packets fit in this. */
#define TX_BUFFER_SIZE 2048
    uint8_t tx_send_buffer[TX_BUFFER_SIZE];
    uint32_t desc_addr = TX_DESC_NTXDSA(emc->regs[REG_CTXDSA]);
    NPCM7xxEMCTxDesc tx_desc;
    uint32_t next_buf_addr, length;
    uint8_t *buf;
    g_autofree uint8_t *malloced_buf = NULL;

    if (emc_read_tx_desc(desc_addr, &tx_desc)) {
        /* Error reading descriptor, already reported. */
        emc_halt_tx(emc, REG_MISTA_TXBERR);
        emc_update_tx_irq(emc);
        return;
    }

    /* Nothing we can do if we don't own the descriptor. */
    if (!(tx_desc.flags & TX_DESC_FLAG_OWNER_MASK)) {
        trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
        emc_halt_tx(emc, REG_MISTA_TDU);
        emc_update_tx_irq(emc);
        return;
     }

    /* Give the descriptor back regardless of what happens. */
    tx_desc.flags &= ~TX_DESC_FLAG_OWNER_MASK;
    tx_desc.status_and_length &= 0xffff;

    /*
     * Despite the h/w documentation saying the tx buffer is word aligned,
     * the linux driver does not word align the buffer. There is value in not
     * aligning the buffer: See the description of NET_IP_ALIGN in linux
     * kernel sources.
     */
    next_buf_addr = tx_desc.txbsa;
    emc->regs[REG_CTXBSA] = next_buf_addr;
    length = TX_DESC_PKT_LEN(tx_desc.status_and_length);
    buf = &tx_send_buffer[0];

    if (length > sizeof(tx_send_buffer)) {
        malloced_buf = g_malloc(length);
        buf = malloced_buf;
    }

    if (dma_memory_read(&address_space_memory, next_buf_addr, buf,
                        length, MEMTXATTRS_UNSPECIFIED)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n",
                      __func__, next_buf_addr);
        emc_set_mista(emc, REG_MISTA_TXBERR);
        emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
        emc_update_tx_irq(emc);
        trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
        return;
    }

    if ((tx_desc.flags & TX_DESC_FLAG_PADEN) && (length < MIN_PACKET_LENGTH)) {
        memset(buf + length, 0, MIN_PACKET_LENGTH - length);
        length = MIN_PACKET_LENGTH;
    }

    /* N.B. emc_receive can get called here. */
    qemu_send_packet(qemu_get_queue(emc->nic), buf, length);
    trace_npcm7xx_emc_sent_packet(length);

    tx_desc.status_and_length |= TX_DESC_STATUS_TXCP;
    if (tx_desc.flags & TX_DESC_FLAG_INTEN) {
        emc_set_mista(emc, REG_MISTA_TXCP);
    }
    if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_TXINTR) {
        tx_desc.status_and_length |= TX_DESC_STATUS_TXINTR;
    }

    emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
    emc_update_tx_irq(emc);
    trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
}

static bool emc_can_receive(NetClientState *nc)
{
    NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));

    bool can_receive = emc->rx_active;
    trace_npcm7xx_emc_can_receive(can_receive);
    return can_receive;
}

/* If result is false then *fail_reason contains the reason. */
static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf,
                                size_t len, const char **fail_reason)
{
    eth_pkt_types_e pkt_type = get_eth_packet_type(PKT_GET_ETH_HDR(buf));

    switch (pkt_type) {
    case ETH_PKT_BCAST:
        if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
            return true;
        } else {
            *fail_reason = "Broadcast packet disabled";
            return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_ABP);
        }
    case ETH_PKT_MCAST:
        if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
            return true;
        } else {
            *fail_reason = "Multicast packet disabled";
            return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_AMP);
        }
    case ETH_PKT_UCAST: {
        bool matches;
        if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) {
            return true;
        }
        matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) &&
                   /* We only support one CAM register, CAM0. */
                   (emc->regs[REG_CAMEN] & (1 << 0)) &&
                   memcmp(buf, emc->conf.macaddr.a, ETH_ALEN) == 0);
        if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
            *fail_reason = "MACADDR matched, comparison complemented";
            return !matches;
        } else {
            *fail_reason = "MACADDR didn't match";
            return matches;
        }
    }
    default:
        g_assert_not_reached();
    }
}

static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
                               size_t len)
{
    const char *fail_reason = NULL;
    bool ok = emc_receive_filter1(emc, buf, len, &fail_reason);
    if (!ok) {
        trace_npcm7xx_emc_packet_filtered_out(fail_reason);
    }
    return ok;
}

static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
{
    NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
    const uint32_t len = len1;
    size_t max_frame_len;
    bool long_frame;
    uint32_t desc_addr;
    NPCM7xxEMCRxDesc rx_desc;
    uint32_t crc;
    uint8_t *crc_ptr;
    uint32_t buf_addr;

    trace_npcm7xx_emc_receiving_packet(len);

    if (!emc_can_receive(nc)) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Unexpected packet\n", __func__);
        return -1;
    }

    if (len < ETH_HLEN ||
        /* Defensive programming: drop unsupportable large packets. */
        len > 0xffff - CRC_LENGTH) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Dropped frame of %u bytes\n",
                      __func__, len);
        return len;
    }

    /*
     * DENI is set if EMC received the Length/Type field of the incoming
     * packet, so it will be set regardless of what happens next.
     */
    emc_set_mista(emc, REG_MISTA_DENI);

    if (!emc_receive_filter(emc, buf, len)) {
        emc_update_rx_irq(emc);
        return len;
    }

    /* Huge frames (> DMARFC) are dropped. */
    max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]);
    if (len + CRC_LENGTH > max_frame_len) {
        trace_npcm7xx_emc_packet_dropped(len);
        emc_set_mista(emc, REG_MISTA_DFOI);
        emc_update_rx_irq(emc);
        return len;
    }

    /*
     * Long Frames (> MAX_ETH_FRAME_SIZE) are also dropped, unless MCMDR.ALP
     * is set.
     */
    long_frame = false;
    if (len + CRC_LENGTH > MAX_ETH_FRAME_SIZE) {
        if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) {
            long_frame = true;
        } else {
            trace_npcm7xx_emc_packet_dropped(len);
            emc_set_mista(emc, REG_MISTA_PTLE);
            emc_update_rx_irq(emc);
            return len;
        }
    }

    desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]);
    if (emc_read_rx_desc(desc_addr, &rx_desc)) {
        /* Error reading descriptor, already reported. */
        emc_halt_rx(emc, REG_MISTA_RXBERR);
        emc_update_rx_irq(emc);
        return len;
    }

    /* Nothing we can do if we don't own the descriptor. */
    if (!(rx_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK)) {
        trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
        emc_halt_rx(emc, REG_MISTA_RDU);
        emc_update_rx_irq(emc);
        return len;
    }

    crc = 0;
    crc_ptr = (uint8_t *) &crc;
    if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
        crc = cpu_to_be32(crc32(~0, buf, len));
    }

    /* Give the descriptor back regardless of what happens. */
    rx_desc.status_and_length &= ~RX_DESC_STATUS_OWNER_MASK;

    buf_addr = rx_desc.rxbsa;
    emc->regs[REG_CRXBSA] = buf_addr;
    if (dma_memory_write(&address_space_memory, buf_addr, buf,
                         len, MEMTXATTRS_UNSPECIFIED) ||
        (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) &&
         dma_memory_write(&address_space_memory, buf_addr + len,
                          crc_ptr, 4, MEMTXATTRS_UNSPECIFIED))) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n",
                      __func__);
        emc_set_mista(emc, REG_MISTA_RXBERR);
        emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
        emc_update_rx_irq(emc);
        trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
        return len;
    }

    trace_npcm7xx_emc_received_packet(len);

    /* Note: We've already verified len+4 <= 0xffff. */
    rx_desc.status_and_length = len;
    if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
        rx_desc.status_and_length += 4;
    }
    rx_desc.status_and_length |= RX_DESC_STATUS_RXGD;
    emc_set_mista(emc, REG_MISTA_RXGD);

    if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) {
        rx_desc.status_and_length |= RX_DESC_STATUS_RXINTR;
    }
    if (long_frame) {
        rx_desc.status_and_length |= RX_DESC_STATUS_PTLE;
    }

    emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
    emc_update_rx_irq(emc);
    trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
    return len;
}

static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
{
    NPCM7xxEMCState *emc = opaque;
    uint32_t reg = offset / sizeof(uint32_t);
    uint32_t result;

    if (reg >= NPCM7XX_NUM_EMC_REGS) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
                      __func__, offset);
        return 0;
    }

    switch (reg) {
    case REG_MIID:
        /*
         * We don't implement MII. For determinism, always return zero as
         * writes record the last value written for debugging purposes.
         */
        qemu_log_mask(LOG_UNIMP, "%s: Read of MIID, returning 0\n", __func__);
        result = 0;
        break;
    case REG_TSDR:
    case REG_RSDR:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Read of write-only reg, %s/%d\n",
                      __func__, emc_reg_name(reg), reg);
        return 0;
    default:
        result = emc->regs[reg];
        break;
    }

    trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg);
    return result;
}

static void npcm7xx_emc_write(void *opaque, hwaddr offset,
                              uint64_t v, unsigned size)
{
    NPCM7xxEMCState *emc = opaque;
    uint32_t reg = offset / sizeof(uint32_t);
    uint32_t value = v;

    g_assert(size == sizeof(uint32_t));

    if (reg >= NPCM7XX_NUM_EMC_REGS) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
                      __func__, offset);
        return;
    }

    trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value);

    switch (reg) {
    case REG_CAMCMR:
        emc->regs[reg] = value;
        break;
    case REG_CAMEN:
        /* Only CAM0 is supported, don't pretend otherwise. */
        if (value & ~1) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "%s: Only CAM0 is supported, cannot enable others"
                          ": 0x%x\n",
                          __func__, value);
        }
        emc->regs[reg] = value & 1;
        break;
    case REG_CAMM_BASE + 0:
        emc->regs[reg] = value;
        emc->conf.macaddr.a[0] = value >> 24;
        emc->conf.macaddr.a[1] = value >> 16;
        emc->conf.macaddr.a[2] = value >> 8;
        emc->conf.macaddr.a[3] = value >> 0;
        break;
    case REG_CAML_BASE + 0:
        emc->regs[reg] = value;
        emc->conf.macaddr.a[4] = value >> 24;
        emc->conf.macaddr.a[5] = value >> 16;
        break;
    case REG_MCMDR: {
        uint32_t prev;
        if (value & REG_MCMDR_SWR) {
            emc_soft_reset(emc);
            /* On h/w the reset happens over multiple cycles. For now KISS. */
            break;
        }
        prev = emc->regs[reg];
        emc->regs[reg] = value;
        /* Update tx state. */
        if (!(prev & REG_MCMDR_TXON) &&
            (value & REG_MCMDR_TXON)) {
            emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA];
            /*
             * Linux kernel turns TX on with CPU still holding descriptor,
             * which suggests we should wait for a write to TSDR before trying
             * to send a packet: so we don't send one here.
             */
        } else if ((prev & REG_MCMDR_TXON) &&
                   !(value & REG_MCMDR_TXON)) {
            emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA;
        }
        if (!(value & REG_MCMDR_TXON)) {
            emc_halt_tx(emc, 0);
        }
        /* Update rx state. */
        if (!(prev & REG_MCMDR_RXON) &&
            (value & REG_MCMDR_RXON)) {
            emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA];
        } else if ((prev & REG_MCMDR_RXON) &&
                   !(value & REG_MCMDR_RXON)) {
            emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
        }
        if (value & REG_MCMDR_RXON) {
            emc_enable_rx_and_flush(emc);
        } else {
            emc_halt_rx(emc, 0);
        }
        break;
    }
    case REG_TXDLSA:
    case REG_RXDLSA:
    case REG_DMARFC:
    case REG_MIID:
        emc->regs[reg] = value;
        break;
    case REG_MIEN:
        emc->regs[reg] = value;
        emc_update_irq_from_reg_change(emc);
        break;
    case REG_MISTA:
        /* Clear the bits that have 1 in "value". */
        emc->regs[reg] &= ~value;
        emc_update_irq_from_reg_change(emc);
        break;
    case REG_MGSTA:
        /* Clear the bits that have 1 in "value". */
        emc->regs[reg] &= ~value;
        break;
    case REG_TSDR:
        if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) {
            emc->tx_active = true;
            /* Keep trying to send packets until we run out. */
            while (emc->tx_active) {
                emc_try_send_next_packet(emc);
            }
        }
        break;
    case REG_RSDR:
        if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
            emc_enable_rx_and_flush(emc);
        }
        break;
    case REG_MIIDA:
        emc->regs[reg] = value & ~REG_MIIDA_BUSY;
        break;
    case REG_MRPC:
    case REG_MRPCC:
    case REG_MREPC:
    case REG_CTXDSA:
    case REG_CTXBSA:
    case REG_CRXDSA:
    case REG_CRXBSA:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Write to read-only reg %s/%d\n",
                      __func__, emc_reg_name(reg), reg);
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "%s: Write to unimplemented reg %s/%d\n",
                      __func__, emc_reg_name(reg), reg);
        break;
    }
}

static const struct MemoryRegionOps npcm7xx_emc_ops = {
    .read = npcm7xx_emc_read,
    .write = npcm7xx_emc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
        .unaligned = false,
    },
};

static void emc_cleanup(NetClientState *nc)
{
    /* Nothing to do yet. */
}

static NetClientInfo net_npcm7xx_emc_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .can_receive = emc_can_receive,
    .receive = emc_receive,
    .cleanup = emc_cleanup,
    .link_status_changed = emc_set_link,
};

static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
{
    NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(emc);

    memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc,
                          TYPE_NPCM7XX_EMC, 4 * KiB);
    sysbus_init_mmio(sbd, &emc->iomem);
    sysbus_init_irq(sbd, &emc->tx_irq);
    sysbus_init_irq(sbd, &emc->rx_irq);

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

static void npcm7xx_emc_unrealize(DeviceState *dev)
{
    NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);

    qemu_del_nic(emc->nic);
}

static const VMStateDescription vmstate_npcm7xx_emc = {
    .name = TYPE_NPCM7XX_EMC,
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(emc_num, NPCM7xxEMCState),
        VMSTATE_UINT32_ARRAY(regs, NPCM7xxEMCState, NPCM7XX_NUM_EMC_REGS),
        VMSTATE_BOOL(tx_active, NPCM7xxEMCState),
        VMSTATE_BOOL(rx_active, NPCM7xxEMCState),
        VMSTATE_END_OF_LIST(),
    },
};

static Property npcm7xx_emc_properties[] = {
    DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf),
    DEFINE_PROP_END_OF_LIST(),
};

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

    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
    dc->desc = "NPCM7xx EMC Controller";
    dc->realize = npcm7xx_emc_realize;
    dc->unrealize = npcm7xx_emc_unrealize;
    dc->reset = npcm7xx_emc_reset;
    dc->vmsd = &vmstate_npcm7xx_emc;
    device_class_set_props(dc, npcm7xx_emc_properties);
}

static const TypeInfo npcm7xx_emc_info = {
    .name = TYPE_NPCM7XX_EMC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(NPCM7xxEMCState),
    .class_init = npcm7xx_emc_class_init,
};

static void npcm7xx_emc_register_type(void)
{
    type_register_static(&npcm7xx_emc_info);
}

type_init(npcm7xx_emc_register_type)
