summaryrefslogtreecommitdiffstats
path: root/hw/net/cadence_gem.c
diff options
context:
space:
mode:
authorPeter Maydell2017-04-20 18:41:34 +0200
committerPeter Maydell2017-04-20 18:41:34 +0200
commitda92ada855036c55bd08b0b0c64c7551d56f3586 (patch)
treec8364bf860d9eb2378cfa9c74bdfc2ed059c2ab7 /hw/net/cadence_gem.c
parentOpen 2.10 development tree (diff)
parentarm: Remove workarounds for old M-profile exception return implementation (diff)
downloadqemu-da92ada855036c55bd08b0b0c64c7551d56f3586.tar.gz
qemu-da92ada855036c55bd08b0b0c64c7551d56f3586.tar.xz
qemu-da92ada855036c55bd08b0b0c64c7551d56f3586.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170420' into staging
target-arm queue: * implement M profile exception return properly * cadence GEM: fix multiqueue handling bugs * pxa2xx.c: QOMify a device * arm/kvm: Remove trailing newlines from error_report() * stellaris: Don't hw_error() on bad register accesses * Add assertion about FSC format for syndrome registers * Move excnames[] array into arm_log_exceptions() * exynos: minor code cleanups * hw/arm/boot: take Linux/arm64 TEXT_OFFSET header field into account * Fix APSR writes via M profile MSR # gpg: Signature made Thu 20 Apr 2017 17:39:35 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170420: (24 commits) arm: Remove workarounds for old M-profile exception return implementation arm: Implement M profile exception return properly arm: Track M profile handler mode state in TB flags arm: Abstract out "are we singlestepping" test to utility function arm: Move condition-failed codepath generation out of if() arm: Move gen_set_condexec() and gen_set_pc_im() up in the file arm: Factor out "generate right kind of step exception" arm: Thumb shift operations should not permit interworking branches arm: Don't implement BXJ on M-profile CPUs xlnx-zynqmp: Set the Cadence GEM revision cadence_gem: Make the revision a property cadence_gem: Correct the interupt logic cadence_gem: Correct the multi-queue can rx logic cadence_gem: Read the correct queue descriptor hw/arm: Qomify pxa2xx.c arm/kvm: Remove trailing newlines from error_report() stellaris: Don't hw_error() on bad register accesses target/arm: Add assertion about FSC format for syndrome registers arm: Move excnames[] array into arm_log_exceptions() target/arm: Add missing entries to excnames[] for log strings ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/net/cadence_gem.c')
-rw-r--r--hw/net/cadence_gem.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index d4de8ad9f1..3943187572 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -300,6 +300,8 @@
#define DESC_1_RX_SOF 0x00004000
#define DESC_1_RX_EOF 0x00008000
+#define GEM_MODID_VALUE 0x00020118
+
static inline unsigned tx_desc_get_buffer(unsigned *desc)
{
return desc[0];
@@ -481,14 +483,17 @@ static int gem_can_receive(NetClientState *nc)
}
for (i = 0; i < s->num_priority_queues; i++) {
- if (rx_desc_get_ownership(s->rx_desc[i]) == 1) {
- if (s->can_rx_state != 2) {
- s->can_rx_state = 2;
- DB_PRINT("can't receive - busy buffer descriptor (q%d) 0x%x\n",
- i, s->rx_desc_addr[i]);
- }
- return 0;
+ if (rx_desc_get_ownership(s->rx_desc[i]) != 1) {
+ break;
+ }
+ };
+
+ if (i == s->num_priority_queues) {
+ if (s->can_rx_state != 2) {
+ s->can_rx_state = 2;
+ DB_PRINT("can't receive - all the buffer descriptors are busy\n");
}
+ return 0;
}
if (s->can_rx_state != 0) {
@@ -506,7 +511,18 @@ static void gem_update_int_status(CadenceGEMState *s)
{
int i;
- if ((s->num_priority_queues == 1) && s->regs[GEM_ISR]) {
+ if (!s->regs[GEM_ISR]) {
+ /* ISR isn't set, clear all the interrupts */
+ for (i = 0; i < s->num_priority_queues; ++i) {
+ qemu_set_irq(s->irq[i], 0);
+ }
+ return;
+ }
+
+ /* If we get here we know s->regs[GEM_ISR] is set, so we don't need to
+ * check it again.
+ */
+ if (s->num_priority_queues == 1) {
/* No priority queues, just trigger the interrupt */
DB_PRINT("asserting int.\n");
qemu_set_irq(s->irq[0], 1);
@@ -790,8 +806,8 @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
{
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
/* read current descriptor */
- cpu_physical_memory_read(s->rx_desc_addr[0],
- (uint8_t *)s->rx_desc[0], sizeof(s->rx_desc[0]));
+ cpu_physical_memory_read(s->rx_desc_addr[q],
+ (uint8_t *)s->rx_desc[q], sizeof(s->rx_desc[q]));
/* Descriptor owned by software ? */
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
@@ -1209,7 +1225,7 @@ static void gem_reset(DeviceState *d)
s->regs[GEM_TXPAUSE] = 0x0000ffff;
s->regs[GEM_TXPARTIALSF] = 0x000003ff;
s->regs[GEM_RXPARTIALSF] = 0x000003ff;
- s->regs[GEM_MODID] = 0x00020118;
+ s->regs[GEM_MODID] = s->revision;
s->regs[GEM_DESCONF] = 0x02500111;
s->regs[GEM_DESCONF2] = 0x2ab13fff;
s->regs[GEM_DESCONF5] = 0x002f2145;
@@ -1271,7 +1287,6 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
{
CadenceGEMState *s;
uint32_t retval;
- int i;
s = (CadenceGEMState *)opaque;
offset >>= 2;
@@ -1282,9 +1297,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
switch (offset) {
case GEM_ISR:
DB_PRINT("lowering irqs on ISR read\n");
- for (i = 0; i < s->num_priority_queues; ++i) {
- qemu_set_irq(s->irq[i], 0);
- }
+ /* The interrupts get updated at the end of the function. */
break;
case GEM_PHYMNTNC:
if (retval & GEM_PHYMNTNC_OP_R) {
@@ -1508,6 +1521,8 @@ static const VMStateDescription vmstate_cadence_gem = {
static Property gem_properties[] = {
DEFINE_NIC_PROPERTIES(CadenceGEMState, conf),
+ DEFINE_PROP_UINT32("revision", CadenceGEMState, revision,
+ GEM_MODID_VALUE),
DEFINE_PROP_UINT8("num-priority-queues", CadenceGEMState,
num_priority_queues, 1),
DEFINE_PROP_UINT8("num-type1-screeners", CadenceGEMState,