mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
e1000: Mask out lower bits of RDBAL/TDBAL
Rx and Tx descriptors are 16 byte aligned, so the lower bits are ignored by real hardware. In fact, they always read back as zero on real hardware, but probably nobody relies on that. Signed-off-by: Kevin Wolf <mail@kevin-wolf.de> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
425189a8ff
commit
d17161f6cc
1 changed files with 18 additions and 3 deletions
21
hw/e1000.c
21
hw/e1000.c
|
@ -517,6 +517,14 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
|
||||||
return E1000_ICR_TXDW;
|
return E1000_ICR_TXDW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t tx_desc_base(E1000State *s)
|
||||||
|
{
|
||||||
|
uint64_t bah = s->mac_reg[TDBAH];
|
||||||
|
uint64_t bal = s->mac_reg[TDBAL] & ~0xf;
|
||||||
|
|
||||||
|
return (bah << 32) + bal;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
start_xmit(E1000State *s)
|
start_xmit(E1000State *s)
|
||||||
{
|
{
|
||||||
|
@ -530,7 +538,7 @@ start_xmit(E1000State *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
|
while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
|
||||||
base = ((uint64_t)s->mac_reg[TDBAH] << 32) + s->mac_reg[TDBAL] +
|
base = tx_desc_base(s) +
|
||||||
sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
|
sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
|
||||||
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
|
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
|
||||||
|
|
||||||
|
@ -651,6 +659,14 @@ e1000_can_receive(VLANClientState *nc)
|
||||||
return (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1);
|
return (s->mac_reg[RCTL] & E1000_RCTL_EN) && e1000_has_rxbufs(s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t rx_desc_base(E1000State *s)
|
||||||
|
{
|
||||||
|
uint64_t bah = s->mac_reg[RDBAH];
|
||||||
|
uint64_t bal = s->mac_reg[RDBAL] & ~0xf;
|
||||||
|
|
||||||
|
return (bah << 32) + bal;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -700,8 +716,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
|
||||||
if (desc_size > s->rxbuf_size) {
|
if (desc_size > s->rxbuf_size) {
|
||||||
desc_size = s->rxbuf_size;
|
desc_size = s->rxbuf_size;
|
||||||
}
|
}
|
||||||
base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +
|
base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];
|
||||||
sizeof(desc) * s->mac_reg[RDH];
|
|
||||||
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
|
cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
|
||||||
desc.special = vlan_special;
|
desc.special = vlan_special;
|
||||||
desc.status |= (vlan_status | E1000_RXD_STAT_DD);
|
desc.status |= (vlan_status | E1000_RXD_STAT_DD);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue