Revision 3ada003a hw/rtl8139.c
b/hw/rtl8139.c | ||
---|---|---|
53 | 53 |
|
54 | 54 |
#include "hw.h" |
55 | 55 |
#include "pci.h" |
56 |
#include "dma.h" |
|
56 | 57 |
#include "qemu-timer.h" |
57 | 58 |
#include "net.h" |
58 | 59 |
#include "loader.h" |
... | ... | |
427 | 428 |
/* Clears all tally counters */ |
428 | 429 |
static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); |
429 | 430 |
|
430 |
/* Writes tally counters to specified physical memory address */ |
|
431 |
static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters); |
|
432 |
|
|
433 | 431 |
typedef struct RTL8139State { |
434 | 432 |
PCIDevice dev; |
435 | 433 |
uint8_t phys[8]; /* mac address */ |
... | ... | |
512 | 510 |
int rtl8139_mmio_io_addr_dummy; |
513 | 511 |
} RTL8139State; |
514 | 512 |
|
513 |
/* Writes tally counters to memory via DMA */ |
|
514 |
static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr); |
|
515 |
|
|
515 | 516 |
static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time); |
516 | 517 |
|
517 | 518 |
static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) |
... | ... | |
773 | 774 |
|
774 | 775 |
if (size > wrapped) |
775 | 776 |
{ |
776 |
cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
|
|
777 |
buf, size-wrapped );
|
|
777 |
pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr,
|
|
778 |
buf, size-wrapped);
|
|
778 | 779 |
} |
779 | 780 |
|
780 | 781 |
/* reset buffer pointer */ |
781 | 782 |
s->RxBufAddr = 0; |
782 | 783 |
|
783 |
cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
|
|
784 |
buf + (size-wrapped), wrapped );
|
|
784 |
pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr,
|
|
785 |
buf + (size-wrapped), wrapped);
|
|
785 | 786 |
|
786 | 787 |
s->RxBufAddr = wrapped; |
787 | 788 |
|
... | ... | |
790 | 791 |
} |
791 | 792 |
|
792 | 793 |
/* non-wrapping path or overwrapping enabled */ |
793 |
cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );
|
|
794 |
pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, buf, size);
|
|
794 | 795 |
|
795 | 796 |
s->RxBufAddr += size; |
796 | 797 |
} |
797 | 798 |
|
798 | 799 |
#define MIN_BUF_SIZE 60 |
799 |
static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
|
|
800 |
static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
|
|
800 | 801 |
{ |
801 | 802 |
#if TARGET_PHYS_ADDR_BITS > 32 |
802 | 803 |
return low | ((target_phys_addr_t)high << 32); |
... | ... | |
979 | 980 |
/* w3 high 32bit of Rx buffer ptr */ |
980 | 981 |
|
981 | 982 |
int descriptor = s->currCPlusRxDesc; |
982 |
target_phys_addr_t cplus_rx_ring_desc;
|
|
983 |
dma_addr_t cplus_rx_ring_desc;
|
|
983 | 984 |
|
984 | 985 |
cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI); |
985 | 986 |
cplus_rx_ring_desc += 16 * descriptor; |
986 | 987 |
|
987 | 988 |
DPRINTF("+++ C+ mode reading RX descriptor %d from host memory at " |
988 |
"%08x %08x = "TARGET_FMT_plx"\n", descriptor, s->RxRingAddrHI,
|
|
989 |
"%08x %08x = "DMA_ADDR_FMT"\n", descriptor, s->RxRingAddrHI,
|
|
989 | 990 |
s->RxRingAddrLO, cplus_rx_ring_desc); |
990 | 991 |
|
991 | 992 |
uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI; |
992 | 993 |
|
993 |
cpu_physical_memory_read(cplus_rx_ring_desc, (uint8_t *)&val, 4);
|
|
994 |
pci_dma_read(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4);
|
|
994 | 995 |
rxdw0 = le32_to_cpu(val); |
995 |
cpu_physical_memory_read(cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
|
|
996 |
pci_dma_read(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
|
|
996 | 997 |
rxdw1 = le32_to_cpu(val); |
997 |
cpu_physical_memory_read(cplus_rx_ring_desc+8, (uint8_t *)&val, 4);
|
|
998 |
pci_dma_read(&s->dev, cplus_rx_ring_desc+8, (uint8_t *)&val, 4);
|
|
998 | 999 |
rxbufLO = le32_to_cpu(val); |
999 |
cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
|
|
1000 |
pci_dma_read(&s->dev, cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
|
|
1000 | 1001 |
rxbufHI = le32_to_cpu(val); |
1001 | 1002 |
|
1002 | 1003 |
DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n", |
... | ... | |
1060 | 1061 |
return size_; |
1061 | 1062 |
} |
1062 | 1063 |
|
1063 |
target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
|
|
1064 |
dma_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
|
|
1064 | 1065 |
|
1065 | 1066 |
/* receive/copy to target memory */ |
1066 | 1067 |
if (dot1q_buf) { |
1067 |
cpu_physical_memory_write(rx_addr, buf, 2 * ETHER_ADDR_LEN);
|
|
1068 |
cpu_physical_memory_write(rx_addr + 2 * ETHER_ADDR_LEN,
|
|
1069 |
buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN, |
|
1070 |
size - 2 * ETHER_ADDR_LEN); |
|
1068 |
pci_dma_write(&s->dev, rx_addr, buf, 2 * ETHER_ADDR_LEN);
|
|
1069 |
pci_dma_write(&s->dev, rx_addr + 2 * ETHER_ADDR_LEN,
|
|
1070 |
buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN,
|
|
1071 |
size - 2 * ETHER_ADDR_LEN);
|
|
1071 | 1072 |
} else { |
1072 |
cpu_physical_memory_write(rx_addr, buf, size);
|
|
1073 |
pci_dma_write(&s->dev, rx_addr, buf, size);
|
|
1073 | 1074 |
} |
1074 | 1075 |
|
1075 | 1076 |
if (s->CpCmd & CPlusRxChkSum) |
... | ... | |
1079 | 1080 |
|
1080 | 1081 |
/* write checksum */ |
1081 | 1082 |
val = cpu_to_le32(crc32(0, buf, size_)); |
1082 |
cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);
|
|
1083 |
pci_dma_write(&s->dev, rx_addr+size, (uint8_t *)&val, 4);
|
|
1083 | 1084 |
|
1084 | 1085 |
/* first segment of received packet flag */ |
1085 | 1086 |
#define CP_RX_STATUS_FS (1<<29) |
... | ... | |
1125 | 1126 |
|
1126 | 1127 |
/* update ring data */ |
1127 | 1128 |
val = cpu_to_le32(rxdw0); |
1128 |
cpu_physical_memory_write(cplus_rx_ring_desc, (uint8_t *)&val, 4);
|
|
1129 |
pci_dma_write(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4);
|
|
1129 | 1130 |
val = cpu_to_le32(rxdw1); |
1130 |
cpu_physical_memory_write(cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
|
|
1131 |
pci_dma_write(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
|
|
1131 | 1132 |
|
1132 | 1133 |
/* update tally counter */ |
1133 | 1134 |
++s->tally_counters.RxOk; |
... | ... | |
1307 | 1308 |
counters->TxUndrn = 0; |
1308 | 1309 |
} |
1309 | 1310 |
|
1310 |
static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters)
|
|
1311 |
static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr)
|
|
1311 | 1312 |
{ |
1313 |
RTL8139TallyCounters *tally_counters = &s->tally_counters; |
|
1312 | 1314 |
uint16_t val16; |
1313 | 1315 |
uint32_t val32; |
1314 | 1316 |
uint64_t val64; |
1315 | 1317 |
|
1316 | 1318 |
val64 = cpu_to_le64(tally_counters->TxOk); |
1317 |
cpu_physical_memory_write(tc_addr + 0, (uint8_t *)&val64, 8);
|
|
1319 |
pci_dma_write(&s->dev, tc_addr + 0, (uint8_t *)&val64, 8);
|
|
1318 | 1320 |
|
1319 | 1321 |
val64 = cpu_to_le64(tally_counters->RxOk); |
1320 |
cpu_physical_memory_write(tc_addr + 8, (uint8_t *)&val64, 8);
|
|
1322 |
pci_dma_write(&s->dev, tc_addr + 8, (uint8_t *)&val64, 8);
|
|
1321 | 1323 |
|
1322 | 1324 |
val64 = cpu_to_le64(tally_counters->TxERR); |
1323 |
cpu_physical_memory_write(tc_addr + 16, (uint8_t *)&val64, 8);
|
|
1325 |
pci_dma_write(&s->dev, tc_addr + 16, (uint8_t *)&val64, 8);
|
|
1324 | 1326 |
|
1325 | 1327 |
val32 = cpu_to_le32(tally_counters->RxERR); |
1326 |
cpu_physical_memory_write(tc_addr + 24, (uint8_t *)&val32, 4);
|
|
1328 |
pci_dma_write(&s->dev, tc_addr + 24, (uint8_t *)&val32, 4);
|
|
1327 | 1329 |
|
1328 | 1330 |
val16 = cpu_to_le16(tally_counters->MissPkt); |
1329 |
cpu_physical_memory_write(tc_addr + 28, (uint8_t *)&val16, 2);
|
|
1331 |
pci_dma_write(&s->dev, tc_addr + 28, (uint8_t *)&val16, 2);
|
|
1330 | 1332 |
|
1331 | 1333 |
val16 = cpu_to_le16(tally_counters->FAE); |
1332 |
cpu_physical_memory_write(tc_addr + 30, (uint8_t *)&val16, 2);
|
|
1334 |
pci_dma_write(&s->dev, tc_addr + 30, (uint8_t *)&val16, 2);
|
|
1333 | 1335 |
|
1334 | 1336 |
val32 = cpu_to_le32(tally_counters->Tx1Col); |
1335 |
cpu_physical_memory_write(tc_addr + 32, (uint8_t *)&val32, 4);
|
|
1337 |
pci_dma_write(&s->dev, tc_addr + 32, (uint8_t *)&val32, 4);
|
|
1336 | 1338 |
|
1337 | 1339 |
val32 = cpu_to_le32(tally_counters->TxMCol); |
1338 |
cpu_physical_memory_write(tc_addr + 36, (uint8_t *)&val32, 4);
|
|
1340 |
pci_dma_write(&s->dev, tc_addr + 36, (uint8_t *)&val32, 4);
|
|
1339 | 1341 |
|
1340 | 1342 |
val64 = cpu_to_le64(tally_counters->RxOkPhy); |
1341 |
cpu_physical_memory_write(tc_addr + 40, (uint8_t *)&val64, 8);
|
|
1343 |
pci_dma_write(&s->dev, tc_addr + 40, (uint8_t *)&val64, 8);
|
|
1342 | 1344 |
|
1343 | 1345 |
val64 = cpu_to_le64(tally_counters->RxOkBrd); |
1344 |
cpu_physical_memory_write(tc_addr + 48, (uint8_t *)&val64, 8);
|
|
1346 |
pci_dma_write(&s->dev, tc_addr + 48, (uint8_t *)&val64, 8);
|
|
1345 | 1347 |
|
1346 | 1348 |
val32 = cpu_to_le32(tally_counters->RxOkMul); |
1347 |
cpu_physical_memory_write(tc_addr + 56, (uint8_t *)&val32, 4);
|
|
1349 |
pci_dma_write(&s->dev, tc_addr + 56, (uint8_t *)&val32, 4);
|
|
1348 | 1350 |
|
1349 | 1351 |
val16 = cpu_to_le16(tally_counters->TxAbt); |
1350 |
cpu_physical_memory_write(tc_addr + 60, (uint8_t *)&val16, 2);
|
|
1352 |
pci_dma_write(&s->dev, tc_addr + 60, (uint8_t *)&val16, 2);
|
|
1351 | 1353 |
|
1352 | 1354 |
val16 = cpu_to_le16(tally_counters->TxUndrn); |
1353 |
cpu_physical_memory_write(tc_addr + 62, (uint8_t *)&val16, 2);
|
|
1355 |
pci_dma_write(&s->dev, tc_addr + 62, (uint8_t *)&val16, 2);
|
|
1354 | 1356 |
} |
1355 | 1357 |
|
1356 | 1358 |
/* Loads values of tally counters from VM state file */ |
... | ... | |
1842 | 1844 |
DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n", |
1843 | 1845 |
txsize, s->TxAddr[descriptor]); |
1844 | 1846 |
|
1845 |
cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
|
|
1847 |
pci_dma_read(&s->dev, s->TxAddr[descriptor], txbuffer, txsize);
|
|
1846 | 1848 |
|
1847 | 1849 |
/* Mark descriptor as transferred */ |
1848 | 1850 |
s->TxStatus[descriptor] |= TxHostOwns; |
... | ... | |
1963 | 1965 |
|
1964 | 1966 |
int descriptor = s->currCPlusTxDesc; |
1965 | 1967 |
|
1966 |
target_phys_addr_t cplus_tx_ring_desc = |
|
1967 |
rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); |
|
1968 |
dma_addr_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]); |
|
1968 | 1969 |
|
1969 | 1970 |
/* Normal priority ring */ |
1970 | 1971 |
cplus_tx_ring_desc += 16 * descriptor; |
1971 | 1972 |
|
1972 | 1973 |
DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at " |
1973 |
"%08x0x%08x = 0x"TARGET_FMT_plx"\n", descriptor, s->TxAddr[1],
|
|
1974 |
"%08x0x%08x = 0x"DMA_ADDR_FMT"\n", descriptor, s->TxAddr[1],
|
|
1974 | 1975 |
s->TxAddr[0], cplus_tx_ring_desc); |
1975 | 1976 |
|
1976 | 1977 |
uint32_t val, txdw0,txdw1,txbufLO,txbufHI; |
1977 | 1978 |
|
1978 |
cpu_physical_memory_read(cplus_tx_ring_desc, (uint8_t *)&val, 4);
|
|
1979 |
pci_dma_read(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4);
|
|
1979 | 1980 |
txdw0 = le32_to_cpu(val); |
1980 |
cpu_physical_memory_read(cplus_tx_ring_desc+4, (uint8_t *)&val, 4);
|
|
1981 |
pci_dma_read(&s->dev, cplus_tx_ring_desc+4, (uint8_t *)&val, 4);
|
|
1981 | 1982 |
txdw1 = le32_to_cpu(val); |
1982 |
cpu_physical_memory_read(cplus_tx_ring_desc+8, (uint8_t *)&val, 4);
|
|
1983 |
pci_dma_read(&s->dev, cplus_tx_ring_desc+8, (uint8_t *)&val, 4);
|
|
1983 | 1984 |
txbufLO = le32_to_cpu(val); |
1984 |
cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
|
|
1985 |
pci_dma_read(&s->dev, cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
|
|
1985 | 1986 |
txbufHI = le32_to_cpu(val); |
1986 | 1987 |
|
1987 | 1988 |
DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor, |
... | ... | |
2047 | 2048 |
} |
2048 | 2049 |
|
2049 | 2050 |
int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK; |
2050 |
target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
|
|
2051 |
dma_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
|
|
2051 | 2052 |
|
2052 | 2053 |
/* make sure we have enough space to assemble the packet */ |
2053 | 2054 |
if (!s->cplus_txbuffer) |
... | ... | |
2086 | 2087 |
/* append more data to the packet */ |
2087 | 2088 |
|
2088 | 2089 |
DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at " |
2089 |
TARGET_FMT_plx" to offset %d\n", txsize, tx_addr,
|
|
2090 |
s->cplus_txbuffer_offset); |
|
2090 |
DMA_ADDR_FMT" to offset %d\n", txsize, tx_addr,
|
|
2091 |
s->cplus_txbuffer_offset);
|
|
2091 | 2092 |
|
2092 |
cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); |
|
2093 |
pci_dma_read(&s->dev, tx_addr, |
|
2094 |
s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize); |
|
2093 | 2095 |
s->cplus_txbuffer_offset += txsize; |
2094 | 2096 |
|
2095 | 2097 |
/* seek to next Rx descriptor */ |
... | ... | |
2116 | 2118 |
|
2117 | 2119 |
/* update ring data */ |
2118 | 2120 |
val = cpu_to_le32(txdw0); |
2119 |
cpu_physical_memory_write(cplus_tx_ring_desc, (uint8_t *)&val, 4);
|
|
2121 |
pci_dma_write(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4);
|
|
2120 | 2122 |
|
2121 | 2123 |
/* Now decide if descriptor being processed is holding the last segment of packet */ |
2122 | 2124 |
if (txdw0 & CP_TX_LS) |
... | ... | |
2475 | 2477 |
target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]); |
2476 | 2478 |
|
2477 | 2479 |
/* dump tally counters to specified memory location */ |
2478 |
RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters);
|
|
2480 |
RTL8139TallyCounters_dma_write(s, tc_addr);
|
|
2479 | 2481 |
|
2480 | 2482 |
/* mark dump completed */ |
2481 | 2483 |
s->TxStatus[0] &= ~0x8; |
Also available in: Unified diff