From patchwork Fri Dec 20 04:17:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Finn Thain X-Patchwork-Id: 11304797 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 0FE5C13A4 for ; Fri, 20 Dec 2019 04:33:26 +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 E3BB4227BF for ; Fri, 20 Dec 2019 04:33:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E3BB4227BF 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]:50654 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii9yf-0000NZ-4I for patchwork-qemu-devel@patchwork.kernel.org; Thu, 19 Dec 2019 23:33:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:55875) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ii9nh-0008UV-7g for qemu-devel@nongnu.org; Thu, 19 Dec 2019 23:22:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ii9nf-00022p-Bj for qemu-devel@nongnu.org; Thu, 19 Dec 2019 23:22:04 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:34448) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ii9ne-00020K-WB; Thu, 19 Dec 2019 23:22:03 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 4C3C428D35; Thu, 19 Dec 2019 23:22:02 -0500 (EST) To: Jason Wang , qemu-devel@nongnu.org Message-Id: <7c5e49e72ef576db03d6290759d3cd01f17197c8.1576815466.git.fthain@telegraphics.com.au> In-Reply-To: References: From: Finn Thain Subject: [PATCH v2 07/13] dp8393x: Don't stop reception upon RBE interrupt assertion Date: Fri, 20 Dec 2019 15:17:46 +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 , =?utf-8?q?Herv=C3=A9_Po?= =?utf-8?q?ussineau?= , 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 9d2c205dce..46b92ebf65 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -158,6 +158,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; @@ -314,6 +315,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; @@ -337,7 +344,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; @@ -706,8 +713,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; }