/*
 * QEMU TULIP Emulation
 *
 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "hw/nvram/eeprom93xx.h"
#include "migration/vmstate.h"
#include "sysemu/sysemu.h"
#include "tulip.h"
#include "trace.h"
#include "net/eth.h"

struct TULIPState {
    PCIDevice dev;
    MemoryRegion io;
    MemoryRegion memory;
    NICConf c;
    qemu_irq irq;
    NICState *nic;
    eeprom_t *eeprom;
    uint32_t csr[16];

    /* state for MII */
    uint32_t old_csr9;
    uint32_t mii_word;
    uint32_t mii_bitcnt;

    hwaddr current_rx_desc;
    hwaddr current_tx_desc;

    uint8_t rx_frame[2048];
    uint8_t tx_frame[2048];
    uint16_t tx_frame_len;
    uint16_t rx_frame_len;
    uint16_t rx_frame_size;

    uint32_t rx_status;
    uint8_t filter[16][6];
};

static const VMStateDescription vmstate_pci_tulip = {
    .name = "tulip",
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(dev, TULIPState),
        VMSTATE_UINT32_ARRAY(csr, TULIPState, 16),
        VMSTATE_UINT32(old_csr9, TULIPState),
        VMSTATE_UINT32(mii_word, TULIPState),
        VMSTATE_UINT32(mii_bitcnt, TULIPState),
        VMSTATE_UINT64(current_rx_desc, TULIPState),
        VMSTATE_UINT64(current_tx_desc, TULIPState),
        VMSTATE_BUFFER(rx_frame, TULIPState),
        VMSTATE_BUFFER(tx_frame, TULIPState),
        VMSTATE_UINT16(rx_frame_len, TULIPState),
        VMSTATE_UINT16(tx_frame_len, TULIPState),
        VMSTATE_UINT16(rx_frame_size, TULIPState),
        VMSTATE_UINT32(rx_status, TULIPState),
        VMSTATE_UINT8_2DARRAY(filter, TULIPState, 16, 6),
        VMSTATE_END_OF_LIST()
    }
};

static void tulip_desc_read(TULIPState *s, hwaddr p,
        struct tulip_descriptor *desc)
{
    const MemTxAttrs attrs = { .memory = true };

    if (s->csr[0] & CSR0_DBO) {
        ldl_be_pci_dma(&s->dev, p, &desc->status, attrs);
        ldl_be_pci_dma(&s->dev, p + 4, &desc->control, attrs);
        ldl_be_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs);
        ldl_be_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs);
    } else {
        ldl_le_pci_dma(&s->dev, p, &desc->status, attrs);
        ldl_le_pci_dma(&s->dev, p + 4, &desc->control, attrs);
        ldl_le_pci_dma(&s->dev, p + 8, &desc->buf_addr1, attrs);
        ldl_le_pci_dma(&s->dev, p + 12, &desc->buf_addr2, attrs);
    }
}

static void tulip_desc_write(TULIPState *s, hwaddr p,
        struct tulip_descriptor *desc)
{
    const MemTxAttrs attrs = { .memory = true };

    if (s->csr[0] & CSR0_DBO) {
        stl_be_pci_dma(&s->dev, p, desc->status, attrs);
        stl_be_pci_dma(&s->dev, p + 4, desc->control, attrs);
        stl_be_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs);
        stl_be_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs);
    } else {
        stl_le_pci_dma(&s->dev, p, desc->status, attrs);
        stl_le_pci_dma(&s->dev, p + 4, desc->control, attrs);
        stl_le_pci_dma(&s->dev, p + 8, desc->buf_addr1, attrs);
        stl_le_pci_dma(&s->dev, p + 12, desc->buf_addr2, attrs);
    }
}

