From patchwork Tue Mar 7 15:53:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 9609299 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 293F36046A for ; Tue, 7 Mar 2017 15:59:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CBEC27165 for ; Tue, 7 Mar 2017 15:59:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 112A7284C9; Tue, 7 Mar 2017 15:59:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6E7B827165 for ; Tue, 7 Mar 2017 15:59:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=776S+kUP8NM6k85o3biVTrx/FsTbz/2UvZYINsRJ8eU=; b=C0xBdFoGZa0fs4rS9fo6Au/LCS IX/MfkmXf/16W/q5K73GYl/PvtYlAB/OM/BdZd8Q2OfLVUUKJYEa6AhjHIm+565mW/QSz5jBJtHQj SJ8zBO2UeJlHcrspM26lYTF5xUzKkoX6ULPYDGjQS+/yhsa7M+mTqVEqs0Acvpd7IK5+QXR7us+7C wQeYiEz3HRlrGLNvCdjMAyrrJwmGcisjmKcaubLmWu7FeX8zncYjcQ3mXVPNkElb7KdCO8vq2aKcf qGEC6cS/9Fw1xcECeU2G6GUZrXrhs6UnykqdAk9nMBpJd41dE2aGkeaTauFBYvjAIaDiVc3Jbd/7n SShIyuQg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1clHWN-0006Pl-Ec; Tue, 07 Mar 2017 15:59:31 +0000 Received: from mail.free-electrons.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1clHRP-0001PU-P3 for linux-arm-kernel@lists.infradead.org; Tue, 07 Mar 2017 15:54:27 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id B2F8F207E8; Tue, 7 Mar 2017 16:53:39 +0100 (CET) Received: from localhost (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 8549020759; Tue, 7 Mar 2017 16:53:39 +0100 (CET) From: Thomas Petazzoni To: "David S. Miller" , netdev@vger.kernel.org, devicetree@vger.kernel.org, Rob Herring , Ian Campbell , Pawel Moll , Mark Rutland , Kumar Gala Subject: [PATCHv3 net-next 06/22] net: mvpp2: store physical address of buffer in rx_desc->buf_cookie Date: Tue, 7 Mar 2017 16:53:04 +0100 Message-Id: <1488902000-2658-7-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488902000-2658-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1488902000-2658-1-git-send-email-thomas.petazzoni@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170307_075424_192670_8771CCEA X-CRM114-Status: GOOD ( 20.63 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Petazzoni , Andrew Lunn , Yehuda Yitschak , Russell King , Jason Cooper , Hanna Hawa , Nadav Haklai , Gregory Clement , Stefan Chulski , Marcin Wojtas , linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The RX descriptors of the PPv2 hardware allow to store several information, amongst which: - the DMA address of the buffer in which the data has been received - a "cookie" field, left to the use of the driver, and not used by the hardware In the current implementation, the "cookie" field is used to store the virtual address of the buffer, so that in the receive completion path, we can easily get the virtual address of the buffer that corresponds to a completed RX descriptors. On PPv2.1, used on 32-bit platforms, those two fields are 32-bit wide, which is enough to store a DMA address in the first field, and a virtual address in the second field. On PPv2.2, used on 64-bit platforms, these two fields have been extended to 40 bits. While 40 bits is enough to store a DMA address (as long as the DMA mask is 40 bits or lower), it is not enough to store a virtual address. Therefore, the "cookie" field can no longer be used to store the virtual address of the buffer. However, as Russell King pointed out, the RX buffers are always allocated in the kernel linear mapping, and therefore using phys_to_virt() on the physical address of the RX buffer is possible and correct. Therefore, this commit changes the driver to use the "cookie" field to store the physical address instead of the virtual address. phys_to_virt() is used in the receive completion path to retrieve the virtual address from the physical address. It is obviously important to realize that the DMA address and physical address are two different things, which is why we store both in the RX descriptors. While those addresses may be identical in some situations, it remains two distinct concepts, and both addresses should be handled separately. Signed-off-by: Thomas Petazzoni --- drivers/net/ethernet/marvell/mvpp2.c | 40 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 9ddda20..35dc071 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -3412,20 +3412,21 @@ static void mvpp2_bm_bufs_free(struct device *dev, struct mvpp2 *priv, for (i = 0; i < bm_pool->buf_num; i++) { dma_addr_t buf_dma_addr; - unsigned long vaddr; + phys_addr_t buf_phys_addr; + void *data; - /* Get buffer virtual address (indirect access) */ buf_dma_addr = mvpp2_read(priv, MVPP2_BM_PHY_ALLOC_REG(bm_pool->id)); - vaddr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG); + buf_phys_addr = mvpp2_read(priv, MVPP2_BM_VIRT_ALLOC_REG); dma_unmap_single(dev, buf_dma_addr, bm_pool->buf_size, DMA_FROM_DEVICE); - if (!vaddr) + data = (void *)phys_to_virt(buf_phys_addr); + if (!data) break; - mvpp2_frag_free(bm_pool, (void *)vaddr); + mvpp2_frag_free(bm_pool, data); } /* Update BM driver with number of buffers removed from pool */ @@ -3542,6 +3543,7 @@ static void mvpp2_rxq_short_pool_set(struct mvpp2_port *port, static void *mvpp2_buf_alloc(struct mvpp2_port *port, struct mvpp2_bm_pool *bm_pool, dma_addr_t *buf_dma_addr, + phys_addr_t *buf_phys_addr, gfp_t gfp_mask) { dma_addr_t dma_addr; @@ -3559,6 +3561,7 @@ static void *mvpp2_buf_alloc(struct mvpp2_port *port, return NULL; } *buf_dma_addr = dma_addr; + *buf_phys_addr = virt_to_phys(data); return data; } @@ -3583,20 +3586,25 @@ static inline int mvpp2_bm_cookie_pool_get(unsigned long cookie) /* Release buffer to BM */ static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool, dma_addr_t buf_dma_addr, - unsigned long buf_virt_addr) + phys_addr_t buf_phys_addr) { - mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_virt_addr); + /* MVPP2_BM_VIRT_RLS_REG is not interpreted by HW, and simply + * returned in the "cookie" field of the RX + * descriptor. Instead of storing the virtual address, we + * store the physical address + */ + mvpp2_write(port->priv, MVPP2_BM_VIRT_RLS_REG, buf_phys_addr); mvpp2_write(port->priv, MVPP2_BM_PHY_RLS_REG(pool), buf_dma_addr); } /* Refill BM pool */ static void mvpp2_pool_refill(struct mvpp2_port *port, u32 bm, dma_addr_t dma_addr, - unsigned long cookie) + phys_addr_t phys_addr) { int pool = mvpp2_bm_cookie_pool_get(bm); - mvpp2_bm_pool_put(port, pool, dma_addr, cookie); + mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr); } /* Allocate buffers for the pool */ @@ -3605,6 +3613,7 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, { int i, buf_size, total_size; dma_addr_t dma_addr; + phys_addr_t phys_addr; void *buf; buf_size = MVPP2_RX_BUF_SIZE(bm_pool->pkt_size); @@ -3619,12 +3628,13 @@ static int mvpp2_bm_bufs_add(struct mvpp2_port *port, } for (i = 0; i < buf_num; i++) { - buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr, GFP_KERNEL); + buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr, + &phys_addr, GFP_KERNEL); if (!buf) break; mvpp2_bm_pool_put(port, bm_pool->id, dma_addr, - (unsigned long)buf); + phys_addr); } /* Update BM driver with number of buffers added to pool */ @@ -4983,14 +4993,16 @@ static int mvpp2_rx_refill(struct mvpp2_port *port, struct mvpp2_bm_pool *bm_pool, u32 bm) { dma_addr_t dma_addr; + phys_addr_t phys_addr; void *buf; /* No recycle or too many buffers are in use, so allocate a new skb */ - buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr, GFP_ATOMIC); + buf = mvpp2_buf_alloc(port, bm_pool, &dma_addr, &phys_addr, + GFP_ATOMIC); if (!buf) return -ENOMEM; - mvpp2_pool_refill(port, bm, dma_addr, (unsigned long)buf); + mvpp2_pool_refill(port, bm, dma_addr, phys_addr); return 0; } @@ -5055,7 +5067,7 @@ static int mvpp2_rx(struct mvpp2_port *port, int rx_todo, rx_status = rx_desc->status; rx_bytes = rx_desc->data_size - MVPP2_MH_SIZE; dma_addr = rx_desc->buf_dma_addr; - data = (void *)(uintptr_t)rx_desc->buf_cookie; + data = (void *)phys_to_virt(rx_desc->buf_cookie); bm = mvpp2_bm_cookie_build(rx_desc); pool = mvpp2_bm_cookie_pool_get(bm);