#include <zlib.h>
#include "hw.h"
-#include "pci.h"
+#include "pci/pci.h"
#include "dma.h"
#include "qemu-timer.h"
#include "net.h"
PCIErr = 0x8000,
PCSTimeout = 0x4000,
RxFIFOOver = 0x40,
- RxUnderrun = 0x20,
+ RxUnderrun = 0x20, /* Packet Underrun / Link Change */
RxOverflow = 0x10,
TxErr = 0x08,
TxOK = 0x04,
#define MIN_BUF_SIZE 60
static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
{
-#if TARGET_PHYS_ADDR_BITS > 32
- return low | ((target_phys_addr_t)high << 32);
-#else
- return low;
-#endif
+ return low | ((uint64_t)high << 32);
}
/* Workaround for buggy guest driver such as linux who allocates rx
return !(s->RxRingAddrLO == 0 && s->RxRingAddrHI == 0);
}
-static int rtl8139_can_receive(VLANClientState *nc)
+static int rtl8139_can_receive(NetClientState *nc)
{
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
int avail;
}
}
-static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
+static ssize_t rtl8139_do_receive(NetClientState *nc, const uint8_t *buf, size_t size_, int do_interrupt)
{
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
/* size is the length of the buffer passed to the driver */
return size_;
}
-static ssize_t rtl8139_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
+static ssize_t rtl8139_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
return rtl8139_do_receive(nc, buf, size, 1);
}
if (descriptor == 0 && (val & 0x8))
{
- target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]);
+ hwaddr tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]);
/* dump tally counters to specified memory location */
RTL8139TallyCounters_dma_write(s, tc_addr);
break;
case MediaStatus:
- ret = 0xd0;
+ /* The LinkDown bit of MediaStatus is inverse with link status */
+ ret = 0xd0 | (~s->BasicModeStatus & 0x04);
DPRINTF("MediaStatus read 0x%x\n", ret);
break;
/* */
-static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void rtl8139_mmio_writeb(void *opaque, hwaddr addr, uint32_t val)
{
rtl8139_io_writeb(opaque, addr & 0xFF, val);
}
-static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+static void rtl8139_mmio_writew(void *opaque, hwaddr addr, uint32_t val)
{
rtl8139_io_writew(opaque, addr & 0xFF, val);
}
-static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
+static void rtl8139_mmio_writel(void *opaque, hwaddr addr, uint32_t val)
{
rtl8139_io_writel(opaque, addr & 0xFF, val);
}
-static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr)
+static uint32_t rtl8139_mmio_readb(void *opaque, hwaddr addr)
{
return rtl8139_io_readb(opaque, addr & 0xFF);
}
-static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr)
-{
- return rtl8139_io_readw(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr)
-{
- return rtl8139_io_readl(opaque, addr & 0xFF);
-}
-
-/* */
-
-static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writeb(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writew(opaque, addr & 0xFF, val);
-}
-
-static void rtl8139_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- rtl8139_io_writel(opaque, addr & 0xFF, val);
-}
-
-static uint32_t rtl8139_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- return rtl8139_io_readb(opaque, addr & 0xFF);
-}
-
-static uint32_t rtl8139_mmio_readw(void *opaque, target_phys_addr_t addr)
+static uint32_t rtl8139_mmio_readw(void *opaque, hwaddr addr)
{
uint32_t val = rtl8139_io_readw(opaque, addr & 0xFF);
return val;
}
-static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint32_t rtl8139_mmio_readl(void *opaque, hwaddr addr)
{
uint32_t val = rtl8139_io_readl(opaque, addr & 0xFF);
return val;
s->cplus_enabled = s->CpCmd != 0;
}
+ /* nc.link_down can't be migrated, so infer link_down according
+ * to link status bit in BasicModeStatus */
+ s->nic->nc.link_down = (s->BasicModeStatus & 0x04) == 0;
+
return 0;
}
/***********************************************************/
/* PCI RTL8139 definitions */
-static const MemoryRegionPortio rtl8139_portio[] = {
- { 0, 0x100, 1, .read = rtl8139_ioport_readb, },
- { 0, 0x100, 1, .write = rtl8139_ioport_writeb, },
- { 0, 0x100, 2, .read = rtl8139_ioport_readw, },
- { 0, 0x100, 2, .write = rtl8139_ioport_writew, },
- { 0, 0x100, 4, .read = rtl8139_ioport_readl, },
- { 0, 0x100, 4, .write = rtl8139_ioport_writel, },
- PORTIO_END_OF_LIST()
-};
+static void rtl8139_ioport_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ switch (size) {
+ case 1:
+ rtl8139_io_writeb(opaque, addr, val);
+ break;
+ case 2:
+ rtl8139_io_writew(opaque, addr, val);
+ break;
+ case 4:
+ rtl8139_io_writel(opaque, addr, val);
+ break;
+ }
+}
+
+static uint64_t rtl8139_ioport_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ switch (size) {
+ case 1:
+ return rtl8139_io_readb(opaque, addr);
+ case 2:
+ return rtl8139_io_readw(opaque, addr);
+ case 4:
+ return rtl8139_io_readl(opaque, addr);
+ }
+
+ return -1;
+}
static const MemoryRegionOps rtl8139_io_ops = {
- .old_portio = rtl8139_portio,
+ .read = rtl8139_ioport_read,
+ .write = rtl8139_ioport_write,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 4,
+ },
.endianness = DEVICE_LITTLE_ENDIAN,
};
rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
}
-static void rtl8139_cleanup(VLANClientState *nc)
+static void rtl8139_cleanup(NetClientState *nc)
{
RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
}
qemu_del_timer(s->timer);
qemu_free_timer(s->timer);
- qemu_del_vlan_client(&s->nic->nc);
+ qemu_del_net_client(&s->nic->nc);
+}
+
+static void rtl8139_set_link_status(NetClientState *nc)
+{
+ RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+ if (nc->link_down) {
+ s->BasicModeStatus &= ~0x04;
+ } else {
+ s->BasicModeStatus |= 0x04;
+ }
+
+ s->IntrStatus |= RxUnderrun;
+ rtl8139_update_irq(s);
}
static NetClientInfo net_rtl8139_info = {
.can_receive = rtl8139_can_receive,
.receive = rtl8139_receive,
.cleanup = rtl8139_cleanup,
+ .link_status_changed = rtl8139_set_link_status,
};
static int pci_rtl8139_init(PCIDevice *dev)