static void tulip_update_int(TULIPState *s)
{
    uint32_t ie = s->csr[5] & s->csr[7];
    bool assert = false;

    s->csr[5] &= ~(CSR5_AIS | CSR5_NIS);

    if (ie & (CSR5_TI | CSR5_TU | CSR5_RI | CSR5_GTE | CSR5_ERI)) {
        s->csr[5] |= CSR5_NIS;
    }

    if (ie & (CSR5_LC | CSR5_GPI | CSR5_FBE | CSR5_LNF | CSR5_ETI | CSR5_RWT |
              CSR5_RPS | CSR5_RU | CSR5_UNF | CSR5_LNP_ANC | CSR5_TJT |
              CSR5_TPS)) {
        s->csr[5] |= CSR5_AIS;
    }

    assert = s->csr[5] & s->csr[7] & (CSR5_AIS | CSR5_NIS);
    trace_tulip_irq(s->csr[5], s->csr[7], assert ? "assert" : "deassert");
    qemu_set_irq(s->irq, assert);
}

static bool tulip_rx_stopped(TULIPState *s)
{
    return ((s->csr[5] >> CSR5_RS_SHIFT) & CSR5_RS_MASK) == CSR5_RS_STOPPED;
}

static void tulip_dump_tx_descriptor(TULIPState *s,
        struct tulip_descriptor *desc)
{
    trace_tulip_descriptor("TX ", s->current_tx_desc,
                desc->status, desc->control >> 22,
                desc->control & 0x7ff, (desc->control >> 11) & 0x7ff,
                desc->buf_addr1, desc->buf_addr2);
}

static void tulip_dump_rx_descriptor(TULIPState *s,
        struct tulip_descriptor *desc)
{
    trace_tulip_descriptor("RX ", s->current_rx_desc,
                desc->status, desc->control >> 22,
                desc->control & 0x7ff, (desc->control >> 11) & 0x7ff,
                desc->buf_addr1, desc->buf_addr2);
}

static void tulip_next_rx_descriptor(TULIPState *s,
    struct tulip_descriptor *desc)
{
    if (desc->control & RDES1_RER) {
        s->current_rx_desc = s->csr[3];
    } else if (desc->control & RDES1_RCH) {
        s->current_rx_desc = desc->buf_addr2;
    } else {
        s->current_rx_desc += sizeof(struct tulip_descriptor) +
                (((s->csr[0] >> CSR0_DSL_SHIFT) & CSR0_DSL_MASK) << 2);
    }
    s->current_rx_desc &= ~3ULL;
}

static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
{
    int len1 = (desc->control >> RDES1_BUF1_SIZE_SHIFT) & RDES1_BUF1_SIZE_MASK;
    int len2 = (desc->control >> RDES1_BUF2_SIZE_SHIFT) & RDES1_BUF2_SIZE_MASK;
    int len;

    if (s->rx_frame_len && len1) {
        if (s->rx_frame_len > len1) {
            len = len1;
        } else {
            len = s->rx_frame_len;
        }

        pci_dma_write(&s->dev, desc->buf_addr1, s->rx_frame +
            (s->rx_frame_size - s->rx_frame_len), len);
        s->rx_frame_len -= len;
    }

    if (s->rx_frame_len && len2) {
        if (s->rx_frame_len > len2) {
            len = len2;
        } else {
            len = s->rx_frame_len;
        }

        pci_dma_write(&s->dev, desc->buf_addr2, s->rx_frame +
            (s->rx_frame_size - s->rx_frame_len), len);
        s->rx_frame_len -= len;
    }
}

static bool tulip_filter_address(TULIPState *s, const uint8_t *addr)
{
    static const char broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    bool ret = false;
    int i;

    for (i = 0; i < 16 && ret == false; i++) {
        if (!memcmp(&s->filter[i], addr, ETH_ALEN)) {
            ret = true;
        }
    }

    if (!memcmp(addr, broadcast, ETH_ALEN)) {
        return true;
    }

    if (s->csr[6] & (CSR6_PR | CSR6_RA)) {
        /* Promiscuous mode enabled */
        s->rx_status |= RDES0_FF;
        return true;
    }

    if ((s->csr[6] & CSR6_PM) && (addr[0] & 1)) {
        /* Pass all Multicast enabled */
        s->rx_status |= RDES0_MF;
        return true;
    }

    if (s->csr[6] & CSR6_IF) {
        ret ^= true;
    }
    return ret;
}

