All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: bifferos <bifferos@yahoo.co.uk>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] Add support for r6040 NIC
Date: Tue, 30 Aug 2011 20:17:30 -0500	[thread overview]
Message-ID: <4E5D8BAA.9010302@codemonkey.ws> (raw)
In-Reply-To: <1314752751.84463.YahooMailClassic@web27003.mail.ukl.yahoo.com>

This won't even come close to passing checkpatch.pl

Regards,

Anthony Liguori

On 08/30/2011 08:05 PM, bifferos wrote:
>
> Signed-off-by: Mark Kelly<mark@bifferos.com>
> diff --git a/Makefile.objs b/Makefile.objs
> index 6991a9f..7d87503 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -240,6 +240,7 @@ hw-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o
>   hw-obj-$(CONFIG_PCNET_COMMON) += pcnet.o
>   hw-obj-$(CONFIG_E1000_PCI) += e1000.o
>   hw-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o
> +hw-obj-$(CONFIG_R6040_PCI) += r6040.o
>
>   hw-obj-$(CONFIG_SMC91C111) += smc91c111.o
>   hw-obj-$(CONFIG_LAN9118) += lan9118.o
> diff --git a/default-configs/pci.mak b/default-configs/pci.mak
> index 22bd350..d2ea7a2 100644
> --- a/default-configs/pci.mak
> +++ b/default-configs/pci.mak
> @@ -10,6 +10,7 @@ CONFIG_PCNET_PCI=y
>   CONFIG_PCNET_COMMON=y
>   CONFIG_LSI_SCSI_PCI=y
>   CONFIG_RTL8139_PCI=y
> +CONFIG_R6040_PCI=y
>   CONFIG_E1000_PCI=y
>   CONFIG_IDE_CORE=y
>   CONFIG_IDE_QDEV=y
> diff --git a/hw/pci.c b/hw/pci.c
> index b904a4e..7e12935 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -1527,6 +1527,7 @@ static const char * const pci_nic_models[] = {
>       "rtl8139",
>       "e1000",
>       "pcnet",
> +    "r6040",
>       "virtio",
>       NULL
>   };
> @@ -1539,6 +1540,7 @@ static const char * const pci_nic_names[] = {
>       "rtl8139",
>       "e1000",
>       "pcnet",
> +    "r6040",
>       "virtio-net-pci",
>       NULL
>   };
> diff --git a/hw/r6040.c b/hw/r6040.c
> new file mode 100644
> index 0000000..83587e7
> --- /dev/null
> +++ b/hw/r6040.c
> @@ -0,0 +1,627 @@
> +/*
> +   Emulation of r6040 ethernet controller found in a number of SoCs.
> +   Copyright (c) 2011 Mark Kelly, mark@bifferos.com
> +
> +   This has been written using the R8610[1] and ip101a[2] datasheets.
> +
> +   ICs with the embedded controller include R8610, R3210, AMRISC20000
> +   and Vortex86SX
> +
> +   The emulation seems good enough to fool Linux 2.6.37.6.  It is
> +   not perfect, but has proven useful.
> +
> +   [1] http://www.sima.com.tw/download/R8610_D06_20051003.pdf
> +   [2] http://www.icplus.com.tw/pp-IP101A.html
> + */
> +
> +#include "hw.h"
> +#include "pci.h"
> +#include "net.h"
> +#include "loader.h"
> +#include "sysemu.h"
> +#include "qemu-timer.h"
> +
> +/* #define DEBUG_R6040 1 */
> +
> +
> +#if defined DEBUG_R6040
> +#define DPRINTF(fmt, ...) \
> +    do { fprintf(stderr, "R6040: " fmt, ## __VA_ARGS__); } while (0)
> +#else
> +static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...)
> +{
> +    return 0;
> +}
> +#endif
> +
> +
> +/* Cast in order of appearance.  _W prevfix means it's used to index the
> +   register word array (RegsW)
> + */
> +
> +#define MPSCCR_W         (0x88 / 2)
> +
> +#define MAC0_W           (0x68 / 2)
> +#define MAC1_W           (0x6a / 2)
> +#define MAC2_W           (0x6c / 2)
> +
> +
> +#define RX_START_LOW_W   (0x34 / 2)
> +#define RX_START_HIGH_W  (0x38 / 2)
> +#define TX_PKT_COUNT_W   (0x5a / 2)
> +#define RX_PKT_COUNT_W   (0x50 / 2)
> +
> +
> +#define MCR0_W           (0x00 / 2)
> +#define MCR1_W           (0x04 / 2)
> +#define BIT_MRST         (1<<  0)
> +
> +#define MTPR_W           (0x14 / 2)
> +#define MRBSR_W          (0x18 / 2)
> +#define MISR_W           (0x3c / 2)
> +#define MIER_W           (0x40 / 2)
> +
> +#define MMDIO_W          (0x20 / 2)
> +#define MDIO_READ_W      (0x24 / 2)
> +#define MDIO_WRITE_W     (0x28 / 2)
> +
> +#define MRCNT_W          (0x50 / 2)
> +#define MTCNT_W          (0x5c / 2)
> +
> +
> +#define MDIO_WRITE      0x4000
> +#define MDIO_READ       0x2000
> +
> +
> +typedef struct R6040State {
> +    PCIDevice dev;
> +    NICState *nic;
> +    NICConf conf;
> +
> +    /* PHY related register sets */
> +    uint16_t MID0[3];
> +    uint16_t phy_regs[32];
> +    uint32_t phy_op_in_progress;
> +
> +    /* Primary IO address space */
> +    union {
> +        uint8_t RegsB[0x100];   /* Byte access */
> +        uint16_t RegsW[0x100/2];  /* word access */
> +        uint32_t RegsL[0x100/4];  /* DWORD access */
> +    };
> +
> +} R6040State;
> +
> +
> +/* some inlines to help access above structure */
> +static inline uint32_t TX_START(R6040State *s)
> +{
> +    uint32_t tmp = s->RegsW[0x2c/2];
> +    return tmp | (s->RegsW[0x30/2]<<  16);
> +}
> +
> +static inline void TX_START_SET(R6040State *s, uint32_t start)
> +{
> +    s->RegsW[0x2c/2] = start&  0xffff;
> +    s->RegsW[0x30/2] = (start>>  16)&  0xffff;
> +}
> +
> +static inline uint32_t RX_START(R6040State *s)
> +{
> +    uint32_t tmp = s->RegsW[0x34/2];
> +    return tmp | (s->RegsW[0x38/2]<<  16);
> +}
> +
> +static inline void RX_START_SET(R6040State *s, uint32_t start)
> +{
> +    s->RegsW[0x34/2] = start&  0xffff;
> +    s->RegsW[0x38/2] = (start>>  16)&  0xffff;
> +}
> +
> +
> +static void r6040_update_irq(R6040State *s)
> +{
> +    uint16_t isr = s->RegsW[MISR_W]&  s->RegsW[MIER_W];
> +
> +    qemu_set_irq(s->dev.irq[0], isr ? 1 : 0);
> +}
> +
> +
> +/* Mark auto-neg complete, NIC up.  */
> +static void PhysicalLinkUp(void *opaque)
> +{
> +    R6040State *s = opaque;
> +    s->phy_regs[1] |= (1<<  2);
> +}
> +
> +
> +/* Transmit and receive descriptors are doubled up
> +   One is a subset of the other anyhow
> + */
> +typedef struct descriptor {
> +    uint16_t DST;
> +    uint16_t DLEN;
> +    uint32_t DBP;
> +    uint32_t DNX;
> +    uint16_t HIDX;
> +    uint16_t Reserved1;
> +    uint16_t Reserved2;
> +} descriptor_t;
> +
> +
> +/* Some debugging functions */
> +
> +#ifdef DEBUG_R6040
> +static void addr_dump16(const char *name, uint16_t val)
> +{
> +    DPRINTF("%s: 0x%04x  ", name, val);
> +}
> +
> +static void addr_dump32(const char *name, uint32_t val)
> +{
> +    DPRINTF("%s: 0x%x  ", name, val);
> +}
> +
> +static void hex_dump(const uint8_t *data, uint32_t len)
> +{
> +    uint8_t i;
> +    DPRINTF("hex: ");
> +    for (i = 0; i<  len; i++) {
> +        fprintf(stderr, "%02x ", *data);
> +        if (i&&  !(i % 0x20)) {
> +            fprintf(stderr, "\n");
> +        }
> +        data++;
> +    }
> +    fprintf(stderr, "\n");
> +}
> +
> +static void desc_dump(descriptor_t *d, uint32_t addr)
> +{
> +    DPRINTF("\nDumping: 0x%x\n", addr);
> +    addr_dump16("DST", d->DST);
> +    addr_dump16("DLEN", d->DLEN);
> +    addr_dump32("DBP", (unsigned long)d->DBP);
> +    addr_dump32("DNX", (unsigned long)d->DNX);
> +    addr_dump16("HIDX", d->HIDX);
> +    printf("\n");
> +}
> +
> +static void dump_phys_mem(uint32_t addr, int len)
> +{
> +    uint8_t buffer[1024];
> +    cpu_physical_memory_read(addr, buffer, len);
> +    hex_dump(buffer, len);
> +}
> +
> +static void dump_pci(uint8_t *pci_conf)
> +{
> +    uint32_t *p = (uint32_t *)pci_conf;
> +    int i = 0;
> +    for (i = 0; i<  0x40; i += 4) {
> +        DPRINTF("Addr: 0x%08x,  Data: 0x%08x\n", i, *p);
> +        p++;
> +    }
> +}
> +#endif
> +
> +
> +static const VMStateDescription vmstate_r6040 = {
> +    .name = "r6040",
> +    .version_id = 3,
> +    .minimum_version_id = 2,
> +    .minimum_version_id_old = 2,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_PCI_DEVICE(dev, R6040State),
> +        VMSTATE_BUFFER(RegsB, R6040State),
> +        VMSTATE_UINT16_ARRAY(MID0, R6040State, 3),
> +        VMSTATE_UINT16_ARRAY(phy_regs, R6040State, 32),
> +        VMSTATE_UINT32(phy_op_in_progress, R6040State),
> +        VMSTATE_MACADDR(conf.macaddr, R6040State),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +
> +static int TryToSendOnePacket(void *opaque)
> +{
> +    R6040State *s = opaque;
> +    descriptor_t d;
> +    uint8_t pkt_buffer[2000];
> +    uint32_t tocopy;
> +
> +    cpu_physical_memory_read(TX_START(s), (uint8_t *)&d, sizeof(d));
> +
> +    if (d.DST&  0x8000) {    /* MAC owns it?  */
> +        tocopy = d.DLEN;
> +        if (tocopy>  sizeof(pkt_buffer)) {
> +            tocopy = sizeof(pkt_buffer);
> +        }
> +        /* copy the packet to send it */
> +        cpu_physical_memory_read(d.DBP, pkt_buffer, tocopy);
> +
> +        qemu_send_packet(&s->nic->nc, pkt_buffer, tocopy);
> +        s->RegsW[TX_PKT_COUNT_W]++;
> +
> +        /* relinquish ownership, we're done with it */
> +        d.DST&= ~0x8000;
> +
> +        /* Copy the new version of the descriptor back */
> +        cpu_physical_memory_write(TX_START(s), (uint8_t *)&d, sizeof(d));
> +
> +        /* Advance to the next buffer if packet processed */
> +        TX_START_SET(s, d.DNX);
> +
> +        return 1;
> +    }
> +
> +    return 0;
> +}
> +
> +
> +static void r6040_transmit(void *opaque)
> +{
> +    R6040State *s = opaque;
> +    int count = 0;
> +
> +    while (TryToSendOnePacket(s)) {
> +        ++count;
> +    }
> +
> +    if (count) {
> +        s->RegsW[MISR_W] |= 0x10;
> +        r6040_update_irq(s);
> +    }
> +}
> +
> +
> +/* Whether to allow callback returning 1 for yes, can receive */
> +static int r6040_can_receive(VLANClientState *nc)
> +{
> +    R6040State *s = DO_UPCAST(NICState, nc, nc)->opaque;
> +    int tmp = (s->RegsW[0]&  (1<<  1)) ? 1 : 0;
> +    return tmp;
> +}
> +
> +
> +static int ReceiveOnePacket(void *opaque, const uint8_t *buf, size_t len)
> +{
> +    R6040State *s = opaque;
> +    uint32_t tocopy = len+4;  /* include checksum */
> +    descriptor_t d;
> +
> +    cpu_physical_memory_read(RX_START(s), (uint8_t *)&d, sizeof(descriptor_t));
> +    /*desc_dump(&d, 0);*/
> +
> +    if (d.DST&  0x8000) {    /* MAC owned? */
> +
> +        uint16_t max_buffer = s->RegsW[MRBSR_W]&  0x07fc;
> +        if (tocopy>  max_buffer) {
> +            tocopy = max_buffer;
> +        }
> +
> +        cpu_physical_memory_write(d.DBP, buf, tocopy-4);
> +
> +        /* indicate received OK */
> +        d.DST |= (1<<  14);
> +        d.DLEN = tocopy;
> +        /* relinquish ownership */
> +        d.DST&= ~0x8000;
> +
> +        /* Copy the descriptor back */
> +        cpu_physical_memory_write(RX_START(s), (uint8_t *)&d,
> +                                   sizeof(descriptor_t));
> +
> +        s->RegsW[RX_PKT_COUNT_W]++;
> +
> +        s->RegsW[MISR_W] |= 1;  /* received pkt interrupt */
> +
> +        r6040_update_irq(s);
> +
> +        RX_START_SET(s, d.DNX);  /* advance */
> +
> +        return 0;
> +    }
> +    return -1;
> +}
> +
> +
> +/* called on incoming packets */
> +static ssize_t r6040_receive(VLANClientState *nc, const uint8_t *buf,
> +                                        size_t len)
> +{
> +    R6040State *s = DO_UPCAST(NICState, nc, nc)->opaque;
> +    DPRINTF("Received incoming packet of len %ld\n", len);
> +
> +    if (0 == ReceiveOnePacket(s, buf, len)) {
> +        return len;  /* copied OK */
> +    }
> +
> +    return 0;
> +}
> +
> +
> +static void r6040_cleanup(VLANClientState *vc)
> +{
> +    DPRINTF("r6040_cleanup\n");
> +}
> +
> +
> +static inline int BIT_SET(uint16_t old, uint16_t new, uint16_t bit)
> +{
> +    uint16_t before = (old&  (1<<  bit));
> +    uint16_t after = (new&  (1<<  bit));
> +    if (!before&&  after) {
> +        return 1;
> +    }
> +    return 0;
> +}
> +
> +
> +static void r6040_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
> +{
> +    R6040State *s = opaque;
> +    uint16_t old;
> +    addr&= 0xff;   /* get relative to base address */
> +    addr /= 2;    /* Get the offset into the word-array */
> +    old = s->RegsW[addr];   /* store the old value for future use */
> +
> +    switch (addr) {
> +    case MCR0_W:   /* 0x00 */
> +        if (BIT_SET(old, val, 12)) {
> +            r6040_transmit(opaque);
> +        }
> +        break;
> +    case MCR1_W:  /* 0x04 */
> +        if (val&  BIT_MRST) {   /* reset request incoming */
> +            /* reset requested, complete it immediately, set this value to
> +               default */
> +            val = 0x0010;
> +        }
> +        break;
> +    case MTPR_W:  /* TX command reg, 0x14 */
> +        if (val&  1) {
> +            r6040_transmit(opaque);
> +            val&= ~1;
> +        }
> +        break;
> +    case MMDIO_W:  /* MDIO control, 0x20 */
> +        {
> +            int phy_exists = ((val&  0x1f00) == 0x100) ? 1 : 0;
> +            uint16_t *phy = s->phy_regs;
> +            phy += (val&  0x1f);
> +
> +            if  (val&  (1<<  13)) {   /* read data */
> +                if (phy_exists) {
> +                    s->RegsW[MDIO_READ_W] = *phy;
> +                } else {
> +                    s->RegsW[MDIO_READ_W] = 0xffff;
> +                }
> +            } else if (val&  (1<<  14)) {  /* write data */
> +                if (phy_exists) {
> +                    *phy = s->RegsW[MDIO_WRITE_W];
> +                }
> +            }
> +
> +            /* Whether you request to read or write, both bits go high while
> +               the operation is in progress, e.g. tell it to read, and the
> +               write-in-progress flag also goes high */
> +            val |= 0x6000;  /* signal operation has started */
> +            s->phy_op_in_progress = 1;
> +
> +            break;
> +        }
> +    case MISR_W:  /* interrupt status reg (read to clear), 0x3c */
> +        return;
> +
> +    case MIER_W:  /* interrupt enable register, 0x40 */
> +        s->RegsW[MIER_W] = val;
> +        r6040_update_irq(s);
> +        return;
> +
> +    case MRCNT_W:   /* 0x50 */
> +    case MTCNT_W:   /* 0x5c */
> +        return;  /* Can't write to pkt count registers, skip */
> +
> +    }
> +    s->RegsW[addr] = val&  0xFFFF;
> +}
> +
> +
> +
> +static uint32_t r6040_ioport_readw(void *opaque, uint32_t addr)
> +{
> +    R6040State *s = opaque;
> +    addr&= 0xff;   /* get relative to base address */
> +    addr /= 2;    /* Get the offset into the word-array */
> +    uint32_t tmp = s->RegsW[addr];  /* get the value */
> +
> +    switch (addr) {
> +
> +    case MMDIO_W:  /* MDIO control, 0x20 */
> +        {
> +            /* Clear any in-progress MDIO activity for the next read
> +               This simulates the polling of the MDIO operation status,
> +               so the driver code always has to read the register twice
> +               before it thinks the operation is complete. */
> +            if (s->phy_op_in_progress) {
> +                s->RegsW[addr]&= ~0x6000;
> +                s->phy_op_in_progress = 0;
> +            }
> +            break;
> +        }
> +    case MISR_W:  /* interrupt status reg (read to clear)  0x3c */
> +        s->RegsW[addr] = 0;
> +        break;
> +    case MIER_W:  /* interrupt enable reg 0x40 */
> +        break;
> +    case MRCNT_W:  /* 0x50 */
> +    case MTCNT_W:  /* 0x5c */
> +        s->RegsW[addr] = 0;   /* read to clear */
> +        break;
> +    default:
> +        break;
> +    }
> +    return tmp;
> +}
> +
> +
> +/* byte and long access are routed via the word operation handlers */
> +static void r6040_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
> +{
> +    R6040State *s = opaque;
> +    addr&= 0xFF;
> +    val&= 0xFF;
> +    uint16_t old = s->RegsW[addr/2];  /* get the current value */
> +    if (addr&  1) {
> +        old&= 0xff;
> +        old |= (val<<  8);
> +    } else {
> +        old&= 0xff00;
> +        old |= val;
> +    }
> +
> +    r6040_ioport_writew(opaque, addr, old);  /* call the word-based version */
> +}
> +
> +static void r6040_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
> +{
> +    /* Set the low value */
> +    r6040_ioport_writew(opaque, addr, val&  0xffff);
> +    /* Set the high value */
> +    r6040_ioport_writew(opaque, addr+2, (val>>  16)&  0xffff);
> +}
> +
> +static uint32_t r6040_ioport_readb(void *opaque, uint32_t addr)
> +{
> +    uint32_t tmp = r6040_ioport_readw(opaque, addr&  ~1);
> +    if (addr&  1) {
> +        return (tmp&  0xff00)>>  8;
> +    }
> +    return tmp&  0xff;
> +}
> +
> +static uint32_t r6040_ioport_readl(void *opaque, uint32_t addr)
> +{
> +    uint32_t tmp = r6040_ioport_readw(opaque, addr);
> +    return tmp | (r6040_ioport_readw(opaque, addr+2)<<  16);
> +}
> +
> +
> +static void r6040_register_ioports(R6040State *s, pcibus_t addr)
> +{
> +    register_ioport_write(addr, 0x100, 1, r6040_ioport_writeb, s);
> +    register_ioport_read(addr, 0x100, 1, r6040_ioport_readb,  s);
> +
> +    register_ioport_write(addr, 0x100, 2, r6040_ioport_writew, s);
> +    register_ioport_read(addr, 0x100, 2, r6040_ioport_readw,  s);
> +
> +    register_ioport_write(addr, 0x100, 4, r6040_ioport_writel, s);
> +    register_ioport_read(addr, 0x100, 4, r6040_ioport_readl,  s);
> +}
> +
> +
> +static void r6040_map(PCIDevice *pci_dev, int region_num,
> +                       pcibus_t addr, pcibus_t size, int type)
> +{
> +    R6040State *s = DO_UPCAST(R6040State, dev, pci_dev);;
> +
> +    DPRINTF("## Mapping to address %lx\n", addr);
> +    r6040_register_ioports(s, addr);
> +}
> +
> +
> +static NetClientInfo net_r6040_info = {
> +    .type = NET_CLIENT_TYPE_NIC,
> +    .size = sizeof(NICState),
> +    .can_receive = r6040_can_receive,
> +    .receive = r6040_receive,
> +    .cleanup = r6040_cleanup,
> +};
> +
> +
> +static int r6040_init_pci(PCIDevice *dev)
> +{
> +    QEMUTimer *timer;
> +
> +    R6040State *s = DO_UPCAST(R6040State, dev, dev);
> +    uint8_t *pci_conf;
> +
> +    /* MAC PHYS status change register.  Linux driver expects something
> +       sensible as default and if not will try to set it */
> +    s->RegsW[MPSCCR_W] = 0x9f07;
> +
> +    /* Default value for maximum packet size */
> +    s->RegsW[MRBSR_W] = 0x600;
> +
> +    /* set the MAC, linux driver reads this when it loads, it is
> +       normally set by the BIOS, but obviously Qemu BIOS isn't going
> +       to do that */
> +    s->RegsW[MAC0_W] = 0x5452;
> +    s->RegsW[MAC1_W] = 0x1200;
> +    s->RegsW[MAC2_W] = 0x5734;
> +
> +    /* Tell Qemu the same thing */
> +    s->conf.macaddr.a[0] = s->RegsW[MAC0_W]&  0xff;
> +    s->conf.macaddr.a[1] = (s->RegsW[MAC0_W]>>  8)&  0xff;
> +    s->conf.macaddr.a[2] = s->RegsW[MAC1_W]&  0xff;
> +    s->conf.macaddr.a[3] = (s->RegsW[MAC1_W]>>  8)&  0xff;
> +    s->conf.macaddr.a[4] = s->RegsW[MAC2_W]&  0xff;
> +    s->conf.macaddr.a[5] = (s->RegsW[MAC2_W]>>  8)&  0xff;
> +
> +    /* no commands running */
> +    s->phy_op_in_progress = 0;
> +
> +    /* PHY auto-neg in progress */
> +    s->phy_regs[1] = 0x786d&  ~(1<<  2);
> +    s->phy_regs[2] = 0x0243;
> +    s->phy_regs[3] = 0x0c54;
> +
> +    pci_conf = (uint8_t *)s->dev.config;
> +
> +    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; /* header_type */
> +    pci_conf[PCI_INTERRUPT_LINE] = 0xa;     /* interrupt line  */
> +    pci_conf[PCI_INTERRUPT_PIN] = 1;      /* interrupt pin 0 */
> +
> +    pci_register_bar(&s->dev, 0, 0x100, PCI_BASE_ADDRESS_SPACE_IO, r6040_map);
> +
> +    s->nic = qemu_new_nic(&net_r6040_info,&s->conf,
> +                            dev->qdev.info->name, dev->qdev.id, s);
> +
> +    qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
> +
> +    /* Simulate a delay of a couple of seconds for the link to come up.
> +       Not required for Linux but very handy for developing BIOS code.
> +     */
> +    timer = qemu_new_timer_ns(vm_clock, PhysicalLinkUp, s);
> +    qemu_mod_timer(timer, qemu_get_clock_ms(vm_clock) + 1500000000);
> +
> +    /* Register IO port access as well */
> +    r6040_register_ioports(s, 0xe800);
> +
> +    return 0;
> +}
> +
> +
> +static PCIDeviceInfo r6040_info = {
> +    .qdev.name = "r6040",
> +    .qdev.size = sizeof(R6040State),
> +    .qdev.vmsd  =&vmstate_r6040,
> +    .init      = r6040_init_pci,
> +    .vendor_id = 0x17f3,  /* RDC */
> +    .device_id = 0x6040,   /* r6040 nic */
> +    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
> +    .qdev.props = (Property[]) {
> +        DEFINE_NIC_PROPERTIES(R6040State, conf),
> +        DEFINE_PROP_END_OF_LIST(),
> +    }
> +};
> +
> +
> +static void r6040_register(void)
> +{
> +    pci_qdev_register(&r6040_info);
> +}
> +
> +
> +device_init(r6040_register)
>
>

  reply	other threads:[~2011-08-31  1:17 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-31  1:05 [Qemu-devel] [PATCH] Add support for r6040 NIC bifferos
2011-08-31  1:17 ` Anthony Liguori [this message]
2011-08-31  1:30   ` malc
2011-08-31  1:59     ` Anthony Liguori
2011-08-31 13:17       ` malc
2011-08-31 13:30         ` Anthony Liguori
2011-08-31 13:39           ` malc
2011-08-31 13:40             ` Anthony Liguori
2011-08-31 13:51               ` malc
2011-08-31 14:29                 ` Anthony Liguori
2011-08-31 14:35                   ` malc
2011-08-31 16:06                     ` Anthony Liguori
2011-08-31 16:24                       ` malc
2011-08-31 18:35                         ` Blue Swirl
2011-08-31 18:37                           ` malc
2011-08-31 17:59                       ` Edgar E. Iglesias
2011-08-31 18:46                         ` Blue Swirl
2011-08-31 18:58                           ` Edgar E. Iglesias
2011-08-31 18:48                         ` Anthony Liguori
2011-08-31 19:12                           ` Edgar E. Iglesias
2011-08-31 19:18                             ` Edgar E. Iglesias
2011-08-31 19:23                             ` Anthony Liguori
2011-08-31 19:52                               ` Blue Swirl
2011-08-31 18:30                       ` Blue Swirl
2011-08-31 21:23                         ` bifferos
2011-09-01  7:39                         ` Markus Armbruster
2011-09-01 21:49                           ` Anthony Liguori
2011-09-03  9:44                             ` Blue Swirl
2011-09-01 10:42                       ` Gerd Hoffmann
2011-08-31 13:35         ` bifferos
2011-08-31 20:03     ` [Qemu-devel] [PATCH v2] " bifferos
2011-09-01  8:43 ` [Qemu-devel] [PATCH] " Avi Kivity
2011-09-01 20:02   ` bifferos

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E5D8BAA.9010302@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=bifferos@yahoo.co.uk \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.