From patchwork Wed May 23 20:18:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Meyer X-Patchwork-Id: 919392 X-Patchwork-Delegate: bhelgaas@google.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=none (p=none dis=none) header.from=gigaio.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gigaio-com.20150623.gappssmtp.com header.i=@gigaio-com.20150623.gappssmtp.com header.b="a/TAPImk"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40rkP55blmz9s16 for ; Thu, 24 May 2018 06:18:49 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933737AbeEWUSs (ORCPT ); Wed, 23 May 2018 16:18:48 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:37119 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934835AbeEWUSo (ORCPT ); Wed, 23 May 2018 16:18:44 -0400 Received: by mail-pl0-f67.google.com with SMTP id w19-v6so13686688plq.4 for ; Wed, 23 May 2018 13:18:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gigaio-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=34V4fJr1o872PtTlo8TS+BvpyeGGPbClSovU7ERZvpI=; b=a/TAPImkvuLLJezc5zM5tlkywwr8EjI8xKRm69smXS9l2GV4OxhGqeRM8/RhzGw4vR 6sVmRBRA1RzcJmPK1GT1jNFkJWlvli9JH73jFbhdjUGycq9U+PWX5wWJom+4xTOmP4yL 222NyGvXGuVBjtibrTOKXn+grwpw/i9Rs2pBWFU338VKbNifZ+RkHGGKvAfQcDBi4wtj xXhglPB30q4sojbh7El/xpNrYV3evDX04Joq/5+Qe7vIOWgjtZgAWDjdbUlKriMPsf6O MP7ZdPA/LqiCGaSZR1n32PuVUuI9sd9p5RGQMcm3gS6BXu72RP00q+v7fI6B8gysvUx+ u1tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=34V4fJr1o872PtTlo8TS+BvpyeGGPbClSovU7ERZvpI=; b=Bo6RlI0J+mSmIWMxYhDFSO3bYPI5zosOuslxkSx+JoZFrZrJOCNd7wi6bbzg3lbMf/ TDmt9GgZ9mWEneqKnRPUi8aaP73YpdnXDhwkO1/5tAdkLZHiSD9vIoGFb/Jt/ZDEFG9N mKr18XGAIawr+pDVkTF63USEXk6Hi/KwJUeqCTI9o36CNt62DSms2UFxTnhgnm0YSvTz UjxGlm5gEPoeqnEKAmec4TvF6ek49RdnxuUINaLgrrqop+xm679lvE21w2d9FbVlWyQx AiuiSv4+BkjELqSPp7d/Hm+C3ql+dgeD9VoM9jtBKk69dqiPftl3Duk/xEiys3TqU6cF HBvQ== X-Gm-Message-State: ALKqPwfH9QYoKdS21pn6B8zyVOiSdJoJcQNCowQhBj+xASl2VB3PAf/j IQGUXBlntX3r6iQcPfcxWvVprw== X-Google-Smtp-Source: AB8JxZqLwDPcTpRPmIt2q37ZSJ4+TEOaHgawEXg2KiOkxuUaQN0iK88Fd/zlzK9y2mBgEc3tdHAG4g== X-Received: by 2002:a17:902:bd84:: with SMTP id q4-v6mr4406806pls.254.1527106724376; Wed, 23 May 2018 13:18:44 -0700 (PDT) Received: from stryx3.evonexus.local ([69.43.204.50]) by smtp.gmail.com with ESMTPSA id f78-v6sm37831091pfk.138.2018.05.23.13.18.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 May 2018 13:18:43 -0700 (PDT) From: dmeyer@gigaio.com To: logang@deltatee.com, kurt.schwemmer@microsemi.com, linux-pci@vger.kernel.org, linux-ntb@googlegroups.com Cc: bhelgaas@google.com, jdmason@kudzu.us, dave.jiang@intel.com, allenbh@gmail.com, linux-kernel@vger.kernel.org, Doug Meyer Subject: [PATCH v2 1/2] NTB: Migrate PCI Constants to Cannonical PCI Header Date: Wed, 23 May 2018 13:18:05 -0700 Message-Id: <1527106686-18852-2-git-send-email-dmeyer@gigaio.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1527106686-18852-1-git-send-email-dmeyer@gigaio.com> References: <1527106686-18852-1-git-send-email-dmeyer@gigaio.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Doug Meyer This is the first of two patches to implement a PCI quirk which will allow the Switchtec NTB code to work with the IOMMU turned on. Here, the Microsemi Switchtec PCI vendor and device ID constants are moved to the canonical location in pci_ids.h. Also, Microsemi class constants are replaced with the standard PCI usage. Signed-off-by: Doug Meyer Reviewed-by: Logan Gunthorpe --- drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 3 ++- drivers/pci/switch/switchtec.c | 15 +++++++-------- include/linux/pci_ids.h | 32 ++++++++++++++++++++++++++++++++ include/linux/switchtec.h | 4 ---- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c index f624ae2..5ee5f40 100644 --- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c +++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c @@ -19,6 +19,7 @@ #include #include #include +#include MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver"); MODULE_VERSION("0.1"); @@ -1487,7 +1488,7 @@ static int switchtec_ntb_add(struct device *dev, stdev->sndev = NULL; - if (stdev->pdev->class != MICROSEMI_NTB_CLASSCODE) + if (stdev->pdev->class != (PCI_CLASS_BRIDGE_OTHER << 8)) return -ENODEV; sndev = kzalloc_node(sizeof(*sndev), GFP_KERNEL, dev_to_node(dev)); diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index 47cd0c0..07a03b9 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -1,4 +1,3 @@ -// SPDX-License-Identifier: GPL-2.0 /* * Microsemi Switchtec(tm) PCIe Management Driver * Copyright (c) 2017, Microsemi Corporation @@ -641,7 +640,7 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { reg = ioread16(&stdev->mmio_pff_csr[i].vendor_id); - if (reg != MICROSEMI_VENDOR_ID) + if (reg != PCI_VENDOR_ID_MICROSEMI) break; reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); @@ -1203,7 +1202,7 @@ static void init_pff(struct switchtec_dev *stdev) for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { reg = ioread16(&stdev->mmio_pff_csr[i].vendor_id); - if (reg != MICROSEMI_VENDOR_ID) + if (reg != PCI_VENDOR_ID_MICROSEMI) break; } @@ -1267,7 +1266,7 @@ static int switchtec_pci_probe(struct pci_dev *pdev, struct switchtec_dev *stdev; int rc; - if (pdev->class == MICROSEMI_NTB_CLASSCODE) + if (pdev->class == (PCI_CLASS_BRIDGE_OTHER << 8)) request_module_nowait("ntb_hw_switchtec"); stdev = stdev_create(pdev); @@ -1321,19 +1320,19 @@ static void switchtec_pci_remove(struct pci_dev *pdev) #define SWITCHTEC_PCI_DEVICE(device_id) \ { \ - .vendor = MICROSEMI_VENDOR_ID, \ + .vendor = PCI_VENDOR_ID_MICROSEMI, \ .device = device_id, \ .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ - .class = MICROSEMI_MGMT_CLASSCODE, \ + .class = (PCI_CLASS_MEMORY_OTHER << 8), \ .class_mask = 0xFFFFFFFF, \ }, \ { \ - .vendor = MICROSEMI_VENDOR_ID, \ + .vendor = PCI_VENDOR_ID_MICROSEMI, \ .device = device_id, \ .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ - .class = MICROSEMI_NTB_CLASSCODE, \ + .class = (PCI_CLASS_BRIDGE_OTHER << 8), \ .class_mask = 0xFFFFFFFF, \ } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index cc608fc5..7b04ca95 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -3073,4 +3073,36 @@ #define PCI_VENDOR_ID_OCZ 0x1b85 +#define PCI_VENDOR_ID_MICROSEMI 0x11f8 +#define PCI_DEVICE_ID_MICROSEMI_PFX24XG3 0x8531 +#define PCI_DEVICE_ID_MICROSEMI_PFX32XG3 0x8532 +#define PCI_DEVICE_ID_MICROSEMI_PFX48XG3 0x8533 +#define PCI_DEVICE_ID_MICROSEMI_PFX64XG3 0x8534 +#define PCI_DEVICE_ID_MICROSEMI_PFX80XG3 0x8535 +#define PCI_DEVICE_ID_MICROSEMI_PFX96XG3 0x8536 +#define PCI_DEVICE_ID_MICROSEMI_PSX24XG3 0x8541 +#define PCI_DEVICE_ID_MICROSEMI_PSX32XG3 0x8542 +#define PCI_DEVICE_ID_MICROSEMI_PSX48XG3 0x8543 +#define PCI_DEVICE_ID_MICROSEMI_PSX64XG3 0x8544 +#define PCI_DEVICE_ID_MICROSEMI_PSX80XG3 0x8545 +#define PCI_DEVICE_ID_MICROSEMI_PSX96XG3 0x8546 +#define PCI_DEVICE_ID_MICROSEMI_PAX24XG3 0x8551 +#define PCI_DEVICE_ID_MICROSEMI_PAX32XG3 0x8552 +#define PCI_DEVICE_ID_MICROSEMI_PAX48XG3 0x8553 +#define PCI_DEVICE_ID_MICROSEMI_PAX64XG3 0x8554 +#define PCI_DEVICE_ID_MICROSEMI_PAX80XG3 0x8555 +#define PCI_DEVICE_ID_MICROSEMI_PAX96XG3 0x8556 +#define PCI_DEVICE_ID_MICROSEMI_PFXL24XG3 0x8561 +#define PCI_DEVICE_ID_MICROSEMI_PFXL32XG3 0x8562 +#define PCI_DEVICE_ID_MICROSEMI_PFXL48XG3 0x8563 +#define PCI_DEVICE_ID_MICROSEMI_PFXL64XG3 0x8564 +#define PCI_DEVICE_ID_MICROSEMI_PFXL80XG3 0x8565 +#define PCI_DEVICE_ID_MICROSEMI_PFXL96XG3 0x8566 +#define PCI_DEVICE_ID_MICROSEMI_PFXI24XG3 0x8571 +#define PCI_DEVICE_ID_MICROSEMI_PFXI32XG3 0x8572 +#define PCI_DEVICE_ID_MICROSEMI_PFXI48XG3 0x8573 +#define PCI_DEVICE_ID_MICROSEMI_PFXI64XG3 0x8574 +#define PCI_DEVICE_ID_MICROSEMI_PFXI80XG3 0x8575 +#define PCI_DEVICE_ID_MICROSEMI_PFXI96XG3 0x8576 + #endif /* _LINUX_PCI_IDS_H */ diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h index ec93e93..ab400af 100644 --- a/include/linux/switchtec.h +++ b/include/linux/switchtec.h @@ -19,10 +19,6 @@ #include #include -#define MICROSEMI_VENDOR_ID 0x11f8 -#define MICROSEMI_NTB_CLASSCODE 0x068000 -#define MICROSEMI_MGMT_CLASSCODE 0x058000 - #define SWITCHTEC_MRPC_PAYLOAD_SIZE 1024 #define SWITCHTEC_MAX_PFF_CSR 48 From patchwork Wed May 23 20:18:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Meyer X-Patchwork-Id: 919393 X-Patchwork-Delegate: bhelgaas@google.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=none (p=none dis=none) header.from=gigaio.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gigaio-com.20150623.gappssmtp.com header.i=@gigaio-com.20150623.gappssmtp.com header.b="vxxLHvx0"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40rkPF1sswz9s08 for ; Thu, 24 May 2018 06:18:57 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934382AbeEWUSx (ORCPT ); Wed, 23 May 2018 16:18:53 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:44400 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934825AbeEWUSu (ORCPT ); Wed, 23 May 2018 16:18:50 -0400 Received: by mail-pf0-f194.google.com with SMTP id q22-v6so11037338pff.11 for ; Wed, 23 May 2018 13:18:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gigaio-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Pt6CmKVv7ej6XmQTy57ZYhpuBWJbF5HGDT2csHgyiJE=; b=vxxLHvx0xY5Nt8pTqAjVbCfX97iQS4mK2dX9nu7EJl0CGFx84TCagDPxp3bDDhxkA1 MrHtmqyk17IwUFGW8qgISXoa85sVDnTz+PJGcH4Oku0SfcBe7oMSyQl8NaNpzcb5UCAb 3/JdZ07azW/pol8/H7TuWCoMulD/IWxBG1OID7OhQOMbNuH/aN4pXp2Rk5pX2iObRfQR KHI9xFf9gPnPDHh4Y8RBRBmukW2yYqAYiSAuhTLX7rzkL63sBgUDouJZqLfND4WWZzXt a+7ovklhkG68zIhyDpYz1nx3u51kc+kmQcaDASo5+SMX4eHfA0VUo/v6GouQw4osSwpC 9tEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Pt6CmKVv7ej6XmQTy57ZYhpuBWJbF5HGDT2csHgyiJE=; b=sm/U2xN5+ouriQ5Zwtw7A4bnqj10ndKKzTMJ7nti95b4AyBucMOvesVvOV7K7jOOBw 3GKfbcu9epmFtD31Twm1tz2p8QimyhHEmYhm64ihQxxUZu+ObRWFZfv/gWntL2qOeyBx bPaCFUgpv+r0UdEFdBLQxPK3UOEMKvw1qeDPQT7FsveVRna0eRkrTdK5Fo/9b50588fp ZRJFsRG3aFICEva5OwiqTQumdaWuGOCyw70Tb4R7ufqtJtPOnL7FvqRiC18y9RTJAPXJ RbgP6cG8pvNuJujXbZGKpa5YkRivTujqbyaW0S2zF7/vxeHb2v9s74as5yJ8E4zIda5p CEEg== X-Gm-Message-State: ALKqPwdFKpnPP5CZYIROISCCOTD/csSEzA+jbIAP/YSR0rqkEXQtZ/c2 63Jg8f7B3TDtm375bjhUkW4nBQ== X-Google-Smtp-Source: AB8JxZpQvzSmc924Z+yw7mm5kDgZh6XGrRHBG2LBhGnhnBXwxmRudKl9mACgbRVX2h+MH627uX5KWg== X-Received: by 2002:a62:568f:: with SMTP id h15-v6mr4239449pfj.131.1527106729317; Wed, 23 May 2018 13:18:49 -0700 (PDT) Received: from stryx3.evonexus.local ([69.43.204.50]) by smtp.gmail.com with ESMTPSA id f78-v6sm37831091pfk.138.2018.05.23.13.18.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 May 2018 13:18:48 -0700 (PDT) From: dmeyer@gigaio.com To: logang@deltatee.com, kurt.schwemmer@microsemi.com, linux-pci@vger.kernel.org, linux-ntb@googlegroups.com Cc: bhelgaas@google.com, jdmason@kudzu.us, dave.jiang@intel.com, allenbh@gmail.com, linux-kernel@vger.kernel.org, Doug Meyer Subject: [PATCH v2 2/2] NTB: PCI Quirk to Enable Switchtec NT Functionality with IOMMU On Date: Wed, 23 May 2018 13:18:06 -0700 Message-Id: <1527106686-18852-3-git-send-email-dmeyer@gigaio.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1527106686-18852-1-git-send-email-dmeyer@gigaio.com> References: <1527106686-18852-1-git-send-email-dmeyer@gigaio.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Doug Meyer Here we add the PCI quirk for the Microsemi Switchtec parts to allow DMA access via non-transparent bridging to work when the IOMMU is turned on. This exclusively addresses the ability of a remote NT endpoint to perform DMA accesses through the locally enumerated NT endpoint. Other aspects of the Switchtec NTB functionality, such as interrupts for doorbells and messages are independent of this quirk, and will work whether the IOMMU is on or off. When a requestor on one NT endpoint accesses memory on another NT endpoint, it does this via a devfn proxy ID. Proxy IDs are statically assigned to each NT endpoint by the NTB hardware as part of the release-from-reset sequence prior to PCI enumeration. These proxy IDs cannot be modified dynamically, and are not visible to the host during enumeration. When the Switchtec NTB driver loads it will map local requestor IDs, such as the root complex and transparent bridge DMA engines, to proxy IDs by populating those requestor IDs in hardware mapping table table entries. This establishes a fixed relationship between a requestor ID and a proxy ID. When a peer on a remote NT endpoint performs an access within a particular translation window in it's NT endpoint BAR address space, that access is translated to a DMA request on the local endpoint's bus. As part of the translation process, the original requestor ID has its devfn replaced with the proxy ID, and the bus portion of the BDF is replaced with the bus of the local NT endpoint. Thus, the DMA access from a remote NT endpoint will appear on the local bus to have come from the unknown devfn which the IOMMU will reject. The quirk introduced here interrogates NTB hardware registers for each remote NT endpoint to obtain the proxy IDs that have been assigned to it, and aliases them to the local (enumerated) NT endpoint's device. The IOMMU then accepts the remote proxy IDs as if they were requests coming directly from the enumerated endpoint, giving remote requestors access to memory resources which the local host has made available. Note that the aliasing of the proxy IDs cannot be performed at the driver level given the current IOMMU architecture. Superficially this is because pci_add_dma_alias() symbol is not exported. Functionally, the current IOMMU design requires the aliasing to be performed prior to the creation of IOMMU groups. If a driver were to attempt to use pci_add_dma_alias() in its probe routine it would fail since the IOMMU groups have been set up by that time. If the Switchtec hardware supported dynamic proxy ID (re-)assignment this would be an issue, but it does not. To further clarify static proxy ID assignment: While the requester ID to proxy ID mapping can be dynamically changed, the number and value of proxy IDs given to an NT EP cannot, even for dynamic reconfiguration such as hot-add. Therefore, the chip configuration must account a priori for the proxy IDs needs, considering both static and dynamic system configurations. For example, a port on the chip may not having anything plugged into it at start of day; but it must have a sufficient number of proxy IDs assigned to accommodate the supported devices which may be hot-added. Switchtec NTB functionality with the IOMMU off is unchanged by this quirk. Signed-off-by: Doug Meyer Reviewed-by: Logan Gunthorpe --- drivers/pci/quirks.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2990ad1..4456165 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /* isa_dma_bridge_buggy */ #include "pci.h" @@ -4741,3 +4742,199 @@ static void quirk_gpu_hda(struct pci_dev *hda) PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda); DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda); + +/* + * Microsemi Switchtec NTB uses devfn proxy IDs to move TLPs between + * NT endpoints via the internal switch fabric. These IDs replace the + * originating requestor ID TLPs which access host memory on peer NTB + * ports. Therefore, all proxy IDs must be aliased to the NTB device + * to permit access when the IOMMU is turned on. + */ +static void quirk_switchtec_ntb_dma_alias(struct pci_dev *pdev) +{ + void __iomem *mmio; + struct ntb_info_regs __iomem *mmio_ntb; + struct ntb_ctrl_regs __iomem *mmio_ctrl; + struct sys_info_regs __iomem *mmio_sys_info; + u64 partition_map; + u8 partition; + int pp; + + if (pci_enable_device(pdev)) { + pci_err(pdev, "Cannot enable Switchtec device\n"); + return; + } + + mmio = pci_iomap(pdev, 0, 0); + if (mmio == NULL) { + pci_disable_device(pdev); + pci_err(pdev, "Cannot iomap Switchtec device\n"); + return; + } + + pci_info(pdev, "Setting Switchtec proxy ID aliases\n"); + + mmio_ntb = mmio + SWITCHTEC_GAS_NTB_OFFSET; + mmio_ctrl = (void * __iomem) mmio_ntb + SWITCHTEC_NTB_REG_CTRL_OFFSET; + mmio_sys_info = mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET; + + partition = ioread8(&mmio_ntb->partition_id); + + partition_map = (u64) ioread32((void * __iomem) &mmio_ntb->ep_map); + partition_map |= + ((u64) ioread32((void * __iomem) &mmio_ntb->ep_map + 4)) << 32; + partition_map &= ~(1ULL << partition); + + for (pp = 0; pp < (sizeof(partition_map) * 8); pp++) { + struct ntb_ctrl_regs __iomem *mmio_peer_ctrl; + u32 table_sz = 0; + int te; + + if (!(partition_map & (1ULL << pp))) + continue; + + pci_dbg(pdev, "Processing partition %d\n", pp); + + mmio_peer_ctrl = &mmio_ctrl[pp]; + + table_sz = ioread16(&mmio_peer_ctrl->req_id_table_size); + if (!table_sz) { + pci_warn(pdev, "Partition %d table_sz 0\n", pp); + continue; + } + + if (table_sz > 512) { + pci_warn(pdev, + "Invalid Switchtec partition %d table_sz %d\n", + pp, table_sz); + continue; + } + + for (te = 0; te < table_sz; te++) { + u32 rid_entry; + u8 devfn; + + rid_entry = ioread32(&mmio_peer_ctrl->req_id_table[te]); + devfn = (rid_entry >> 1) & 0xFF; + pci_dbg(pdev, + "Aliasing Partition %d Proxy ID %02d.%d\n", + pp, PCI_SLOT(devfn), PCI_FUNC(devfn)); + pci_add_dma_alias(pdev, devfn); + } + } + + pci_iounmap(pdev, mmio); + pci_disable_device(pdev); +} +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX24XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX32XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX48XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX64XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX80XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFX96XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PSX48XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PSX64XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PSX80XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PSX96XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX24XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX32XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX48XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX64XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX80XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PAX96XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL24XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL32XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL48XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL64XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL80XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXL96XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI24XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI32XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI48XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI64XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI80XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_MICROSEMI, + PCI_DEVICE_ID_MICROSEMI_PFXI96XG3, + PCI_CLASS_BRIDGE_OTHER, 8, + quirk_switchtec_ntb_dma_alias);