static ssize_t tulip_receive(TULIPState *s, const uint8_t *buf, size_t size)
{
    struct tulip_descriptor desc;

    trace_tulip_receive(buf, size);

    if (size < 14 || size > sizeof(s->rx_frame) - 4
        || s->rx_frame_len || tulip_rx_stopped(s)) {
        return 0;
    }

    if (!tulip_filter_address(s, buf)) {
        return size;
    }

    do {
        tulip_desc_read(s, s->current_rx_desc, &desc);
        tulip_dump_rx_descriptor(s, &desc);

        if (!(desc.status & RDES0_OWN)) {
            s->csr[5] |= CSR5_RU;
            tulip_update_int(s);
            return s->rx_frame_size - s->rx_frame_len;
        }
        desc.status = 0;

        if (!s->rx_frame_len) {
            s->rx_frame_size = size + 4;
            s->rx_status = RDES0_LS |
                 ((s->rx_frame_size & RDES0_FL_MASK) << RDES0_FL_SHIFT);
            desc.status |= RDES0_FS;
            memcpy(s->rx_frame, buf, size);
            s->rx_frame_len = s->rx_frame_size;
        }

        tulip_copy_rx_bytes(s, &desc);

        if (!s->rx_frame_len) {
            desc.status |= s->rx_status;
            s->csr[5] |= CSR5_RI;
            tulip_update_int(s);
        }
        tulip_dump_rx_descriptor(s, &desc);
        tulip_desc_write(s, s->current_rx_desc, &desc);
        tulip_next_rx_descriptor(s, &desc);
    } while (s->rx_frame_len);
    return size;
}

static ssize_t tulip_receive_nc(NetClientState *nc,
                             const uint8_t *buf, size_t size)
{
    return tulip_receive(qemu_get_nic_opaque(nc), buf, size);
}

static NetClientInfo net_tulip_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .receive = tulip_receive_nc,
};

static const char *tulip_reg_name(const hwaddr addr)
{
    switch (addr) {
    case CSR(0):
        return "CSR0";

    case CSR(1):
        return "CSR1";

    case CSR(2):
        return "CSR2";

    case CSR(3):
        return "CSR3";

    case CSR(4):
        return "CSR4";

    case CSR(5):
        return "CSR5";

    case CSR(6):
        return "CSR6";

    case CSR(7):
        return "CSR7";

    case CSR(8):
        return "CSR8";

    case CSR(9):
        return "CSR9";

    case CSR(10):
        return "CSR10";

    case CSR(11):
        return "CSR11";

    case CSR(12):
        return "CSR12";

    case CSR(13):
        return "CSR13";

    case CSR(14):
        return "CSR14";

    case CSR(15):
        return "CSR15";

    default:
        break;
    }
    return "";
}

static const char *tulip_rx_state_name(int state)
{
    switch (state) {
    case CSR5_RS_STOPPED:
        return "STOPPED";

    case CSR5_RS_RUNNING_FETCH:
        return "RUNNING/FETCH";

    case CSR5_RS_RUNNING_CHECK_EOR:
        return "RUNNING/CHECK EOR";

    case CSR5_RS_RUNNING_WAIT_RECEIVE:
        return "WAIT RECEIVE";

    case CSR5_RS_SUSPENDED:
        return "SUSPENDED";

    case CSR5_RS_RUNNING_CLOSE:
        return "RUNNING/CLOSE";

    case CSR5_RS_RUNNING_FLUSH:
        return "RUNNING/FLUSH";

    case CSR5_RS_RUNNING_QUEUE:
        return "RUNNING/QUEUE";

    default:
        break;
    }
    return "";
}

