diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index 68956aeb94..80f9cd56d5 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -175,6 +175,8 @@ #define FTGMAC100_TXDES1_TX2FIC (1 << 30) #define FTGMAC100_TXDES1_TXIC (1 << 31) +#define FTGMAC100_TXDES2_TXBUF_BADR_HI(x) (((x) >> 16) & 0x7) + /* * Receive descriptor */ @@ -208,13 +210,15 @@ #define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26) #define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27) +#define FTGMAC100_RXDES2_RXBUF_BADR_HI(x) (((x) >> 16) & 0x7) + /* * Receive and transmit Buffer Descriptor */ typedef struct { uint32_t des0; uint32_t des1; - uint32_t des2; /* not used by HW */ + uint32_t des2; /* used by HW 64 bits DMA */ uint32_t des3; } FTGMAC100Desc; @@ -531,6 +535,7 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring, int frame_size = 0; uint8_t *ptr = s->frame; uint64_t addr = tx_descriptor; + uint64_t buf_addr = 0; uint32_t flags = 0; while (1) { @@ -569,7 +574,12 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring, len = sizeof(s->frame) - frame_size; } - if (dma_memory_read(&address_space_memory, bd.des3, + buf_addr = bd.des3; + if (s->dma64) { + buf_addr = deposit64(buf_addr, 32, 32, + FTGMAC100_TXDES2_TXBUF_BADR_HI(bd.des2)); + } + if (dma_memory_read(&address_space_memory, buf_addr, ptr, len, MEMTXATTRS_UNSPECIFIED)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read packet @ 0x%x\n", __func__, bd.des3); @@ -1022,7 +1032,7 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, uint32_t flags = 0; uint64_t addr; uint32_t crc; - uint32_t buf_addr; + uint64_t buf_addr = 0; uint8_t *crc_ptr; uint32_t buf_len; size_t size = len; @@ -1087,7 +1097,12 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf, if (size < 4) { buf_len += size - 4; } + buf_addr = bd.des3; + if (s->dma64) { + buf_addr = deposit64(buf_addr, 32, 32, + FTGMAC100_RXDES2_RXBUF_BADR_HI(bd.des2)); + } if (first && proto == ETH_P_VLAN && buf_len >= 18) { bd.des1 = lduw_be_p(buf + 14) | FTGMAC100_RXDES1_VLANTAG_AVAIL;