Received: by 10.213.65.68 with SMTP id h4csp4175637imn; Tue, 10 Apr 2018 10:23:02 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/P89WqHQQWXjKjlfkR1SuzZI8DlboxfWgMpSflPtzNXv9cZ3yo8T+7W31fT5FSkyi6RxDD X-Received: by 2002:a17:902:44c:: with SMTP id 70-v6mr1359085ple.354.1523380982515; Tue, 10 Apr 2018 10:23:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523380982; cv=none; d=google.com; s=arc-20160816; b=FXdnHiXXhzW7iL4b0j7hmcWP6mTxYXP4UYXJm/OHYTwvaUO6cR98ixl73TzFNNYv/P YpFg7eGtZZuxdr6fAZCTRJntuxjk72XJ992k2oTlHfoqiBuhCnIs/VsSh6+YE9/iUb3S NjFNO9ekO/SGSWYaxdyijDoYFuwroCjKbUDC76+5EiSBT+3DqEedCZ3/AU5599vGSy6e RDF+wp5Q+Mt8gVPpxB+ttH9FDQ5pQdKBfLUO31pgmwL3zKVnX94kQ8X7WG7Q3RguLDI8 LtuOglJ/uCKnbskkSOIcCvwS5mU0Sc4ZATXtkQKNmrb0iRG35nbGZ6OoYij9VfSk7Zge ZS0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=ogFc7hskZkDAu32GiDoRtLKe+7JNQ9kuSChymvD9TwE=; b=ejmUed1iKEJF5eYCs+Efs/bx/BvK3fEtnJXUlzLhS8gi7zduZD7DnHqipGFMS3LgU5 lpDWekGE6jVqJKFLCsmglA/AxPe3tFEoU8+utIXMOt0UU+tAMOd4WXKlMsHzLYb4gz7+ iYYuFKaaJilJbk60nZJ3nt01VL8ETsAO3XL9k7gBDMuB01+yyXam1O/RoFTUvr8Ih6cz A/410V7Qwx0rRY+2CXcxqXU8CsfVnyMCSGMQNB7AzdrvgFQ3SAkB7blXEDBfWkMe4LZr rJWGVB5SfZ3ajQXLXueloE5iOk9q0pl0bY47s5THZ8VX4Qlb7Fcj6vgblJiVt1o6M5rR PnWA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t25si2125510pge.714.2018.04.10.10.22.25; Tue, 10 Apr 2018 10:23:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=synopsys.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752250AbeDJRPf (ORCPT + 99 others); Tue, 10 Apr 2018 13:15:35 -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-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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); } -- 2.7.4