static const char *tulip_tx_state_name(int state)
{
    switch (state) {
    case CSR5_TS_STOPPED:
        return "STOPPED";

    case CSR5_TS_RUNNING_FETCH:
        return "RUNNING/FETCH";

    case CSR5_TS_RUNNING_WAIT_EOT:
        return "RUNNING/WAIT EOT";

    case CSR5_TS_RUNNING_READ_BUF:
        return "RUNNING/READ BUF";

    case CSR5_TS_RUNNING_SETUP:
        return "RUNNING/SETUP";

    case CSR5_TS_SUSPENDED:
        return "SUSPENDED";

    case CSR5_TS_RUNNING_CLOSE:
        return "RUNNING/CLOSE";

    default:
        break;
    }
    return "";
}

static void tulip_update_rs(TULIPState *s, int state)
{
    s->csr[5] &= ~(CSR5_RS_MASK << CSR5_RS_SHIFT);
    s->csr[5] |= (state & CSR5_RS_MASK) << CSR5_RS_SHIFT;
    trace_tulip_rx_state(tulip_rx_state_name(state));
}

static uint16_t tulip_mdi_default[] = {
    /* MDI Registers 0 - 6, 7 */
    0x3100, 0xf02c, 0x7810, 0x0000, 0x0501, 0x4181, 0x0000, 0x0000,
    /* MDI Registers 8 - 15 */
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    /* MDI Registers 16 - 31 */
    0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};

/* Readonly mask for MDI (PHY) registers */
static const uint16_t tulip_mdi_mask[] = {
    0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
    0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};

static uint16_t tulip_mii_read(TULIPState *s, int phy, int reg)
{
    uint16_t ret = 0;
    if (phy == 1) {
        ret = tulip_mdi_default[reg];
    }
    trace_tulip_mii_read(phy, reg, ret);
    return ret;
}

static void tulip_mii_write(TULIPState *s, int phy, int reg, uint16_t data)
{
    trace_tulip_mii_write(phy, reg, data);

    if (phy != 1) {
        return;
    }

    tulip_mdi_default[reg] &= ~tulip_mdi_mask[reg];
    tulip_mdi_default[reg] |= (data & tulip_mdi_mask[reg]);
}

static void tulip_mii(TULIPState *s)
{
    uint32_t changed = s->old_csr9 ^ s->csr[9];
    uint16_t data;
    int op, phy, reg;

    if (!(changed & CSR9_MDC)) {
        return;
    }

    if (!(s->csr[9] & CSR9_MDC)) {
        return;
    }

    s->mii_bitcnt++;
    s->mii_word <<= 1;

    if (s->csr[9] & CSR9_MDO && (s->mii_bitcnt < 16 ||
        !(s->csr[9] & CSR9_MII))) {
        /* write op or address bits */
        s->mii_word |= 1;
    }

    if (s->mii_bitcnt >= 16 && (s->csr[9] & CSR9_MII)) {
        if (s->mii_word & 0x8000) {
            s->csr[9] |= CSR9_MDI;
        } else {
            s->csr[9] &= ~CSR9_MDI;
        }
    }

    if (s->mii_word == 0xffffffff) {
        s->mii_bitcnt = 0;
    } else if (s->mii_bitcnt == 16) {
        op = (s->mii_word >> 12) & 0x0f;
        phy = (s->mii_word >> 7) & 0x1f;
        reg = (s->mii_word >> 2) & 0x1f;

        if (op == 6) {
            s->mii_word = tulip_mii_read(s, phy, reg);
        }
    } else if (s->mii_bitcnt == 32) {
            op = (s->mii_word >> 28) & 0x0f;
            phy = (s->mii_word >> 23) & 0x1f;
            reg = (s->mii_word >> 18) & 0x1f;
            data = s->mii_word & 0xffff;

        if (op == 5) {
            tulip_mii_write(s, phy, reg, data);
        }
    }
}

static uint32_t tulip_csr9_read(TULIPState *s)
{
    if (s->csr[9] & CSR9_SR) {
        if (eeprom93xx_read(s->eeprom)) {
            s->csr[9] |= CSR9_SR_DO;
        } else {
            s->csr[9] &= ~CSR9_SR_DO;
        }
    }

    tulip_mii(s);
    return s->csr[9];
}

