From nobody Tue Nov 4 23:53:48 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1531730695467904.3793331176638; Mon, 16 Jul 2018 01:44:55 -0700 (PDT) Received: from localhost ([::1]:49797 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fez7m-0006S0-GG for importer@patchew.org; Mon, 16 Jul 2018 04:44:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39998) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fez1Q-0001Dc-Rn for qemu-devel@nongnu.org; Mon, 16 Jul 2018 04:38:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fez1N-0004zE-PN for qemu-devel@nongnu.org; Mon, 16 Jul 2018 04:38:20 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:34751) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fez1M-0004sy-K7; Mon, 16 Jul 2018 04:38:17 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41TcHm5pgQz9s29; Mon, 16 Jul 2018 18:38:12 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1531730292; bh=uG+7cH1N2xLy+xVh/cvmiwVdYQb7j9s/4dliGvy75G4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Nn7pDMeCWL5/0KvyAiz0FYfZpKsK/jc1wyjwsahcayO/oIYledKtXBNwI/hZW4lVc 7Hb5OHaQODxLhJC71HKLGY6+B7T3znf8MmC2X1L7E23mnBH62lb+/eVOR/kcEvbhFO bl3TpaYNMFpK7Qo4qieMHvWf27JUaRYM1qLs8BYc= From: David Gibson To: peter.maydell@linaro.org Date: Mon, 16 Jul 2018 18:38:07 +1000 Message-Id: <20180716083809.17115-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180716083809.17115-1-david@gibson.dropbear.id.au> References: <20180716083809.17115-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PULL 4/6] etsec: fix IRQ (un)masking X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michael Davidsaver , David Gibson , qemu-ppc@nongnu.org, groug@kaod.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Michael Davidsaver Interrupt conditions occurring while masked are not being signaled when later unmasked. The fix is to raise/lower IRQs when IMASK is changed. To avoid problems like this in future, consolidate IRQ pin update logic in one function. Also fix probable typo "IEVENT_TXF | IEVENT_TXF", and update IRQ pins on reset. Signed-off-by: Michael Davidsaver Reviewed-by: C=C3=A9dric Le Goater Signed-off-by: David Gibson --- hw/net/fsl_etsec/etsec.c | 68 +++++++++++++++++++----------------- hw/net/fsl_etsec/etsec.h | 2 ++ hw/net/fsl_etsec/registers.h | 10 ++++++ hw/net/fsl_etsec/rings.c | 12 +------ 4 files changed, 49 insertions(+), 43 deletions(-) diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c index 9da1932970..0b66274ce3 100644 --- a/hw/net/fsl_etsec/etsec.c +++ b/hw/net/fsl_etsec/etsec.c @@ -49,6 +49,28 @@ static const int debug_etsec; } \ } while (0) =20 +/* call after any change to IEVENT or IMASK */ +void etsec_update_irq(eTSEC *etsec) +{ + uint32_t ievent =3D etsec->regs[IEVENT].value; + uint32_t imask =3D etsec->regs[IMASK].value; + uint32_t active =3D ievent & imask; + + int tx =3D !!(active & IEVENT_TX_MASK); + int rx =3D !!(active & IEVENT_RX_MASK); + int err =3D !!(active & IEVENT_ERR_MASK); + + DPRINTF("%s IRQ ievent=3D%"PRIx32" imask=3D%"PRIx32" %c%c%c", + __func__, ievent, imask, + tx ? 'T' : '_', + rx ? 'R' : '_', + err ? 'E' : '_'); + + qemu_set_irq(etsec->tx_irq, tx); + qemu_set_irq(etsec->rx_irq, rx); + qemu_set_irq(etsec->err_irq, err); +} + static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size) { eTSEC *etsec =3D opaque; @@ -139,31 +161,6 @@ static void write_rbasex(eTSEC *etsec, etsec->regs[RBPTR0 + (reg_index - RBASE0)].value =3D value & ~0x7; } =20 -static void write_ievent(eTSEC *etsec, - eTSEC_Register *reg, - uint32_t reg_index, - uint32_t value) -{ - /* Write 1 to clear */ - reg->value &=3D ~value; - - if (!(reg->value & (IEVENT_TXF | IEVENT_TXF))) { - qemu_irq_lower(etsec->tx_irq); - } - if (!(reg->value & (IEVENT_RXF | IEVENT_RXF))) { - qemu_irq_lower(etsec->rx_irq); - } - - if (!(reg->value & (IEVENT_MAG | IEVENT_GTSC | IEVENT_GRSC | IEVENT_TX= C | - IEVENT_RXC | IEVENT_BABR | IEVENT_BABT | IEVENT_LC= | - IEVENT_CRL | IEVENT_FGPI | IEVENT_FIR | IEVENT_FIQ= | - IEVENT_DPE | IEVENT_PERR | IEVENT_EBERR | IEVENT_T= XE | - IEVENT_XFUN | IEVENT_BSY | IEVENT_MSRO | IEVENT_MM= RD | - IEVENT_MMRW))) { - qemu_irq_lower(etsec->err_irq); - } -} - static void write_dmactrl(eTSEC *etsec, eTSEC_Register *reg, uint32_t reg_index, @@ -178,9 +175,7 @@ static void write_dmactrl(eTSEC *etsec, } else { /* Graceful receive stop now */ etsec->regs[IEVENT].value |=3D IEVENT_GRSC; - if (etsec->regs[IMASK].value & IMASK_GRSCEN) { - qemu_irq_raise(etsec->err_irq); - } + etsec_update_irq(etsec); } } =20 @@ -191,9 +186,7 @@ static void write_dmactrl(eTSEC *etsec, } else { /* Graceful transmit stop now */ etsec->regs[IEVENT].value |=3D IEVENT_GTSC; - if (etsec->regs[IMASK].value & IMASK_GTSCEN) { - qemu_irq_raise(etsec->err_irq); - } + etsec_update_irq(etsec); } } =20 @@ -222,7 +215,16 @@ static void etsec_write(void *opaque, =20 switch (reg_index) { case IEVENT: - write_ievent(etsec, reg, reg_index, value); + /* Write 1 to clear */ + reg->value &=3D ~value; + + etsec_update_irq(etsec); + break; + + case IMASK: + reg->value =3D value; + + etsec_update_irq(etsec); break; =20 case DMACTRL: @@ -337,6 +339,8 @@ static void etsec_reset(DeviceState *d) MII_SR_EXTENDED_STATUS | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_C= APS | MII_SR_10T_HD_CAPS | MII_SR_10T_FD_CAPS | MII_SR_100X_HD_CA= PS | MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS; + + etsec_update_irq(etsec); } =20 static ssize_t etsec_receive(NetClientState *nc, diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h index 30c828e241..877988572e 100644 --- a/hw/net/fsl_etsec/etsec.h +++ b/hw/net/fsl_etsec/etsec.h @@ -163,6 +163,8 @@ DeviceState *etsec_create(hwaddr base, qemu_irq rx_irq, qemu_irq err_irq); =20 +void etsec_update_irq(eTSEC *etsec); + void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr); void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr); ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size); diff --git a/hw/net/fsl_etsec/registers.h b/hw/net/fsl_etsec/registers.h index c4ed2b9d62..f085537ecd 100644 --- a/hw/net/fsl_etsec/registers.h +++ b/hw/net/fsl_etsec/registers.h @@ -74,6 +74,16 @@ extern const eTSEC_Register_Definition eTSEC_registers_d= ef[]; #define IEVENT_RXC (1 << 30) #define IEVENT_BABR (1 << 31) =20 +/* Mapping between interrupt pin and interrupt flags */ +#define IEVENT_RX_MASK (IEVENT_RXF | IEVENT_RXB) +#define IEVENT_TX_MASK (IEVENT_TXF | IEVENT_TXB) +#define IEVENT_ERR_MASK (IEVENT_MAG | IEVENT_GTSC | IEVENT_GRSC | IEVENT_T= XC | \ + IEVENT_RXC | IEVENT_BABR | IEVENT_BABT | IEVENT_LC | \ + IEVENT_CRL | IEVENT_FGPI | IEVENT_FIR | IEVENT_FIQ | \ + IEVENT_DPE | IEVENT_PERR | IEVENT_EBERR | IEVENT_TXE | \ + IEVENT_XFUN | IEVENT_BSY | IEVENT_MSRO | IEVENT_MMRD | \ + IEVENT_MMRW) + #define IMASK_RXFEN (1 << 7) #define IMASK_GRSCEN (1 << 8) #define IMASK_RXBEN (1 << 15) diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c index d0f93eebfc..337a55fc95 100644 --- a/hw/net/fsl_etsec/rings.c +++ b/hw/net/fsl_etsec/rings.c @@ -152,17 +152,7 @@ static void ievent_set(eTSEC *etsec, { etsec->regs[IEVENT].value |=3D flags; =20 - if ((flags & IEVENT_TXB && etsec->regs[IMASK].value & IMASK_TXBEN) - || (flags & IEVENT_TXF && etsec->regs[IMASK].value & IMASK_TXFEN))= { - qemu_irq_raise(etsec->tx_irq); - RING_DEBUG("%s Raise Tx IRQ\n", __func__); - } - - if ((flags & IEVENT_RXB && etsec->regs[IMASK].value & IMASK_RXBEN) - || (flags & IEVENT_RXF && etsec->regs[IMASK].value & IMASK_RXFEN))= { - qemu_irq_raise(etsec->rx_irq); - RING_DEBUG("%s Raise Rx IRQ\n", __func__); - } + etsec_update_irq(etsec); } =20 static void tx_padding_and_crc(eTSEC *etsec, uint32_t min_frame_len) --=20 2.17.1