/*
 * OpenCores Ethernet MAC 10/100 + subset of
 * National Semiconductors DP83848C 10/100 PHY
 *
 * http://opencores.org/svnget,ethmac?file=%2Ftrunk%2F%2Fdoc%2Feth_speci.pdf
 * http://cache.national.com/ds/DP/DP83848C.pdf
 *
 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Open Source and Linux Lab nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/net/mii.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "qemu/module.h"
#include "net/eth.h"
#include "trace.h"

/* RECSMALL is not used because it breaks tap networking in linux:
 * incoming ARP responses are too short
 */
#undef USE_RECSMALL

#define GET_FIELD(v, field) (((v) & (field)) >> (field ## _LBN))
#define GET_REGBIT(s, reg, field) ((s)->regs[reg] & (reg ## _ ## field))
#define GET_REGFIELD(s, reg, field) \
    GET_FIELD((s)->regs[reg], reg ## _ ## field)

#define SET_FIELD(v, field, data) \
    ((v) = (((v) & ~(field)) | (((data) << (field ## _LBN)) & (field))))
#define SET_REGFIELD(s, reg, field, data) \
    SET_FIELD((s)->regs[reg], reg ## _ ## field, data)

/* PHY MII registers */
enum {
    MII_REG_MAX = 16,
};

typedef struct Mii {
    uint16_t regs[MII_REG_MAX];
    bool link_ok;
} Mii;

static void mii_set_link(Mii *s, bool link_ok)
{
    if (link_ok) {
        s->regs[MII_BMSR] |= MII_BMSR_LINK_ST;
        s->regs[MII_ANLPAR] |= MII_ANLPAR_TXFD | MII_ANLPAR_TX |
            MII_ANLPAR_10FD | MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
    } else {
        s->regs[MII_BMSR] &= ~MII_BMSR_LINK_ST;
        s->regs[MII_ANLPAR] &= 0x01ff;
    }
    s->link_ok = link_ok;
}

static void mii_reset(Mii *s)
{
    memset(s->regs, 0, sizeof(s->regs));
    s->regs[MII_BMCR] = MII_BMCR_AUTOEN;
    s->regs[MII_BMSR] = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD |
        MII_BMSR_10T_FD | MII_BMSR_10T_HD | MII_BMSR_MFPS |
        MII_BMSR_AN_COMP | MII_BMSR_AUTONEG;
    s->regs[MII_PHYID1] = 0x2000;
    s->regs[MII_PHYID2] = 0x5c90;
    s->regs[MII_ANAR] = MII_ANAR_TXFD | MII_ANAR_TX |
        MII_ANAR_10FD | MII_ANAR_10 | MII_ANAR_CSMACD;
    mii_set_link(s, s->link_ok);
}

static void mii_ro(Mii *s, uint16_t v)
{
}

static void mii_write_bmcr(Mii *s, uint16_t v)
{
    if (v & MII_BMCR_RESET) {
        mii_reset(s);
    } else {
        s->regs[MII_BMCR] = v;
    }
}

static void mii_write_host(Mii *s, unsigned idx, uint16_t v)
{
    static void (*reg_write[MII_REG_MAX])(Mii *s, uint16_t v) = {
        [MII_BMCR] = mii_write_bmcr,
        [MII_BMSR] = mii_ro,
        [MII_PHYID1] = mii_ro,
        [MII_PHYID2] = mii_ro,
    };

    if (idx < MII_REG_MAX) {
        trace_open_eth_mii_write(idx, v);
        if (reg_write[idx]) {
            reg_write[idx](s, v);
        } else {
            s->regs[idx] = v;
        }
    }
}

static uint16_t mii_read_host(Mii *s, unsigned idx)
{
    trace_open_eth_mii_read(idx, s->regs[idx]);
    return s->regs[idx];
}

/* OpenCores Ethernet registers */
enum {
    MODER,
    INT_SOURCE,
    INT_MASK,
    IPGT,
    IPGR1,
    IPGR2,
    PACKETLEN,
    COLLCONF,
    TX_BD_NUM,
    CTRLMODER,
    MIIMODER,
    MIICOMMAND,
    MIIADDRESS,
    MIITX_DATA,
    MIIRX_DATA,
    MIISTATUS,
    MAC_ADDR0,
    MAC_ADDR1,
    HASH0,
    HASH1,
    TXCTRL,
    REG_MAX,
};

enum {
    MODER_RECSMALL = 0x10000,
    MODER_PAD = 0x8000,
    MODER_HUGEN = 0x4000,
    MODER_RST = 0x800,
    MODER_LOOPBCK = 0x80,
    MODER_PRO = 0x20,
    MODER_IAM = 0x10,
    MODER_BRO = 0x8,
    MODER_TXEN = 0x2,
    MODER_RXEN = 0x1,
};

enum {
    INT_SOURCE_BUSY = 0x10,
    INT_SOURCE_RXB = 0x4,
    INT_SOURCE_TXB = 0x1,
};

enum {
    PACKETLEN_MINFL = 0xffff0000,
    PACKETLEN_MINFL_LBN = 16,
    PACKETLEN_MAXFL = 0xffff,
    PACKETLEN_MAXFL_LBN = 0,
};

enum {
    MIICOMMAND_WCTRLDATA = 0x4,
    MIICOMMAND_RSTAT = 0x2,
    MIICOMMAND_SCANSTAT = 0x1,
};

enum {
    MIIADDRESS_RGAD = 0x1f00,
    MIIADDRESS_RGAD_LBN = 8,
    MIIADDRESS_FIAD = 0x1f,
    MIIADDRESS_FIAD_LBN = 0,
};

enum {
    MIITX_DATA_CTRLDATA = 0xffff,
    MIITX_DATA_CTRLDATA_LBN = 0,
};

enum {
    MIIRX_DATA_PRSD = 0xffff,
    MIIRX_DATA_PRSD_LBN = 0,
};

enum {
    MIISTATUS_LINKFAIL = 0x1,
    MIISTATUS_LINKFAIL_LBN = 0,
};

enum {
    MAC_ADDR0_BYTE2 = 0xff000000,
    MAC_ADDR0_BYTE2_LBN = 24,
    MAC_ADDR0_BYTE3 = 0xff0000,
    MAC_ADDR0_BYTE3_LBN = 16,
    MAC_ADDR0_BYTE4 = 0xff00,
    MAC_ADDR0_BYTE4_LBN = 8,
    MAC_ADDR0_BYTE5 = 0xff,
    MAC_ADDR0_BYTE5_LBN = 0,
};

enum {
    MAC_ADDR1_BYTE0 = 0xff00,
    MAC_ADDR1_BYTE0_LBN = 8,
    MAC_ADDR1_BYTE1 = 0xff,
    MAC_ADDR1_BYTE1_LBN = 0,
};

enum {
    TXD_LEN = 0xffff0000,
    TXD_LEN_LBN = 16,
    TXD_RD = 0x8000,
    TXD_IRQ = 0x4000,
    TXD_WR = 0x2000,
    TXD_PAD = 0x1000,
    TXD_CRC = 0x800,
    TXD_UR = 0x100,
    TXD_RTRY = 0xf0,
    TXD_RTRY_LBN = 4,
    TXD_RL = 0x8,
    TXD_LC = 0x4,
    TXD_DF = 0x2,
    TXD_CS = 0x1,
};

enum {
    RXD_LEN = 0xffff0000,
    RXD_LEN_LBN = 16,
    RXD_E = 0x8000,
    RXD_IRQ = 0x4000,
    RXD_WRAP = 0x2000,
    RXD_CF = 0x100,
    RXD_M = 0x80,
    RXD_OR = 0x40,
    RXD_IS = 0x20,
    RXD_DN = 0x10,
    RXD_TL = 0x8,
    RXD_SF = 0x4,
    RXD_CRC = 0x2,
    RXD_LC = 0x1,
};

typedef struct desc {
    uint32_t len_flags;
    uint32_t buf_ptr;
} desc;

#define DEFAULT_PHY 1

#define TYPE_OPEN_ETH "open_eth"
#define OPEN_ETH(obj) OBJECT_CHECK(OpenEthState, (obj), TYPE_OPEN_ETH)

typedef struct OpenEthState {
    SysBusDevice parent_obj;

    NICState *nic;
    NICConf conf;
    MemoryRegion reg_io;
    MemoryRegion desc_io;
    qemu_irq irq;

    Mii mii;
    uint32_t regs[REG_MAX];
    unsigned tx_desc;
    unsigned rx_desc;
    desc desc[128];
} OpenEthState;

static desc *rx_desc(OpenEthState *s)
{
    return s->desc + s->rx_desc;
}

static desc *tx_desc(OpenEthState *s)
{
    return s->desc + s->tx_desc;
}

static void open_eth_update_irq(OpenEthState *s,
        uint32_t old, uint32_t new)
{
    if (!old != !new) {
        trace_open_eth_update_irq(new);
        qemu_set_irq(s->irq, new);
    }
}

static void open_eth_int_source_write(OpenEthState *s,
        uint32_t val)
{
    uint32_t old_val = s->regs[INT_SOURCE];

    s->regs[INT_SOURCE] = val;
    open_eth_update_irq(s, old_val & s->regs[INT_MASK],
            s->regs[INT_SOURCE] & s->regs[INT_MASK]);
}

static void open_eth_set_link_status(NetClientState *nc)
{
    OpenEthState *s = qemu_get_nic_opaque(nc);

    if (GET_REGBIT(s, MIICOMMAND, SCANSTAT)) {
        SET_REGFIELD(s, MIISTATUS, LINKFAIL, nc->link_down);
    }
    mii_set_link(&s->mii, !nc->link_down);
}

static void open_eth_reset(void *opaque)
{
    OpenEthState *s = opaque;

    memset(s->regs, 0, sizeof(s->regs));
    s->regs[MODER] = 0xa000;
    s->regs[IPGT] = 0x12;
    s->regs[IPGR1] = 0xc;
    s->regs[IPGR2] = 0x12;
    s->regs[PACKETLEN] = 0x400600;
    s->regs[COLLCONF] = 0xf003f;
    s->regs[TX_BD_NUM] = 0x40;
    s->regs[MIIMODER] = 0x64;

    s->tx_desc = 0;
    s->rx_desc = 0x40;

    mii_reset(&s->mii);
    open_eth_set_link_status(qemu_get_queue(s->nic));
}

static bool open_eth_can_receive(NetClientState *nc)
{
    OpenEthState *s = qemu_get_nic_opaque(nc);

    return GET_REGBIT(s, MODER, RXEN) && (s->regs[TX_BD_NUM] < 0x80);
}

static ssize_t open_eth_receive(NetClientState *nc,
        const uint8_t *buf, size_t size)
{
    OpenEthState *s = qemu_get_nic_opaque(nc);
    size_t maxfl = GET_REGFIELD(s, PACKETLEN, MAXFL);
    size_t minfl = GET_REGFIELD(s, PACKETLEN, MINFL);
    size_t fcsl = 4;
    bool miss = true;

    trace_open_eth_receive((unsigned)size);

    if (size >= 6) {
        static const uint8_t bcast_addr[] = {
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff
        };
        if (memcmp(buf, bcast_addr, sizeof(bcast_addr)) == 0) {
            miss = GET_REGBIT(s, MODER, BRO);
        } else if ((buf[0] & 0x1) || GET_REGBIT(s, MODER, IAM)) {
            unsigned mcast_idx = net_crc32(buf, ETH_ALEN) >> 26;
            miss = !(s->regs[HASH0 + mcast_idx / 32] &
                    (1 << (mcast_idx % 32)));
            trace_open_eth_receive_mcast(
                    mcast_idx, s->regs[HASH0], s->regs[HASH1]);
        } else {
            miss = GET_REGFIELD(s, MAC_ADDR1, BYTE0) != buf[0] ||
                GET_REGFIELD(s, MAC_ADDR1, BYTE1) != buf[1] ||
                GET_REGFIELD(s, MAC_ADDR0, BYTE2) != buf[2] ||
                GET_REGFIELD(s, MAC_ADDR0, BYTE3) != buf[3] ||
                GET_REGFIELD(s, MAC_ADDR0, BYTE4) != buf[4] ||
                GET_REGFIELD(s, MAC_ADDR0, BYTE5) != buf[5];
        }
    }

    if (miss && !GET_REGBIT(s, MODER, PRO)) {
        trace_open_eth_receive_reject();
        return size;
    }

#ifdef USE_RECSMALL
    if (GET_REGBIT(s, MODER, RECSMALL) || size >= minfl) {
#else
    {
#endif
        static const uint8_t zero[64] = {0};
        desc *desc = rx_desc(s);
        size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl;

        if (!(desc->len_flags & RXD_E)) {
            open_eth_int_source_write(s,
                    s->regs[INT_SOURCE] | INT_SOURCE_BUSY);
            return size;
        }

        desc->len_flags &= ~(RXD_CF | RXD_M | RXD_OR |
                RXD_IS | RXD_DN | RXD_TL | RXD_SF | RXD_CRC | RXD_LC);

        if (copy_size > size) {
            copy_size = size;
        } else {
            fcsl = 0;
        }
        if (miss) {
            desc->len_flags |= RXD_M;
        }
        if (GET_REGBIT(s, MODER, HUGEN) && size > maxfl) {
            desc->len_flags |= RXD_TL;
        }
#ifdef USE_RECSMALL
        if (size < minfl) {
            desc->len_flags |= RXD_SF;
        }
#endif

        cpu_physical_memory_write(desc->buf_ptr, buf, copy_size);

        if (GET_REGBIT(s, MODER, PAD) && copy_size < minfl) {
            if (minfl - copy_size > fcsl) {
                fcsl = 0;
            } else {
                fcsl -= minfl - copy_size;
            }
            while (copy_size < minfl) {
                size_t zero_sz = minfl - copy_size < sizeof(zero) ?
                    minfl - copy_size : sizeof(zero);

                cpu_physical_memory_write(desc->buf_ptr + copy_size,
                        zero, zero_sz);
                copy_size += zero_sz;
            }
        }

        /* There's no FCS in the frames handed to us by the QEMU, zero fill it.
         * Don't do it if the frame is cut at the MAXFL or padded with 4 or
         * more bytes to the MINFL.
         */
        cpu_physical_memory_write(desc->buf_ptr + copy_size, zero, fcsl);
        copy_size += fcsl;

        SET_FIELD(desc->len_flags, RXD_LEN, copy_size);

        if ((desc->len_flags & RXD_WRAP) || s->rx_desc == 0x7f) {
            s->rx_desc = s->regs[TX_BD_NUM];
        } else {
            ++s->rx_desc;
        }
        desc->len_flags &= ~RXD_E;

        trace_open_eth_receive_desc(desc->buf_ptr, desc->len_flags);

        if (desc->len_flags & RXD_IRQ) {
            open_eth_int_source_write(s,
                    s->regs[INT_SOURCE] | INT_SOURCE_RXB);
        }
    }
    return size;
}

static NetClientInfo net_open_eth_info = {
    .type = NET_CLIENT_DRIVER_NIC,
    .size = sizeof(NICState),
    .can_receive = open_eth_can_receive,
    .receive = open_eth_receive,
    .link_status_changed = open_eth_set_link_status,
};

static void open_eth_start_xmit(OpenEthState *s, desc *tx)
{
    uint8_t *buf = NULL;
    uint8_t buffer[0x600];
    unsigned len = GET_FIELD(tx->len_flags, TXD_LEN);
    unsigned tx_len = len;

    if ((tx->len_flags & TXD_PAD) &&
            tx_len < GET_REGFIELD(s, PACKETLEN, MINFL)) {
        tx_len = GET_REGFIELD(s, PACKETLEN, MINFL);
    }
    if (!GET_REGBIT(s, MODER, HUGEN) &&
            tx_len > GET_REGFIELD(s, PACKETLEN, MAXFL)) {
        tx_len = GET_REGFIELD(s, PACKETLEN, MAXFL);
    }

    trace_open_eth_start_xmit(tx->buf_ptr, len, tx_len);

    if (tx_len > sizeof(buffer)) {
        buf = g_new(uint8_t, tx_len);
    } else {
        buf = buffer;
    }
    if (len > tx_len) {
        len = tx_len;
    }
    cpu_physical_memory_read(tx->buf_ptr, buf, len);
    if (tx_len > len) {
        memset(buf + len, 0, tx_len - len);
    }
    qemu_send_packet(qemu_get_queue(s->nic), buf, tx_len);
    if (tx_len > sizeof(buffer)) {
        g_free(buf);
    }

    if (tx->len_flags & TXD_WR) {
        s->tx_desc = 0;
    } else {
        ++s->tx_desc;
        if (s->tx_desc >= s->regs[TX_BD_NUM]) {
            s->tx_desc = 0;
        }
    }
    tx->len_flags &= ~(TXD_RD | TXD_UR |
            TXD_RTRY | TXD_RL | TXD_LC | TXD_DF | TXD_CS);
    if (tx->len_flags & TXD_IRQ) {
        open_eth_int_source_write(s, s->regs[INT_SOURCE] | INT_SOURCE_TXB);
    }

}

static void open_eth_check_start_xmit(OpenEthState *s)
{
    desc *tx = tx_desc(s);
    if (GET_REGBIT(s, MODER, TXEN) && s->regs[TX_BD_NUM] > 0 &&
            (tx->len_flags & TXD_RD) &&
            GET_FIELD(tx->len_flags, TXD_LEN) > 4) {
        open_eth_start_xmit(s, tx);
    }
}

static uint64_t open_eth_reg_read(void *opaque,
        hwaddr addr, unsigned int size)
{
    static uint32_t (*reg_read[REG_MAX])(OpenEthState *s) = {
    };
    OpenEthState *s = opaque;
    unsigned idx = addr / 4;
    uint64_t v = 0;

    if (idx < REG_MAX) {
        if (reg_read[idx]) {
            v = reg_read[idx](s);
        } else {
            v = s->regs[idx];
        }
    }
    trace_open_eth_reg_read((uint32_t)addr, (uint32_t)v);
    return v;
}

static void open_eth_notify_can_receive(OpenEthState *s)
{
    NetClientState *nc = qemu_get_queue(s->nic);

    if (open_eth_can_receive(nc)) {
        qemu_flush_queued_packets(nc);
    }
}

static void open_eth_ro(OpenEthState *s, uint32_t val)
{
}

static void open_eth_moder_host_write(OpenEthState *s, uint32_t val)
{
    uint32_t set = val & ~s->regs[MODER];

    if (set & MODER_RST) {
        open_eth_reset(s);
    }

    s->regs[MODER] = val;

    if (set & MODER_RXEN) {
        s->rx_desc = s->regs[TX_BD_NUM];
        open_eth_notify_can_receive(s);
    }
    if (set & MODER_TXEN) {
        s->tx_desc = 0;
        open_eth_check_start_xmit(s);
    }
}

static void open_eth_int_source_host_write(OpenEthState *s, uint32_t val)
{
    uint32_t old = s->regs[INT_SOURCE];

    s->regs[INT_SOURCE] &= ~val;
    open_eth_update_irq(s, old & s->regs[INT_MASK],
            s->regs[INT_SOURCE] & s->regs[INT_MASK]);
}

static void open_eth_int_mask_host_write(OpenEthState *s, uint32_t val)
{
    uint32_t old = s->regs[INT_MASK];

    s->regs[INT_MASK] = val;
    open_eth_update_irq(s, s->regs[INT_SOURCE] & old,
            s->regs[INT_SOURCE] & s->regs[INT_MASK]);
}

static void open_eth_tx_bd_num_host_write(OpenEthState *s, uint32_t val)
{
    if (val < 0x80) {
        bool enable = s->regs[TX_BD_NUM] == 0x80;

        s->regs[TX_BD_NUM] = val;
        if (enable) {
            open_eth_notify_can_receive(s);
        }
    }
}

static void open_eth_mii_command_host_write(OpenEthState *s, uint32_t val)
{
    unsigned fiad = GET_REGFIELD(s, MIIADDRESS, FIAD);
    unsigned rgad = GET_REGFIELD(s, MIIADDRESS, RGAD);

    if (val & MIICOMMAND_WCTRLDATA) {
        if (fiad == DEFAULT_PHY) {
            mii_write_host(&s->mii, rgad,
                    GET_REGFIELD(s, MIITX_DATA, CTRLDATA));
        }
    }
    if (val & MIICOMMAND_RSTAT) {
        if (fiad == DEFAULT_PHY) {
            SET_REGFIELD(s, MIIRX_DATA, PRSD,
                    mii_read_host(&s->mii, rgad));
        } else {
            s->regs[MIIRX_DATA] = 0xffff;
        }
        SET_REGFIELD(s, MIISTATUS, LINKFAIL, qemu_get_queue(s->nic)->link_down);
    }
}

static void open_eth_mii_tx_host_write(OpenEthState *s, uint32_t val)
{
    SET_REGFIELD(s, MIITX_DATA, CTRLDATA, val);
    if (GET_REGFIELD(s, MIIADDRESS, FIAD) == DEFAULT_PHY) {
        mii_write_host(&s->mii, GET_REGFIELD(s, MIIADDRESS, RGAD),
                GET_REGFIELD(s, MIITX_DATA, CTRLDATA));
    }
}

static void open_eth_reg_write(void *opaque,
        hwaddr addr, uint64_t val, unsigned int size)
{
    static void (*reg_write[REG_MAX])(OpenEthState *s, uint32_t val) = {
        [MODER] = open_eth_moder_host_write,
        [INT_SOURCE] = open_eth_int_source_host_write,
        [INT_MASK] = open_eth_int_mask_host_write,
        [TX_BD_NUM] = open_eth_tx_bd_num_host_write,
        [MIICOMMAND] = open_eth_mii_command_host_write,
        [MIITX_DATA] = open_eth_mii_tx_host_write,
        [MIISTATUS] = open_eth_ro,
    };
    OpenEthState *s = opaque;
    unsigned idx = addr / 4;

    if (idx < REG_MAX) {
        trace_open_eth_reg_write((uint32_t)addr, (uint32_t)val);
        if (reg_write[idx]) {
            reg_write[idx](s, val);
        } else {
            s->regs[idx] = val;
        }
    }
}

static uint64_t open_eth_desc_read(void *opaque,
        hwaddr addr, unsigned int size)
{
    OpenEthState *s = opaque;
    uint64_t v = 0;

    addr &= 0x3ff;
    memcpy(&v, (uint8_t *)s->desc + addr, size);
    trace_open_eth_desc_read((uint32_t)addr, (uint32_t)v);
    return v;
}

static void open_eth_desc_write(void *opaque,
        hwaddr addr, uint64_t val, unsigned int size)
{
    OpenEthState *s = opaque;

    addr &= 0x3ff;
    trace_open_eth_desc_write((uint32_t)addr, (uint32_t)val);
    memcpy((uint8_t *)s->desc + addr, &val, size);
    open_eth_check_start_xmit(s);
}


static const MemoryRegionOps open_eth_reg_ops = {
    .read = open_eth_reg_read,
    .write = open_eth_reg_write,
};

static const MemoryRegionOps open_eth_desc_ops = {
    .read = open_eth_desc_read,
    .write = open_eth_desc_write,
};

static void sysbus_open_eth_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    OpenEthState *s = OPEN_ETH(dev);

    memory_region_init_io(&s->reg_io, OBJECT(dev), &open_eth_reg_ops, s,
            "open_eth.regs", 0x54);
    sysbus_init_mmio(sbd, &s->reg_io);

    memory_region_init_io(&s->desc_io, OBJECT(dev), &open_eth_desc_ops, s,
            "open_eth.desc", 0x400);
    sysbus_init_mmio(sbd, &s->desc_io);

    sysbus_init_irq(sbd, &s->irq);

    s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
                          object_get_typename(OBJECT(s)), dev->id, s);
}

static void qdev_open_eth_reset(DeviceState *dev)
{
    OpenEthState *d = OPEN_ETH(dev);

    open_eth_reset(d);
}

static Property open_eth_properties[] = {
    DEFINE_NIC_PROPERTIES(OpenEthState, conf),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = sysbus_open_eth_realize;
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
    dc->desc = "Opencores 10/100 Mbit Ethernet";
    dc->reset = qdev_open_eth_reset;
    device_class_set_props(dc, open_eth_properties);
}

static const TypeInfo open_eth_info = {
    .name          = TYPE_OPEN_ETH,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(OpenEthState),
    .class_init    = open_eth_class_init,
};

static void open_eth_register_types(void)
{
    type_register_static(&open_eth_info);
}

type_init(open_eth_register_types)