static void tulip_update_ts(TULIPState *s, int state)
{
        s->csr[5] &= ~(CSR5_TS_MASK << CSR5_TS_SHIFT);
        s->csr[5] |= (state & CSR5_TS_MASK) << CSR5_TS_SHIFT;
        trace_tulip_tx_state(tulip_tx_state_name(state));
}

static uint64_t tulip_read(void *opaque, hwaddr addr,
                              unsigned size)
{
    TULIPState *s = opaque;
    uint64_t data = 0;

    switch (addr) {
    case CSR(9):
        data = tulip_csr9_read(s);
        break;

    case CSR(12):
        /* Fake autocompletion complete until we have PHY emulation */
        data = 5 << CSR12_ANS_SHIFT;
        break;

    default:
        if (addr & 7) {
            qemu_log_mask(LOG_GUEST_ERROR, "%s: read access at unknown address"
                " 0x%"PRIx64"\n", __func__, addr);
        } else {
            data = s->csr[addr >> 3];
        }
        break;
    }
    trace_tulip_reg_read(addr, tulip_reg_name(addr), size, data);
    return data;
}

static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
{
    if (s->tx_frame_len) {
        if ((s->csr[6] >> CSR6_OM_SHIFT) & CSR6_OM_MASK) {
            /* Internal or external Loopback */
            tulip_receive(s, s->tx_frame, s->tx_frame_len);
        } else if (s->tx_frame_len <= sizeof(s->tx_frame)) {
            qemu_send_packet(qemu_get_queue(s->nic),
                s->tx_frame, s->tx_frame_len);
        }
    }

    if (desc->control & TDES1_IC) {
        s->csr[5] |= CSR5_TI;
        tulip_update_int(s);
    }
}

static int tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
{
    int len1 = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK;
    int len2 = (desc->control >> TDES1_BUF2_SIZE_SHIFT) & TDES1_BUF2_SIZE_MASK;

    if (s->tx_frame_len + len1 > sizeof(s->tx_frame)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: descriptor overflow (ofs: %u, len:%d, size:%zu)\n",
                      __func__, s->tx_frame_len, len1, sizeof(s->tx_frame));
        return -1;
    }
    if (len1) {
        pci_dma_read(&s->dev, desc->buf_addr1,
            s->tx_frame + s->tx_frame_len, len1);
        s->tx_frame_len += len1;
    }

    if (s->tx_frame_len + len2 > sizeof(s->tx_frame)) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: descriptor overflow (ofs: %u, len:%d, size:%zu)\n",
                      __func__, s->tx_frame_len, len2, sizeof(s->tx_frame));
        return -1;
    }
    if (len2) {
        pci_dma_read(&s->dev, desc->buf_addr2,
            s->tx_frame + s->tx_frame_len, len2);
        s->tx_frame_len += len2;
    }
    desc->status = (len1 + len2) ? 0 : 0x7fffffff;

    return 0;
}

static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n)
{
    int offset = n * 12;

    s->filter[n][0] = buf[offset];
    s->filter[n][1] = buf[offset + 1];

    s->filter[n][2] = buf[offset + 4];
    s->filter[n][3] = buf[offset + 5];

    s->filter[n][4] = buf[offset + 8];
    s->filter[n][5] = buf[offset + 9];

    trace_tulip_setup_filter(n, s->filter[n][5], s->filter[n][4],
            s->filter[n][3], s->filter[n][2], s->filter[n][1], s->filter[n][0]);
}

static void tulip_setup_frame(TULIPState *s,
        struct tulip_descriptor *desc)
{
    uint8_t buf[4096];
    int len = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK;
    int i;

    trace_tulip_setup_frame();

    if (len == 192) {
        pci_dma_read(&s->dev, desc->buf_addr1, buf, len);
        for (i = 0; i < 16; i++) {
            tulip_setup_filter_addr(s, buf, i);
        }
    }

    desc->status = 0x7fffffff;

    if (desc->control & TDES1_IC) {
        s->csr[5] |= CSR5_TI;
        tulip_update_int(s);
    }
}

