From patchwork Tue Feb 25 09:11:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 1243937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=L2rjLmEk; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48RY3W5ZJ8z9sRQ for ; Tue, 25 Feb 2020 20:07:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729153AbgBYJHS (ORCPT ); Tue, 25 Feb 2020 04:07:18 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:57030 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729393AbgBYJHR (ORCPT ); Tue, 25 Feb 2020 04:07:17 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01P97A11114982; Tue, 25 Feb 2020 03:07:10 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582621630; bh=qpB5Venlyxo4sKSWGb+++fS0KMNoB1LVzbHh61l1dmY=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=L2rjLmEk+LwoSSlj4J+0h7R3VsC+Un80FQ9z0OlPXoIdMHV/7uVxKpxpti0DAWD0O 973Yuh5pICKTZuw+imGs/4Vj7iz7QVNxFBLpHzgFGjaZQ5u3rR38yCg8kPfcqBF/Sf fhxTLfdulJ+XMQ9ZKdOfJrbl5IWuXAvLUqCbvGFk= Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01P97AnA027452 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 25 Feb 2020 03:07:10 -0600 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Tue, 25 Feb 2020 03:07:10 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Tue, 25 Feb 2020 03:07:10 -0600 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01P973Pp052643; Tue, 25 Feb 2020 03:07:07 -0600 From: Kishon Vijay Abraham I To: Lorenzo Pieralisi , Arnd Bergmann , Andrew Murray , Kishon Vijay Abraham I CC: Greg Kroah-Hartman , Bjorn Helgaas , Alan Mikhak , , Subject: [PATCH 1/5] PCI: endpoint: functions/pci-epf-test: Add DMA support to transfer data Date: Tue, 25 Feb 2020 14:41:26 +0530 Message-ID: <20200225091130.29467-2-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200225091130.29467-1-kishon@ti.com> References: <20200225091130.29467-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Use dmaengine API and add support for transferring data using DMA. Signed-off-by: Kishon Vijay Abraham I --- drivers/pci/endpoint/functions/pci-epf-test.c | 205 +++++++++++++++++- 1 file changed, 202 insertions(+), 3 deletions(-) diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index bddff15052cc..4e5ed37110ed 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #define STATUS_SRC_ADDR_INVALID BIT(7) #define STATUS_DST_ADDR_INVALID BIT(8) +#define FLAG_USE_DMA BIT(0) + #define TIMER_RESOLUTION 1 static struct workqueue_struct *kpcitest_workqueue; @@ -48,6 +51,9 @@ struct pci_epf_test { struct pci_epf *epf; enum pci_barno test_reg_bar; struct delayed_work cmd_handler; + struct dma_chan *dma_chan; + struct completion transfer_complete; + bool dma_supported; const struct pci_epc_features *epc_features; }; @@ -61,6 +67,7 @@ struct pci_epf_test_reg { u32 checksum; u32 irq_type; u32 irq_number; + u32 flags; } __packed; static struct pci_epf_header test_header = { @@ -72,9 +79,121 @@ static struct pci_epf_header test_header = { static size_t bar_size[] = { 512, 512, 1024, 16384, 131072, 1048576 }; +static void pci_epf_test_dma_callback(void *param) +{ + struct pci_epf_test *epf_test = param; + + complete(&epf_test->transfer_complete); +} + +/** + * pci_epf_test_data_transfer() - Helper to use dmaengine API to transfer data + * between PCIe EP and remote PCIe RC + * @epf: the EPF device that performs the data transfer operation + * @dma_dst: The destination address of the data transfer. It can be a physical + * address given by pci_epc_mem_alloc_addr or DMA mapping APIs. + * @dma_src: The source address of the data transfer. It can be a physical + * address given by pci_epc_mem_alloc_addr or DMA mapping APIs. + * @len: The size of the data transfer + * + * Helper to use dmaengine API to transfer data between PCIe EP and remote PCIe + * RC. The source and destination address can be a physical address given by + * pci_epc_mem_alloc_addr or the one obtained using DMA mapping APIs. + * + * The function returns '0' on success and negative value on failure. + */ +static int pci_epf_test_data_transfer(struct pci_epf_test *epf_test, + dma_addr_t dma_dst, dma_addr_t dma_src, + size_t len) +{ + enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; + struct dma_chan *chan = epf_test->dma_chan; + struct pci_epf *epf = epf_test->epf; + struct dma_async_tx_descriptor *tx; + struct device *dev = &epf->dev; + dma_cookie_t cookie; + int ret; + + if (IS_ERR_OR_NULL(chan)) { + dev_err(dev, "Invalid DMA memcpy channel\n"); + return -EINVAL; + } + + tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags); + if (!tx) { + dev_err(dev, "Failed to prepare DMA memcpy\n"); + return -EIO; + } + + tx->callback = pci_epf_test_dma_callback; + tx->callback_param = epf_test; + cookie = tx->tx_submit(tx); + reinit_completion(&epf_test->transfer_complete); + + ret = dma_submit_error(cookie); + if (ret) { + dev_err(dev, "Failed to do DMA tx_submit %d\n", cookie); + return -EIO; + } + + dma_async_issue_pending(chan); + ret = wait_for_completion_interruptible(&epf_test->transfer_complete); + if (ret < 0) { + dmaengine_terminate_sync(chan); + dev_err(dev, "DMA wait_for_completion_timeout\n"); + return -ETIMEDOUT; + } + + return 0; +} + +/** + * pci_epf_init_dma_chan() - Helper to initialize EPF DMA channel + * @epf: the EPF device that has to perform the data transfer operation + * + * Helper to initialize EPF DMA channel. + */ +static int pci_epf_init_dma_chan(struct pci_epf_test *epf_test) +{ + struct pci_epf *epf = epf_test->epf; + struct device *dev = &epf->dev; + struct dma_chan *dma_chan; + dma_cap_mask_t mask; + int ret; + + dma_cap_zero(mask); + dma_cap_set(DMA_MEMCPY, mask); + + dma_chan = dma_request_chan_by_mask(&mask); + if (IS_ERR(dma_chan)) { + ret = PTR_ERR(dma_chan); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get DMA channel\n"); + return ret; + } + init_completion(&epf_test->transfer_complete); + + epf_test->dma_chan = dma_chan; + + return 0; +} + +/** + * pci_epf_clean_dma_chan() - Helper to cleanup EPF DMA channel + * @epf: the EPF device that performed the data transfer operation + * + * Helper to cleanup EPF DMA channel. + */ +static void pci_epf_clean_dma_chan(struct pci_epf_test *epf_test) +{ + dma_release_channel(epf_test->dma_chan); + epf_test->dma_chan = NULL; +} + static int pci_epf_test_copy(struct pci_epf_test *epf_test) { int ret; + bool use_dma; void __iomem *src_addr; void __iomem *dst_addr; phys_addr_t src_phys_addr; @@ -117,8 +236,23 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_dst_addr; } - memcpy(dst_addr, src_addr, reg->size); + use_dma = !!(reg->flags & FLAG_USE_DMA); + if (use_dma) { + if (!epf_test->dma_supported) { + dev_err(dev, "Cannot transfer data using DMA\n"); + ret = -EINVAL; + goto err_map_addr; + } + ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr, + src_phys_addr, reg->size); + if (ret) + dev_err(dev, "Data transfer failed\n"); + } else { + memcpy(dst_addr, src_addr, reg->size); + } + +err_map_addr: pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr); err_dst_addr: @@ -140,10 +274,13 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) void __iomem *src_addr; void *buf; u32 crc32; + bool use_dma; phys_addr_t phys_addr; + phys_addr_t dst_phys_addr; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; + struct device *dma_dev = epf->epc->dev.parent; enum pci_barno test_reg_bar = epf_test->test_reg_bar; struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; @@ -169,12 +306,38 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) goto err_map_addr; } - memcpy_fromio(buf, src_addr, reg->size); + use_dma = !!(reg->flags & FLAG_USE_DMA); + if (use_dma) { + if (!epf_test->dma_supported) { + dev_err(dev, "Cannot transfer data using DMA\n"); + ret = -EINVAL; + goto err_map_addr; + } + + dst_phys_addr = dma_map_single(dma_dev, buf, reg->size, + DMA_FROM_DEVICE); + if (dma_mapping_error(dma_dev, dst_phys_addr)) { + dev_err(dev, "Failed to map destination buffer addr\n"); + ret = -ENOMEM; + goto err_dma_map; + } + + ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr, + phys_addr, reg->size); + if (ret) + dev_err(dev, "Data transfer failed\n"); + + dma_unmap_single(dma_dev, dst_phys_addr, reg->size, + DMA_FROM_DEVICE); + } else { + memcpy_fromio(buf, src_addr, reg->size); + } crc32 = crc32_le(~0, buf, reg->size); if (crc32 != reg->checksum) ret = -EIO; +err_dma_map: kfree(buf); err_map_addr: @@ -192,10 +355,13 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) int ret; void __iomem *dst_addr; void *buf; + bool use_dma; phys_addr_t phys_addr; + phys_addr_t src_phys_addr; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; + struct device *dma_dev = epf->epc->dev.parent; enum pci_barno test_reg_bar = epf_test->test_reg_bar; struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; @@ -224,7 +390,32 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) get_random_bytes(buf, reg->size); reg->checksum = crc32_le(~0, buf, reg->size); - memcpy_toio(dst_addr, buf, reg->size); + use_dma = !!(reg->flags & FLAG_USE_DMA); + if (use_dma) { + if (!epf_test->dma_supported) { + dev_err(dev, "Cannot transfer data using DMA\n"); + ret = -EINVAL; + goto err_map_addr; + } + + src_phys_addr = dma_map_single(dma_dev, buf, reg->size, + DMA_TO_DEVICE); + if (dma_mapping_error(dma_dev, src_phys_addr)) { + dev_err(dev, "Failed to map source buffer addr\n"); + ret = -ENOMEM; + goto err_dma_map; + } + + ret = pci_epf_test_data_transfer(epf_test, phys_addr, + src_phys_addr, reg->size); + if (ret) + dev_err(dev, "Data transfer failed\n"); + + dma_unmap_single(dma_dev, src_phys_addr, reg->size, + DMA_TO_DEVICE); + } else { + memcpy_toio(dst_addr, buf, reg->size); + } /* * wait 1ms inorder for the write to complete. Without this delay L3 @@ -232,6 +423,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) */ usleep_range(1000, 2000); +err_dma_map: kfree(buf); err_map_addr: @@ -380,6 +572,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf) int bar; cancel_delayed_work(&epf_test->cmd_handler); + pci_epf_clean_dma_chan(epf_test); pci_epc_stop(epc); for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { epf_bar = &epf->bar[bar]; @@ -550,6 +743,12 @@ static int pci_epf_test_bind(struct pci_epf *epf) } } + epf_test->dma_supported = true; + + ret = pci_epf_init_dma_chan(epf_test); + if (ret) + epf_test->dma_supported = false; + if (linkup_notifier) { epf->nb.notifier_call = pci_epf_test_notifier; pci_epc_register_notifier(epc, &epf->nb); From patchwork Tue Feb 25 09:11:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 1243938 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=qV56VK/A; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48RY3f4SdSz9sRY for ; Tue, 25 Feb 2020 20:07:26 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729903AbgBYJHW (ORCPT ); Tue, 25 Feb 2020 04:07:22 -0500 Received: from lelv0143.ext.ti.com ([198.47.23.248]:57048 "EHLO lelv0143.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729898AbgBYJHV (ORCPT ); Tue, 25 Feb 2020 04:07:21 -0500 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01P97Eth115001; Tue, 25 Feb 2020 03:07:14 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582621634; bh=Bq3pAD0OdG6ZmZKpUZqs5/tQpPJOIse28CO39y2SDaw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=qV56VK/AujqAuPkEJWQz76Bim+hfYiEGW/X3QzgEGduVRbUdAk8qrKqVNNbI2rgkL /pZ1m3CHV45vFMbZNS/zwEcVHx4O7KeGIEYSPd2+bw9F4jSBwwgmxve43NBPOMjDdP EHOpX3q5cjqtjpG7wvHVhsOWhjpV/zOMb6e/mNgw= Received: from DLEE104.ent.ti.com (dlee104.ent.ti.com [157.170.170.34]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01P97EDl038406 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 25 Feb 2020 03:07:14 -0600 Received: from DLEE112.ent.ti.com (157.170.170.23) by DLEE104.ent.ti.com (157.170.170.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Tue, 25 Feb 2020 03:07:13 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE112.ent.ti.com (157.170.170.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Tue, 25 Feb 2020 03:07:13 -0600 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01P973Pq052643; Tue, 25 Feb 2020 03:07:11 -0600 From: Kishon Vijay Abraham I To: Lorenzo Pieralisi , Arnd Bergmann , Andrew Murray , Kishon Vijay Abraham I CC: Greg Kroah-Hartman , Bjorn Helgaas , Alan Mikhak , , Subject: [PATCH 2/5] PCI: endpoint: functions/pci-epf-test: Print throughput information Date: Tue, 25 Feb 2020 14:41:27 +0530 Message-ID: <20200225091130.29467-3-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200225091130.29467-1-kishon@ti.com> References: <20200225091130.29467-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Print throughput information in KB/s after every completed transfer, including information on whether DMA is used or not. Signed-off-by: Kishon Vijay Abraham I --- drivers/pci/endpoint/functions/pci-epf-test.c | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 4e5ed37110ed..db15b080519d 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -190,6 +190,36 @@ static void pci_epf_clean_dma_chan(struct pci_epf_test *epf_test) epf_test->dma_chan = NULL; } +static void pci_epf_print_rate(const char *ops, u64 size, + struct timespec64 *start, struct timespec64 *end, + bool dma) +{ + struct timespec64 ts; + u64 rate, ns; + + ts = timespec64_sub(*end, *start); + + /* convert both size (stored in 'rate') and time in terms of 'ns' */ + ns = timespec64_to_ns(&ts); + rate = size * NSEC_PER_SEC; + + /* Divide both size (stored in 'rate') and ns by a common factor */ + while (ns > UINT_MAX) { + rate >>= 1; + ns >>= 1; + } + + if (!ns) + return; + + /* calculate the rate */ + do_div(rate, (uint32_t)ns); + + pr_info("\n%s => Size: %llu bytes\t DMA: %s\t Time: %llu.%09u seconds\t" + "Rate: %llu KB/s\n", ops, size, dma ? "YES" : "NO", + (u64)ts.tv_sec, (u32)ts.tv_nsec, rate / 1024); +} + static int pci_epf_test_copy(struct pci_epf_test *epf_test) { int ret; @@ -198,6 +228,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) void __iomem *dst_addr; phys_addr_t src_phys_addr; phys_addr_t dst_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -236,6 +267,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_dst_addr; } + ktime_get_ts64(&start); use_dma = !!(reg->flags & FLAG_USE_DMA); if (use_dma) { if (!epf_test->dma_supported) { @@ -251,6 +283,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) } else { memcpy(dst_addr, src_addr, reg->size); } + ktime_get_ts64(&end); + pci_epf_print_rate("COPY", reg->size, &start, &end, use_dma); err_map_addr: pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr); @@ -277,6 +311,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) bool use_dma; phys_addr_t phys_addr; phys_addr_t dst_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -322,17 +357,23 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) goto err_dma_map; } + ktime_get_ts64(&start); ret = pci_epf_test_data_transfer(epf_test, dst_phys_addr, phys_addr, reg->size); if (ret) dev_err(dev, "Data transfer failed\n"); + ktime_get_ts64(&end); dma_unmap_single(dma_dev, dst_phys_addr, reg->size, DMA_FROM_DEVICE); } else { + ktime_get_ts64(&start); memcpy_fromio(buf, src_addr, reg->size); + ktime_get_ts64(&end); } + pci_epf_print_rate("READ", reg->size, &start, &end, use_dma); + crc32 = crc32_le(~0, buf, reg->size); if (crc32 != reg->checksum) ret = -EIO; @@ -358,6 +399,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) bool use_dma; phys_addr_t phys_addr; phys_addr_t src_phys_addr; + struct timespec64 start, end; struct pci_epf *epf = epf_test->epf; struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; @@ -406,17 +448,23 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) goto err_dma_map; } + ktime_get_ts64(&start); ret = pci_epf_test_data_transfer(epf_test, phys_addr, src_phys_addr, reg->size); if (ret) dev_err(dev, "Data transfer failed\n"); + ktime_get_ts64(&end); dma_unmap_single(dma_dev, src_phys_addr, reg->size, DMA_TO_DEVICE); } else { + ktime_get_ts64(&start); memcpy_toio(dst_addr, buf, reg->size); + ktime_get_ts64(&end); } + pci_epf_print_rate("WRITE", reg->size, &start, &end, use_dma); + /* * wait 1ms inorder for the write to complete. Without this delay L3 * error in observed in the host system. From patchwork Tue Feb 25 09:11:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 1243941 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=ZCBv65Tp; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48RY3v2RH2z9sPK for ; Tue, 25 Feb 2020 20:07:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729671AbgBYJH0 (ORCPT ); Tue, 25 Feb 2020 04:07:26 -0500 Received: from lelv0142.ext.ti.com ([198.47.23.249]:47774 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729898AbgBYJH0 (ORCPT ); Tue, 25 Feb 2020 04:07:26 -0500 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01P97HMZ037706; Tue, 25 Feb 2020 03:07:17 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582621637; bh=hCKNQuZUkcO4X0mn7TApsybUnUlRIUHHECrZXl5Tk+M=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=ZCBv65TplXENW9la844gM+R0apc1iThbJL4yhuI/qFYxihbKrUA56vgP5NwVyiO/G yvE+Eie4ZyIvXbwY98bZ4yRrN1XI7METAmqsDNjzghkIsmF5vQLxZYdsr4xVc1LRIf MRNZSZg1fHPW6M6wDcyf3/qhRv+dN8vihYrmLjDM= Received: from DFLE108.ent.ti.com (dfle108.ent.ti.com [10.64.6.29]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01P97HYl035122 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 25 Feb 2020 03:07:17 -0600 Received: from DFLE112.ent.ti.com (10.64.6.33) by DFLE108.ent.ti.com (10.64.6.29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Tue, 25 Feb 2020 03:07:17 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE112.ent.ti.com (10.64.6.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Tue, 25 Feb 2020 03:07:17 -0600 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01P973Pr052643; Tue, 25 Feb 2020 03:07:14 -0600 From: Kishon Vijay Abraham I To: Lorenzo Pieralisi , Arnd Bergmann , Andrew Murray , Kishon Vijay Abraham I CC: Greg Kroah-Hartman , Bjorn Helgaas , Alan Mikhak , , , Sekhar Nori Subject: [PATCH 3/5] misc: pci_endpoint_test: Use streaming DMA APIs for buffer allocation Date: Tue, 25 Feb 2020 14:41:28 +0530 Message-ID: <20200225091130.29467-4-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200225091130.29467-1-kishon@ti.com> References: <20200225091130.29467-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Use streaming DMA APIs (dma_map_single/dma_unmap_single) for buffers transmitted/received by the endpoint device instead of allocating a coherent memory. Also add default_data to set the alignment to 4KB since dma_map_single might not return a 4KB aligned address. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Sekhar Nori --- drivers/misc/pci_endpoint_test.c | 100 ++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 21 deletions(-) diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index a5e317073d95..5998df1c84e9 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -341,14 +341,22 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) goto err; } - orig_src_addr = dma_alloc_coherent(dev, size + alignment, - &orig_src_phys_addr, GFP_KERNEL); + orig_src_addr = kzalloc(size + alignment, GFP_KERNEL); if (!orig_src_addr) { dev_err(dev, "Failed to allocate source buffer\n"); ret = false; goto err; } + get_random_bytes(orig_src_addr, size + alignment); + orig_src_phys_addr = dma_map_single(dev, orig_src_addr, + size + alignment, DMA_TO_DEVICE); + if (dma_mapping_error(dev, orig_src_phys_addr)) { + dev_err(dev, "failed to map source buffer address\n"); + ret = false; + goto err_src_phys_addr; + } + if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) { src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment); offset = src_phys_addr - orig_src_phys_addr; @@ -364,15 +372,21 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR, upper_32_bits(src_phys_addr)); - get_random_bytes(src_addr, size); src_crc32 = crc32_le(~0, src_addr, size); - orig_dst_addr = dma_alloc_coherent(dev, size + alignment, - &orig_dst_phys_addr, GFP_KERNEL); + orig_dst_addr = kzalloc(size + alignment, GFP_KERNEL); if (!orig_dst_addr) { dev_err(dev, "Failed to allocate destination address\n"); ret = false; - goto err_orig_src_addr; + goto err_dst_addr; + } + + orig_dst_phys_addr = dma_map_single(dev, orig_dst_addr, + size + alignment, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, orig_dst_phys_addr)) { + dev_err(dev, "failed to map destination buffer address\n"); + ret = false; + goto err_dst_phys_addr; } if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) { @@ -399,16 +413,22 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) wait_for_completion(&test->irq_raised); + dma_unmap_single(dev, orig_dst_phys_addr, size + alignment, + DMA_FROM_DEVICE); + dst_crc32 = crc32_le(~0, dst_addr, size); if (dst_crc32 == src_crc32) ret = true; - dma_free_coherent(dev, size + alignment, orig_dst_addr, - orig_dst_phys_addr); +err_dst_phys_addr: + kfree(orig_dst_addr); -err_orig_src_addr: - dma_free_coherent(dev, size + alignment, orig_src_addr, - orig_src_phys_addr); +err_dst_addr: + dma_unmap_single(dev, orig_src_phys_addr, size + alignment, + DMA_TO_DEVICE); + +err_src_phys_addr: + kfree(orig_src_addr); err: return ret; @@ -436,14 +456,23 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) goto err; } - orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, - GFP_KERNEL); + orig_addr = kzalloc(size + alignment, GFP_KERNEL); if (!orig_addr) { dev_err(dev, "Failed to allocate address\n"); ret = false; goto err; } + get_random_bytes(orig_addr, size + alignment); + + orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, orig_phys_addr)) { + dev_err(dev, "failed to map source buffer address\n"); + ret = false; + goto err_phys_addr; + } + if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) { phys_addr = PTR_ALIGN(orig_phys_addr, alignment); offset = phys_addr - orig_phys_addr; @@ -453,8 +482,6 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) addr = orig_addr; } - get_random_bytes(addr, size); - crc32 = crc32_le(~0, addr, size); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM, crc32); @@ -477,7 +504,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) if (reg & STATUS_READ_SUCCESS) ret = true; - dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr); + dma_unmap_single(dev, orig_phys_addr, size + alignment, + DMA_TO_DEVICE); + +err_phys_addr: + kfree(orig_addr); err: return ret; @@ -504,14 +535,21 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) goto err; } - orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, - GFP_KERNEL); + orig_addr = kzalloc(size + alignment, GFP_KERNEL); if (!orig_addr) { dev_err(dev, "Failed to allocate destination address\n"); ret = false; goto err; } + orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment, + DMA_FROM_DEVICE); + if (dma_mapping_error(dev, orig_phys_addr)) { + dev_err(dev, "failed to map source buffer address\n"); + ret = false; + goto err_phys_addr; + } + if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) { phys_addr = PTR_ALIGN(orig_phys_addr, alignment); offset = phys_addr - orig_phys_addr; @@ -535,11 +573,15 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) wait_for_completion(&test->irq_raised); + dma_unmap_single(dev, orig_phys_addr, size + alignment, + DMA_FROM_DEVICE); + crc32 = crc32_le(~0, addr, size); if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM)) ret = true; - dma_free_coherent(dev, size + alignment, orig_addr, orig_phys_addr); +err_phys_addr: + kfree(orig_addr); err: return ret; } @@ -667,6 +709,12 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, init_completion(&test->irq_raised); mutex_init(&test->mutex); + if ((dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48)) != 0) && + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { + dev_err(dev, "Cannot set DMA mask\n"); + return -EINVAL; + } + err = pci_enable_device(pdev); if (err) { dev_err(dev, "Cannot enable PCI device\n"); @@ -783,6 +831,12 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) pci_disable_device(pdev); } +static const struct pci_endpoint_test_data default_data = { + .test_reg_bar = BAR_0, + .alignment = SZ_4K, + .irq_type = IRQ_TYPE_MSI, +}; + static const struct pci_endpoint_test_data am654_data = { .test_reg_bar = BAR_2, .alignment = SZ_64K, @@ -790,8 +844,12 @@ static const struct pci_endpoint_test_data am654_data = { }; static const struct pci_device_id pci_endpoint_test_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) }, - { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) }, + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x), + .driver_data = (kernel_ulong_t)&default_data, + }, + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x), + .driver_data = (kernel_ulong_t)&default_data, + }, { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0) }, { PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) }, { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654), From patchwork Tue Feb 25 09:11:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 1243939 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=TGkMs6a3; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48RY3k6SKjz9sQt for ; Tue, 25 Feb 2020 20:07:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729945AbgBYJH2 (ORCPT ); Tue, 25 Feb 2020 04:07:28 -0500 Received: from fllv0016.ext.ti.com ([198.47.19.142]:54924 "EHLO fllv0016.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729939AbgBYJH2 (ORCPT ); Tue, 25 Feb 2020 04:07:28 -0500 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01P97K8S069057; Tue, 25 Feb 2020 03:07:20 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582621640; bh=2hjND1deYWq3ajV8ZakOoqLQXl+slE0s02toOqNb+4o=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=TGkMs6a3+9BttUmw8QZsK/5AsiSoNxBujxATODDFRLtJnzyS4dLEwcrU02gV7kRXV qjaX/ddob5Ln1dCq7wAv5ETHQiOL9AF2jzmyCNEBn2uPOYdOKvhbtDteRS65Ye/Q0b xx38uRNVOI5gB23/4BDsW0RfeFx63TYLOa4J3emw= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01P97KNo038537 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 25 Feb 2020 03:07:20 -0600 Received: from DFLE113.ent.ti.com (10.64.6.34) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Tue, 25 Feb 2020 03:07:20 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DFLE113.ent.ti.com (10.64.6.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Tue, 25 Feb 2020 03:07:20 -0600 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01P973Ps052643; Tue, 25 Feb 2020 03:07:17 -0600 From: Kishon Vijay Abraham I To: Lorenzo Pieralisi , Arnd Bergmann , Andrew Murray , Kishon Vijay Abraham I CC: Greg Kroah-Hartman , Bjorn Helgaas , Alan Mikhak , , Subject: [PATCH 4/5] tools: PCI: Add 'd' command line option to support DMA Date: Tue, 25 Feb 2020 14:41:29 +0530 Message-ID: <20200225091130.29467-5-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200225091130.29467-1-kishon@ti.com> References: <20200225091130.29467-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Add a new command line option 'd' to use DMA for data transfers. It should be used with read, write or copy commands. Signed-off-by: Kishon Vijay Abraham I --- include/uapi/linux/pcitest.h | 5 +++++ tools/pci/pcitest.c | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h index cbf422e56696..1a63999e3deb 100644 --- a/include/uapi/linux/pcitest.h +++ b/include/uapi/linux/pcitest.h @@ -20,4 +20,9 @@ #define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int) #define PCITEST_GET_IRQTYPE _IO('P', 0x9) +struct pci_endpoint_test_xfer_param { + unsigned long size; + bool use_dma; +}; + #endif /* __UAPI_LINUX_PCITEST_H */ diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index 32b7c6f9043d..be79ec10cefc 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -34,10 +34,12 @@ struct pci_test { bool write; bool copy; unsigned long size; + bool use_dma; }; static int run_test(struct pci_test *test) { + struct pci_endpoint_test_xfer_param param; int ret = -EINVAL; int fd; @@ -102,7 +104,9 @@ static int run_test(struct pci_test *test) } if (test->write) { - ret = ioctl(fd, PCITEST_WRITE, test->size); + param.size = test->size; + param.use_dma = test->use_dma; + ret = ioctl(fd, PCITEST_WRITE, ¶m); fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); if (ret < 0) fprintf(stdout, "TEST FAILED\n"); @@ -111,7 +115,9 @@ static int run_test(struct pci_test *test) } if (test->read) { - ret = ioctl(fd, PCITEST_READ, test->size); + param.size = test->size; + param.use_dma = test->use_dma; + ret = ioctl(fd, PCITEST_READ, ¶m); fprintf(stdout, "READ (%7ld bytes):\t\t", test->size); if (ret < 0) fprintf(stdout, "TEST FAILED\n"); @@ -120,7 +126,9 @@ static int run_test(struct pci_test *test) } if (test->copy) { - ret = ioctl(fd, PCITEST_COPY, test->size); + param.size = test->size; + param.use_dma = test->use_dma; + ret = ioctl(fd, PCITEST_COPY, ¶m); fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size); if (ret < 0) fprintf(stdout, "TEST FAILED\n"); @@ -153,7 +161,7 @@ int main(int argc, char **argv) /* set default endpoint device */ test->device = "/dev/pci-endpoint-test.0"; - while ((c = getopt(argc, argv, "D:b:m:x:i:Ilhrwcs:")) != EOF) + while ((c = getopt(argc, argv, "D:b:m:x:i:dIlhrwcs:")) != EOF) switch (c) { case 'D': test->device = optarg; @@ -197,6 +205,9 @@ int main(int argc, char **argv) case 's': test->size = strtoul(optarg, NULL, 0); continue; + case 'd': + test->use_dma = true; + continue; case 'h': default: usage: @@ -209,6 +220,7 @@ int main(int argc, char **argv) "\t-x \tMSI-X test (msix number between 1..2048)\n" "\t-i \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n" "\t-I Get current IRQ type configured\n" + "\t-d Use DMA\n" "\t-l Legacy IRQ test\n" "\t-r Read buffer test\n" "\t-w Write buffer test\n" From patchwork Tue Feb 25 09:11:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kishon Vijay Abraham I X-Patchwork-Id: 1243940 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=vBssXWcV; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 48RY3p6Cbgz9sRY for ; Tue, 25 Feb 2020 20:07:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729960AbgBYJHc (ORCPT ); Tue, 25 Feb 2020 04:07:32 -0500 Received: from lelv0142.ext.ti.com ([198.47.23.249]:47814 "EHLO lelv0142.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729939AbgBYJHc (ORCPT ); Tue, 25 Feb 2020 04:07:32 -0500 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 01P97OGU037744; Tue, 25 Feb 2020 03:07:24 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1582621644; bh=JRl5ARotx9L0/8W2ZWBpmQ2FofoiaRYaIrBYg+s9K+o=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=vBssXWcV9JJRIxNEimRPO96+IRamMXSc0g68WQHDEmdBR3Kt8JYEMxoEAwHJnD+EC RrBT+qThMcSefaASiSzK4eqQe2bPisqwauLk5pcbZZz6EbaVfhi6gDmlybYN8o9F0s jjFnyd2xFDU5jCnPiNT3NMDUFWy8iGA8qUbnwUsI= Received: from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 01P97Oag035346 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 25 Feb 2020 03:07:24 -0600 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE101.ent.ti.com (157.170.170.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3; Tue, 25 Feb 2020 03:07:23 -0600 Received: from lelv0326.itg.ti.com (10.180.67.84) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1847.3 via Frontend Transport; Tue, 25 Feb 2020 03:07:23 -0600 Received: from a0393678ub.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0326.itg.ti.com (8.15.2/8.15.2) with ESMTP id 01P973Pt052643; Tue, 25 Feb 2020 03:07:21 -0600 From: Kishon Vijay Abraham I To: Lorenzo Pieralisi , Arnd Bergmann , Andrew Murray , Kishon Vijay Abraham I CC: Greg Kroah-Hartman , Bjorn Helgaas , Alan Mikhak , , Subject: [PATCH 5/5] misc: pci_endpoint_test: Add support to get DMA option from userspace Date: Tue, 25 Feb 2020 14:41:30 +0530 Message-ID: <20200225091130.29467-6-kishon@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200225091130.29467-1-kishon@ti.com> References: <20200225091130.29467-1-kishon@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org 'pcitest' utility now uses '-d' option to allow the user to test DMA. Add support to parse option to use DMA from userspace application. Signed-off-by: Kishon Vijay Abraham I --- drivers/misc/pci_endpoint_test.c | 65 ++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 5998df1c84e9..3f102356b600 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ #define STATUS_SRC_ADDR_INVALID BIT(7) #define STATUS_DST_ADDR_INVALID BIT(8) +#define PCI_ENDPOINT_TEST_STATUS 0x8 #define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0x0c #define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10 @@ -64,6 +66,9 @@ #define PCI_ENDPOINT_TEST_IRQ_TYPE 0x24 #define PCI_ENDPOINT_TEST_IRQ_NUMBER 0x28 +#define PCI_ENDPOINT_TEST_FLAGS 0x2c +#define FLAG_USE_DMA BIT(0) + #define PCI_DEVICE_ID_TI_AM654 0xb00c #define is_am654_pci_dev(pdev) \ @@ -315,11 +320,16 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, return false; } -static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) +static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, + unsigned long arg) { + struct pci_endpoint_test_xfer_param param; bool ret = false; void *src_addr; void *dst_addr; + u32 flags = 0; + bool use_dma; + size_t size; dma_addr_t src_phys_addr; dma_addr_t dst_phys_addr; struct pci_dev *pdev = test->pdev; @@ -332,10 +342,22 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) size_t alignment = test->alignment; u32 src_crc32; u32 dst_crc32; + int err; + + err = copy_from_user(¶m, (void *)arg, sizeof(param)); + if (err) { + dev_err(dev, "Failed to get transfer param\n"); + return false; + } + size = param.size; if (size > SIZE_MAX - alignment) goto err; + use_dma = param.use_dma; + if (use_dma) + flags |= FLAG_USE_DMA; + if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) { dev_err(dev, "Invalid IRQ type option\n"); goto err; @@ -406,6 +428,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, @@ -434,9 +457,13 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) return ret; } -static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) +static bool pci_endpoint_test_write(struct pci_endpoint_test *test, + unsigned long arg) { + struct pci_endpoint_test_xfer_param param; bool ret = false; + u32 flags = 0; + bool use_dma; u32 reg; void *addr; dma_addr_t phys_addr; @@ -446,11 +473,24 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) dma_addr_t orig_phys_addr; size_t offset; size_t alignment = test->alignment; + size_t size; u32 crc32; + int err; + err = copy_from_user(¶m, (void *)arg, sizeof(param)); + if (err != 0) { + dev_err(dev, "Failed to get transfer param\n"); + return false; + } + + size = param.size; if (size > SIZE_MAX - alignment) goto err; + use_dma = param.use_dma; + if (use_dma) + flags |= FLAG_USE_DMA; + if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) { dev_err(dev, "Invalid IRQ type option\n"); goto err; @@ -493,6 +533,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, @@ -514,9 +555,14 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) return ret; } -static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) +static bool pci_endpoint_test_read(struct pci_endpoint_test *test, + unsigned long arg) { + struct pci_endpoint_test_xfer_param param; bool ret = false; + u32 flags = 0; + bool use_dma; + size_t size; void *addr; dma_addr_t phys_addr; struct pci_dev *pdev = test->pdev; @@ -526,10 +572,22 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) size_t offset; size_t alignment = test->alignment; u32 crc32; + int err; + err = copy_from_user(¶m, (void *)arg, sizeof(param)); + if (err) { + dev_err(dev, "Failed to get transfer param\n"); + return false; + } + + size = param.size; if (size > SIZE_MAX - alignment) goto err; + use_dma = param.use_dma; + if (use_dma) + flags |= FLAG_USE_DMA; + if (irq_type < IRQ_TYPE_LEGACY || irq_type > IRQ_TYPE_MSIX) { dev_err(dev, "Invalid IRQ type option\n"); goto err; @@ -566,6 +624,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1); pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,