From patchwork Sat Dec 14 01:25:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Finn Thain X-Patchwork-Id: 11292075 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EB75914BD for ; Sat, 14 Dec 2019 01:35:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8E17E206C3 for ; Sat, 14 Dec 2019 01:35:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8E17E206C3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=telegraphics.com.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:55054 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ifwL2-0003ow-It for patchwork-qemu-devel@patchwork.kernel.org; Fri, 13 Dec 2019 20:35:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41595) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ifwEe-00041w-Bp for qemu-devel@nongnu.org; Fri, 13 Dec 2019 20:28:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ifwEc-00019J-On for qemu-devel@nongnu.org; Fri, 13 Dec 2019 20:28:44 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:47410) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ifwEc-00016t-8z; Fri, 13 Dec 2019 20:28:42 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 70CAB27DAC; Fri, 13 Dec 2019 20:28:41 -0500 (EST) To: Jason Wang , qemu-devel@nongnu.org Message-Id: In-Reply-To: References: From: Finn Thain Subject: [PATCH 09/10] dp8393x: Don't stop reception upon RBE interrupt assertion Date: Sat, 14 Dec 2019 12:25:57 +1100 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 98.124.60.144 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Aleksandar Rikalo , Herve Poussineau , Laurent Vivier , qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Section 5.4.7 of the datasheet explains that the RBE interrupt is an "early warning". It indicates that the last RBA is still available to receive a packet. It doesn't imply actual receive buffer exhaustion. This is an important distinction because Linux will not check and clear the RBE interrupt until it receives another packet. But that won't happen if can_receive returns false. So the SONIC becomes deaf (until reset). Fix this with a new flag to indicate actual receive buffer exhaustion. Signed-off-by: Finn Thain --- hw/net/dp8393x.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 24f2e19f07..8e66b1f5de 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -157,6 +157,7 @@ typedef struct dp8393xState { /* Hardware */ uint8_t it_shift; bool big_endian; + bool last_rba_is_full; qemu_irq irq; #ifdef DEBUG_SONIC int irq_level; @@ -311,6 +312,12 @@ static void dp8393x_do_read_rra(dp8393xState *s) { int width, size; + /* Already on the last RBA? */ + s->last_rba_is_full = s->regs[SONIC_ISR] & SONIC_ISR_RBE; + if (s->last_rba_is_full) { + return; + } + /* Read memory */ width = (s->regs[SONIC_DCR] & SONIC_DCR_DW) ? 2 : 1; size = sizeof(uint16_t) * 4 * width; @@ -334,7 +341,7 @@ static void dp8393x_do_read_rra(dp8393xState *s) s->regs[SONIC_RRP] = s->regs[SONIC_RSA]; } - /* Check resource exhaustion */ + /* Warn the host if this entry is the last one */ if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP]) { s->regs[SONIC_ISR] |= SONIC_ISR_RBE; @@ -703,8 +710,9 @@ static int dp8393x_can_receive(NetClientState *nc) if (!(s->regs[SONIC_CR] & SONIC_CR_RXEN)) return 0; - if (s->regs[SONIC_ISR] & SONIC_ISR_RBE) + if (s->last_rba_is_full) { return 0; + } return 1; }