static void tulip_next_tx_descriptor(TULIPState *s,
    struct tulip_descriptor *desc)
{
    if (desc->control & TDES1_TER) {
        s->current_tx_desc = s->csr[4];
    } else if (desc->control & TDES1_TCH) {
        s->current_tx_desc = desc->buf_addr2;
    } else {
        s->current_tx_desc += sizeof(struct tulip_descriptor) +
                (((s->csr[0] >> CSR0_DSL_SHIFT) & CSR0_DSL_MASK) << 2);
    }
    s->current_tx_desc &= ~3ULL;
}

static uint32_t tulip_ts(TULIPState *s)
{
    return (s->csr[5] >> CSR5_TS_SHIFT) & CSR5_TS_MASK;
}

static void tulip_xmit_list_update(TULIPState *s)
{
#define TULIP_DESC_MAX 128
    uint8_t i = 0;
    struct tulip_descriptor desc;

    if (tulip_ts(s) != CSR5_TS_SUSPENDED) {
        return;
    }

    for (i = 0; i < TULIP_DESC_MAX; i++) {
        tulip_desc_read(s, s->current_tx_desc, &desc);
        tulip_dump_tx_descriptor(s, &desc);

        if (!(desc.status & TDES0_OWN)) {
            tulip_update_ts(s, CSR5_TS_SUSPENDED);
            s->csr[5] |= CSR5_TU;
            tulip_update_int(s);
            return;
        }

        if (desc.control & TDES1_SET) {
            tulip_setup_frame(s, &desc);
        } else {
            if (desc.control & TDES1_FS) {
                s->tx_frame_len = 0;
            }

            if (!tulip_copy_tx_buffers(s, &desc)) {
                if (desc.control & TDES1_LS) {
                    tulip_tx(s, &desc);
                }
            }
        }
        tulip_desc_write(s, s->current_tx_desc, &desc);
        tulip_next_tx_descriptor(s, &desc);
    }
}

static void tulip_csr9_write(TULIPState *s, uint32_t old_val,
        uint32_t new_val)
{
    if (new_val & CSR9_SR) {
        eeprom93xx_write(s->eeprom,
            !!(new_val & CSR9_SR_CS),
            !!(new_val & CSR9_SR_SK),
            !!(new_val & CSR9_SR_DI));
    }
}

static void tulip_reset(TULIPState *s)
{
    trace_tulip_reset();

    s->csr[0] = 0xfe000000;
    s->csr[1] = 0xffffffff;
    s->csr[2] = 0xffffffff;
    s->csr[5] = 0xf0000000;
    s->csr[6] = 0x32000040;
    s->csr[7] = 0xf3fe0000;
    s->csr[8] = 0xe0000000;
    s->csr[9] = 0xfff483ff;
    s->csr[11] = 0xfffe0000;
    s->csr[12] = 0x000000c6;
    s->csr[13] = 0xffff0000;
    s->csr[14] = 0xffffffff;
    s->csr[15] = 0x8ff00000;
}

static void tulip_qdev_reset(DeviceState *dev)
{
    PCIDevice *d = PCI_DEVICE(dev);
    TULIPState *s = TULIP(d);

    tulip_reset(s);
}

