From patchwork Tue Apr 10 17:14:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896845 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDQY4DPcz9s2S for ; Wed, 11 Apr 2018 03:18:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751983AbeDJRR6 (ORCPT ); Tue, 10 Apr 2018 13:17:58 -0400 Received: from us01smtprelay-2.synopsys.com ([198.182.60.111]:60194 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751799AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id 779B410C0A41; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from pt02.synopsys.com (pt02.internal.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id D0ACA3F2B; Tue, 10 Apr 2018 10:14:53 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 355A43D7BF; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 01/10] PCI: dwc: Add MSI-X callbacks handler Date: Tue, 10 Apr 2018 18:14:40 +0100 Message-Id: <77b7b2687e9618d3f7d1f11c3fc6ecec9a9442ef.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Changes the pcie_raise_irq function signature, namely the interrupt_num variable type from u8 to u16 to accommodate the MSI-X maximum interrupts of 2048. Implements a PCIe config space capability iterator function to search and save the MSI and MSI-X pointers. With this method the code becomes more generic and flexible. Implements MSI-X set/get functions for sysfs interface in order to change the EP entries number. Implements EP MSI-X interface for triggering interruptions. Signed-off-by: Gustavo Pimentel --- drivers/pci/dwc/pci-dra7xx.c | 2 +- drivers/pci/dwc/pcie-artpec6.c | 2 +- drivers/pci/dwc/pcie-designware-ep.c | 145 ++++++++++++++++++++++++++++++++- drivers/pci/dwc/pcie-designware-plat.c | 6 +- drivers/pci/dwc/pcie-designware.h | 23 +++++- 5 files changed, 173 insertions(+), 5 deletions(-) diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c index ed8558d..5265725 100644 --- a/drivers/pci/dwc/pci-dra7xx.c +++ b/drivers/pci/dwc/pci-dra7xx.c @@ -369,7 +369,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx, } static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, - enum pci_epc_irq_type type, u8 interrupt_num) + enum pci_epc_irq_type type, u16 interrupt_num) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c index e66cede..96dc259 100644 --- a/drivers/pci/dwc/pcie-artpec6.c +++ b/drivers/pci/dwc/pcie-artpec6.c @@ -428,7 +428,7 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep) } static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, - enum pci_epc_irq_type type, u8 interrupt_num) + enum pci_epc_irq_type type, u16 interrupt_num) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 15b22a6..874d4c2 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -40,6 +40,44 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) __dw_pcie_ep_reset_bar(pci, bar, 0); } +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + u8 next_ptr, curr_ptr, cap_id; + u16 reg; + + memset(&ep->cap_addr, 0, sizeof(ep->cap_addr)); + + reg = dw_pcie_readw_dbi(pci, PCI_STATUS); + if (!(reg & PCI_STATUS_CAP_LIST)) + return; + + reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST); + next_ptr = (reg & 0x00ff); + if (!next_ptr) + return; + + reg = dw_pcie_readw_dbi(pci, next_ptr); + curr_ptr = next_ptr; + next_ptr = (reg & 0xff00) >> 8; + cap_id = (reg & 0x00ff); + + while (next_ptr && (cap_id <= PCI_CAP_ID_MAX)) { + switch (cap_id) { + case PCI_CAP_ID_MSI: + ep->cap_addr.msi_addr = curr_ptr; + break; + case PCI_CAP_ID_MSIX: + ep->cap_addr.msix_addr = curr_ptr; + break; + } + reg = dw_pcie_readw_dbi(pci, next_ptr); + curr_ptr = next_ptr; + next_ptr = (reg & 0xff00) >> 8; + cap_id = (reg & 0x00ff); + } +} + static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, struct pci_epf_header *hdr) { @@ -241,8 +279,47 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) return 0; } +static int dw_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no) +{ + struct dw_pcie_ep *ep = epc_get_drvdata(epc); + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + u32 val, reg; + + if (ep->cap_addr.msix_addr == 0) + return 0; + + reg = ep->cap_addr.msix_addr + PCI_MSIX_FLAGS; + val = dw_pcie_readw_dbi(pci, reg); + if (!(val & PCI_MSIX_FLAGS_ENABLE)) + return -EINVAL; + + val &= PCI_MSIX_FLAGS_QSIZE; + + return val; +} + +static int dw_pcie_ep_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts) +{ + struct dw_pcie_ep *ep = epc_get_drvdata(epc); + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + u32 val, reg; + + if (ep->cap_addr.msix_addr == 0) + return 0; + + reg = ep->cap_addr.msix_addr + PCI_MSIX_FLAGS; + val = dw_pcie_readw_dbi(pci, reg); + val &= ~PCI_MSIX_FLAGS_QSIZE; + val |= interrupts; + dw_pcie_dbi_ro_wr_en(pci); + dw_pcie_writew_dbi(pci, reg, val); + dw_pcie_dbi_ro_wr_dis(pci); + + return 0; +} + static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, - enum pci_epc_irq_type type, u8 interrupt_num) + enum pci_epc_irq_type type, u16 interrupt_num) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -282,6 +359,8 @@ static const struct pci_epc_ops epc_ops = { .unmap_addr = dw_pcie_ep_unmap_addr, .set_msi = dw_pcie_ep_set_msi, .get_msi = dw_pcie_ep_get_msi, + .set_msix = dw_pcie_ep_set_msix, + .get_msix = dw_pcie_ep_get_msix, .raise_irq = dw_pcie_ep_raise_irq, .start = dw_pcie_ep_start, .stop = dw_pcie_ep_stop, @@ -322,6 +401,60 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, return 0; } +int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, + u16 interrupt_num) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + struct pci_epc *epc = ep->epc; + u16 tbl_offset, bir; + u32 bar_addr_upper, bar_addr_lower; + u32 msg_addr_upper, msg_addr_lower; + u32 reg, msg_data; + u64 tbl_addr, msg_addr, reg_u64; + void __iomem *msix_tbl; + int ret; + + reg = ep->cap_addr.msix_addr + PCI_MSIX_TABLE; + tbl_offset = dw_pcie_readl_dbi(pci, reg); + bir = (tbl_offset & PCI_MSIX_TABLE_BIR); + tbl_offset &= PCI_MSIX_TABLE_OFFSET; + tbl_offset >>= 3; + + reg = PCI_BASE_ADDRESS_0 + (4 * bir); + bar_addr_lower = dw_pcie_readl_dbi(pci, reg); + reg_u64 = (bar_addr_lower & PCI_BASE_ADDRESS_MEM_TYPE_MASK); + if (reg_u64 == PCI_BASE_ADDRESS_MEM_TYPE_64) + bar_addr_upper = dw_pcie_readl_dbi(pci, reg + 4); + else + bar_addr_upper = 0; + + tbl_addr = ((u64) bar_addr_upper) << 32 | bar_addr_lower; + tbl_addr += (tbl_offset + ((interrupt_num - 1) * PCI_MSIX_ENTRY_SIZE)); + tbl_addr &= PCI_BASE_ADDRESS_MEM_MASK; + + msix_tbl = ioremap_nocache(ep->phys_base + tbl_addr, ep->addr_size); + if (!msix_tbl) + return -EINVAL; + + msg_addr_lower = readl(msix_tbl + PCI_MSIX_ENTRY_LOWER_ADDR); + msg_addr_upper = readl(msix_tbl + PCI_MSIX_ENTRY_UPPER_ADDR); + msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower; + msg_data = readl(msix_tbl + PCI_MSIX_ENTRY_DATA); + + iounmap(msix_tbl); + + ret = dw_pcie_ep_map_addr(epc, func_no, ep->msix_mem_phys, msg_addr, + epc->mem->page_size); + if (ret) + return ret; + + writel(msg_data, ep->msix_mem); + + dw_pcie_ep_unmap_addr(epc, func_no, ep->msix_mem_phys); + + return 0; +} + void dw_pcie_ep_exit(struct dw_pcie_ep *ep) { struct pci_epc *epc = ep->epc; @@ -329,6 +462,9 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep) pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem, epc->mem->page_size); + pci_epc_mem_free_addr(epc, ep->msix_mem_phys, ep->msix_mem, + epc->mem->page_size); + pci_epc_mem_exit(epc); } @@ -411,6 +547,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) return -ENOMEM; } + ep->msix_mem = pci_epc_mem_alloc_addr(epc, &ep->msix_mem_phys, + epc->mem->page_size); + if (!ep->msix_mem) { + dev_err(dev, "Failed to reserve memory for MSI-\n"); + return -ENOMEM; + } + ep->epc = epc; epc_set_drvdata(epc, ep); dw_pcie_setup(pci); diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c index 2bad68d..c3a4707 100644 --- a/drivers/pci/dwc/pcie-designware-plat.c +++ b/drivers/pci/dwc/pcie-designware-plat.c @@ -74,11 +74,13 @@ static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep) for (bar = BAR_0; bar <= BAR_5; bar++) dw_pcie_ep_reset_bar(pci, bar); + + dw_pcie_ep_find_cap_addr(ep); } static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, enum pci_epc_irq_type type, - u8 interrupt_num) + u16 interrupt_num) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -88,6 +90,8 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, return -EINVAL; case PCI_EPC_IRQ_MSI: return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); + case PCI_EPC_IRQ_MSIX: + return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num); default: dev_err(pci->dev, "UNKNOWN IRQ type\n"); } diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index bee4e25..456fd94 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h @@ -191,7 +191,12 @@ enum dw_pcie_as_type { struct dw_pcie_ep_ops { void (*ep_init)(struct dw_pcie_ep *ep); int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, - enum pci_epc_irq_type type, u8 interrupt_num); + enum pci_epc_irq_type type, u16 interrupt_num); +}; + +struct dw_pcie_cap_addr { + u8 msi_addr; + u8 msix_addr; }; struct dw_pcie_ep { @@ -208,6 +213,9 @@ struct dw_pcie_ep { u32 num_ob_windows; void __iomem *msi_mem; phys_addr_t msi_mem_phys; + void __iomem *msix_mem; + phys_addr_t msix_mem_phys; + struct dw_pcie_cap_addr cap_addr; }; struct dw_pcie_ops { @@ -359,7 +367,10 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep); void dw_pcie_ep_exit(struct dw_pcie_ep *ep); int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num); +int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, + u16 interrupt_num); void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar); +void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep); #else static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) { @@ -380,8 +391,18 @@ static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, return 0; } +static inline int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, + u16 interrupt_num) +{ + return 0; +} + static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) { } + +static inline void dw_pcie_ep_find_cap_addr(struct dw_pcie_ep *ep) +{ +} #endif #endif /* _PCIE_DESIGNWARE_H */ From patchwork Tue Apr 10 17:14:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896835 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDMR3cQsz9s3C for ; Wed, 11 Apr 2018 03:15:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752099AbeDJRO6 (ORCPT ); Tue, 10 Apr 2018 13:14:58 -0400 Received: from smtprelay.synopsys.com ([198.182.47.9]:35901 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751676AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id 5527F24E0BDF; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from pt02.synopsys.com (pt02.internal.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 175923F30; Tue, 10 Apr 2018 10:14:53 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 424B93D7C2; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 02/10] PCI: cadence: Update cdns_pcie_ep_raise_irq function signature Date: Tue, 10 Apr 2018 18:14:41 +0100 Message-Id: <52314006c63f8d21907dfaa03207b39e36bb8171.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Changes the cdns_pcie_ep_raise_irq function signature, namely the interrupt_num variable type from u8 to u16 to accommodate the MSI-X maximum interrupts of 2048. Signed-off-by: Gustavo Pimentel Acked-by: Alan Douglas --- drivers/pci/cadence/pcie-cadence-ep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c index 3d8283e..6d6322c 100644 --- a/drivers/pci/cadence/pcie-cadence-ep.c +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -363,7 +363,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn, } static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn, - enum pci_epc_irq_type type, u8 interrupt_num) + enum pci_epc_irq_type type, u16 interrupt_num) { struct cdns_pcie_ep *ep = epc_get_drvdata(epc); From patchwork Tue Apr 10 17:14:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896844 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDQ634fSz9s2S for ; Wed, 11 Apr 2018 03:17:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752574AbeDJRRW (ORCPT ); Tue, 10 Apr 2018 13:17:22 -0400 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9]:35915 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751790AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 9447824E0C01; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from pt02.synopsys.com (pt02.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 1763C3D43; Tue, 10 Apr 2018 10:14:53 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 4F07E3D7C6; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 03/10] PCI: endpoint: Add MSI-X interfaces Date: Tue, 10 Apr 2018 18:14:42 +0100 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Implements the generic method for calling the get/set callbacks. Adds the PCI_EPC_IRQ_MSIX type. Adds the MSI-X callbacks signatures to the ops structure. Adds sysfs interface for altering the number of MSI-X entries. Signed-off-by: Gustavo Pimentel --- drivers/pci/endpoint/pci-ep-cfs.c | 24 ++++++++++++++++ drivers/pci/endpoint/pci-epc-core.c | 57 +++++++++++++++++++++++++++++++++++++ include/linux/pci-epc.h | 11 ++++++- include/linux/pci-epf.h | 1 + 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 018ea34..d1288a0 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -286,6 +286,28 @@ static ssize_t pci_epf_msi_interrupts_show(struct config_item *item, to_pci_epf_group(item)->epf->msi_interrupts); } +static ssize_t pci_epf_msix_interrupts_store(struct config_item *item, + const char *page, size_t len) +{ + u16 val; + int ret; + + ret = kstrtou16(page, 0, &val); + if (ret) + return ret; + + to_pci_epf_group(item)->epf->msix_interrupts = val; + + return len; +} + +static ssize_t pci_epf_msix_interrupts_show(struct config_item *item, + char *page) +{ + return sprintf(page, "%d\n", + to_pci_epf_group(item)->epf->msix_interrupts); +} + PCI_EPF_HEADER_R(vendorid) PCI_EPF_HEADER_W_u16(vendorid) @@ -327,6 +349,7 @@ CONFIGFS_ATTR(pci_epf_, subsys_vendor_id); CONFIGFS_ATTR(pci_epf_, subsys_id); CONFIGFS_ATTR(pci_epf_, interrupt_pin); CONFIGFS_ATTR(pci_epf_, msi_interrupts); +CONFIGFS_ATTR(pci_epf_, msix_interrupts); static struct configfs_attribute *pci_epf_attrs[] = { &pci_epf_attr_vendorid, @@ -340,6 +363,7 @@ static struct configfs_attribute *pci_epf_attrs[] = { &pci_epf_attr_subsys_id, &pci_epf_attr_interrupt_pin, &pci_epf_attr_msi_interrupts, + &pci_epf_attr_msix_interrupts, NULL, }; diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index b0ee427..294a383 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -218,6 +218,63 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts) EXPORT_SYMBOL_GPL(pci_epc_set_msi); /** + * pci_epc_get_msix() - get the number of MSI-X interrupt numbers allocated + * @epc: the EPC device to which MSI-X interrupts was requested + * @func_no: the endpoint function number in the EPC device + * + * Invoke to get the number of MSI-X interrupts allocated by the RC + */ +int pci_epc_get_msix(struct pci_epc *epc, u8 func_no) +{ + int interrupt; + unsigned long flags; + + if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) + return 0; + + if (!epc->ops->get_msix) + return 0; + + spin_lock_irqsave(&epc->lock, flags); + interrupt = epc->ops->get_msix(epc, func_no); + spin_unlock_irqrestore(&epc->lock, flags); + + if (interrupt < 0) + return 0; + + return interrupt++; +} +EXPORT_SYMBOL_GPL(pci_epc_get_msix); + +/** + * pci_epc_set_msix() - set the number of MSI-X interrupt numbers required + * @epc: the EPC device on which MSI-X has to be configured + * @func_no: the endpoint function number in the EPC device + * @interrupts: number of MSI-X interrupts required by the EPF + * + * Invoke to set the required number of MSI-X interrupts. + */ +int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts) +{ + int ret; + unsigned long flags; + + if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions || + interrupts < 1 || interrupts > 2048) + return -EINVAL; + + if (!epc->ops->set_msix) + return 0; + + spin_lock_irqsave(&epc->lock, flags); + ret = epc->ops->set_msix(epc, func_no, interrupts - 1); + spin_unlock_irqrestore(&epc->lock, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(pci_epc_set_msix); + +/** * pci_epc_unmap_addr() - unmap CPU address from PCI address * @epc: the EPC device on which address is allocated * @func_no: the endpoint function number in the EPC device diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index af657ca..32e8961 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -17,6 +17,7 @@ enum pci_epc_irq_type { PCI_EPC_IRQ_UNKNOWN, PCI_EPC_IRQ_LEGACY, PCI_EPC_IRQ_MSI, + PCI_EPC_IRQ_MSIX, }; /** @@ -30,6 +31,10 @@ enum pci_epc_irq_type { * capability register * @get_msi: ops to get the number of MSI interrupts allocated by the RC from * the MSI capability register + * @set_msix: ops to set the requested number of MSI-X interrupts in the + * MSI-X capability register + * @get_msix: ops to get the number of MSI-X interrupts allocated by the RC + * from the MSI-X capability register * @raise_irq: ops to raise a legacy or MSI interrupt * @start: ops to start the PCI link * @stop: ops to stop the PCI link @@ -48,8 +53,10 @@ struct pci_epc_ops { phys_addr_t addr); int (*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts); int (*get_msi)(struct pci_epc *epc, u8 func_no); + int (*set_msix)(struct pci_epc *epc, u8 func_no, u16 interrupts); + int (*get_msix)(struct pci_epc *epc, u8 func_no); int (*raise_irq)(struct pci_epc *epc, u8 func_no, - enum pci_epc_irq_type type, u8 interrupt_num); + enum pci_epc_irq_type type, u16 interrupt_num); int (*start)(struct pci_epc *epc); void (*stop)(struct pci_epc *epc); struct module *owner; @@ -136,6 +143,8 @@ void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no, phys_addr_t phys_addr); int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts); int pci_epc_get_msi(struct pci_epc *epc, u8 func_no); +int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts); +int pci_epc_get_msix(struct pci_epc *epc, u8 func_no); int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, enum pci_epc_irq_type type, u8 interrupt_num); int pci_epc_start(struct pci_epc *epc); diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h index f7d6f48..9bb1f31 100644 --- a/include/linux/pci-epf.h +++ b/include/linux/pci-epf.h @@ -119,6 +119,7 @@ struct pci_epf { struct pci_epf_header *header; struct pci_epf_bar bar[6]; u8 msi_interrupts; + u16 msix_interrupts; u8 func_no; struct pci_epc *epc; From patchwork Tue Apr 10 17:14:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896836 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDMX3jK5z9s2S for ; Wed, 11 Apr 2018 03:15:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751959AbeDJRO4 (ORCPT ); Tue, 10 Apr 2018 13:14:56 -0400 Received: from smtprelay.synopsys.com ([198.182.60.111]:60187 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751546AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id 60E4110C09B5; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from pt02.synopsys.com (pt02.internal.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 176565A5A; Tue, 10 Apr 2018 10:14:53 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 5B75D3D7C9; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 04/10] PCI: dwc: MSI callbacks handler rework Date: Tue, 10 Apr 2018 18:14:43 +0100 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Adds in pci_epc_set_msi function a maximum number of 32 interrupts validation. Removes duplicate defines located on pcie-designware.h file. Uses now the defines available on /include/uapi/linux/pci-regs.h file. Signed-off-by: Gustavo Pimentel --- drivers/pci/dwc/pcie-designware-ep.c | 46 +++++++++++++++++++++++------------- drivers/pci/dwc/pcie-designware.h | 11 --------- drivers/pci/endpoint/pci-epc-core.c | 3 ++- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 874d4c2..e352786 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -251,29 +251,38 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) { - int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + u32 val, reg; + + if (ep->cap_addr.msi_addr == 0) + return 0; - val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); - if (!(val & MSI_CAP_MSI_EN_MASK)) + reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS; + val = dw_pcie_readw_dbi(pci, reg); + if (!(val & PCI_MSI_FLAGS_ENABLE)) return -EINVAL; - val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT; + val = (val & PCI_MSI_FLAGS_QSIZE) >> 4; + return val; } -static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) +static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts) { - int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + u32 val, reg; + + if (ep->cap_addr.msi_addr == 0) + return 0; - val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); - val &= ~MSI_CAP_MMC_MASK; - val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK; + reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS; + val = dw_pcie_readw_dbi(pci, reg); + val &= ~PCI_MSI_FLAGS_QMASK; + val |= (interrupts << 1) & PCI_MSI_FLAGS_QMASK; dw_pcie_dbi_ro_wr_en(pci); - dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val); + dw_pcie_writew_dbi(pci, reg, val); dw_pcie_dbi_ro_wr_dis(pci); return 0; @@ -372,21 +381,26 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, struct dw_pcie *pci = to_dw_pcie_from_ep(ep); struct pci_epc *epc = ep->epc; u16 msg_ctrl, msg_data; - u32 msg_addr_lower, msg_addr_upper; + u32 msg_addr_lower, msg_addr_upper, reg; u64 msg_addr; bool has_upper; int ret; /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */ - msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL); + reg = ep->cap_addr.msi_addr + PCI_MSI_FLAGS; + msg_ctrl = dw_pcie_readw_dbi(pci, reg); has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT); - msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32); + reg = ep->cap_addr.msi_addr + PCI_MSI_ADDRESS_LO; + msg_addr_lower = dw_pcie_readl_dbi(pci, reg); if (has_upper) { - msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32); - msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64); + reg = ep->cap_addr.msi_addr + PCI_MSI_ADDRESS_HI; + msg_addr_upper = dw_pcie_readl_dbi(pci, reg); + reg = ep->cap_addr.msi_addr + PCI_MSI_DATA_64; + msg_data = dw_pcie_readw_dbi(pci, reg); } else { msg_addr_upper = 0; - msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32); + reg = ep->cap_addr.msi_addr + PCI_MSI_DATA_32; + msg_data = dw_pcie_readw_dbi(pci, reg); } msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower; ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr, diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index 456fd94..2acf18b0 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h @@ -96,17 +96,6 @@ #define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \ ((0x3 << 20) | ((region) << 9) | (0x1 << 8)) -#define MSI_MESSAGE_CONTROL 0x52 -#define MSI_CAP_MMC_SHIFT 1 -#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT) -#define MSI_CAP_MME_SHIFT 4 -#define MSI_CAP_MSI_EN_MASK 0x1 -#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT) -#define MSI_MESSAGE_ADDR_L32 0x54 -#define MSI_MESSAGE_ADDR_U32 0x58 -#define MSI_MESSAGE_DATA_32 0x58 -#define MSI_MESSAGE_DATA_64 0x5C - #define MAX_MSI_IRQS 256 #define MAX_MSI_IRQS_PER_CTRL 32 #define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 294a383..dbd17e4 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -201,7 +201,8 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts) u8 encode_int; unsigned long flags; - if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions) + if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions || + interrupts > 32) return -EINVAL; if (!epc->ops->set_msi) From patchwork Tue Apr 10 17:14:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896842 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDPb5yntz9s2S for ; Wed, 11 Apr 2018 03:17:23 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752255AbeDJRRV (ORCPT ); Tue, 10 Apr 2018 13:17:21 -0400 Received: from smtprelay.synopsys.com ([198.182.47.9]:35922 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751825AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 3CA1724E060F; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id EEFE03D56; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 663AF3D7CC; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 05/10] PCI: dwc: Add legacy interrupt callback handler Date: Tue, 10 Apr 2018 18:14:44 +0100 Message-Id: <97da44571e71e527eb3799c2fabd49e7460c3727.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Adds a legacy interrupt callback handler. Currently Designware IP doesn't allow triggering the legacy interrupt. Signed-off-by: Gustavo Pimentel --- drivers/pci/dwc/pcie-designware-ep.c | 10 ++++++++++ drivers/pci/dwc/pcie-designware-plat.c | 3 +-- drivers/pci/dwc/pcie-designware.h | 6 ++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index e352786..fb55259 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -375,6 +375,16 @@ static const struct pci_epc_ops epc_ops = { .stop = dw_pcie_ep_stop, }; +int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) +{ + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + struct device *dev = pci->dev; + + dev_err(dev, "EP cannot trigger legacy IRQs\n"); + + return -EINVAL; +} + int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num) { diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c index c3a4707..3874b02 100644 --- a/drivers/pci/dwc/pcie-designware-plat.c +++ b/drivers/pci/dwc/pcie-designware-plat.c @@ -86,8 +86,7 @@ static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no, switch (type) { case PCI_EPC_IRQ_LEGACY: - dev_err(pci->dev, "EP cannot trigger legacy IRQs\n"); - return -EINVAL; + return dw_pcie_ep_raise_legacy_irq(ep, func_no); case PCI_EPC_IRQ_MSI: return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); case PCI_EPC_IRQ_MSIX: diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index 2acf18b0..808b280 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h @@ -354,6 +354,7 @@ static inline int dw_pcie_allocate_domains(struct pcie_port *pp) void dw_pcie_ep_linkup(struct dw_pcie_ep *ep); int dw_pcie_ep_init(struct dw_pcie_ep *ep); void dw_pcie_ep_exit(struct dw_pcie_ep *ep); +int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no); int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num); int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, @@ -374,6 +375,11 @@ static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep) { } +static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) +{ + return 0; +} + static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, u8 interrupt_num) { From patchwork Tue Apr 10 17:14:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896838 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDN25dqcz9s2S for ; Wed, 11 Apr 2018 03:16:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751624AbeDJRPe (ORCPT ); Tue, 10 Apr 2018 13:15:34 -0400 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9]:35941 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751882AbeDJRO4 (ORCPT ); Tue, 10 Apr 2018 13:14:56 -0400 Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by smtprelay.synopsys.com (Postfix) with ESMTP id 9DF0924E0C85; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.internal.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 360AE5A77; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 71DAD3D7CF; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 06/10] misc: pci_endpoint_test: Add MSI-X support Date: Tue, 10 Apr 2018 18:14:45 +0100 Message-Id: <8b88f8c2b766f36c71659deb0fce635154b2b39f.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Adds the MSI-X support and updates driver documentation accordingly. Changes the driver parameter in order to allow the interruption type selection. Signed-off-by: Gustavo Pimentel --- Documentation/misc-devices/pci-endpoint-test.txt | 3 + drivers/misc/pci_endpoint_test.c | 102 +++++++++++++++++------ 2 files changed, 79 insertions(+), 26 deletions(-) diff --git a/Documentation/misc-devices/pci-endpoint-test.txt b/Documentation/misc-devices/pci-endpoint-test.txt index 4ebc359..fdfa0f6 100644 --- a/Documentation/misc-devices/pci-endpoint-test.txt +++ b/Documentation/misc-devices/pci-endpoint-test.txt @@ -10,6 +10,7 @@ The PCI driver for the test device performs the following tests *) verifying addresses programmed in BAR *) raise legacy IRQ *) raise MSI IRQ + *) raise MSI-X IRQ *) read data *) write data *) copy data @@ -25,6 +26,8 @@ ioctl PCITEST_LEGACY_IRQ: Tests legacy IRQ PCITEST_MSI: Tests message signalled interrupts. The MSI number to be tested should be passed as argument. + PCITEST_MSIX: Tests message signalled interrupts. The MSI-X number + to be tested should be passed as argument. PCITEST_WRITE: Perform write tests. The size of the buffer should be passed as argument. PCITEST_READ: Perform read tests. The size of the buffer should be passed diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 37db0fc..a7d9354 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -42,11 +42,16 @@ #define PCI_ENDPOINT_TEST_COMMAND 0x4 #define COMMAND_RAISE_LEGACY_IRQ BIT(0) #define COMMAND_RAISE_MSI_IRQ BIT(1) -#define MSI_NUMBER_SHIFT 2 -/* 6 bits for MSI number */ -#define COMMAND_READ BIT(8) -#define COMMAND_WRITE BIT(9) -#define COMMAND_COPY BIT(10) +#define COMMAND_RAISE_MSIX_IRQ BIT(2) +#define IRQ_TYPE_SHIFT 3 +#define IRQ_TYPE_LEGACY 0 +#define IRQ_TYPE_MSI 1 +#define IRQ_TYPE_MSIX 2 +#define MSI_NUMBER_SHIFT 5 +/* 12 bits for MSI number */ +#define COMMAND_READ BIT(17) +#define COMMAND_WRITE BIT(18) +#define COMMAND_COPY BIT(19) #define PCI_ENDPOINT_TEST_STATUS 0x8 #define STATUS_READ_SUCCESS BIT(0) @@ -73,9 +78,9 @@ static DEFINE_IDA(pci_endpoint_test_ida); #define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \ miscdev) -static bool no_msi; -module_param(no_msi, bool, 0444); -MODULE_PARM_DESC(no_msi, "Disable MSI interrupt in pci_endpoint_test"); +static int irq_type = IRQ_TYPE_MSIX; +module_param(irq_type, int, 0444); +MODULE_PARM_DESC(irq_type, "IRQ mode selection in pci_endpoint_test (0 - Legacy, 1 - MSI, 2 - MSI-X)"); enum pci_barno { BAR_0, @@ -103,7 +108,7 @@ struct pci_endpoint_test { struct pci_endpoint_test_data { enum pci_barno test_reg_bar; size_t alignment; - bool no_msi; + int irq_type; }; static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test, @@ -177,10 +182,10 @@ static bool pci_endpoint_test_bar(struct pci_endpoint_test *test, static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test) { - u32 val; + u32 val = COMMAND_RAISE_LEGACY_IRQ; - pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, - COMMAND_RAISE_LEGACY_IRQ); + val |= (IRQ_TYPE_LEGACY << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); val = wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000)); if (!val) @@ -192,12 +197,12 @@ static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test) static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, u8 msi_num) { - u32 val; + u32 val = COMMAND_RAISE_MSI_IRQ; struct pci_dev *pdev = test->pdev; - pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, - msi_num << MSI_NUMBER_SHIFT | - COMMAND_RAISE_MSI_IRQ); + val |= (msi_num << MSI_NUMBER_SHIFT); + val |= (IRQ_TYPE_MSI << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); val = wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000)); if (!val) @@ -209,6 +214,26 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test, return false; } +static bool pci_endpoint_test_msix_irq(struct pci_endpoint_test *test, + u16 msix_num) +{ + u32 val = COMMAND_RAISE_MSIX_IRQ; + struct pci_dev *pdev = test->pdev; + + val |= (msix_num << MSI_NUMBER_SHIFT); + val |= (IRQ_TYPE_MSIX << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); + val = wait_for_completion_timeout(&test->irq_raised, + msecs_to_jiffies(1000)); + if (!val) + return false; + + if (test->last_irq - pdev->irq == msix_num - 1) + return true; + + return false; +} + static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) { bool ret = false; @@ -226,6 +251,7 @@ 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; + u32 val = COMMAND_COPY; if (size > SIZE_MAX - alignment) goto err; @@ -281,8 +307,9 @@ 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_COMMAND, - 1 << MSI_NUMBER_SHIFT | COMMAND_COPY); + val |= (1 << MSI_NUMBER_SHIFT); + val |= (irq_type << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); wait_for_completion(&test->irq_raised); @@ -314,6 +341,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) size_t offset; size_t alignment = test->alignment; u32 crc32; + u32 val = COMMAND_READ; if (size > SIZE_MAX - alignment) goto err; @@ -348,8 +376,9 @@ 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_COMMAND, - 1 << MSI_NUMBER_SHIFT | COMMAND_READ); + val |= (1 << MSI_NUMBER_SHIFT); + val |= (irq_type << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); wait_for_completion(&test->irq_raised); @@ -375,6 +404,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) size_t offset; size_t alignment = test->alignment; u32 crc32; + u32 val = COMMAND_WRITE; if (size > SIZE_MAX - alignment) goto err; @@ -403,8 +433,9 @@ 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_COMMAND, - 1 << MSI_NUMBER_SHIFT | COMMAND_WRITE); + val |= (1 << MSI_NUMBER_SHIFT); + val |= (irq_type << IRQ_TYPE_SHIFT); + pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, val); wait_for_completion(&test->irq_raised); @@ -438,6 +469,9 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, case PCITEST_MSI: ret = pci_endpoint_test_msi_irq(test, arg); break; + case PCITEST_MSIX: + ret = pci_endpoint_test_msix_irq(test, arg); + break; case PCITEST_WRITE: ret = pci_endpoint_test_write(test, arg); break; @@ -490,7 +524,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, if (data) { test_reg_bar = data->test_reg_bar; test->alignment = data->alignment; - no_msi = data->no_msi; + irq_type = data->irq_type; } init_completion(&test->irq_raised); @@ -510,11 +544,24 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, pci_set_master(pdev); - if (!no_msi) { + switch (irq_type) { + case IRQ_TYPE_LEGACY: + break; + case IRQ_TYPE_MSI: irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); if (irq < 0) dev_err(dev, "failed to get MSI interrupts\n"); test->num_irqs = irq; + break; + case IRQ_TYPE_MSIX: + irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX); + if (irq < 0) + dev_err(dev, "Failed to get MSI-X interrupts\n"); + test->num_irqs = irq; + break; + default: + dev_err(dev, "Invalid IRQ type selected\n"); + goto err_disable_msi; } err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler, @@ -529,8 +576,9 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, pci_endpoint_test_irqhandler, IRQF_SHARED, DRV_MODULE_NAME, test); if (err) - dev_err(dev, "failed to request IRQ %d for MSI %d\n", - pdev->irq + i, i + 1); + dev_err(dev, "Failed to request IRQ %d for MSI%s %d\n", + pdev->irq + i, + irq_type == IRQ_TYPE_MSIX ? "-X" : "", i + 1); } for (bar = BAR_0; bar <= BAR_5; bar++) { @@ -596,6 +644,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, err_disable_msi: pci_disable_msi(pdev); + pci_disable_msix(pdev); pci_release_regions(pdev); err_disable_pdev: @@ -627,6 +676,7 @@ static void pci_endpoint_test_remove(struct pci_dev *pdev) for (i = 0; i < test->num_irqs; i++) devm_free_irq(&pdev->dev, pdev->irq + i, test); pci_disable_msi(pdev); + pci_disable_msix(pdev); pci_release_regions(pdev); pci_disable_device(pdev); } From patchwork Tue Apr 10 17:14:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896839 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDN81bt7z9s2S for ; Wed, 11 Apr 2018 03:16:08 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752334AbeDJRQE (ORCPT ); Tue, 10 Apr 2018 13:16:04 -0400 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9]:35932 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751862AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 8713C24E0C7F; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id F2E4A3D57; Tue, 10 Apr 2018 10:14:54 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 7E15A3D7D2; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 07/10] misc: pci_endpoint_test: Replace lower into upper case characters Date: Tue, 10 Apr 2018 18:14:46 +0100 Message-Id: <48fee5fd7c31a22d1122ae3428810b6d1dba2f81.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Replaces lower into upper case characters in comments and debug printks. Signed-off-by: Gustavo Pimentel --- drivers/misc/pci_endpoint_test.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index a7d9354..7212a7d 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -259,7 +259,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) orig_src_addr = dma_alloc_coherent(dev, size + alignment, &orig_src_phys_addr, GFP_KERNEL); if (!orig_src_addr) { - dev_err(dev, "failed to allocate source buffer\n"); + dev_err(dev, "Failed to allocate source buffer\n"); ret = false; goto err; } @@ -285,7 +285,7 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size) orig_dst_addr = dma_alloc_coherent(dev, size + alignment, &orig_dst_phys_addr, GFP_KERNEL); if (!orig_dst_addr) { - dev_err(dev, "failed to allocate destination address\n"); + dev_err(dev, "Failed to allocate destination address\n"); ret = false; goto err_orig_src_addr; } @@ -349,7 +349,7 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size) orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, GFP_KERNEL); if (!orig_addr) { - dev_err(dev, "failed to allocate address\n"); + dev_err(dev, "Failed to allocate address\n"); ret = false; goto err; } @@ -412,7 +412,7 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size) orig_addr = dma_alloc_coherent(dev, size + alignment, &orig_phys_addr, GFP_KERNEL); if (!orig_addr) { - dev_err(dev, "failed to allocate destination address\n"); + dev_err(dev, "Failed to allocate destination address\n"); ret = false; goto err; } @@ -550,7 +550,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, case IRQ_TYPE_MSI: irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI); if (irq < 0) - dev_err(dev, "failed to get MSI interrupts\n"); + dev_err(dev, "Failed to get MSI interrupts\n"); test->num_irqs = irq; break; case IRQ_TYPE_MSIX: @@ -567,7 +567,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler, IRQF_SHARED, DRV_MODULE_NAME, test); if (err) { - dev_err(dev, "failed to request IRQ %d\n", pdev->irq); + dev_err(dev, "Failed to request IRQ %d\n", pdev->irq); goto err_disable_msi; } @@ -585,7 +585,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { base = pci_ioremap_bar(pdev, bar); if (!base) { - dev_err(dev, "failed to read BAR%d\n", bar); + dev_err(dev, "Failed to read BAR%d\n", bar); WARN_ON(bar == test_reg_bar); } test->bar[bar] = base; @@ -605,7 +605,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL); if (id < 0) { err = id; - dev_err(dev, "unable to get id\n"); + dev_err(dev, "Unable to get id\n"); goto err_iounmap; } @@ -621,7 +621,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, err = misc_register(misc_device); if (err) { - dev_err(dev, "failed to register device\n"); + dev_err(dev, "Failed to register device\n"); goto err_kfree_name; } From patchwork Tue Apr 10 17:14:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896841 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDPV2qqdz9s2S for ; Wed, 11 Apr 2018 03:17:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752354AbeDJRQF (ORCPT ); Tue, 10 Apr 2018 13:16:05 -0400 Received: from smtprelay2.synopsys.com ([198.182.60.111]:60200 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751845AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 48DE910C0ABC; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 0439A3D59; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 887C63D7D5; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 08/10] PCI: endpoint: functions/pci-epf-test: Add MSI-X support Date: Tue, 10 Apr 2018 18:14:47 +0100 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Adds driver's MSI-X support. Signed-off-by: Gustavo Pimentel --- drivers/pci/endpoint/functions/pci-epf-test.c | 87 +++++++++++++++++++++------ 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 63dca44..5997c6e 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -20,11 +20,18 @@ #define COMMAND_RAISE_LEGACY_IRQ BIT(0) #define COMMAND_RAISE_MSI_IRQ BIT(1) -#define MSI_NUMBER_SHIFT 2 +#define COMMAND_RAISE_MSIX_IRQ BIT(2) +#define IRQ_TYPE_SHIFT 3 +#define MSI_NUMBER_SHIFT 5 +#define IRQ_TYPE_MASK (0x3 << IRQ_TYPE_SHIFT) +#define IRQ_TYPE_LEGACY 0 +#define IRQ_TYPE_MSI 1 +#define IRQ_TYPE_MSIX 2 #define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT) -#define COMMAND_READ BIT(8) -#define COMMAND_WRITE BIT(9) -#define COMMAND_COPY BIT(10) +#define MSIX_NUMBER_MASK (0xfff << MSI_NUMBER_SHIFT) +#define COMMAND_READ BIT(17) +#define COMMAND_WRITE BIT(18) +#define COMMAND_COPY BIT(19) #define STATUS_READ_SUCCESS BIT(0) #define STATUS_READ_FAIL BIT(1) @@ -244,31 +251,44 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) return ret; } -static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq) +static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq_type, + u16 irq) { - u8 msi_count; struct pci_epf *epf = epf_test->epf; + struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; enum pci_barno test_reg_bar = epf_test->test_reg_bar; struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; reg->status |= STATUS_IRQ_RAISED; - msi_count = pci_epc_get_msi(epc, epf->func_no); - if (irq > msi_count || msi_count <= 0) - pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0); - else + + switch (irq_type) { + case IRQ_TYPE_LEGACY: + pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, irq); + break; + case IRQ_TYPE_MSI: pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq); + break; + case IRQ_TYPE_MSIX: + pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq); + break; + default: + dev_err(dev, "Failed to raise IRQ, unknown type\n"); + break; + } } static void pci_epf_test_cmd_handler(struct work_struct *work) { int ret; - u8 irq; - u8 msi_count; + u16 irq; + u8 irq_type; + u16 msi_count; u32 command; struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test, cmd_handler.work); struct pci_epf *epf = epf_test->epf; + struct device *dev = &epf->dev; struct pci_epc *epc = epf->epc; enum pci_barno test_reg_bar = epf_test->test_reg_bar; struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar]; @@ -280,11 +300,25 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) reg->command = 0; reg->status = 0; - irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; + irq_type = (command & IRQ_TYPE_MASK) >> IRQ_TYPE_SHIFT; + switch (irq_type) { + case IRQ_TYPE_LEGACY: + irq = 0; + break; + case IRQ_TYPE_MSI: + irq = (command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT; + break; + case IRQ_TYPE_MSIX: + irq = (command & MSIX_NUMBER_MASK) >> MSI_NUMBER_SHIFT; + break; + default: + dev_err(dev, "Failed to detect IRQ type\n"); + goto reset_handler; + } if (command & COMMAND_RAISE_LEGACY_IRQ) { reg->status = STATUS_IRQ_RAISED; - pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0); + pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, irq); goto reset_handler; } @@ -294,7 +328,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) reg->status |= STATUS_WRITE_FAIL; else reg->status |= STATUS_WRITE_SUCCESS; - pci_epf_test_raise_irq(epf_test, irq); + pci_epf_test_raise_irq(epf_test, irq_type, irq); goto reset_handler; } @@ -304,7 +338,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) reg->status |= STATUS_READ_SUCCESS; else reg->status |= STATUS_READ_FAIL; - pci_epf_test_raise_irq(epf_test, irq); + pci_epf_test_raise_irq(epf_test, irq_type, irq); goto reset_handler; } @@ -314,7 +348,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) reg->status |= STATUS_COPY_SUCCESS; else reg->status |= STATUS_COPY_FAIL; - pci_epf_test_raise_irq(epf_test, irq); + pci_epf_test_raise_irq(epf_test, irq_type, irq); goto reset_handler; } @@ -327,6 +361,15 @@ static void pci_epf_test_cmd_handler(struct work_struct *work) goto reset_handler; } + if (command & COMMAND_RAISE_MSIX_IRQ) { + msi_count = pci_epc_get_msix(epc, epf->func_no); + if (irq > msi_count || msi_count <= 0) + goto reset_handler; + reg->status = STATUS_IRQ_RAISED; + pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSIX, irq); + goto reset_handler; + } + reset_handler: queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler, msecs_to_jiffies(1)); @@ -450,8 +493,16 @@ static int pci_epf_test_bind(struct pci_epf *epf) return ret; ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts); - if (ret) + if (ret) { + dev_err(dev, "MSI configuration failed\n"); return ret; + } + + ret = pci_epc_set_msix(epc, epf->func_no, epf->msix_interrupts); + if (ret) { + dev_err(dev, "MSI-X configuration failed\n"); + return ret; + } if (!epf_test->linkup_notifier) queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work); From patchwork Tue Apr 10 17:14:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896840 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDNw1v4Pz9s2S for ; Wed, 11 Apr 2018 03:16:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752379AbeDJRQF (ORCPT ); Tue, 10 Apr 2018 13:16:05 -0400 Received: from smtprelay.synopsys.com ([198.182.47.9]:35928 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751490AbeDJROz (ORCPT ); Tue, 10 Apr 2018 13:14:55 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 4963B24E0C6E; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 059793D5A; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 93AD33D7DA; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 09/10] PCI: endpoint: functions/pci-epf-test: Replace lower into upper case characters Date: Tue, 10 Apr 2018 18:14:48 +0100 Message-Id: <91e6911cd73a3a61b14b392591a124581085ace2.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Replaces lower into upper case characters in comments and debug printks. Signed-off-by: Gustavo Pimentel --- drivers/pci/endpoint/functions/pci-epf-test.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 5997c6e..e3d4af0 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -94,7 +94,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size); if (!src_addr) { - dev_err(dev, "failed to allocate source address\n"); + dev_err(dev, "Failed to allocate source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; ret = -ENOMEM; goto err; @@ -103,14 +103,14 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr, reg->size); if (ret) { - dev_err(dev, "failed to map source address\n"); + dev_err(dev, "Failed to map source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; goto err_src_addr; } dst_addr = pci_epc_mem_alloc_addr(epc, &dst_phys_addr, reg->size); if (!dst_addr) { - dev_err(dev, "failed to allocate destination address\n"); + dev_err(dev, "Failed to allocate destination address\n"); reg->status = STATUS_DST_ADDR_INVALID; ret = -ENOMEM; goto err_src_map_addr; @@ -119,7 +119,7 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr, reg->size); if (ret) { - dev_err(dev, "failed to map destination address\n"); + dev_err(dev, "Failed to map destination address\n"); reg->status = STATUS_DST_ADDR_INVALID; goto err_dst_addr; } @@ -156,7 +156,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); if (!src_addr) { - dev_err(dev, "failed to allocate address\n"); + dev_err(dev, "Failed to allocate address\n"); reg->status = STATUS_SRC_ADDR_INVALID; ret = -ENOMEM; goto err; @@ -165,7 +165,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test) ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr, reg->size); if (ret) { - dev_err(dev, "failed to map address\n"); + dev_err(dev, "Failed to map address\n"); reg->status = STATUS_SRC_ADDR_INVALID; goto err_addr; } @@ -208,7 +208,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size); if (!dst_addr) { - dev_err(dev, "failed to allocate address\n"); + dev_err(dev, "Failed to allocate address\n"); reg->status = STATUS_DST_ADDR_INVALID; ret = -ENOMEM; goto err; @@ -217,7 +217,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test) ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr, reg->size); if (ret) { - dev_err(dev, "failed to map address\n"); + dev_err(dev, "Failed to map address\n"); reg->status = STATUS_DST_ADDR_INVALID; goto err_addr; } @@ -422,7 +422,7 @@ static int pci_epf_test_set_bar(struct pci_epf *epf) ret = pci_epc_set_bar(epc, epf->func_no, epf_bar); if (ret) { pci_epf_free_space(epf, epf_test->reg[bar], bar); - dev_err(dev, "failed to set BAR%d\n", bar); + dev_err(dev, "Failed to set BAR%d\n", bar); if (bar == test_reg_bar) return ret; } @@ -449,7 +449,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), test_reg_bar); if (!base) { - dev_err(dev, "failed to allocated register space\n"); + dev_err(dev, "Failed to allocated register space\n"); return -ENOMEM; } epf_test->reg[test_reg_bar] = base; @@ -459,7 +459,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) continue; base = pci_epf_alloc_space(epf, bar_size[bar], bar); if (!base) - dev_err(dev, "failed to allocate space for BAR%d\n", + dev_err(dev, "Failed to allocate space for BAR%d\n", bar); epf_test->reg[bar] = base; } @@ -480,7 +480,7 @@ static int pci_epf_test_bind(struct pci_epf *epf) ret = pci_epc_write_header(epc, epf->func_no, header); if (ret) { - dev_err(dev, "configuration header write failed\n"); + dev_err(dev, "Configuration header write failed\n"); return ret; } @@ -578,7 +578,7 @@ static int __init pci_epf_test_init(void) WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); ret = pci_epf_register_driver(&test_driver); if (ret) { - pr_err("failed to register pci epf test driver --> %d\n", ret); + pr_err("Failed to register pci epf test driver --> %d\n", ret); return ret; } From patchwork Tue Apr 10 17:14:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gustavo Pimentel X-Patchwork-Id: 896837 X-Patchwork-Delegate: lorenzo.pieralisi@arm.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=fail (p=none dis=none) header.from=synopsys.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40LDMp0Rxlz9s2S for ; Wed, 11 Apr 2018 03:15:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751882AbeDJRPf (ORCPT ); Tue, 10 Apr 2018 13:15:35 -0400 Received: from smtprelay2.synopsys.com ([198.182.60.111]:60210 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751504AbeDJRO4 (ORCPT ); Tue, 10 Apr 2018 13:14:56 -0400 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id 8D9D110C0C22; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from pt02.synopsys.com (pt02.internal.synopsys.com [10.107.23.240]) by mailhost.synopsys.com (Postfix) with ESMTP id 0A4413F45; Tue, 10 Apr 2018 10:14:55 -0700 (PDT) Received: from UbuntuMate-64Bits.internal.synopsys.com (gustavo-e7480.internal.synopsys.com [10.107.25.102]) by pt02.synopsys.com (Postfix) with ESMTP id 9DE173D7DD; Tue, 10 Apr 2018 18:14:53 +0100 (WEST) From: Gustavo Pimentel To: bhelgaas@google.com, lorenzo.pieralisi@arm.com, Joao.Pinto@synopsys.com, jingoohan1@gmail.com, kishon@ti.com, adouglas@cadence.com, niklas.cassel@axis.com, jesper.nilsson@axis.com Cc: linux-pci@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, gustavo.pimentel@synopsys.com Subject: [RFC 10/10] tools: PCI: Add MSI-X support Date: Tue, 10 Apr 2018 18:14:49 +0100 Message-Id: <9865822fb89ea84cb55fe93e151295afcd5c96b3.1523379766.git.gustavo.pimentel@synopsys.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Adds MSI-X support to the pcitest tool and modified the pcitest.sh script to accomodate this new type of interruption test. Signed-off-by: Gustavo Pimentel --- include/uapi/linux/pcitest.h | 1 + tools/pci/pcitest.c | 18 +++++++++++++++++- tools/pci/pcitest.sh | 25 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h index 953cf03..d746fb1 100644 --- a/include/uapi/linux/pcitest.h +++ b/include/uapi/linux/pcitest.h @@ -16,5 +16,6 @@ #define PCITEST_WRITE _IOW('P', 0x4, unsigned long) #define PCITEST_READ _IOW('P', 0x5, unsigned long) #define PCITEST_COPY _IOW('P', 0x6, unsigned long) +#define PCITEST_MSIX _IOW('P', 0x7, int) #endif /* __UAPI_LINUX_PCITEST_H */ diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index 9074b47..9d145a3 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -37,6 +37,7 @@ struct pci_test { char barnum; bool legacyirq; unsigned int msinum; + unsigned int msixnum; bool read; bool write; bool copy; @@ -83,6 +84,15 @@ static int run_test(struct pci_test *test) fprintf(stdout, "%s\n", result[ret]); } + if (test->msixnum > 0 && test->msixnum <= 2048) { + ret = ioctl(fd, PCITEST_MSIX, test->msixnum); + fprintf(stdout, "MSI-X%d:\t\t", test->msixnum); + if (ret < 0) + fprintf(stdout, "TEST FAILED\n"); + else + fprintf(stdout, "%s\n", result[ret]); + } + if (test->write) { ret = ioctl(fd, PCITEST_WRITE, test->size); fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); @@ -133,7 +143,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:lrwcs:")) != EOF) + while ((c = getopt(argc, argv, "D:b:m:x:lrwcs:")) != EOF) switch (c) { case 'D': test->device = optarg; @@ -151,6 +161,11 @@ int main(int argc, char **argv) if (test->msinum < 1 || test->msinum > 32) goto usage; continue; + case 'x': + test->msixnum = atoi(optarg); + if (test->msixnum < 1 || test->msixnum > 2048) + goto usage; + continue; case 'r': test->read = true; continue; @@ -173,6 +188,7 @@ int main(int argc, char **argv) "\t-D PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" "\t-b BAR test (bar number between 0..5)\n" "\t-m MSI test (msi number between 1..32)\n" + "\t-x MSI-X test (msix number between 1..2048)\n" "\t-l Legacy IRQ test\n" "\t-r Read buffer test\n" "\t-w Write buffer test\n" diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh index 77e8c85..86709a2 100644 --- a/tools/pci/pcitest.sh +++ b/tools/pci/pcitest.sh @@ -4,6 +4,8 @@ echo "BAR tests" echo +modprobe pci_endpoint_test +sleep 2 bar=0 while [ $bar -lt 6 ] @@ -16,7 +18,14 @@ echo echo "Interrupt tests" echo +rmmod pci_endpoint_test +sleep 2 +modprobe pci_endpoint_test irq_type=0 pcitest -l + +rmmod pci_endpoint_test +sleep 2 +modprobe pci_endpoint_test irq_type=1 msi=1 while [ $msi -lt 33 ] @@ -26,9 +35,25 @@ do done echo +rmmod pci_endpoint_test +sleep 2 +modprobe pci_endpoint_test irq_type=2 +msix=1 + +while [ $msix -lt 2049 ] +do + pcitest -x $msix + msix=`expr $msix + 1` +done +echo + echo "Read Tests" echo +rmmod pci_endpoint_test +sleep 2 +modprobe pci_endpoint_test irq_type=1 + pcitest -r -s 1 pcitest -r -s 1024 pcitest -r -s 1025