Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2755555pxj; Mon, 31 May 2021 09:57:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwAlijTgaFAn8qYRt++mD304AmP+wwhd2HMVD8gntVo0BPloHMNq/NxWYT5+rkGYSaJEkBS X-Received: by 2002:a17:906:b294:: with SMTP id q20mr5136416ejz.382.1622480223630; Mon, 31 May 2021 09:57:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622480223; cv=none; d=google.com; s=arc-20160816; b=jxIRHjskZ2EuCp5VndV7lheY1zbALhX+C7xk9Q4hq+e3OnEW/ESDQce2lgp1m3xoNA Ev2AcDjciTDI4aYmvGXUTuT3AJ0Ve2lLhcTVgC2f2rhOVupcSutjPoF5LlrESaqKNphN Jpd85qmB3v9ia9YAamNJxyHDGY7OkdOXtAdOY5s/8xB/uVUNzXkliBK1e7rUbVb2loBp MM/QuusSu5PFGsVL8ZeB8wY/wbnOzgat6XJ5mqCYyt9Yqy60M3jxQBk/E5z+8eXjqelS dReO0/1g414NPBozsc8BxSVt+eWfzkrce2T+3m1gzDnH38Jpp4WqkNorDmP+T98UyLQq Y7lA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qwVc8skMBnZuy00hgq0+poTZuoOYf/j1Ab26Fedmg1k=; b=a9lUPc2vr2bf6N+u5sum3DnyiRYMfLZh6/aQBYKEzMeSdJPPooVOm9hUoSunliFLfr tMvI7qICmaHY0HGfQSc3wSfQiUWh4ACR+ePb7x33N3GC2YyY6zYqoHElhHQRgNJ/A2HK pAjcnQ20c+o09tdp8t6wivbis0G3g/W2tLyoEQsp4GAwsLnrtTNDLdnmwm46dZAUYOYK IiWZhx271kF83oYawciayuvpkMKSgKjdHI5uV5fy/M2pdOlslO5ePH6BxHMrxbsKsnNv cFUoi1OgcDbpRrbucGthjtACf3prTxKSH+i3WtU1yvHQxXRTQh+aYoZu988GNZwnEbWO U3Nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ps5Lb4c6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l21si13267066ejn.568.2021.05.31.09.56.41; Mon, 31 May 2021 09:57:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ps5Lb4c6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234464AbhEaQyu (ORCPT + 99 others); Mon, 31 May 2021 12:54:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:51050 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234371AbhEaO7V (ORCPT ); Mon, 31 May 2021 10:59:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id A409A61CE2; Mon, 31 May 2021 14:01:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1622469683; bh=7PFeLZafVQ6dj3ubSamHOGzkWKXqeD/Q2Y4Acl122fg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ps5Lb4c6qxxhWy2Kbxf9Ccm9C+9NgdHlASqoGvvKDaYg6mGyFhFDGCFyUEJ605fsj BZcg9t3l3JFOynRagCXyor93uUP2MejKal4E+fH3ivcELxQ66paZ5yghWuFItTiPa0 m1SsKAvcStKikYONJNYl3rwVceWF07Be1INpr++Y= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Russell King , Stefan Chulski , "David S. Miller" , Sasha Levin Subject: [PATCH 5.12 284/296] net: mvpp2: add buffer header handling in RX Date: Mon, 31 May 2021 15:15:39 +0200 Message-Id: <20210531130713.267499876@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531130703.762129381@linuxfoundation.org> References: <20210531130703.762129381@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Stefan Chulski [ Upstream commit 17f9c1b63cdd4439523cfcdf5683e5070b911f24 ] If Link Partner sends frames larger than RX buffer size, MAC mark it as oversize but still would pass it to the Packet Processor. In this scenario, Packet Processor scatter frame between multiple buffers, but only a single buffer would be returned to the Buffer Manager pool and it would not refill the poll. Patch add handling of oversize error with buffer header handling, so all buffers would be returned to the Buffer Manager pool. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Reported-by: Russell King Signed-off-by: Stefan Chulski Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 22 ++++++++ .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 54 +++++++++++++++---- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index 8edba5ea90f0..4a61c90003b5 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -993,6 +993,14 @@ enum mvpp22_ptp_packet_format { #define MVPP2_DESC_DMA_MASK DMA_BIT_MASK(40) +/* Buffer header info bits */ +#define MVPP2_B_HDR_INFO_MC_ID_MASK 0xfff +#define MVPP2_B_HDR_INFO_MC_ID(info) ((info) & MVPP2_B_HDR_INFO_MC_ID_MASK) +#define MVPP2_B_HDR_INFO_LAST_OFFS 12 +#define MVPP2_B_HDR_INFO_LAST_MASK BIT(12) +#define MVPP2_B_HDR_INFO_IS_LAST(info) \ + (((info) & MVPP2_B_HDR_INFO_LAST_MASK) >> MVPP2_B_HDR_INFO_LAST_OFFS) + struct mvpp2_tai; /* Definitions */ @@ -1002,6 +1010,20 @@ struct mvpp2_rss_table { u32 indir[MVPP22_RSS_TABLE_ENTRIES]; }; +struct mvpp2_buff_hdr { + __le32 next_phys_addr; + __le32 next_dma_addr; + __le16 byte_count; + __le16 info; + __le16 reserved1; /* bm_qset (for future use, BM) */ + u8 next_phys_addr_high; + u8 next_dma_addr_high; + __le16 reserved2; + __le16 reserved3; + __le16 reserved4; + __le16 reserved5; +}; + /* Shared Packet Processor resources */ struct mvpp2 { /* Shared registers' base addresses */ diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 1767c60056c5..6c81e4f175ac 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -3840,6 +3840,35 @@ mvpp2_run_xdp(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq, return ret; } +static void mvpp2_buff_hdr_pool_put(struct mvpp2_port *port, struct mvpp2_rx_desc *rx_desc, + int pool, u32 rx_status) +{ + phys_addr_t phys_addr, phys_addr_next; + dma_addr_t dma_addr, dma_addr_next; + struct mvpp2_buff_hdr *buff_hdr; + + phys_addr = mvpp2_rxdesc_dma_addr_get(port, rx_desc); + dma_addr = mvpp2_rxdesc_cookie_get(port, rx_desc); + + do { + buff_hdr = (struct mvpp2_buff_hdr *)phys_to_virt(phys_addr); + + phys_addr_next = le32_to_cpu(buff_hdr->next_phys_addr); + dma_addr_next = le32_to_cpu(buff_hdr->next_dma_addr); + + if (port->priv->hw_version >= MVPP22) { + phys_addr_next |= ((u64)buff_hdr->next_phys_addr_high << 32); + dma_addr_next |= ((u64)buff_hdr->next_dma_addr_high << 32); + } + + mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); + + phys_addr = phys_addr_next; + dma_addr = dma_addr_next; + + } while (!MVPP2_B_HDR_INFO_IS_LAST(le16_to_cpu(buff_hdr->info))); +} + /* Main rx processing */ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, int rx_todo, struct mvpp2_rx_queue *rxq) @@ -3886,14 +3915,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, MVPP2_RXD_BM_POOL_ID_OFFS; bm_pool = &port->priv->bm_pools[pool]; - /* In case of an error, release the requested buffer pointer - * to the Buffer Manager. This request process is controlled - * by the hardware, and the information about the buffer is - * comprised by the RX descriptor. - */ - if (rx_status & MVPP2_RXD_ERR_SUMMARY) - goto err_drop_frame; - if (port->priv->percpu_pools) { pp = port->priv->page_pool[pool]; dma_dir = page_pool_get_dma_dir(pp); @@ -3905,6 +3926,18 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi, rx_bytes + MVPP2_MH_SIZE, dma_dir); + /* Buffer header not supported */ + if (rx_status & MVPP2_RXD_BUF_HDR) + goto err_drop_frame; + + /* In case of an error, release the requested buffer pointer + * to the Buffer Manager. This request process is controlled + * by the hardware, and the information about the buffer is + * comprised by the RX descriptor. + */ + if (rx_status & MVPP2_RXD_ERR_SUMMARY) + goto err_drop_frame; + /* Prefetch header */ prefetch(data); @@ -3986,7 +4019,10 @@ err_drop_frame: dev->stats.rx_errors++; mvpp2_rx_error(port, rx_desc); /* Return the buffer to the pool */ - mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); + if (rx_status & MVPP2_RXD_BUF_HDR) + mvpp2_buff_hdr_pool_put(port, rx_desc, pool, rx_status); + else + mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); } rcu_read_unlock(); -- 2.30.2