static void tulip_write(void *opaque, hwaddr addr,
                           uint64_t data, unsigned size)
{
    TULIPState *s = opaque;
    trace_tulip_reg_write(addr, tulip_reg_name(addr), size, data);

    switch (addr) {
    case CSR(0):
        s->csr[0] = data;
        if (data & CSR0_SWR) {
            tulip_reset(s);
            tulip_update_int(s);
        }
        break;

    case CSR(1):
        tulip_xmit_list_update(s);
        break;

    case CSR(2):
        qemu_flush_queued_packets(qemu_get_queue(s->nic));
        break;

    case CSR(3):
        s->csr[3] = data & ~3ULL;
        s->current_rx_desc = s->csr[3];
        qemu_flush_queued_packets(qemu_get_queue(s->nic));
        break;

    case CSR(4):
        s->csr[4] = data & ~3ULL;
        s->current_tx_desc = s->csr[4];
        tulip_xmit_list_update(s);
        break;

    case CSR(5):
        /* Status register, write clears bit */
        s->csr[5] &= ~(data & (CSR5_TI | CSR5_TPS | CSR5_TU | CSR5_TJT |
                               CSR5_LNP_ANC | CSR5_UNF | CSR5_RI | CSR5_RU |
                               CSR5_RPS | CSR5_RWT | CSR5_ETI | CSR5_GTE |
                               CSR5_LNF | CSR5_FBE | CSR5_ERI | CSR5_AIS |
                               CSR5_NIS | CSR5_GPI | CSR5_LC));
        tulip_update_int(s);
        break;

    case CSR(6):
        s->csr[6] = data;
        if (s->csr[6] & CSR6_SR) {
            tulip_update_rs(s, CSR5_RS_RUNNING_WAIT_RECEIVE);
            qemu_flush_queued_packets(qemu_get_queue(s->nic));
        } else {
            tulip_update_rs(s, CSR5_RS_STOPPED);
        }

        if (s->csr[6] & CSR6_ST) {
            tulip_update_ts(s, CSR5_TS_SUSPENDED);
            tulip_xmit_list_update(s);
        } else {
            tulip_update_ts(s, CSR5_TS_STOPPED);
        }
        break;

    case CSR(7):
        s->csr[7] = data;
        tulip_update_int(s);
        break;

    case CSR(8):
        s->csr[9] = data;
        break;

    case CSR(9):
        tulip_csr9_write(s, s->csr[9], data);
        /* don't clear MII read data */
        s->csr[9] &= CSR9_MDI;
        s->csr[9] |= (data & ~CSR9_MDI);
        tulip_mii(s);
        s->old_csr9 = s->csr[9];
        break;

    case CSR(10):
        s->csr[10] = data;
        break;

    case CSR(11):
        s->csr[11] = data;
        break;

    case CSR(12):
        /* SIA Status register, some bits are cleared by writing 1 */
        s->csr[12] &= ~(data & (CSR12_MRA | CSR12_TRA | CSR12_ARA));
        break;

    case CSR(13):
        s->csr[13] = data;
        break;

    case CSR(14):
        s->csr[14] = data;
        break;

    case CSR(15):
        s->csr[15] = data;
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: write to CSR at unknown address "
                "0x%"PRIx64"\n", __func__, addr);
        break;
    }
}

