Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp447859ybl; Tue, 28 Jan 2020 06:09:12 -0800 (PST) X-Google-Smtp-Source: APXvYqw1KW8YUwEvDN5DAoRmuAkGC3xD8ylF1Pf5Mn7xBMlFN0fNuco6rgPsUHeCkfpR3MhLrS7T X-Received: by 2002:a54:4117:: with SMTP id l23mr2812093oic.140.1580220552538; Tue, 28 Jan 2020 06:09:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580220552; cv=none; d=google.com; s=arc-20160816; b=fK/Hus2870FJOnyHq7ZejAqSEGoyQQlMLUeRoJ7ch3zgAt7cdK0HDs8w69oBvI7OwU zafLpn/W1bjJixQlYdiLCgj87+5M2XnkwRcK35PE+cbv5AlhomCTEZTqahT7IYaniCUF y4E01B9+cDbCx6aQMLVAVUGHl/CtqdXX98oFcW6NWC10f0lJ1QxpZq7zlXmJDl8K/q8Q cKPGWQlbXYrm9A2ptlGlfbehqBq4UVbtc8yDV5znt1ezRlsrcDxmOyHRNb7A03EW8+/p 97TI8slBec4IkaLh3R93RBI5DZU6I5mficW/YKviQr05wVvpvdukkVj7AoYmX1GABA8G /Clg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=tgTEFxLqN+sRmicT74LqTFxHVPa/lOCh2+NkrCS19kk=; b=GCnDkRxom+B9vWArH4VSm8plOP0ZHk2KLcOsxejJvFjtHcki68DuPMINfP9Yk8PY4A Jj6YD//RDvmGrL88NVvNzoNZjYiNqTmncG74i1ppgY88rCXx6ZPgNSQ/iPOgJE9f2bCy sG6ODZAmuPvQFH/+9FffmAC9kuq7FCB0x7xdayALamyECl7o1gBVw1PF80CYFifkuk+0 +dMrtBnU9GJjKrX78PTN7PMIC+xQ4DEm2hbptu6pkdz2Zjrz7jFwxbm3OuFKF1AFY9SD kEIZkZhDMVJothLEHv0jLhYI+3Wfoos3Aajo+FR/4Z8EAnI8sjMkHCrfZDi1B8Y417Ob JJ3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="ZQ/vTIoF"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 64si7584452otx.50.2020.01.28.06.08.51; Tue, 28 Jan 2020 06:09:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="ZQ/vTIoF"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727825AbgA1OGV (ORCPT + 99 others); Tue, 28 Jan 2020 09:06:21 -0500 Received: from mail.kernel.org ([198.145.29.99]:52090 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727516AbgA1OEp (ORCPT ); Tue, 28 Jan 2020 09:04:45 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8DCB32468A; Tue, 28 Jan 2020 14:04:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1580220285; bh=PYphjFZGudtWXkMPyMsi6nCahUV4wWTlUwYQJN9QVGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZQ/vTIoF4DVi9qnG5S+YERWAg7Ux3HxF83baE1mgRw0ne8TK6QNA7ApwOBp+qexJa l4+QdeD+4RtbTNCSONiQO6HIAyLG9aIj1JlQTRRYBv4WlSOZTBUB/3OqjO/K2dpgN9 jl+VFxgiEYage/sVYxRM/i+RQSNG4W8RdSiBQAPQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Stan Johnson , Finn Thain , "David S. Miller" Subject: [PATCH 5.4 091/104] net/sonic: Fix receive buffer handling Date: Tue, 28 Jan 2020 15:00:52 +0100 Message-Id: <20200128135829.642237685@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200128135817.238524998@linuxfoundation.org> References: <20200128135817.238524998@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Finn Thain commit 9e311820f67e740f4fb8dcb82b4c4b5b05bdd1a5 upstream. The SONIC can sometimes advance its rx buffer pointer (RRP register) without advancing its rx descriptor pointer (CRDA register). As a result the index of the current rx descriptor may not equal that of the current rx buffer. The driver mistakenly assumes that they are always equal. This assumption leads to incorrect packet lengths and possible packet duplication. Avoid this by calling a new function to locate the buffer corresponding to a given descriptor. Fixes: efcce839360f ("[PATCH] macsonic/jazzsonic network drivers update") Tested-by: Stan Johnson Signed-off-by: Finn Thain Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/natsemi/sonic.c | 35 ++++++++++++++++++++++++++++++----- drivers/net/ethernet/natsemi/sonic.h | 5 +++-- 2 files changed, 33 insertions(+), 7 deletions(-) --- a/drivers/net/ethernet/natsemi/sonic.c +++ b/drivers/net/ethernet/natsemi/sonic.c @@ -413,6 +413,21 @@ static irqreturn_t sonic_interrupt(int i return IRQ_HANDLED; } +/* Return the array index corresponding to a given Receive Buffer pointer. */ +static int index_from_addr(struct sonic_local *lp, dma_addr_t addr, + unsigned int last) +{ + unsigned int i = last; + + do { + i = (i + 1) & SONIC_RRS_MASK; + if (addr == lp->rx_laddr[i]) + return i; + } while (i != last); + + return -ENOENT; +} + /* * We have a good packet(s), pass it/them up the network stack. */ @@ -432,6 +447,16 @@ static void sonic_rx(struct net_device * status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); if (status & SONIC_RCR_PRX) { + u32 addr = (sonic_rda_get(dev, entry, + SONIC_RD_PKTPTR_H) << 16) | + sonic_rda_get(dev, entry, SONIC_RD_PKTPTR_L); + int i = index_from_addr(lp, addr, entry); + + if (i < 0) { + WARN_ONCE(1, "failed to find buffer!\n"); + break; + } + /* Malloc up new buffer. */ new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); if (new_skb == NULL) { @@ -453,7 +478,7 @@ static void sonic_rx(struct net_device * /* now we have a new skb to replace it, pass the used one up the stack */ dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE); - used_skb = lp->rx_skb[entry]; + used_skb = lp->rx_skb[i]; pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN); skb_trim(used_skb, pkt_len); used_skb->protocol = eth_type_trans(used_skb, dev); @@ -462,13 +487,13 @@ static void sonic_rx(struct net_device * lp->stats.rx_bytes += pkt_len; /* and insert the new skb */ - lp->rx_laddr[entry] = new_laddr; - lp->rx_skb[entry] = new_skb; + lp->rx_laddr[i] = new_laddr; + lp->rx_skb[i] = new_skb; bufadr_l = (unsigned long)new_laddr & 0xffff; bufadr_h = (unsigned long)new_laddr >> 16; - sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l); - sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h); + sonic_rra_put(dev, i, SONIC_RR_BUFADR_L, bufadr_l); + sonic_rra_put(dev, i, SONIC_RR_BUFADR_H, bufadr_h); } else { /* This should only happen, if we enable accepting broken packets. */ } --- a/drivers/net/ethernet/natsemi/sonic.h +++ b/drivers/net/ethernet/natsemi/sonic.h @@ -275,8 +275,9 @@ #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ -#define SONIC_RDS_MASK (SONIC_NUM_RDS-1) -#define SONIC_TDS_MASK (SONIC_NUM_TDS-1) +#define SONIC_RRS_MASK (SONIC_NUM_RRS - 1) +#define SONIC_RDS_MASK (SONIC_NUM_RDS - 1) +#define SONIC_TDS_MASK (SONIC_NUM_TDS - 1) #define SONIC_RBSIZE 1520 /* size of one resource buffer */