* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw/hw.h"
-#include "hw/pci/pci.h"
-#include "net/net.h"
+
+#include "qemu/osdep.h"
+#include "net/eth.h"
+#include "qemu/module.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
#include "ne2000.h"
-#include "hw/loader.h"
#include "sysemu/sysemu.h"
+#include "trace.h"
/* debug NE2000 card */
//#define DEBUG_NE2000
#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
-typedef struct PCINE2000State {
- PCIDevice dev;
- NE2000State ne2000;
-} PCINE2000State;
-
void ne2000_reset(NE2000State *s)
{
int i;
isr = (s->isr & s->imr) & 0x7f;
#if defined(DEBUG_NE2000)
printf("NE2000: Set IRQ to %d (%02x %02x)\n",
- isr ? 1 : 0, s->isr, s->imr);
+ isr ? 1 : 0, s->isr, s->imr);
#endif
qemu_set_irq(s->irq, (isr != 0));
}
{
int avail, index, boundary;
+ if (s->stop <= s->start) {
+ return 1;
+ }
+
index = s->curpag << 8;
boundary = s->boundary << 8;
if (index < boundary)
ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
{
NE2000State *s = qemu_get_nic_opaque(nc);
- int size = size_;
+ size_t size = size_;
uint8_t *p;
unsigned int total_len, next, avail, len, index, mcast_idx;
uint8_t buf1[60];
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#if defined(DEBUG_NE2000)
- printf("NE2000: received len=%d\n", size);
+ printf("NE2000: received len=%zu\n", size);
#endif
if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
/* multicast */
if (!(s->rxcr & 0x08))
return size;
- mcast_idx = compute_mcast_idx(buf);
+ mcast_idx = net_crc32(buf, ETH_ALEN) >> 26;
if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
return size;
} else if (s->mem[0] == buf[0] &&
int offset, page, index;
addr &= 0xf;
-#ifdef DEBUG_NE2000
- printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
+ trace_ne2000_ioport_write(addr, val);
if (addr == E8390_CMD) {
/* control register */
s->cmd = val;
case EN0_ISR:
ret = s->isr;
break;
- case EN0_RSARLO:
- ret = s->rsar & 0x00ff;
- break;
- case EN0_RSARHI:
- ret = s->rsar >> 8;
- break;
+ case EN0_RSARLO:
+ ret = s->rsar & 0x00ff;
+ break;
+ case EN0_RSARHI:
+ ret = s->rsar >> 8;
+ break;
case EN1_PHYS ... EN1_PHYS + 5:
ret = s->phys[offset - EN1_PHYS];
break;
case EN2_STOPPG:
ret = s->stop >> 8;
break;
- case EN0_RTL8029ID0:
- ret = 0x50;
- break;
- case EN0_RTL8029ID1:
- ret = 0x43;
- break;
- case EN3_CONFIG0:
- ret = 0; /* 10baseT media */
- break;
- case EN3_CONFIG2:
- ret = 0x40; /* 10baseT active */
- break;
- case EN3_CONFIG3:
- ret = 0x40; /* Full duplex */
- break;
+ case EN0_RTL8029ID0:
+ ret = 0x50;
+ break;
+ case EN0_RTL8029ID1:
+ ret = 0x43;
+ break;
+ case EN3_CONFIG0:
+ ret = 0; /* 10baseT media */
+ break;
+ case EN3_CONFIG2:
+ ret = 0x40; /* 10baseT active */
+ break;
+ case EN3_CONFIG3:
+ ret = 0x40; /* Full duplex */
+ break;
default:
ret = 0x00;
break;
}
}
-#ifdef DEBUG_NE2000
- printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
-#endif
+ trace_ne2000_ioport_read(addr, ret);
return ret;
}
}
};
-static const VMStateDescription vmstate_pci_ne2000 = {
- .name = "ne2000",
- .version_id = 3,
- .minimum_version_id = 3,
- .fields = (VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, PCINE2000State),
- VMSTATE_STRUCT(ne2000, PCINE2000State, 0, vmstate_ne2000, NE2000State),
- VMSTATE_END_OF_LIST()
- }
-};
-
static uint64_t ne2000_read(void *opaque, hwaddr addr,
unsigned size)
{
NE2000State *s = opaque;
+ uint64_t val;
if (addr < 0x10 && size == 1) {
- return ne2000_ioport_read(s, addr);
+ val = ne2000_ioport_read(s, addr);
} else if (addr == 0x10) {
if (size <= 2) {
- return ne2000_asic_ioport_read(s, addr);
+ val = ne2000_asic_ioport_read(s, addr);
} else {
- return ne2000_asic_ioport_readl(s, addr);
+ val = ne2000_asic_ioport_readl(s, addr);
}
} else if (addr == 0x1f && size == 1) {
- return ne2000_reset_ioport_read(s, addr);
+ val = ne2000_reset_ioport_read(s, addr);
+ } else {
+ val = ((uint64_t)1 << (size * 8)) - 1;
}
- return ((uint64_t)1 << (size * 8)) - 1;
+ trace_ne2000_read(addr, val);
+
+ return val;
}
static void ne2000_write(void *opaque, hwaddr addr,
{
NE2000State *s = opaque;
+ trace_ne2000_write(addr, data);
if (addr < 0x10 && size == 1) {
ne2000_ioport_write(s, addr, data);
} else if (addr == 0x10) {
{
memory_region_init_io(&s->io, OBJECT(dev), &ne2000_ops, s, "ne2000", size);
}
-
-static NetClientInfo net_ne2000_info = {
- .type = NET_CLIENT_OPTIONS_KIND_NIC,
- .size = sizeof(NICState),
- .receive = ne2000_receive,
-};
-
-static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
-{
- PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
- NE2000State *s;
- uint8_t *pci_conf;
-
- pci_conf = d->dev.config;
- pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
-
- s = &d->ne2000;
- ne2000_setup_io(s, DEVICE(pci_dev), 0x100);
- pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
- s->irq = pci_allocate_irq(&d->dev);
-
- qemu_macaddr_default_if_unset(&s->c.macaddr);
- ne2000_reset(s);
-
- s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
- object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
- qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
-}
-
-static void pci_ne2000_exit(PCIDevice *pci_dev)
-{
- PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
- NE2000State *s = &d->ne2000;
-
- qemu_del_nic(s->nic);
- qemu_free_irq(s->irq);
-}
-
-static void ne2000_instance_init(Object *obj)
-{
- PCIDevice *pci_dev = PCI_DEVICE(obj);
- PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
- NE2000State *s = &d->ne2000;
-
- device_add_bootindex_property(obj, &s->c.bootindex,
- "bootindex", "/ethernet-phy@0",
- &pci_dev->qdev, NULL);
-}
-
-static Property ne2000_properties[] = {
- DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void ne2000_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->realize = pci_ne2000_realize;
- k->exit = pci_ne2000_exit;
- k->romfile = "efi-ne2k_pci.rom",
- k->vendor_id = PCI_VENDOR_ID_REALTEK;
- k->device_id = PCI_DEVICE_ID_REALTEK_8029;
- k->class_id = PCI_CLASS_NETWORK_ETHERNET;
- dc->vmsd = &vmstate_pci_ne2000;
- dc->props = ne2000_properties;
- set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
-}
-
-static const TypeInfo ne2000_info = {
- .name = "ne2k_pci",
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(PCINE2000State),
- .class_init = ne2000_class_init,
- .instance_init = ne2000_instance_init,
-};
-
-static void ne2000_register_types(void)
-{
- type_register_static(&ne2000_info);
-}
-
-type_init(ne2000_register_types)