static const MemoryRegionOps tulip_ops = {
    .read = tulip_read,
    .write = tulip_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static void tulip_idblock_crc(TULIPState *s, uint16_t *srom)
{
    int word;
    int bit;
    unsigned char bitval, crc;
    const int len = 9;
    crc = -1;

    for (word = 0; word < len; word++) {
        for (bit = 15; bit >= 0; bit--) {
            if ((word == (len - 1)) && (bit == 7)) {
                /*
                 * Insert the correct CRC result into input data stream
                 * in place.
                 */
                srom[len - 1] = (srom[len - 1] & 0xff00) | (unsigned short)crc;
                break;
            }
            bitval = ((srom[word] >> bit) & 1) ^ ((crc >> 7) & 1);
            crc = crc << 1;
            if (bitval == 1) {
                crc ^= 6;
                crc |= 0x01;
            }
        }
    }
}

static uint16_t tulip_srom_crc(TULIPState *s, uint8_t *eeprom, size_t len)
{
    unsigned long crc = 0xffffffff;
    unsigned long flippedcrc = 0;
    unsigned char currentbyte;
    unsigned int msb, bit, i;

    for (i = 0; i < len; i++) {
        currentbyte = eeprom[i];
        for (bit = 0; bit < 8; bit++) {
            msb = (crc >> 31) & 1;
            crc <<= 1;
            if (msb ^ (currentbyte & 1)) {
                crc ^= 0x04c11db6;
                crc |= 0x00000001;
            }
            currentbyte >>= 1;
        }
    }

    for (i = 0; i < 32; i++) {
        flippedcrc <<= 1;
        bit = crc & 1;
        crc >>= 1;
        flippedcrc += bit;
    }
    return (flippedcrc ^ 0xffffffff) & 0xffff;
}

static const uint8_t eeprom_default[128] = {
    0x3c, 0x10, 0x4f, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x56, 0x08, 0x04, 0x01, 0x00, 0x80, 0x48, 0xb3,
    0x0e, 0xa7, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x08,
    0x01, 0x8d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x78,
    0xe0, 0x01, 0x00, 0x50, 0x00, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x6b,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0x48, 0xb3, 0x0e, 0xa7, 0x40, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

static void tulip_fill_eeprom(TULIPState *s)
{
    uint16_t *eeprom = eeprom93xx_data(s->eeprom);
    memcpy(eeprom, eeprom_default, 128);

    /* patch in our mac address */
    eeprom[10] = cpu_to_le16(s->c.macaddr.a[0] | (s->c.macaddr.a[1] << 8));
    eeprom[11] = cpu_to_le16(s->c.macaddr.a[2] | (s->c.macaddr.a[3] << 8));
    eeprom[12] = cpu_to_le16(s->c.macaddr.a[4] | (s->c.macaddr.a[5] << 8));
    tulip_idblock_crc(s, eeprom);
    eeprom[63] = cpu_to_le16(tulip_srom_crc(s, (uint8_t *)eeprom, 126));
}

static void pci_tulip_realize(PCIDevice *pci_dev, Error **errp)
{
    TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);
    uint8_t *pci_conf;

    pci_conf = s->dev.config;
    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */

    qemu_macaddr_default_if_unset(&s->c.macaddr);

    s->eeprom = eeprom93xx_new(&pci_dev->qdev, 64);
    tulip_fill_eeprom(s);

    memory_region_init_io(&s->io, OBJECT(&s->dev), &tulip_ops, s,
            "tulip-io", 128);

    memory_region_init_io(&s->memory, OBJECT(&s->dev), &tulip_ops, s,
            "tulip-mem", 128);

    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->memory);

    s->irq = pci_allocate_irq(&s->dev);

    s->nic = qemu_new_nic(&net_tulip_info, &s->c,
                          object_get_typename(OBJECT(pci_dev)),
                          pci_dev->qdev.id,
                          &pci_dev->qdev.mem_reentrancy_guard, s);
    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
}

static void pci_tulip_exit(PCIDevice *pci_dev)
{
    TULIPState *s = DO_UPCAST(TULIPState, dev, pci_dev);

    qemu_del_nic(s->nic);
    qemu_free_irq(s->irq);
    eeprom93xx_free(&pci_dev->qdev, s->eeprom);
}

static void tulip_instance_init(Object *obj)
{
    PCIDevice *pci_dev = PCI_DEVICE(obj);
    TULIPState *d = DO_UPCAST(TULIPState, dev, pci_dev);

    device_add_bootindex_property(obj, &d->c.bootindex,
                                  "bootindex", "/ethernet-phy@0",
                                  &pci_dev->qdev);
}

static Property tulip_properties[] = {
    DEFINE_NIC_PROPERTIES(TULIPState, c),
    DEFINE_PROP_END_OF_LIST(),
};

static void tulip_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = pci_tulip_realize;
    k->exit = pci_tulip_exit;
    k->vendor_id = PCI_VENDOR_ID_DEC;
    k->device_id = PCI_DEVICE_ID_DEC_21143;
    k->subsystem_vendor_id = 0x103c;
    k->subsystem_id = 0x104f;
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
    dc->vmsd = &vmstate_pci_tulip;
    device_class_set_props(dc, tulip_properties);
    dc->reset = tulip_qdev_reset;
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}

static const TypeInfo tulip_info = {
    .name          = TYPE_TULIP,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(TULIPState),
    .class_init    = tulip_class_init,
    .instance_init = tulip_instance_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void tulip_register_types(void)
{
    type_register_static(&tulip_info);
}

type_init(tulip_register_types)
