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: 1209592 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=telegraphics.com.au 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 ozlabs.org (Postfix) with ESMTPS id 47ZVTN6W5Hz9s4Y for ; Sat, 14 Dec 2019 12:35:03 +1100 (AEDT) Received: from localhost ([::1]:55020 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ifwKh-0002im-TI for incoming@patchwork.ozlabs.org; Fri, 13 Dec 2019 20:34:59 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41546) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ifwEe-00041t-6i 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-00019F-KF for qemu-devel@nongnu.org; Fri, 13 Dec 2019 20:28:44 -0500 Received: from kvm5.telegraphics.com.au ([98.124.60.144]:47408) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ifwEc-00016s-78; Fri, 13 Dec 2019 20:28:42 -0500 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 5238A27C43; 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 07/10] dp8393x: Implement TBWC0 and TBWC1 registers to restore buffer state 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Restore the receive buffer state when the SONIC runs out of receive descriptors. Otherwise it may write the next packet past the end of the buffer and corrupt guest memory. This implements behaviour described in section 3.4.6.2 in the datasheet. Signed-off-by: Finn Thain --- hw/net/dp8393x.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 3fdc6cc6f9..5e4494a945 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -39,7 +39,7 @@ static const char* reg_names[] = { "CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA", "TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0", "CRBA1", "RBWC0", "RBWC1", "EOBC", "URRA", "RSA", "REA", "RRP", - "RWP", "TRBA0", "TRBA1", "0x1b", "0x1c", "0x1d", "0x1e", "LLFA", + "RWP", "TRBA0", "TRBA1", "TBWC0", "TBWC1", "0x1d", "0x1e", "LLFA", "TTDA", "CEP", "CAP2", "CAP1", "CAP0", "CE", "CDP", "CDC", "SR", "WT0", "WT1", "RSC", "CRCT", "FAET", "MPT", "MDT", "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", @@ -78,6 +78,8 @@ do { printf("sonic ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) #define SONIC_RWP 0x18 #define SONIC_TRBA0 0x19 #define SONIC_TRBA1 0x1a +#define SONIC_TBWC0 0x1b +#define SONIC_TBWC1 0x1c #define SONIC_LLFA 0x1f #define SONIC_TTDA 0x20 #define SONIC_CEP 0x21 @@ -777,6 +779,8 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, /* Save current position */ s->regs[SONIC_TRBA1] = s->regs[SONIC_CRBA1]; s->regs[SONIC_TRBA0] = s->regs[SONIC_CRBA0]; + s->regs[SONIC_TBWC1] = s->regs[SONIC_RBWC1]; + s->regs[SONIC_TBWC0] = s->regs[SONIC_RBWC0]; /* Calculate the ethernet checksum */ checksum = cpu_to_le32(crc32(0, buf, rx_len)); @@ -827,6 +831,12 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, if (s->regs[SONIC_LLFA] & 0x1) { /* EOL detected */ s->regs[SONIC_ISR] |= SONIC_ISR_RDE; + + /* Restore buffer state */ + s->regs[SONIC_CRBA1] = s->regs[SONIC_TRBA1]; + s->regs[SONIC_CRBA0] = s->regs[SONIC_TRBA0]; + s->regs[SONIC_RBWC1] = s->regs[SONIC_TBWC1]; + s->regs[SONIC_RBWC0] = s->regs[SONIC_TBWC0]; } else { /* Clear in_use */ int offset = dp8393x_crda(s) + sizeof(uint16_t) * 6 * width;